找回密码
 FreeOZ用户注册
查看: 7843|回复: 11
打印 上一主题 下一主题

Google等离线地图下载方法解析

[复制链接]
跳转到指定楼层
1#
发表于 23-6-2010 15:03:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?FreeOZ用户注册

x
在使用Google Map, Microsoft Map 等在线地图时,常常想知道这些地图在服务器上是如何存放的,目前大部分地图服务器都是将地图以图片存储以提高响应速度。 一般大小为256X256个像素。

地图分片原理 http://msdn.microsoft.com/en-us/library/bb259689.aspx

如果知道每个图片的URL,自己写个地图下载软件并不困难。从而做成离线地图。

下面程序片段给出了常用地图服务器上地图图片存取的URL计算方法。
  1. using System.Collections.Generic;
  2. using System.Text;

  3. namespace MapTileURL
  4. {
  5.     class Program
  6.     {
  7.         private static Dictionary<string, string> MapTypeURLs = new Dictionary<string, string>
  8.         {
  9.             { "GoogleSatURL", "http://khm{GOOG_DIGIT}.google.com/kh/v=58&x={X}&y={Y}&z={ZOOM}&s={GALILEO}" },
  10.             { "GoogleMapURL", "http://mt{GOOG_DIGIT}.google.com/vt/lyrs=m@121&hl=en&x={X}&y={Y}&z={ZOOM}&s={GALILEO}" },
  11.             { "GoogleHybURL", "http://mt{GOOG_DIGIT}.google.com/vt/lyrs=h@121&hl=en&x={X}&y={Y}&z={ZOOM}&s={GALILEO}" },
  12.             { "GoogleTerURL", "http://mt{GOOG_DIGIT}.google.com/vt/lyrs=t@108,r@121&hl=en&x={X}&y={Y}&z={ZOOM}&s={GALILEO}" },
  13.             { "GoogleChinaURL", "http://mt{GOOG_DIGIT}.google.cn/vt/lyrs=m@121&hl=en&gl=cn&x={X}&y={Y}&z={ZOOM}&s={GALILEO}" },
  14.             { "YahooMapURL", "http://maps{Y_DIGIT}.yimg.com/hx/tl?v=4.3&.intl=en&x={X}&y={YAHOO_Y}&z={YAHOO_ZOOM}&r=1" },
  15.             { "YahooSatURL", "http://maps{Y_DIGIT}.yimg.com/ae/ximg?v=1.9&t=a&s=256&.intl=en&x={X}&y={YAHOO_Y}&z={YAHOO_ZOOM}&r=1" },
  16.             { "YahooInMapURL", "http://maps.yimg.com/hw/tile?locale=en&imgtype=png&yimgv=1.2&v=4.1&x={X}&y={YAHOO_Y}&z={YAHOO_ZOOM_2}" },
  17.             { "YahooInHybURL", "http://maps.yimg.com/hw/tile?imgtype=png&yimgv=0.95&t=h&x={X}&y={YAHOO_Y}&z={YAHOO_ZOOM_2}" },
  18.             { "YahooHybURL", "http://maps{Y_DIGIT}.yimg.com/hx/tl?v=4.3&t=h&.intl=en&x={X}&y={YAHOO_Y}&z={YAHOO_ZOOM}&r=1" },
  19.             { "MicrosoftBrMapURL", "http://imakm{MS_DIGITBR}.maplink3.com.br/maps.ashx?v={QUAD}|t&call=2.2.4" },
  20.             { "MicrosoftHybURL", "http://ecn.t{MS_DIGIT}.tiles.virtualearth.net/tiles/h{QUAD}.png?g=441&mkt=en-us&n=z" },
  21.             { "MicrosoftSatURL", "http://ecn.t{MS_DIGIT}.tiles.virtualearth.net/tiles/a{QUAD}.png?g=441&mkt=en-us&n=z" },
  22.             { "MicrosoftMapURL", "http://ecn.t{MS_DIGIT}.tiles.virtualearth.net/tiles/r{QUAD}.png?g=441&mkt=en-us&n=z" },
  23.             { "MicrosoftTerURL", "http://ecn.t{MS_DIGIT}.tiles.virtualearth.net/tiles/r{QUAD}.png?g=441&mkt=en-us&shading=hill&n=z" },
  24.             { "OpenStreetMapURL", "http://tile.openstreetmap.org/{ZOOM}/{X}/{Y}.png" },
  25.             { "OSMARenderURL", "http://tah.openstreetmap.org/Tiles/tile/{ZOOM}/{X}/{Y}.png" },
  26.             { "OpenAerialMapURL", "http://tile.openaerialmap.org/tiles/?v=mgm&layer=openaerialmap-900913&x={X}&y={Y}&zoom={OAM_ZOOM}" },
  27.             { "OpenCycleMapURL", "http://andy.sandbox.cloudmade.com/tiles/cycle/{ZOOM}/{X}/{Y}.png" }

  28.         };

  29.         readonly static char[] Lookup = new[] { 'q', 't', 'r', 's' };

  30.         public static string GetQuadtreeFromXYZoom(int x, int y, int zoom)
  31.         {
  32.             var quad = new StringBuilder();
  33.             for (int i = 0; i < zoom; i++)
  34.             {
  35.                 int rx = x % 2;
  36.                 int ry = y % 2;
  37.                 x /= 2;
  38.                 y /= 2;
  39.                 quad.Insert(0, Lookup[rx * 2 + ry]);
  40.             }
  41.             quad.Insert(0, 't');
  42.             return quad.ToString();
  43.         }


  44.         public static string BuildUrl(string tileType, int x,int y,int zoom)
  45.         {
  46.      
  47.             string url = "";

  48.             switch (tileType)
  49.             {
  50.                 case "GoogleSat":
  51.                 case "GoogleSatH":
  52.                     url = MapTypeURLs["GoogleSatURL"];
  53.                     break;
  54.                 case "GoogleMap":
  55.                     url = MapTypeURLs["GoogleMapURL"];
  56.                     break;
  57.                 case "GoogleHyb":
  58.                     url = MapTypeURLs["GoogleHybURL"];
  59.                     break;
  60.                 case "GoogleTer":
  61.                     url = MapTypeURLs["GoogleTerURL"];
  62.                     break;
  63.                 case "GoogleChina":
  64.                     url = MapTypeURLs["GoogleChinaURL"];
  65.                     break;
  66.                 case "MicrosoftMap":
  67.                     url = MapTypeURLs["MicrosoftMapURL"];
  68.                     break;
  69.                 case "MicrosoftSat":
  70.                     url = MapTypeURLs["MicrosoftSatURL"];
  71.                     break;
  72.                 case "MicrosoftHyb":
  73.                     url = MapTypeURLs["MicrosoftHybURL"];
  74.                     break;
  75.                 case "MicrosoftTer":
  76.                     url = MapTypeURLs["MicrosoftTerURL"];
  77.                     break;
  78.                 case "MicrosoftBrMap":
  79.                     if (zoom <= 10)
  80.                         url =  MapTypeURLs["MicrosoftMapURL"];
  81.                     else
  82.                         url = MapTypeURLs["MicrosoftBrMapURL"];
  83.                     break;
  84.                 case "YahooMap":
  85.                     url = MapTypeURLs["YahooMapURL"];
  86.                     break;
  87.                 case "YahooSat":
  88.                 case "YahooSatH":
  89.                 case "YahooSatH2":
  90.                     url = MapTypeURLs["YahooSatURL"];
  91.                     break;
  92.                 case "YahooHyb":
  93.                     url = MapTypeURLs["YahooHybURL"];
  94.                     break;
  95.                 case "YahooInMap":
  96.                     url = MapTypeURLs["YahooInMapURL"];
  97.                     break;
  98.                 case "YahooInHyb":
  99.                     url = MapTypeURLs["YahooInHybURL"];
  100.                     break;
  101.                 case "OpenStreetMap":
  102.                     url = MapTypeURLs["OpenStreetMapURL"];
  103.                     break;
  104.                 case "OSMARender":
  105.                     url = MapTypeURLs["OSMARenderURL"];
  106.                     break;
  107.                 case "OpenAerialMap":
  108.                     url = MapTypeURLs["OpenAerialMapURL"];
  109.                     break;
  110.                 case "OpenCycleMap":
  111.                     url = MapTypeURLs["OpenCycleMapURL"];
  112.                     break;
  113.             }

  114.      
  115.             string quadcode = "";
  116.             for (int i = (int)zoom - 1; i >= 0; i--)
  117.                 quadcode = quadcode + (((((y >> i) & 1) << 1) + ((x >> i) & 1)));

  118.             url = url.Replace("{X}", x.ToString());
  119.             url = url.Replace("{Y}", y.ToString());
  120.             url = url.Replace("{Z}", ((int)zoom).ToString());
  121.             url = url.Replace("{ZOOM}", ((int)zoom).ToString());
  122.             url = url.Replace("{QUAD}", quadcode);

  123.             url = url.Replace("{YAHOO_Y}", (((1 << ((int)zoom)) >> 1) - 1 - y).ToString());
  124.             url = url.Replace("{YAHOO_ZOOM}", ((int)zoom + 1).ToString());
  125.             url = url.Replace("{YAHOO_ZOOM_2}", (17 - (int)zoom + 1).ToString());
  126.             url = url.Replace("{OAM_ZOOM}", (17 - (int)zoom).ToString());

  127.             url = url.Replace("{GOOG_DIGIT}", ((x + y) & 3).ToString());
  128.             url = url.Replace("{GOOG_QUAD}", GetQuadtreeFromXYZoom(x, y, zoom));
  129.             url = url.Replace("{MS_DIGITBR}", ((((y & 1) << 1) + (x & 1)) + 1).ToString());
  130.             url = url.Replace("{MS_DIGIT}", ((((y & 3) << 1) + (x & 1))).ToString());
  131.             url = url.Replace("{Y_DIGIT}", ((x + y + zoom) % 3 +1).ToString());

  132.             url = url.Replace("{GALILEO}", "Galileo".Substring(0, ((3 * x + y) & 7)));

  133.             // support old style {} vars
  134.             url = url.Replace("QQQQ", GetQuadtreeFromXYZoom(x,y,zoom));
  135.             url = url.Replace("XXXX", x.ToString());
  136.             url = url.Replace("YYYY", y.ToString());
  137.             url = url.Replace("ZZZZ", (17 - (int)zoom).ToString());
  138.             url = url.Replace("{OSM_ZOOM}", ((int)zoom).ToString());
  139.             url = url.Replace("{MS_QUADCODE}", quadcode);
  140.             url = url.Replace("*", ((x+y+zoom) %4).ToString());

  141.             return url;
  142.         }

  143.         static void Main(string[] args)
  144.         {

  145.             string url = BuildUrl("GoogleMap", 1, 1, 1);
  146.             //return http://mt2.google.com/vt/lyrs=m@121&hl=en&x=1&y=1&z=1&s=Gali
  147.         }
  148.     }
  149. }
复制代码
例子中取出 google map ,在 zoom=1 及 x=1,y=1是的图片。

http://mt2.google.com/vt/lyrs=m@ ... &z=1&s=Gali


                               
登录/注册后可看大图


[ 本帖最后由 trisun 于 23-6-2010 15:07 编辑 ]

评分

参与人数 1威望 +30 收起 理由
coredump + 30 你太有才了!

查看全部评分

回复  

使用道具 举报

2#
发表于 23-6-2010 19:52:07 | 只看该作者

回复 #1 trisun 的帖子

把gmap地图搬到本地,这想法太有才了
回复  

使用道具 举报

3#
发表于 23-6-2010 21:25:26 | 只看该作者
LZ算过如果保存悉尼的所有level,到底要多大存储吗? 有哪位下载了,共享一下。呵呵。
回复  

使用道具 举报

4#
 楼主| 发表于 24-6-2010 12:47:21 | 只看该作者
180 M 左右。几万片到几十万片,下载很费时间的, 下载的Level 越多,片数几何级数增加。

[ 本帖最后由 trisun 于 24-6-2010 12:55 编辑 ]

评分

参与人数 1威望 +30 收起 理由
coredump + 30 你太有才了!

查看全部评分

回复  

使用道具 举报

5#
 楼主| 发表于 24-6-2010 13:09:53 | 只看该作者

GNavigator lite

http://store.ovi.com/content/21464

Guidebee Navigatior Lite

by: Guidebee

City guides & Maps - 0.67 MB

Mobile World Map, GPS Compass, MSN Messenger, IP Search, Find address, Get Direction

这个支持离线地图。

GNavigator.rar

495.78 KB, 下载次数: 5

user manual

评分

参与人数 1威望 +30 收起 理由
ubuntuhk + 30 你太有才了!

查看全部评分

回复  

使用道具 举报

6#
 楼主| 发表于 25-6-2010 00:09:39 | 只看该作者
有需要下载工具的请到
   http://www.mapdigit.com/forum/vi ... &extra=page%3D1下载
   这个地图可以直接用于 Gnavigator lite

评分

参与人数 1威望 +30 收起 理由
coredump + 30 你太有才了!

查看全部评分

回复  

使用道具 举报

7#
发表于 25-6-2010 01:02:35 | 只看该作者
感觉是个好资源,

可是貌似不太容易上手,

我能把地图下到电脑上,然后很容易的看我的路线吗?
回复  

使用道具 举报

8#
发表于 25-6-2010 01:16:03 | 只看该作者

回复 #7 sundaliang 的帖子

呵呵,这个地图可以供有兴趣研究地图的同学用,如果要用来查找新路,还是得用online的方式或者装个tomtom之类的。
回复  

使用道具 举报

9#
发表于 25-6-2010 13:43:16 | 只看该作者
这个思想挺有意思。比如,要搞个显示位置的东西,可以把一个区域的各个level的tiles都下载,然后根据经纬度按照LZ给的链接里的方法,显示附近的tiles和位置。应该可行吧。
回复  

使用道具 举报

10#
发表于 25-6-2010 14:57:23 | 只看该作者

回复 #9 GPS 的帖子

当然可行,绝大部分地图软件都是这么干的
回复  

使用道具 举报

11#
发表于 25-6-2010 15:53:43 | 只看该作者
牛啊...
回复  

使用道具 举报

12#
发表于 25-6-2010 16:12:28 | 只看该作者
itouch 上就可以装离线地图,用googledownloadtool工具
回复  

使用道具 举报

您需要登录后才可以回帖 登录 | FreeOZ用户注册

本版积分规则

小黑屋|手机版|Archiver|FreeOZ论坛

GMT+10, 20-4-2024 08:28 , Processed in 0.056206 second(s), 35 queries , Gzip On, Redis On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表