zoukankan      html  css  js  c++  java
  • (转)深入理解最强桌面地图控件GMAP.NET --- 百度地图

    GMAP.NET支持了Google, Bing, Ovi, Openstreetmap, Yahoo,GIS等多种地图,但国内的地图支持得比较少。

    不过没有关系,我们可以为GMAP.NET添加百度地图的支持,只要了解了地图加载的原理,就很容易集成进来,

    最重要的是,它是支持离线的,也就是说利用GMAP.NET,我们可以制作各种离线地图供我们桌面应用程序使用,

    这也是我为什么称之为最强地图控件的原因。

    如何在你的程序中使用GMAP.NET百度地图

    整个代码已经提交到 http://ypmap.googlecode.com/ ,有兴趣的朋友可以Check out代码。

    如果要使用的话,首先要参考文章:深入理解最强桌面地图控件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.BaiduMapProvider;//或BaiduSateliteMapProvider
                    this.MainMap.DragButton = MouseButton.Left;
                    this.MainMap.Zoom = 13;
                    this.MainMap.MinZoom = 8;
                    this.MainMap.MaxZoom = 24;
    复制代码

    GMAP.NET百度地图的效果

    普通地图

    卫星地图

     

    百度地图加载原理

    要理解GMAP.NET如何使用百度地图的,那么首先了解下百度地图的加载原理还是有一定的必要。

    我们先用Chrome浏览器打开百度地图,定位到某个地方(例如,重庆),同时打开开发者工具,如下图所示:

    再继续看,原来百度地图就是由这样一张一张的图片构成的,再看看其中一张图片的链接地址:

    http://q5.baidu.com/it/u=x=1450;y=418;z=13;v=014;type=web&fm=44。这几个参数是什么意思呢,其中

    q5应该是分布式服务器的地址,q3,q4也可以;

    u,x,y应该是根据MercatorProjection算法得到的一个值,这个会在理论篇具体阐述;

    z=13是代表当前的Zoom,v是版本号;

    type表示通过浏览器访问,fm是个固定的值。

    那么GMAP.NET也应该根据用户的鼠标位置和当前的缩放级别构造一个url去获取图片。

     

    GMapProvider

    GMAP.NET采取了良好的代码结构,缓存、数据结构都遵循了低耦合-高内聚的原则,每个模块之间的联系

    也都是基于接口进行编程的。同样,地图数据源的接口MapProvider也遵循了这个原则。

    GMapProvider是地图数据源的接口,当客户端在初始化调用this.MainMap.MapProvider = GMapProviders.BaiduMapProvider的时候,

    就会根据不同地图的不同规则进行加载数据了,下面就以百度地图为例说明如何扩展一个地图数据源的接口。

    1).BaiduMapProviderBase

    增加抽象类BaiduMapProviderBase继承GMapProvider

    BaiduMapProviderBase主要完成了三个事情

    初始化了RefereUrl,Copyright等信息,只是在版权上有用;

    返回一MercatorProjection的实例,谈到MercatorProjection,可以参考Google’s tile engine explain, 理论篇会作详细描述;

    初始化Overlays.

    虽然可能现在还不太懂,没有关系,我最开始写的时候也不太懂,但看到基本上所有的Provider都这样写,依样画葫芦就好了。唯一需要注意的是,这里取名叫XXXProviderBase,

    并且是 abstract,原因就在于地图会有卫星和普通地图两种模式,所以肯定会有些公用方法。

    复制代码
        public abstract class BaiduMapProviderBase : GMapProvider
        {
            public BaiduMapProviderBase()
            {
                MaxZoom = null;
                RefererUrl = "http://map.baidu.com";
                Copyright = string.Format("©{0} Baidu 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;
                }
            }
        }
    复制代码

    2).BaiduMapProvider

    增加BaiduMapProvider,继承于BaiduMapProviderBase,并实现GetTileImage方法。其中GetTileImage就是根据当前的鼠标信息pos和缩放比zoom获取图片。

    GetTileImageUsingHttp(url)是根据url获取图片的。OK,现在就可以根据百度地图加载原理去构造url了。

    具体代码如下:

    复制代码
     public class BaiduMapProvider : BaiduMapProviderBase
        {
            ....public override PureImage GetTileImage(GPoint pos, int zoom)
            {
                string url = MakeTileImageUrl(pos, zoom, LanguageStr);
    
                return GetTileImageUsingHttp(url);
            }
    
            string MakeTileImageUrl(GPoint pos, int zoom, string language)
            {
                zoom = zoom - 1;
                var offsetX = Math.Pow(2, zoom);
                var offsetY = offsetX - 1;
    
                var numX = pos.X - offsetX;
                var numY = -pos.Y + offsetY;
    
                zoom = zoom + 1;
                var num = (pos.X + pos.Y)%8 + 1;
                var x = numX.ToString().Replace("-", "M");
                var y = numY.ToString().Replace("-", "M");
    
                //http://q3.baidu.com/it/u=x=721;y=209;z=12;v=014;type=web&fm=44
    string url = string.Format(UrlFormat, num, x, y, zoom, "014", "web", "44");
                Console.WriteLine("url:" + url);
                return url;
            }
    
            static readonly string UrlFormat = "http://q{0}.baidu.com/it/u=x={1};y={2};z={3};v={4};type={5}&fm={6}";
            
        }
    复制代码

     原文链接:http://www.cnblogs.com/enjoyeclipse/archive/2013/01/14/2859026.html

  • 相关阅读:
    14_java之变量|参数|返回值|修饰符
    NYOJ 202 红黑树 (二叉树)
    NYOJ 138 找球号(二) (哈希)
    NYOJ 136 等式 (哈希)
    NYOJ 133 子序列 (离散化)
    NYOJ 129 树的判定 (并查集)
    NYOJ 117 求逆序数 (树状数组)
    NYOJ 93 汉诺塔 (数学)
    HDU 2050 折线分割平面 (数学)
    天梯赛L2-008 最长对称子串 (字符串处理)
  • 原文地址:https://www.cnblogs.com/plRobotics-RD-Center/p/4008898.html
Copyright © 2011-2022 走看看