WebGIS开发0基础必看教程:WebGIS中的要素(Feature)

1.前言

在GIS中元素一般分为点元素,线元素,面元素以及symbol元素(特殊的点元素)等。与此对应,图层可以分为点图层,线图层,面图层以及标注图层等。从第9章到第10章,我给大家讲解了什么是矢量数据、矢量数据的来源、矢量数据的构造、以及矢量数据中的地理坐标与屏幕坐标之间的转换。在了解了这些概念和算法以及流程后,这一章我们将开始讲解设计出一个矢量图层前的最后一步,设计WebGIS中的要素(Feature)。

2.要素设计的思路

2.1 需求

要素应该具有如下功能:

(1)能够绘制出矢量数据的Shape。

(2)能够存储矢量数据的atrributes。

(3)可以响应鼠标事件。

(4)可以响应自定义事件,如自定义的一系列地图事件。

(5)能够添加入Canvas组成一个矢量图层。

(6)要素是有很多种类的,比如点、线、面等。

2.2 基本分析

(1)在前面我们已经阐述了要素的本质,即UIComponent。因为UIComponent是前端语言中已经封装好了的类,我们只用继承其即可,如此我们便同时能实现上面所说的第三个需求以及第五个需求。

(2) 需求中要求要素中能够绘制出矢量数据的Shape。所以得定义类似于Draw这样的功能函数,以解决第一个需求。

(3)要素中还需要有个一变量存放attributes,即FeatureInfo以解决第二个需求。

(4)设计的类中还要定义一个监听事件的函数和一个移除监听事件的函数,即:addMapEventListener和removeMapEventListener,以解决第四个需求。

2.3 扩展分析

2.3.1重绘

当地图刷新,比如放大和缩小时,此时的UIComponent必须重绘,否则地图上的Shape将不再在地图上表示正确的位置,于是这里对Feature的设计有两点需要注意:

(1)对地图放大和缩小进行监听。

(2)增加重绘函数,即reDraw函数。当地图放大和缩小时触发重绘函数。

2.3.2 基类

需求中提到了要素具有多种类型,我们设计时需要将这几种类型均涉及到的属性和函数抽象出来作为一个基类,即Feature类。可以抽象出来的属性和类有:

(1)reDraw和Draw函数

(2)FeatureInfo属性

(3)addMapEventListener和removeMapEventListener函数

(4)对地图放大缩小事件的监听,此功能的实现可以放在Feature的构造函数中。

2.3.3 hook到主框架

在绘制shape时,我们需要用到地理坐标与平面坐标互相转换的函数,即上一章提到过的geoXYToScreenXY和screenXYToGeoXY。但是这两种方法是不可能封装到Feature类中的。因为这两种方法为系统中通用方法,不是专为Feature类而存在。所以这两个方法是放在主框架类中,这里我将这个主框架定义为FrameMap。于是,我们的Feature类中还应该有可以注入主框架的属性,即Map。

3.UML设计

基于上述分析,我们现在要开始真正的设计要素了。我们首先定义一个Feature类,其继承于UIComponent,然后再根据需求定义一系列具体的基础要素类,比如PointFeature、LineFeature和PolygonFeature等。并且如果需求出现变更,原有的基础要素已经不能满足需求时,可以在基础要素上进行继承从而进一步扩展基础要素类。

如下是最后设计出的要素类的UML图:

img

4.问题及解决方法

4.1如何控制每种基础要素类中要求shape以不同样式展现的需求?

在实际应用中,对同一个要素,用户需要的展现方式可能不尽相同。比如对面要素,有时候需要展现成黄色,有时候需要展现成蓝色等,而有时候需要面要素内的填充为网格状,有时候需要面在移动上去时变色,有时候又不需要等等。

解决此问题的方法,并不是去为每种需求重新将基础要素继承,然后修改draw方式,如果这样的话,代码的重复量太大。在设计模式中,我们有一个原则是能用组合时尽量用组合,能不用继承时尽量不用继承,因为继承是种高度的耦合,派生类和基类被紧紧的绑在一起,灵活性大大降低,而且,滥用继承,也会使继承树变得又大又复杂,很难理解和维护。在这个需求里,目前用不上组合,但是继承就更不需要了。

我们的解决方法一般是:

(1)首先将需求分类。外观上:一类是改变颜色的,一类是改变要素内部构造的。行为上:一类是需要某些监听并且做出相关变化的,一类是不需要某些监听的。这样我们可以在具体要素类,比如polygon类中添加两个共有属性,一个是DrewType,一个是ActionType。如果不希望把控制行为的重担都放在polygon类中,我们也可以不用定义ActionType,此类中本来就设计有addMapEventListener和removeMapEventListener。可以开放给调用者,让其自行判断。

(2)然后我们在Draw函数中,通过判断DrawType来进行绘制方面的控制。每个具体要素类中有自己定义的内部透明度(Sopacity)、外部透明度(opacity)以及内部填充色(SColor)和外部填充色(color)以及填充图标(Symbol)等等绘制方面的属性。回到上面的需求中,我们一类是想改变要素颜色,一类是想改变内部构造。还是假设这是一个对于polygon要素的需求,我们把DrawType定义为0和1。当DrawType为0时,我们将使用Sopacity,opacity、Scolor和color等绘画要素进行绘制,这些要素均是有默认值的公有属性,调用者可以自己设定。但是当DrawType是1时,这时候会将Symbol进行加载,然后改变绘制polygon的方式,将Symbol作为内部填充物进行填充。同样,Symbol也是有默认值的公有属性,调用者可以自己设定。

4.2地图发生平移时,Canvas的左上角坐标也出现平移,如何解决此时要素重绘时要素偏移问题?

在后面探讨设计WebGIS的地图平移功能时,我们会讲到每次地图被拖拽后,矢量图层(Canvas)的左上角坐标均会加减相同的屏幕平移量。这时候如果仅仅是将要素中的地理坐标转换为屏幕坐标后就直接将其绘制在UIComponent,然后添加到该Canvas里,便会出现绘制的要素不在地图上实际的地点的现象,即发生了偏移。这个问题是一个有一定难度的问题,我会在以后的WebGIS基础功能设计篇里专门花一个章节跟大家探讨这个问题。

5.通过设计模式再次探讨我们的设计

以上的设计基本上是遵循了面向对象的设计思维。不过,依据设计模式的原则,此中依然有可以改进的地方。

(1)根据依赖倒转原则,我们可以定义一个接口,比如IFeature,然后基类继承于此接口,这样可以通过接口来规范基类应该实现哪些方法。

(2)我们可以考虑使用简单工厂模式,从而进一步减少界面层类和Feature类中的耦合度。

不过,设计模式除非真有效用时再用才比较好,目前的元素设计在实际的编写代码中已经很好用了,当用到工厂类时,需要再次编写很多类出来,而且效果也不一定好。

点击获取更多GIS开发学习教程

  • 19
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
通过该课程的学习,主要掌握地理信息系统(GIS)概念,空间分析功能;开源GIS及内容;了解常见开源桌面、Web和移动GIS等各种平台软件功能和设计;学习开源开发方法和开源GIS项目设计。达到以下教学目的: 1、了解开源精神——自由、开放、共享,树立开源学习理念。掌握开源GIS设计方法和技术,重点掌握开源GIS软件的基本应用 2、通过对典型开源GIS项目的分析,重点学习GIS设计的基本内容:项目规划,组织管理,系统设计,编码技能和系统测试与维护 3、通过典型模式分析,掌握设计模式在GIS项目的使用原则和方法以及技巧,难点是分析设计模式在GIS设计应用 4、了解GIS应用性框架、插件式GIS、通用GIS解决方案设计等内容 课时1:试听 课时2:付费学员服务指引 课时3:1.GIS空间分析 课时4:2.开源软件 课时5:3.开源GIS课程 课时6:4.开源GIS实验环境 课时7:课件资料 课时8:1.PostgreSQL简介 课时9:2.空间数据库概述 课时10:3.PostGIS简介 课时11:4.PostGIS实践操作 课时12:课件资料 课时13:1.PostgreSQL扩展 课时14:2.PostgreSQL索引和PG的GIST注意事项 课时15:3.PostGIS raster 课时16:4.PostGIS开源开发 课时17:5.PostGIS栅格操作 课时18:6.实践操作 课时19:课件资料 课时20:1.PG企业应用 课时21:2.其他开源空间数据库 课时22:课件资料 课时23:1.QGIS简介 课时24:2.地图配准 课时25:3.GRASS TSP分析 课时26:4.实践操作 课时27:课件资料 课时28:1.GRASS栅格分析和影像分析 课时29:2.GRASS地图动画 课时30:3.GRASS TSP分析 课时31:课件资料 课时32:1.GRASS与PG的互链 课时33:2.GRASS开源开发 课时34:3.实践操作 课时35:课件资料 课时36:1.WEBGIS简述 课时37:2.WEBGIS模式和开源WEBGIS简介 课时38:3.CGI原理和编程 课时39:4.CGI模式WEBGIS-WEB地图 课时40:5.CGI模式WEBGIS-GeoMoose项目 课时41:课件资料 课时42:1.Mapserver项目(MIT) 课时43:2.Mapserver发布数据(1) 课时44:3.Mapserver发布数据(2) 课时45:4.Mapserver开发:两种开发方式 课时46:5.Mapserver应用 课时47:课件资料 课时48:1.GeoServer项目(GPL) 课时49:2.GeoServer体系特点(JavaServlet) 课时50:3.GeoServer体系特点和GeoServer发布数据 课时51:4.实践操作 课时52:课件资料 课时53:1.OGC OpenGIS 课时54:2.OGC OWS 课时55:3.SOA WEBGIS 课时56:4.实际操作 课时57:课件资料 课时58:1.开源移动GIS简介 课时59:2.gvSIG Mobile GIS 课时60:3.移动GIS开发模式 课时61:4.实践操作 课时62:《开源GIS》课程总结 课时63:课件资料 本课程为开源GIS视频课程的优化版(经改良过的完整版)。因此部分课程与该目录有出入,但是出入不大。
arcgis开发教程,ao开发教程,arcobjects开发教程,arcgis objects开发教程,arcgis桌面开发教程,AE开发教程,Arcgis Engine开发教程 1.3. GeoDataBase 34 1.3.1. 如何加载Shape文件 34 1.3.2. 如何在ArcMap加入Text和dBASE文件 35 1.3.3. 如何连接GeoDataBase文件 37 1.3.4. 如何连接Coverage文件 39 1.3.5. 如何连接栅格文件 41 1.3.6. 如何创建Shape文件 42 1.3.7. 如何创建DBF文件 45 1.3.8. 如何创建GeoDataBase文件 47 1.3.9. 如何创建Coverage文件 48 1.3.10. 如何建立文件连接(Join / Link) 50 1.3.11. 如何浏览纪录(属性查询) 52 1.3.12. 如何编辑记录 53 1.3.13. 如何增加记录 54 1.3.14. 如何删除记录 56 1.3.15. 如何纪录排序(ITableSort) 58 1.3.16. 如何添加字段 59 1.3.17. 如何删除字段 61 1.3.18. 如何进行空间查询 62 1.3.19. 如何进行高级空间查询(两个层之间的空间查询) 64 1.3.20. 如何进行层与层之间的逻辑运算 65 1.3.21. 如何将shape文件转化成GeoDataBase(各种文件格式的转换) 67 1.3.22. 如何将Map显示的图形转化成栅格文件 70 1.3.23. 如何打开选的层或独立表的属性窗口 71 1.3.24. 如何拷贝属性表的一行 73 1.3.25. 如何为当前层或独立表创建一个Summary表 75 1.3.26. 如何利用用户定义的规则创建定制的排序 78 1.3.27. 如何实现在ArcMap上进行属性查询(Identify) 84 1.3.28. 如何设置和修改层的数据源 87 1.4. Display 88 1.4.1. 如何实现在ArcMap放大缩小地图 88 1.4.2. 如何实现在ArcMap移动地图 90 1.4.3. 如何实现在ArcMap上画Polygon 92 1.4.4. 如何实现在ArcMap上进行测量 94 1.4.5. 如何实现在ArcMap上选取记录 100 1.4.6. 如何实现在ArcMap进行动作的撤销和重做 101 1.4.7. 如何画Polygon Buffers 102 1.5. 图元编辑 104 1.5.1. 如何得到图形的基本属性 104 1.5.2. 如何将选的点集转换成Polygon 105 1.5.3. 如何将Multipoint转换成Points 109 1.5.4. 如何通过Polygon的多个Ring创建多个Polygon 111 1.5.5. 如何从Polyline创建Polygon 113 1.5.6. 如何从Polygon创建Polyline 115 1.5.7. 如何将Polygon/PolyCurve一般化(Generalize) 117 1.5.8. 如何获得Polygon的点 119 1.5.9. 如何判断图形间的逻辑运算 121 1.5.10. 如何进行图形间的逻辑运算 124 1.5.11. 如何创建Envelope的Boundary 127 1.5.12. 如何通过鼠标移动图形 130 1.5.13. 如何为一个图形添加一个顶点 133 1.5.14. 如何删除一个图形上的一个顶点 136 1.5.15. 如何移动一个图形上的一个顶点 138 1.6. Element 141 1.6.1. 如何创建MarkerElement 141 1.6.2. 如何创建TextElement 142 1.6.3. 如何创建Balloon Callout 144 1.6.4. 如何创建PolygonElement 145 1.6.5. 如何选一个Element 146 1.6.6. 如何移动Element 147 1.6.7. 如何排列Element 151 1.6.8. 如何通过名字查询Element 153 1.6.9. 如何拷贝Element 155 1.6.10. 如何沿着折线路径显示Text 158 1.7. Symbol和Renderer 159 1.7.1. 如何为一个层设置Simple Renderer 159 1.7.2. 如何为一个层设置UniqueValue Renderer 161 1.7.3. 如何为一个层设置ClassBreaks Renderer 165 1.7.4. 如何为一个层设置ProportionalSymbol Renderer 168 1.7.5. 如何为一个层设置Chart Renderer 170 1.7.6. 如何为一个层设置DotDensity Renderer 173 1.8. Layout和打印 175 1.8.1. 如何在Page Layout上添加Text 175 1.8.2. 如何在Page Layout上添加Legend 176 1.8.3. 如何在Page Layout上添加North Arrow 179 1.8.4. 如何在Page Layout上添加Scale bar 180 1.8.5. 如何在Page Layout上添加Scale Text 182 1.8.6. 如何在Page Layout上添加Picture 184 1.8.7. 如何创建、删除地图网格(Map Grid) 185 1.8.8. 如何设置LayoutMapFrame的外观风格属性 187 1.8.9. 何设置LayoutPage的边框(Border)和背景(Background) 189 1.8.10. 如何设置打印纸张的大小和方向 192 1.9. 坐标系统 193 1.9.1. 如何在ArcMap设置地理坐标系和投影坐标系 193 1.9.2. 如何修改层的坐标系统 194 1.9.3. 如何把Polygon的顶点从经纬度坐标转换到平面直角坐标 196 1.10. ArcGis相关文件 198 1.10.1. 如何夹载grf文件 198 1.10.2. 如何新建指向Shape文件的lyr文件 199 1.10.3. 如何新建指向GeoDataBase文件的lyr文件 200 1.10.4. 如何加载mxd文件 202 1.10.5. 如何加载Apr文件(ArcView32) 203 1.10.6. 如何加载lyr文件 204 1.10.7. lyr文件的属性的设置 205 1.11. 其他 208 1.11.1. 如何创建简单的Column Chart 208 1.11.2. 如何将数据输出到Excel 209 1.11.3. 如何把Labels转换为Annotation 211 1.11.4. 如何把Annotation转换为Polygon Features 215 1.11.5. 如何设置Featurelayer的Label 218 1.11.6. 如何设置图层显示的透明度 220 1.11.7. 如何过滤层要显示的Features 220 1.11.8. 如何在MapControl新建一个Document并且保存 221
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值