如何在你的程序中使用GMAP.NET SOSO地图
国内的地图都差不多,我觉得做得最好的是高德,下一篇会结合理论章节讲讲为什么,至少从GMAP.NET的角度讲讲为什么。
this.MainMap.Position = new PointLatLng(double.Parse(ConfigurationManager.AppSettings["defaultLat"]), double.Parse(ConfigurationManager.AppSettings["defaultLng"])); this.MainMap.MapProvider.Area = new RectLatLng(30.981178, 105.351914, 2.765142, 4.120995); this.MainMap.BoundsOfMap = new RectLatLng(30.981178, 105.351914, 2.765142, 4.120995); this.MainMap.Manager.Mode = AccessMode.CacheOnly; this.MainMap.MapProvider = GMapProviders.SosoMapProvider; this.MainMap.DragButton = MouseButton.Left; this.MainMap.Zoom = 13; this.MainMap.MinZoom = 8; this.MainMap.MaxZoom = 24;
GMAP.NET SOSO地图的效果
普通地图
卫星地图
搜搜地图加载原理
同样,要理解如何加载soso地图,也要理解下加载原理,我们用Chrome打开 map.soso.com,随便定位一个地址,打开开发者工具:
可以发现,搜搜地图也是根据url一张一张拼接而来的,以链接http://p3.map.soso.com/maptilesv2/11/102/75/1633_1200.png为例,每个参数的含义如下:
p0也是分布式站点的一个,p1,p2,p3都可以;
maptilesv2是版本号的东西,
11是缩放级别,
1633是鼠标所在地图网格的X,1200是地图网格的Y (关于地图网格,参考下Google Tile's Engine Explaine),以后的理论章节会专门讲这个东西。
102 = 1633/16后最接近的整数值,75 = 1200/16后最接近的整数值。
SOSOMapProvider
同上一篇百度地图的操作流程一样,也采用下面的流程添加SOSOMapProvider的支持。
1)添加abstract class SosoMapProviderBase
由于搜搜也有普通地图和卫星地图,因此提供了一个有公共方法的抽象类,可以复用。
public abstract class SosoMapProviderBase : GMapProvider { public SosoMapProviderBase() { MaxZoom = null; RefererUrl = "http://map.soso.com"; Copyright = string.Format("©{0} Tencent Corporation, ©{0} NAVTEQ, ©{0} Image courtesy of NASA", DateTime.Today.Year); } public override PureProjection Projection { get { return MercatorProjection.Instance; } } GMapProvider[] overlays; public override GMapProvider[] Overlays { get { if (overlays == null) { overlays = new GMapProvider[] { this }; } return overlays; } } protected override bool CheckTileImageHttpResponse(System.Net.HttpWebResponse response) { var pass = base.CheckTileImageHttpResponse(response); if (!pass) { return response.ResponseUri.AbsoluteUri.EndsWith(".png") || response.ResponseUri.AbsoluteUri.EndsWith(".JPG"); } return true; } }
2).SoSoMapProvider
主要是MakeTileImageUrl方法,就是根据搜索地图加载原理来的:本质上就是要构造一个获取图片的url链接。如果是卫星地图,只要将UrlFormat从
http://p0.map.soso.com/maptilesv2/{0}/{1}/{2}/{3}_{4}.png
替换成
http://p1.map.soso.com/sateTiles/{0}/{1}/{2}/{3}_{4}.jpg
即可。
public class SosoMapProvider: SosoMapProviderBase { public static readonly SosoMapProvider Instance; readonly Guid id = new Guid("30D069B3-F6A5-4feb-9B5E-84CBF1E34F34"); public override Guid Id { get { return id; } } readonly string name = "SoSoMap"; public override string Name { get { return name; } } static SosoMapProvider() { Instance = new SosoMapProvider(); } public override PureImage GetTileImage(GPoint pos, int zoom) { string url = MakeTileImageUrl(pos, zoom, LanguageStr); return GetTileImageUsingHttp(url); } static int[] _scope = new int[]{0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 0, 3, 0, 7, 0, 7, 0, 15, 0, 15, 0, 31, 0, 31, 0, 63, 4, 59, 0, 127, 12, 115, 0, 225, 28, 227, 356, 455, 150, 259, 720, 899, 320, 469, 1440, 1799, 650, 929, 2880, 3589, 1200, 2069, 5760, 7179, 2550, 3709, 11520, 14349, 5100, 7999, 23060, 28689, 10710, 15429, 46120, 57369, 20290, 29849, 89990, 124729, 41430, 60689, 184228, 229827, 84169, 128886}; string MakeTileImageUrl(GPoint pos, int zoom, string language) { var f = zoom*4; var i = _scope[f++]; var j = _scope[f++]; var l = _scope[f++]; var scope = _scope[f]; if (pos.X >= i && pos.X <= j && pos.Y >= l && pos.Y <= scope) { pos.Y = (long) (Math.Pow(2, zoom) - 1 - pos.Y); } //http://p0.map.soso.com/maptilesv2/11/102/74/1633_1198.png string url = string.Format(UrlFormat, zoom, Math.Floor((decimal)(pos.X / 16)), Math.Floor((decimal)(pos.Y / 16)), pos.X, pos.Y); Console.WriteLine("url:" + url); return url; } static readonly string UrlFormat = "http://p0.map.soso.com/maptilesv2/{0}/{1}/{2}/{3}_{4}.png"; }