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开发学习教程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/723842.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣大厂热门面试算法题 - 动态规划

爬梯子、跳跃游戏、最小路径和、杨辉三角、接雨水。每题做详细思路梳理,配套Python&Java双语代码, 2024.03.05 可通过leetcode所有测试用例。 目录 70. 爬楼梯 解题思路 完整代码 Python Java 55. 跳跃游戏 解题思路 完整代码 Python 代码…

kafka高水位和leader epoch

什么是高水位? 高水位表示分区下副本消息到哪里是算正常提交的。比如如下图:leader副本写到8了,follower副本也写到8,那么这个8就代表要求的副本都写入了。消息到8这里才算提交成功,后面的15写入了也不算提交成功&…

【Leetcode 2673】使二叉树所有路径值相等的最小代价 —— 贪心法

2673. 使二叉树所有路径值相等的最小代价 给你一个整数n表示一棵 满二叉树 里面节点的数目,节点编号从1到n。根节点编号为1,树中每个非叶子节点i都有两个孩子,分别是左孩子2 * i和右孩子2 * i 1。 树中每个节点都有一个值,用下…

Vscode C/C++ 编译问题

1.最近开始在VScode上编写程序,遇到了以下的坑 This may occur if the process’s executable was changed after the process wasstarted, such as when installing an update. Try re-launching the application orrestarting the machine. 2.原因 这个不是由vs…

技术上的判断令你如何确定现货黄金卖出时机?

要讨论现货黄金卖出时机,我们首先要搞清楚一个问题,就是开仓和平仓的问题,如果投资者已经成了市场中的多头,那他寻找的卖出时机就是要找多头平仓的时机,如果投资者还没开仓,正在寻找市场中的开仓机会&#…

【RS】最新欧空局Sentinel-2卫星数据下载(哨兵1、2、3、5P、6系列)

之前分享过Sentinel2数据下载的方法,但是有粉丝反应欧空局的网站更新了,之前的网站已经不能用了。所以自己抽空研究了一下新版的欧空局网站,今天就和大家分享一下如何使用新版的欧空局网站下载哨兵系列的卫星数据,本文以Sentinel2…

c语言-大小写字母的转换

目录 方法一:库函数直接转换 1、toupper的测试代码 2、tolower的测试代码 方法二:通过修改ASCII码值转换 1、自己实现大写转小写 2、自己实现小写转大写 结语 前言: 在使用c语言写代码时,通常会遇到很多将大小写字母相互…

IP定位在公安部门的使用及其重要性

随着信息技术的迅猛发展,互联网已成为现代社会不可或缺的一部分。然而,与此同时,网络犯罪也呈现出日益猖獗的趋势,给社会治安带来了极大的挑战。在这样的背景下,IP定位技术在公安部门的应用显得尤为重要。本文将对IP定…

geoserver+mapbox-gl 离线部署矢量切片地图服务学习笔记

geoserver安装 geoserver的安装包可以在官网下载Download - GeoServer,想要选择版本点击Archived找到指定版本进行下载http://geoserver.org/download/ (如果网络不稳定,也可以直接使用下面的下载地址) geoserver-2.15.0.rar资…

手把手带你申请【Sora】内测资格,附申请提示词

自从OpenAI发布了Sora之后,由于其流畅的画面,极高的真实度的60秒超长视频,瞬间秒杀当前市面上所有的视频胜场模型。 附上体验地址:https://openai.com/research/video-generation-models-as-world-simulators 相信Sora发布之后也…

PRewrite: Prompt Rewriting with Reinforcement Learning

PRewrite: Prompt Rewriting with Reinforcement Learning 基本信息 2024-01谷歌团队提交到arXiv 博客贡献人 徐宁 作者 Weize Kong,Spurthi Amba Hombaiah,Mingyang Zhang 摘要 工程化的启发式编写对于LLM(大型语言模型)应…

uniapp 滑动页面至某个元素或顶部

直接上代码: uni.pageScrollTo({selector: #top, // 需要返回顶部的元素id或class名称duration: 300 // 过渡时间(单位为ms) }); 官方文档:

什么是云游戏?云游戏平台可以运行3A游戏吗?

对于不熟悉游戏行业的人来说,面对云游戏可能会有一个疑问——除了单机游戏,现在所有游戏不都是联网玩吗?云游戏和网络游戏有什么区别? 实际上,云游戏和传统网络游戏有着本质的不同。 传统网络游戏需要玩家先下载并在本…

工时管理软件:为什么企业需要工时跟踪?

工时跟踪对于企业经营来说,可能不是首要事项。工时跟踪有什么用? 管理学大师彼得德鲁克曾说过:If you can’t measure it, you can’t improve it(如果无法衡量,就无法改进)。企业经营也是同样道理&#x…

注解校验备忘

NotNull 可用于一切包装类型 NotEmpty 用于String类型,表示不为空,并且长度大于0 用于List集合,表示不为空,并且size大于0 NotBlank 只用于字符串,去除两端空格后,长度大于0 Min和Max 包含当前值&a…

基于Python dlib的人脸识别的上课考勤管理系统(V2.0)

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝30W、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

2024年Android开发陷入饱和,想拿高工资

前言 从16年毕业至今,就职过两家公司,大大小小项目做了几个,非常感谢我的两位老大,在我的android成长路上给予我很多指导,亦师亦友的关系。 从年前至今参加面试了很多公司,也收到了几家巨头的offer&#…

2024Java大厂面试真题,java高级开发面试经验

概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术。不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理,很多人可能并不知晓。因此本文将通过大量的手绘图,…

一次线上JVM GC 长暂停排查,加班搞了好久

给大家分享一篇我在知乎上看到的,针对长时间 GC 问题排查定位过程的文章。 最终原因定位到 swap 空间上,是我未曾设想过的角度,因为常规的 GC 问题,相当大一部分原因最终定位出来都是代码相关、流量相关、配置相关的,…

需求并行开发场景,如何高效发布

云布道师 微服务架构下,每个应用服务独立开发、独立发布,小步快跑,持续快速交付业务需求。多人协同开发同一个应用时,分支开发模式是一个适合的协同方案。该模式下一个需求或任务通常对应一个 feature 分支,多个需求一…