我与SharpMap的爱恨情仇
从5月17日开始,在同师门师兄的推荐下我开始接触SharpMap,刚开始的时候我对于SharpMap是一无所知的,但迫于项目的需要我也是不得不转战它。对于一个对开源编程尚未入门的我而言多多少少还是充满了挑战!但问题不大!接下来我就会慢慢交代我跟SharpMap这刚好一个月来的心酸故事。
什么是SharpMap
简单来说就是一个基于.net平台使用C#开发的地图渲染库,什么意思呢?也就是用SharpMap这个库我们可以开发出一个简单的GIS系统,像桌面端的Arcgis、超图、Web端的Arcgis Online等等它都能通过开发的手段做出来,听起来就是短小精悍型的Map库。
当然,最重要是因为这是一个开源的库,即意味着可以对其源码进行学习,从而做一些满足我们需求的二次开发!
关于它的身世
那既然它听起来那么强,为什么在我本科期间老师却极少谈及呢?这个主要是由于SharpMap其实是很早很早之前就已经问世了,绝大多数的SharpMap资料都停留在2005年到2011年期间,那为什么现在有关SharpMap的资料那么少呢?我想从自身的角度来看,SharpMap这个库的源码只有一万多行,相比而言是比较简短的;从外部的角度来看,随着AE老大哥和众多优秀开源库的崛起,并且随着应用市场不断的缩小,SharpMap就自然而然落后了。但我还是强烈建议学习GIS的同学学习一下,一方面锻炼开发能力,另一方面在学习源码的过程中深化GIS知识。
浅谈安装
我了解到的SharpMap的安装主要有以下三种方式:
- 如果可以科学上网的,可以从官网上下载SharpMap库, 官网直通车:http://sharpmap.codeplex.com/ 然后在VS里引入DLL即可。
- 下载GitHub上SharpMap的源码进行编译,链接直通车:https://github.com/SharpMap/SharpMap 这个方法不需要科学上网,前提会编译源码😢
- 使用NuGet程序包来下载,我推荐这种方式,较为简单快捷!
我的第一个SharpMap窗口
准备工作
- 首先创建完WinForm窗口后需要准备一下Sharpmap这个库,首先点开NuGet程序包。
- 搜索SharpMap,认准版本是1.2.0,然后下载SharpMap和SharpMap.UI这两个库。
3.当我们下载好之后,我们会惊喜地发现工具箱里多了两个工具栏,没错,这个就是我们待会需要用来创建地图控件的工具。
- 在SharpMap.UI下找到MapBox这个工具,然后拖到我们的Form里面,这样我们就初始化好了一个地图,类似于在加载地图之前,你得准备一个空白的画布,待会方便把地图加载在这块空白的画布上。
- 接着我们修改一下背景颜色让其更加地显眼。
接下来,就让我们来尝试加载一些数据上去!
加载数据
在加载数据之前,我们需要先对Program.cs文件先添加几行代码,因为在SharpMap问世的这些年来,随着各种依赖库的更新和弃用,Sharpmap里原本加载数据的功能也受到了一定影响,在Program.cs文件里添加下面两行神奇的代码可以维持它的这项功能。
using NetTopologySuite;
using ProjNet.CoordinateSystems;
using ProjNet.CoordinateSystems.Transformations;
var gss = new NtsGeometryServices();
var css = new SharpMap.CoordinateSystems.CoordinateSystemServices(
new CoordinateSystemFactory(),
new CoordinateTransformationFactory(),
SharpMap.Converters.WellKnownText.SpatialReference.GetAllReferenceSystems());
GeoAPI.GeometryServiceProvider.Instance = gss;
SharpMap.Session.Instance
.SetGeometryServices(gss)
.SetCoordinateSystemServices(css)
.SetCoordinateSystemRepository(css);
好吧,我承认有点多行…但无伤大雅,全部复制过去,像下面这个样子就行了。
这个时候,不出意外的话意外就出现了,下面的报错显示我们缺少了ProjNet这个库。
Tips:这里有个坑,在Nuget程序包里下载的ProjNet这个库是2.0版本的,会跟SharpMap发生冲突,只能兼容ProjNet 1.4版本,那怎么办呢?问题不大,我也准备好了!放在百度网盘这里:[网盘链接] 提取码:i36l
找到dll然后引入一下即可继续SharpMap的欢快之旅。
加载数据的函数
这里的话我用矢量数据先来做个例子(其实是因为我还没加载过栅格数据…)
首先构造一个加载数据的函数LoadData(),然后再实例化一个矢量图层vlay并命名为广州市,vlay.DataSource的意思是为vlay设置数据源。
最核心的地方在于mapbox、Map、Layer三者的理解。
mapbox是存放地图数据的容器,而Map是layer图层的集合。
我们可以把mapbox理解成存放试卷的箱子,那layer就是一张张的试卷,很多张试卷叠放在一起,那我们称这一堆试卷叫做Map。
using SharpMap;
using SharpMap.Layers;
private void LoadData()
{
VectorLayer vlay = new VectorLayer("广州市");
vlay.DataSource = new SharpMap.Data.Providers.ShapeFile(@"D:\New Desktop\GISdata\Guangzhou.shp", true);
//向mapbox里添加图层
mapBox1.Map.Layers.Add(vlay);
//缩放到全局
mapBox1.Map.ZoomToExtents();
//缩放至全局
mapBox1.Refresh();
}
然后呢,在函数入口那里调用一下这个LoadData()就可以啦!
public Form1()
{
InitializeComponent();
LoadData();
}
点击运行,就可以看到地图完美地被渲染出来了。虽然是一片黝黑,但好歹也是亲生的。
接下来设置一下样式,让它稍微好看一点。在刚刚LoadData()函数里面对vlay进行样式修改,再重新运行一下。
其中,Fill是指填充的颜色,Outline是要素的轮廓线,EnableOutline指是否渲染轮廓线。
private void LoadData()
{
VectorLayer vlay = new VectorLayer("广州市");
vlay.DataSource = new SharpMap.Data.Providers.ShapeFile(@"D:\New Desktop\GISdata\Guangzhou.shp", true);
vlay.Style.Fill = new SolidBrush(Color.SeaGreen);
vlay.Style.Outline = new Pen(Color.Black);
vlay.Style.EnableOutline = true;
//向mapbox里添加图层
mapBox1.Map.Layers.Add(vlay);
//缩放到全局
mapBox1.Map.ZoomToExtents();
//缩放至全局
mapBox1.Refresh();
}
运行结构
总结
这里简单地只是介绍了SharpMap的安装和简单的矢量数据加载,还有许多的功能我们后面再一点点介绍!!!