SharpMap介绍及源码分析

2024-04-12 00:18
文章标签 分析 源码 介绍 sharpmap

本文主要是介绍SharpMap介绍及源码分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SharpMap介绍及源码分析

SharpMap是一个基于.net 2.0使用C#开发的Map渲染类库,可以渲染各类GIS数据(目前支持ESRI Shape和PostGIS格式),可应用于桌面和Web程序。 其网址为: http://sharpmap.iter.dk/ SharpMap的发布许可(License)为GNU General Public License,开发者为Morten Nielsen( http://www.iter.dk/)。目前的稳定版本为0.8(9.0beta已发布),代码行数近10000行,实现了以下功能: 支持的数据格式:       PostGreSQL/PostGIS,ESRI Shapefile       支持WMS layers       支持ECW 和 JPEG2000 栅格数据格式 Windows Forms 控件,可以移动和缩放 通过HttpHandler支持ASP.net程序 点、线、多边形、多点、多线和多多边形等几何类型 几何集合(GeometryCollections)等OpenGIS Simple Features Specification 可通过Data Providers(增加数据类型支持)、Layer Types(增加层类型)和Geometry Types等扩展 图形使用GDI+渲染,支持anti-aliased等 专题图 可以看出,SharpMap目前可以算是一个实现了最基本功能的GIS系统,但一些很重要的功能,例如投影,比例尺,空间分析,图形的属性信息,查询检索等等,还没有或者还在开发中。一个好消息是,作者在SharpMap的网站写到:Diego Guidi(NetTopologySuite的开发者)已经创建了一个SharpMap和NTS之间的一个连接,这样,就可以在SharpMap中使用NTS的空间变换、缓冲区等功能。 笔者之所以在这里分析ShrapMap,出于以下原因:       SharpMap足够小(小于10000行),且具备了一个GIS软件的基本功能,容易下手;       基于.net和C#开发;       开放源码(不开放就没有办法分析,废话);       SharpMap还在开发中,可以通过跟踪其源码学习提高。 一项技术或者一个工具,知其然和知其所以然,对于应用的深度和熟练程度还是具有很大的影响,特别是程序开发。分析SharpMap,不一定是要使用SharpMap,是希望通过分析SharpMap,可以了解一个GIS系统的纵剖面,从而可以更好的进行GIS的应用和开发。 源码结构以下是SharpMap在VS 2005下的Class视图和Solution视图,可以看出SharpMap由SharpMap和其他14个次级名称空间组成,其中SharpMap名称空间下的Map类为这个系统的核心所在。 Map类,位于SharpMap命名空间下,通过创建Map对象的实例来生成地图。Map对象由包含Layer对象组成Layers集合,通过GetMap方法来Render地图。 Converts名称空间,提供数据转换服务。 Forms名称空间,包含MapImage控件,一个简单的User Control(用户控件),封装了Map类,用于Windows Form编程。 Geometries名称空间,包括了SharpMap要使用到的各种几何类及其接口类,例如点、线、面等类。 是SharpMap的基础之一,所有几何对象都继承自Geometry这个抽象类,其中定义了几何对象应该具备的公共操作,例如大小、ID、外接矩阵、几何运算等等。 Layers名称空间,包括了ILayer接口,Layer集合类等,代表地图的图层。 Layer是一个抽象类,实现了ILayer接口,Layer目前有3个子类,分别是VectorLayer、LabelLayer和WmsLayer,分别代3种不同数据类型的图层。 Providers名称空间,包括了IProvider接口和Shape文件、PostGIS数据的读取实现。该名称空间为SharpMap提供数据读(写)支持,通过面向接口的设计,可以比较容易的增加各类数据格式。 Rendering名称空间,目前包括矢量渲染器类和几个专题图渲染器类,该类可以将几何对象根据其Style设置渲染为一个System.Drawing.Graphics对象。 Styles名称空间,该名称空间主要提供了图层的样式设置类,例如线样式、点样式、填充样式等. Utilities名称空间包括Algorithms类(目前仅实现了一个方法);Providers类,是Provider的一个Helper,应用了反射机制;Surrogates主要用于系统的Pen和Brush的序列化;Transform提供了从图片坐标到地理坐标的互相变换,也即桌面GIS的二次开发中经常使用的屏幕坐标和地理坐标的转换,主要用于地图的渲染、交互操作等。 Utilities.SpatialIndexing用于对象的空间索引,我们后面还会继续介绍,Web名称空间实现了HttpHandler和Caching类,用于网络环境。 运行机制 通过剖析其名称空间,我们对SharpMap源码的结构和组成有了大概的了解,下来我们通过上面的应用实例来剖析其运行机制。 SharpMap.Map myMap = new SharpMap.Map(picMap.Size); 这句代码创建了一个新的Map的对象,Map对象包括了中点、大小、缩放比例、图层等字段,Layers集合对象包括了地图的各个图层,可以通过Layers.Add方法增加新的图层,通过GetLayerByName方法返回某个图层。缩放等方法是通过Center和Zoom属性来控制的。当地图图层修改和地图渲染后会触发相应的事件。 接着就需要新建不同的Layer对象,设置其属性和数据源以及样式。例如: SharpMap.Layers.VectorLayer myLayer = new SharpMap.Layers.VectorLayer("My layer"); string C; //创建图层的数据源 myLayer.DataSource = new SharpMap.Providers.PostGIS(ConnStr, "myTable", "the_geom", 32632); 不同的Providers对象,例如PostGIS或者Shape对象负责打开相应的空间数据集,读取数据,返回部分或者全部的空间对象。 接着就需要设置Layer的样式,例如填充、线形等属性。目前,Style对象只是简单的封装了System.Drawing.Pen、System.Drawing.Brush、System.Drawing.Bitmap等对象。并增加图层到Map的Layers集合: myMap.Layers.Add(myLayer); 我们可以通过设置Map的Center、Zoom、Size等属性来进行Map操作,例如缩放、平移等操作,例如封装Map对象为一个User Control控件,主要的动作就是操作Map的各个属性。 最后,我们就可以通过GetMap对象返回一个System.Drawing.Image对象,代表目前的地图,用于显示或输出: System.Drawing.Image imgMap = myMap.GetMap(); //Renders the map GetMap是整个SharpMap的核心之一,我们来一步步剖析其流程。 System.Drawing.Image img = new System.Drawing.Bitmap(); System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(img); g.Clear(this.BackColor); foreach (SharpMap.ILayer layer in this.Layers) {    if(layer.Enabled && layer.MaxVisible>=this.Zoom &&     layer.MinVisible<this.Zoom)         layer.Render(g,this); } if (MapRendered != null) MapRendered(g); //Fire render event g.Dispose(); return img; 以上代码就是GetMap的全部代码,首先创建一个System.Drawing.Image对象,然后为其创建一个System.Drawing.Graphics对象,通过这个对象来渲染地图到这个Image对象,最后返回这个对象。 其核心在于循环所有图层,如果其在显示范围之内,则调用Layer对象的Render方法,渲染这个图层。 抽象类Layer中的Render方法为: if(LayerRendered!=null) LayerRendered(this, g); VectorLayer子类的Render方法为: g.SmoothingMode = this.SmoothingMode; List<SharpMap.Geometries.Geometry> features = this.DataSource.GetFeaturesInView(map.Envelope); //Linestring outlines is drawn by drawing the layer once with a thicker line //before drawing the "inline" on top. if (this.Style.EnableOutline) {     foreach (SharpMap.Geometries.Geometry feature in features)     {         //首先绘制所有图形对象的线轮廓             } } //double i = 0; foreach (Geometries.Geometry feature in features) {     switch (feature.GeometryType)     {         //根据不同的图形绘制其             } } base.Render(g,map); 这段代码首先根据地图的显示范围,获取范围内的所有对象:GetFeaturesInView,然后逐次绘制不同这些对象。绘制对象时,调用了SharpMap.Rendering对象的不同方法。在SharpMap.Rendering对象中,不同几何对象的绘制方法最终调用了.net的System.Drawing中的GDI+的绘制方法,完成地图的绘制。 需要说明的是不同的数据源的GetFeaturesInView方法实现方法是不同的,目前版本的Shape数据源的Provider是使用了空间索引算法,PostGIS数据源则通过PostGIS的空间索引接口来获取需要的数据。 系统效率的好坏,基本上就在于这里,一个是如何获取视图内的空间对象,关键在于空间索引;一个是渲染机制,例如使用DirectX加快渲染。 这样,我们就基本完成了对SharpMap的剖析。SharpMap是一个刚刚启动不久的项目,开发者到目前为止只有一人,所以,实现的功能有限,有些设计也不是很成熟,例如缺乏空间分析和检索功能,但完全可以作为一个非常好的教学系统来使用。 从作者Morten Nielsen了解到,该项目是从2005年夏天开始的,目的是:
It was a good case for learning some of the new .NET 2.0 features and for getting "under the hood" of many of the GIS-related algorithms needed, like spatial indexing, spatial translations and topology rules. 通过项目,可以学习.net 2.0的一些新的特性,而且可以了解GIS相关的一些底层算法,例如空间索引、空间变换、拓扑规则等。
从中我们是否可以看到对技术的一种不同的态度,少一些空谈,多一些务实,这是笔者个人的感受。
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>

这篇关于SharpMap介绍及源码分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/895572

相关文章

Go使用pprof进行CPU,内存和阻塞情况分析

《Go使用pprof进行CPU,内存和阻塞情况分析》Go语言提供了强大的pprof工具,用于分析CPU、内存、Goroutine阻塞等性能问题,帮助开发者优化程序,提高运行效率,下面我们就来深入了解下... 目录1. pprof 介绍2. 快速上手:启用 pprof3. CPU Profiling:分析 C

MySQL表锁、页面锁和行锁的作用及其优缺点对比分析

《MySQL表锁、页面锁和行锁的作用及其优缺点对比分析》MySQL中的表锁、页面锁和行锁各有特点,适用于不同的场景,表锁锁定整个表,适用于批量操作和MyISAM存储引擎,页面锁锁定数据页,适用于旧版本... 目录1. 表锁(Table Lock)2. 页面锁(Page Lock)3. 行锁(Row Lock

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

四种Flutter子页面向父组件传递数据的方法介绍

《四种Flutter子页面向父组件传递数据的方法介绍》在Flutter中,如果父组件需要调用子组件的方法,可以通过常用的四种方式实现,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录方法 1:使用 GlobalKey 和 State 调用子组件方法方法 2:通过回调函数(Callb

Go中sync.Once源码的深度讲解

《Go中sync.Once源码的深度讲解》sync.Once是Go语言标准库中的一个同步原语,用于确保某个操作只执行一次,本文将从源码出发为大家详细介绍一下sync.Once的具体使用,x希望对大家有... 目录概念简单示例源码解读总结概念sync.Once是Go语言标准库中的一个同步原语,用于确保某个操

Python进阶之Excel基本操作介绍

《Python进阶之Excel基本操作介绍》在现实中,很多工作都需要与数据打交道,Excel作为常用的数据处理工具,一直备受人们的青睐,本文主要为大家介绍了一些Python中Excel的基本操作,希望... 目录概述写入使用 xlwt使用 XlsxWriter读取修改概述在现实中,很多工作都需要与数据打交

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制