Skip to content

Instantly share code, notes, and snippets.

@understar
Forked from praeclarum/TileSticher.cs
Created April 26, 2014 08:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save understar/11315238 to your computer and use it in GitHub Desktop.
Save understar/11315238 to your computer and use it in GitHub Desktop.
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