DotSpatial如何加载GeoServer谷歌 百度腾讯的WMS地图

Posted 岬淢箫声

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DotSpatial如何加载GeoServer谷歌 百度腾讯的WMS地图相关的知识,希望对你有一定的参考价值。

转载请注明来源:http://blog.csdn.net/caoshiying

首先说明一下,这篇文章讲解的是WMS地图,不是WMTS地图,讲的不是瓦片索引计算方法与坐标转换。朋友们在动手之前需要申请好腾讯的开发密钥以及百度的开发密钥,在局域网中搭建好GeoServer服务器。百度的开发密钥不需要高级认证。我的GeoServer服务浏览效果如下:


开篇以加载GeoServer的地图为例说明加载WMS的方法。考虑到WMS地图的本质是从网络上得到一张当前视野的图片,GeoServer、谷歌、百度、腾讯的WMS地图存在相同点,只是URL等细节不同。因上抽像出一个StaticImageLayer类型,代码如下:

using DotSpatial.Controls;
using DotSpatial.Data;
using DotSpatial.Symbology;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace wms

    abstract class StaticImageLayer : Layer, IMapLayer
    
        public abstract string UrlFormat  get; 

        private Bitmap syncBuffer;
        public int ZoomLevel  get; set; 
        public Size WindowSize  get; set; 

        public StaticImageLayer()
        
            WindowSize = new Size();
            ZoomLevel = 0;
        

        public void DrawRegions(MapArgs args, List<Extent> regions)
        
            foreach (var region in regions)
            
                if (region.Width <= 0 || region.Height <= 0)
                    continue;
                if (WindowSize.Width <= 0 || WindowSize.Height <= 0 || ZoomLevel <= 0)
                    continue;
                var bmp = GetBitmap(region);
                if (bmp == null)
                    continue;
                args.Device.DrawImage(bmp, 0, 0);
            
        

        protected virtual Image GetBitmap(Extent e)
        
            string geoserverUrl = GetURL(e);
            Console.WriteLine(geoserverUrl);
            var wc = new WebClient();
            var bytes = wc.DownloadData(geoserverUrl);
            if (bytes.Length < 400)
            
                var text = Encoding.GetEncoding("UTF-8").GetString(bytes);
                Console.WriteLine(text);
                return null;
            
            var str = new MemoryStream(bytes);
            syncBuffer = new Bitmap(str);
            str.Close();
            str.Dispose();
            return syncBuffer;
        

        protected virtual string GetURL(Extent e)
        
            return string.Format(UrlFormat, e.Center.X, e.Center.Y, WindowSize.Width, WindowSize.Height, ZoomLevel);
        

    

本类设置为象类型,不允许实例化。变化核心在于URL和图像获取算法,因此把这两个方法设为虚方法。不同的地图,比例尺、分辨率、坐标系是不同的,因此需要新建一个地图函数类型以支持不同的地图行为,代码如下:

using DotSpatial.Controls;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace wms

    class StaticImageFunction : MapFunction
    
        StaticImageLayer baiduLayer;
        Point firstPoint;
        Point lastPoint;
        public StaticImageFunction(IMap mapCtrl, StaticImageLayer layer)
            : base(mapCtrl)
        
            this.baiduLayer = layer;
        

        protected override void OnMouseWheel(GeoMouseArgs e)
        
            if (e.Delta > 0)
            
                baiduLayer.ZoomLevel++;
            
            else
            
                baiduLayer.ZoomLevel--;
            
            if (baiduLayer.ZoomLevel < 3)
                baiduLayer.ZoomLevel = 3;
            if (baiduLayer.ZoomLevel > 19)
                baiduLayer.ZoomLevel = 19;
            base.OnMouseWheel(e);
        

        protected override void OnMouseDown(GeoMouseArgs e)
        
            e.Handled = true;
            firstPoint = e.Location;
            base.OnMouseDown(e);
        

        protected override void OnMouseUp(GeoMouseArgs e)
        
            e.Handled = true;
            lastPoint = e.Location;
            base.OnMouseUp(e);
            
        

        protected override void OnMouseMove(GeoMouseArgs e)
        
            base.OnMouseMove(e);
        
    

这个StaticImageFunction其实只实现了百度地图的缩放行为。朋友们有不同的需求请参照此方法自行实现。
GeoServer图层的实现代码如下:

using DotSpatial.Controls;
using DotSpatial.Data;
using DotSpatial.Symbology;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace wms

    class GeoserverStaticImageLayer : StaticImageLayer
    
        string geoserverUrlFormat = "http://192.168.1.4:8080/geoserver/wms?bbox=0,1,2,3&styles=&Format=image/png&request=GetMap&layers=bj54:china&width=4&height=5&srs=EPSG:2432";

        public GeoserverStaticImageLayer()
        
            LegendText = "Geoserver WMS地图";
        

        protected override string GetURL(Extent e)
        
            return string.Format(geoserverUrlFormat, e.MinX, e.MinY, e.MaxX, e.MaxY, WindowSize.Width, WindowSize.Height);
        

        public override string UrlFormat
        
            get  return geoserverUrlFormat; 
        
    

百度WMS图层的实现代码如下:

using DotSpatial.Controls;
using DotSpatial.Data;
using DotSpatial.Symbology;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace wms

    class BaiduStaticImageLayer : StaticImageLayer
    
        string urlFormat = "http://api.map.baidu.com/staticimage/v2?ak=<span style="color:#ff0000;"><您申请的AK密钥></span>¢er=0,1&width=2&height=3&zoom=4";
        public BaiduStaticImageLayer():
            base()
        
            LegendText = "百度WMS地图";
        

        public override string UrlFormat
        
            get  return urlFormat; 
        
    

谷歌WMS地图不需要开发者申请密钥,实现代码如下:
using DotSpatial.Data;
using DotSpatial.Projections;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace wms

    class GoogleStaticImageLayer : StaticImageLayer
    
        public string urlFormat = "http://maps.google.cn/maps/api/staticmap?center=0,1&zoom=2&size=3x4&format=png&maptype=roadmap&sensor=false";
        ProjectionInfo googleProj;
        ProjectionInfo wgs84Proj;

        public GoogleStaticImageLayer()
        
            LegendText = "谷歌WMS地图";
            googleProj = ProjectionInfo.FromProj4String("+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs");
            wgs84Proj = ProjectionInfo.FromEpsgCode(4326);
        

        protected override string GetURL(Extent e)
        
            var xys = new double[]  e.Center.X, e.Center.Y ;
            var z = new double[1]  0 ;
            DotSpatial.Projections.Reproject.ReprojectPoints(xys, z, wgs84Proj, googleProj, 0, 1);
            return string.Format(urlFormat, xys[0], xys[1], ZoomLevel, WindowSize.Width, WindowSize.Height);
        

        public override string UrlFormat
        
            get  return urlFormat; 
        
    

腾讯WMS地图效果如下:

using DotSpatial.Controls;
using DotSpatial.Symbology;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace wms

    class TencentStaticImageLayer : StaticImageLayer
    
        string urlFormat = "http://apis.map.qq.com/ws/staticmap/v2/?center=0,1&size=2*3&zoom=4&maptype=roadmap&key=<请替换成您申请的密钥>";

        public TencentStaticImageLayer()
        
            LegendText = "腾讯WMS地图";
        

        public override string UrlFormat
        
            get  return urlFormat; 
        

        protected override string GetURL(DotSpatial.Data.Extent e)
        
            return string.Format(UrlFormat, e.Center.Y, e.Center.X, WindowSize.Width, WindowSize.Height, ZoomLevel);
        
    

这些图层加入DotSpatial地图控件的代码如下:

            mapCtrl = new Map()
            
                Width = Width,
                Height = Height,
                Left = 0,
                Top = 0,
                FunctionMode = FunctionMode.Pan,
                Dock = DockStyle.Fill
            ;
            imageLayer = new GeoserverStaticImageLayer()
            
                Projection = mapCtrl.Projection,
                WindowSize = this.Size,
                ZoomLevel = 11
            ;
            imageFunction = new StaticImageFunction(mapCtrl, imageLayer);
            mapCtrl.Layers.Add(imageLayer);
            mapCtrl.MapFunctions.Add(imageFunction);
            Controls.Add(mapCtrl);
            mapCtrl.ActivateMapFunction(imageFunction);
            mapCtrl.ViewExtents = new Extent(114.29189, 30.39661, 114.52518, 30.51317);
最终一个桌面WinForm程序运行效果如下:


以上是关于DotSpatial如何加载GeoServer谷歌 百度腾讯的WMS地图的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 https 从 Geoserver 加载地图?

比较ArcGIS、TatukGIS、ThinkGeo、dotspatial、mapinfo、gmap.net和SuperMap这几个GIS软件

如何在 android google map v2 实现上为 geoserver 瓦片重新加载 TileOverlay

通过 brutile/sharpmap 向 geoserver 发送 wms 请求以加载平铺地图 (tiled=true)

如何在 geoserver 2.9 中启用 CORS?

如何使用 Tomcat 在 Geoserver 上提供 https?