Google 地图下载工具 (C#)

这是一个用于下载 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();
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/coolypf/article/details/8563894