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地图的主要内容,如果未能解决你的问题,请参考以下文章
比较ArcGIS、TatukGIS、ThinkGeo、dotspatial、mapinfo、gmap.net和SuperMap这几个GIS软件
如何在 android google map v2 实现上为 geoserver 瓦片重新加载 TileOverlay
通过 brutile/sharpmap 向 geoserver 发送 wms 请求以加载平铺地图 (tiled=true)