这是一个用于下载 Google 地图的小工具,相关内容参见
https://on4wp7.codeplex.com/ 。
- //
- // Google Map Tiles Downloader in C# by coolypf
- // No rights reserved, neither warranty nor guarantee
- //
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Net;
- namespace GMapsDownloader
- {
- class Program
- {
- const double EarthRadius = 6378137;
- const double MinLatitude = -85.05112878;
- const double MaxLatitude = 85.05112878;
- const double MinLongitude = -180;
- const double MaxLongitude = 180;
- const string NameFormat = "{0}-{1}-{2}.png";
- const string TileSource = "https://mts{0}.google.com/vt/lyrs=m@207000000&hl=zh-CN&gl=CN&src=app&x={1}&y={2}&z={3}&s={4}";
- const string SourceTail = "Galileo";
- static Random rng = new Random();
- static double Clip(double n, double minValue, double maxValue)
- {
- return Math.Min(Math.Max(n, minValue), maxValue);
- }
- static void LatLongToTileXY(double latitude, double longitude, int levelOfDetail, out int tileX, out int tileY)
- {
- double x = (longitude + 180) / 360;
- double sinLatitude = Math.Sin(latitude * Math.PI / 180);
- double y = 0.5 - Math.Log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI);
- uint mapSize = 1u << levelOfDetail;
- tileX = (int)Clip(x * mapSize + 0.5, 0, mapSize - 1);
- tileY = (int)Clip(y * mapSize + 0.5, 0, mapSize - 1);
- }
- static bool Validate(int x, int y, int l)
- {
- bool ret = false;
- try
- {
- Bitmap bmp = new Bitmap(string.Format(NameFormat, x, y, l));
- ret = (bmp.Height == 256 && bmp.Width == 256);
- bmp.Dispose();
- }
- catch (Exception) { }
- return ret;
- }
- static void Download(int x, int y, int l)
- {
- try
- {
- WebClient client = new WebClient();
- client.Headers.Add("user-agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:21.0) Gecko/20130109 Firefox/21.0");
- string loc = string.Format(TileSource, rng.Next(4), x, y, l,
- SourceTail.Substring(0, rng.Next(SourceTail.Length)));
- string name = string.Format(NameFormat, x, y, l);
- client.DownloadFile(loc, name);
- }
- catch (Exception ex)
- {
- Console.WriteLine();
- Console.WriteLine(ex.Message);
- }
- }
- static void Main(string[] args)
- {
- try
- {
- Console.WriteLine("Google Map Tiles Downloader");
- Console.WriteLine("lat1, long1 lat2, long2 level");
- double[] array = new double[4];
- int level = 1, i = 0;
- string[] splits = Console.ReadLine().Split(' ', ',');
- foreach (string s in splits)
- {
- if (s.Trim() == "")
- continue;
- if (i < 4) array[i++] = double.Parse(s);
- else level = int.Parse(s);
- }
- double lat1 = Clip(array[0], MinLatitude, MaxLatitude);
- double lat2 = Clip(array[2], MinLatitude, MaxLatitude);
- double long1 = Clip(array[1], MinLongitude, MaxLongitude);
- double long2 = Clip(array[3], MinLongitude, MaxLongitude);
- if (level < 1) level = 1;
- if (level > 19) level = 19;
- Console.WriteLine("Generating download list...");
- List<int> list = new List<int>();
- for (i = 1; i <= level; ++i)
- {
- int x1, y1, x2, y2;
- LatLongToTileXY(lat1, long1, i, out x1, out y1);
- LatLongToTileXY(lat2, long2, i, out x2, out y2);
- for (int u = x1; u <= x2; ++u)
- for (int v = y1; v <= y2; ++v)
- {
- list.Add(u);
- list.Add(v);
- list.Add(i);
- }
- }
- Console.WriteLine(list.Count / 3 + " in list");
- Console.WriteLine("Validating existing tiles...");
- List<int> dlist = new List<int>();
- for (i = 0; i < list.Count; i += 3)
- {
- int x = list[i], y = list[i + 1], l = list[i + 2];
- if (Validate(x, y, l))
- continue;
- dlist.Add(x);
- dlist.Add(y);
- dlist.Add(l);
- }
- Console.WriteLine(dlist.Count / 3 + " to download");
- if (dlist.Count == 0)
- return;
- Console.WriteLine("Press ENTER");
- Console.ReadLine();
- for (i = 0; i < dlist.Count; i += 3)
- {
- int x = dlist[i], y = dlist[i + 1], l = dlist[i + 2];
- Console.Write("\rDownloading " + i / 3);
- Download(x, y, l);
- }
- Console.WriteLine();
- Console.WriteLine("Done.");
- }
- catch (Exception ex)
- {
- Console.WriteLine();
- Console.WriteLine(ex.Message);
- Console.WriteLine(ex.Source);
- Console.WriteLine(ex.StackTrace);
- Console.WriteLine();
- }
- }
- }
- }