-
-
Save arkty/77dd03d1f50bf8a93959 to your computer and use it in GitHub Desktop.
Downloads and stitches map tiles
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Net; | |
using System.IO; | |
using Gdk; | |
namespace TileSticher | |
{ | |
class App | |
{ | |
public static int Main (string[] args) | |
{ | |
if (args.Length != 5) { | |
Console.WriteLine ("TileSticher.exe latitude longitude zoom numHorizontal numVertical"); | |
return 1; | |
} | |
// | |
// Get the root tile | |
// | |
var latitude = double.Parse (args [0]); | |
var longitude = double.Parse (args [1]); | |
var zoom = int.Parse (args [2]); | |
var numHorizontal = int.Parse (args [3]); | |
var numVertical = int.Parse (args [4]); | |
var t = GetTileIndex (latitude, longitude, zoom); | |
// | |
// Download all the tiles | |
// | |
var style = SatelliteUrlTemplate; | |
var xo = -numHorizontal / 2; | |
var yo = -numVertical / 2; | |
for (var i = 0; i < numHorizontal; i++) { | |
for (var j = 0; j < numVertical; j++) { | |
var index = new Point (t.X + i + xo, t.Y + j + yo); | |
DownloadTile (style, index, zoom); | |
} | |
} | |
// | |
// Merge them | |
// | |
var rootImage = LoadTile (style, t, zoom); | |
var width = rootImage.Width; | |
var height = rootImage.Height; | |
var outputWidth = width * numHorizontal; | |
var outputHeight = height * numVertical; | |
var output = new Pixbuf (Colorspace.Rgb, false, 8, outputWidth, outputHeight); | |
for (var i = 0; i < numHorizontal; i++) { | |
for (var j = 0; j < numVertical; j++) { | |
var index = new Point (t.X + i + xo, t.Y + j + yo); | |
using (var image = LoadTile (style, index, zoom)) { | |
image.Composite ( | |
output, | |
width * i, height * j, | |
width, height, | |
width * i, height * j, | |
1, 1, | |
InterpType.Bilinear, 255); | |
} | |
} | |
} | |
output.Save ("Poop.png", "png"); | |
Console.WriteLine ("Created {0}x{1} Poop.png", outputWidth, outputHeight); | |
return 0; | |
} | |
static Pixbuf LoadTile (string style, Point index, int zoom) | |
{ | |
return new Pixbuf (GetTileFilename (style, index, zoom)); | |
} | |
static string GetTileFilename (string style, Point index, int zoom) | |
{ | |
return string.Format ("{0}-{1}-{2}-{3}.png", index.X, index.Y, zoom, style.Length); | |
} | |
static void DownloadTile (string style, Point index, int zoom) | |
{ | |
var filename = GetTileFilename (style, index, zoom); | |
if (File.Exists (filename)) | |
return; | |
var url = string.Format (style, index.X, index.Y, zoom); | |
Console.WriteLine ("Downloading {0}", url); | |
var web = new WebClient (); | |
web.Headers.Add ("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)"); | |
web.DownloadFile (url, filename); | |
} | |
const string MapUrlTemplate = "https://www.google.com/maps/vt/pb=!1m4!1m3!1i{2}!2i{0}!3i{1}!2m3!1e0!2sm!3i258145710"; | |
const string SatelliteUrlTemplate = "https://khms2.google.com/kh/v=147&x={0}&y={1}&z={2}"; | |
static Point GetTileIndex (double latitude, double longitude, int zoom) | |
{ | |
var lat_rad = latitude / 180 * Math.PI; | |
var n = 1 << zoom; | |
var xtile = n * ((longitude + 180) / 360); | |
var ytile = n * (1 - (Math.Log (Math.Tan (lat_rad) + 1/Math.Cos (lat_rad)) / Math.PI)) / 2; | |
return new Point ((int)xtile, (int)ytile); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment