好久没更新了,因为我在 – 憋 – 大 – 招 –,对,就是明天这篇。
明天跟大家分享一下我的开源 GIS 解决方案经验。
– 额 – 思考到单聊技术解决方案你可能会很快睡着,所以我明天会把重点放在我封装地图 API 这个事件上,以封装地图 API 的经验为线索,穿插着讲一些过后用到的开源 GIS 架构。
文章略微有点长,如果你只是想理解一下最新的开源 GIS 架构,能够间接跳过后面,去看第五版和最初的总结,但我倡议你还是从第一版开始看,因为没有后面的 4 个版本就不会有第五版,只看总结就和读名言警句成果一样,看的时候感觉有情理,过后就忘了,因为不能感同身受。
缘起
我始终在传统 IT 行业的公司工作,公司都是以做政府我的项目为主,俗称 toG 业务。
这种公司里,GIS 在其中的利用通常为两种,一种是 GIS 联合公司的业务造成一个 xx 地理信息系统,或是 xx 一张图零碎,另一种是联合公司业务封装一套地图 API,为公司的其它业务零碎提供地图技术撑持,相似于高德地图 API、百度地图 API。地图 API 的背地通常有一套 GIS 解决方案作为撑持
明天咱们就来聊一聊封装地图 API 这点事。
从我封装的第一个地图 API 版本诞生到当初,曾经过来了 7 年工夫,两头经验了 3 家公司,迭代了 5 个版本。5 个版本中,第 1 个版本应用的 ArcGIS,前面 4 个版本次要应用的开源 GIS。
第一版 2014 年
背景
公司做环保业务,业务零碎次要用 C# 开发,业务零碎中波及地图的局部应用 ArcGIS Flex API 开发,由 GIS 开发人员负责。那个年代,地图还次要是用 Flex 开发,因为 Flex 在那时给人感觉是很炫酷。
随着我的项目的减少,发现很多业务性能在我的项目里是通用的,再起初发现,如果把业务性能和地图功能拆散,再把 Flex 编写的地图功能封装一套面向 JS 的接口,C# 开发人员就能够本人实现地图相干的工作,不必受 Flex 语言的限度了。
于是咱们筹备封装一套用 Felx 编写的,面向 C# 开发人员的 JS 地图 API。
技术架构
- 前台应用 ArcGIS Flex API 开发地图功能,Flex 反对和 JS 交互,利用这一个性将 Flex 开发的地图功能,封装成面向 JS 的接口。
- 地图后盾应用 ArcGIS Server,空间剖析应用 GP 服务。
- 空间数据库应用 Arc SDE。
- 开发了一个简略的帮忙网站,提供前台 JS 接口的调用示例和应用阐明。
经验总结
地图 API 公布后,在做技术支持的过程中发现一个乏味的景象,对于地图 API 的应用,齐全不懂 GIS 的高级 C# 开发人员感觉好用,起因是能帮他们解决问题,有艰难时能够随时找咱们技术支持。
理解一点 GIS 的中级 C# 开发人员感觉不好用,他们会拿咱们的地图 API 和 ArcGIS JS API 比照,感觉后者更好用,但因为 ArcGIS JS API 的地图偏丑,咱们也不提供技术支持,须要他们本人去钻研,最终还是抉择用咱们的地图 API。
理解一点 GIS 的高级 C# 开发人员根本不必,其中有两个共事的反馈令我印象粗浅,一个共事说:”你们本人开发的货色,本人都不必“。话中有话是,你们本人都不必的货色不会好用。但咱们的想法是,把 Flex 封装一套 JS 的地图接口是因为 Flex 入门有门槛,咱们 GIS 开发人员既然都会 Flex 了,而且咱们开发的地理信息系统,整个都是用 Flex 开发的,那必定是间接用 ArcGIS Flex API 会更灵便,所以不必。
还有一个共事更牛,他间接去钻研 Flex,不会的就问咱们,入门后间接封装了一套地图接口本人用。咱们钻研过他封装的接口,尽管性能简略了些,但定义接口时的出发点感觉显著和咱们不一样,咱们是站在性能的角度封装,尽量保障接口的复用度高,比方增加点,增加线,缓冲等性能。他是站在用户的角度封装,比方从数据库查出来一堆数据,把这堆数据间接丢给接口,就在地图上展现进去了。总体而言,他的接口封装度更高,更贴近他的理论应用习惯,而咱们的接口更像是把 ArcGIS 的 Flex 接口翻译了一套 JS 的。
还留神到一个景象,常常有应用咱们接口的业务开发人员跑过来问,为什么我的地图不显示?经验的多了,发现通常有两种起因,一种是地图服务的地址不对,过后的地图服务都是用 ArcGIS server 公布的,ArcGIS server 地图服务的 rest 地址是个网页,这个网页关上后,有很多级的链接地址,业务人员不晓得应该拷贝哪一级的地址,常常拷错,所以地图出不来。另一种是,增加多个地图时,地图间的坐标不统一,导致增加的地图不显示。
想想也是,地图服务和地图坐标这些常识对于不懂 GIS 的开发人员来说还是挺难的。
尽管第一版有这样那样的问题,但在过后还是晋升了部门的整体工作效率。不光是 C# 开发人员能够本人去开发地图功能了,GIS 组外部也通过这种模式,把扩散在各个我的项目中的技术成绩收集了起来,并一直的积攒欠缺。
第二版 2016 年
背景
换公司了,新公司做网安业务,有海量定位数据,GIS 在其中的作用是,对定位数据进行提取、剖析、展现,从而帮忙客户解决业务问题。
公司的所有零碎必须部署在客户内网,客户的内网是无法访问互联网的,而地图应用的又是互联网地图,这就须要把互联网地图瓦片下载下来,拷贝到客户内网公布。
公司有一个 GIS 利用零碎,和 GIS 强关联的业务功会能放在这里。另外,其它部门有地图功能需要时,也会找到咱们 GIS 部门,这个场景和上家公司很像。
所以,二话不说,第二版地图 API 走起。
技术架构
-
这一版开始应用开源 GIS。GIS 前台抉择了 openlayers,有了第一版的教训,这一版重点解决了地图资源问题,和地图坐标问题。
- 解决地图资源问题。对立治理底图资源,提供多种互联网地图,包含高德地图、谷歌地图、天地图等,每种地图有个 id,初始化地图时,依据 id 应用不同的底图。
- 解决地图坐标问题。对外对立应用 wgs84 坐标,地图 API 外部负责将 wgs84 坐标转换为和底图匹配的坐标,包含 gcj02 坐标、bd09 坐标等。
- GIS 后盾方面,因为定位数据都寄存在大数据框架的数据库中,后盾只有互联网离线地图瓦片须要公布,所以间接应用了 tomcat 公布瓦片,再在 openlayers 中写一个加载本地瓦片的性能,这就算 GIS 后盾了。
- 没有应用空间数据库,空间剖析应用 ArcGIS Engine 开发控制台程序,再用 Java 后盾调用控制台程序。
- 接口写了具体的阐明文档和调用示例。没有做包装,间接是 word 文档 +html 示例文件。
经验总结
- 解决地图资源和坐标问题,能够大大晋升用户体验。
- 对于地图下载器,尽管大家都有能力本人写一个进去,但真的挺不划算的,最好的解决方案就是花公司的钱去买一个许可,站在公司的角度这都没几块钱。
- ArcGIS Engine 的版本,C#版的比较稳定,Java 版的超级难用,十分不稳固,动不动就死给你看,更不要尝试去把它部署到 Linux 服务器,不要问我是怎么晓得的。我过后为了在 linux 上部署,先开发了一版 java 的,部署后一天解体好几次,动不动就内存溢出,基本没法用,没方法只能从新写了一版 C# 的部署在 windows 服务器上。
第三版 2017 年
背景
换公司了,新公司做管网业务,相比后面两家,业务和 GIS 的相关性更强一些,业务中须要对管网 GIS 数据进行编辑、存储、公布和利用。公司之前地图都是应用 ArcGIS 开发的,正在筹备转开源 GIS,于是我到公司后就牵强附会的开始了第三版地图 API 的开发。
在开发之前,我先认真钻研了高德和百度地图 API,并问了本人两个问题:
一、为什么非 GIS 开发人员,可能用高德、百度地图 API 解决问题,却用不了 ArcGIS,openlayers,leaflet?
二、非 GIS 开发人员在用互联网地图 API 时遇到了哪些问题?
上面是我本人的了解:
第一个问题是因为:1、非 GIS 开发人员不须要本人公布地图数据,地图都是官网提供的,只管用就行。2、互联网地图 API 的帮忙文档和示例都是中文的。
第二个问题,我本人尝试应用后发现:1、互联网地图 API 的离线应用是个问题,它们都只能在线应用,如果遇到不能拜访互联网的状况,就无奈应用了,这问题在 toG 业务中还是挺常见的。2、互联网地图 API 只能用官网提供的地图坐标,不能集成其它坐标的地图资源。
从这一版起,咱们开始尝试在用户体验上对标高德、百度地图 API,学习对方的长处,防止对方的问题。
技术选型
GIS 前台没有再持续应用 openlayers,而是转向了更为笨重的 leaflet,过后的思考是:
- leaflet 很玲珑,外围代码构造简略容易了解,可塑性强,适宜拿来革新为本人的 API。
- leaflet 能够同时兼容 web 端和挪动端。
- 有 esri 保护的 leaflet 插件,能更好的兼容公司之前公布的 ArcGIS 地图服务。
GIS 后盾抉择了 geoserver。因为 geoserver 的材料比拟丰盛,能同时反对 postGIS 和 SDE 空间数据库。
GIS 空间数据库抉择了 postGIS,空间剖析也次要应用 postGIS 的空间剖析函数实现。
桌面端开发持续应用 ArcGIS Engine,没有去尝试 QGIS,次要起因是,公司之前在 ArcGIS Engine 上有大量的技术积攒,曾经造成了成熟的产品,转换老本会很高。
技术架构
在 leaflet 的根底上封装了一层本人的接口,原生 leaflet 接口不对外,过后的思考是:
- 和上一版一样,封装后容易解决互联网地图偏移的问题,对外对立应用 wgs84 坐标,外部依据不同的底图将数据转换为对应的坐标。
- 能够实现相似 JQuery 那样的扁平化接口,简略易用。
- leaflet 中点的写法是 [纬度, 经度],而咱们通常更习惯应用[经度, 纬度] 的写法,能够通过封装顺便解决这个问题。
当须要简单的 GIS 空间剖析时,编写 geoserver 的扩大插件,插件连贯 PostGIS 数据库,通过应用 PostGIS 空间剖析性能,本人编写函数实现空间剖析工作。
基于 geoserver 的 rest 接口实现地图服务的主动公布。在 ArcGIS Engine 开发的桌面软件中,先将 GIS 数据导入到空间数据库,再调用 geoserver 的 rest 接口公布地图,最终实现的成果和 ArcGIS 公布地图的体验雷同。
搭建一个门户网站,内容包含帮忙文档、地图资源、更新阐明等,帮忙文档以接口为线索,接口外部有接口阐明和调用事例。地图资源中提供能够应用的所有地图,包含互联网地图和本人公布的业务地图,每个地图有个 id,依据 id 就能够在 API 中轻松加载地图,不须要关怀地图服务是如何公布的。
将 PostGIS、geoserver、tomcat 全副批改为绿色版本,不便我的项目部署。
经验总结
- 能够应用 SLDEditor 软件解决 geoserver 不容易配图的问题。geoserver 的配图不好用,尝试了在 QGIS 上配图,而后公布到 geoserver 上,发现 QGIS 上配图后生成的 sld 款式文件格式,有很多 geoserver 都不反对,也不晓得是版本没对应上还是其它起因,最初找了个开源工具 SLDEditor 来编辑款式文件,完满解决问题,但整体的应用体验跟 ArcGIS 差很多。
- PostGIS 的空间剖析性能很好用、很弱小。所以空间剖析性能,咱们就次要用 PostGIS 来实现了,比方之前分享过的图形缓冲性能。
- geoserver 扩大更适宜开发和生成地图服务相干的性能。GIS 的空间剖析性能一开始通过 geoserver 扩大插件实现,起初发现扩大插件的后台程序次要作用是数据传输,最次要的剖析环节是在空间数据库 PostGIS 中实现的,而 geoserver 的扩大开发环境比较复杂,不如本人写的 java 后盾好保护。geoserver 扩大的劣势是能够间接调用 geoserver 的资源和性能,它更适宜开发和生成地图服务相干的性能。
第四版 2019 年
背景
开发出第三版后,在部门中应用了一年多,整体反馈良好,有一部分懂 GIS 的共事,之前应用的 ArcGIS JS API,用了 leaflet 封装的上一版地图 API 后,他们的第一反馈是这个好轻便,比 ArcGIS JS API 小了好多,加载很快。
上一版公布后,咱们注意了用户的应用习惯,大家的应用习惯根本都是先看示例,找到示例后,会间接把代码拷走应用,当示例不齐全满足要求时,再去翻看 API 阐明,最好的状况就是示例代码正文欠缺,一眼就能看懂,拷过去就能用。
当然在应用的过程中,也缓缓发现了一些问题。
懂 GIS 的共事反馈最强烈的是,能不能把原生接口放开。有个共事,每次都会先本人在网上找 leaflet 代码,确认能实现了再来找咱们,让咱们增加这个性能,甚至把材料链接都发过来了,整的咱们都挺不好意思的。如果能把 leaflet 原生接口放开,有很多工作他本人就能解决了。
而后是我本人,当我须要钻研一个新性能时,我的第一反馈不是去用我本人封装的地图 API,而是更违心应用原生 leaflet 去写,因为是我感觉本人封装的地图 API 用起来不够灵便。
天呐!!!
这不就和第一版时,共事说:”你们本人开发的货色,本人都不必”,是一样一样的嘛,如果说第一版时还有 Flex 语言的因素,那这第三版从内到外都是 JS 写的,没什么好解释的,就是让人家说中了。
咱们平时的工作,除了封装地图 API,咱们还有其它工作要做,上一版中,感觉咱们很大一部分精力被耗费在了封装根底性能这件事上,导致没有工夫去钻研高级地图功能。如果能把原始接口放开,根底性能就能够间接应用原生接口,咱们就有更多工夫去钻研高级地图功能。
能不能放开原生接口?
要放开原生接口面临几个问题:
- 地图坐标偏移问题。之前通过封装,在对外接口和地图之间构建了一个坐标适配层,解决了坐标偏移问题。如果放开原生接口,就没有方法再应用这形式,须要想其它方法。
- 用户应用习惯问题。不懂 GIS 的用户会不会习惯了扁平化接口,放开后感觉原生接口不好了解?leaflet 中点的写法是 [纬度, 经度],和平时应用的[经度,纬度] 不同,会不会有人适应不了?
- 版本向前兼容问题。上一个版本中为了谋求接口的极简性,简化了很多数据格式类型,如果放开原生接口后,还要兼容这些格局将会产生很大的工作量,而且后续每减少一个性能都要思考兼容这类数据的问题。
解决方案:
-
针对坐标偏移问题。
有两个计划,一是给用户提供一个坐标转换的接口,用户本人来转换坐标,但这样对用户不敌对。二是对互联网地图瓦片进行纠偏,让地图对立坐标,不再偏移,这是最现实的,但有技术难点。不过,咱们最终还是攻克了技术难点,采纳了第二种解决方案,详见:leaflet 中如何优雅的解决百度、高德地图的偏移问题。
-
针对用户习惯问题。
为什么百度、高德的地图 API 并没有应用扁平化接口,大家也没有感觉它们难用?咱们钻研后得出的论断是:在接口没有特地简单的前提下,地图 API 如果能做到:能解决用户问题,bug 少,示例丰盛,阐明文档清晰,大家就会感觉好用。接口是否是扁平化其实不怎么重要。而且,leaflet 的原生接口自身就曾经十分简洁了,单从简洁性思考的话,没必要再封装。
- 针对版本向前兼容问题。咱们决定不对上一个版本兼容,让两个版本同时保留,缓缓过渡,新我的项目新产品举荐大家用这一版,老我的项目咱们持续提供技术支持,但不再做性能降级。这样通过 1、2 年后,就能缓缓切换过去。事实证明这个决定是对的,当初曾经过来 2 年多工夫,部门里大部分零碎都曾经切换都了新版本。
技术架构
技术架构在上一版的根底上做如下调整:
- 放开 leaflet 原生接口,不再对接口进行封装,改为以插件模式进行性能扩大。
- 集成多种互联网地图资源,通过对瓦片纠偏的形式解决它们的坐标偏移问题,对外对立应用 wgs84 坐标。
- 帮忙文档由接口为线索改成以示例为线索,示例中的正文保障欠缺清晰,将示例代码中用到的办法给出类参考链接。
- 将 leaflet 的类参考文档进行翻译,放到平台中。
- 当有新的性能需要时,简略的性能不封装,间接给出示例,简单的性能再思考封装到插件中。
- 和 geoserver 相关性不强的地图分析性能,迁徙到 java 后盾,geoserver 中只保留和制图相干的性能。
经验总结
- leaflet 类参考的翻译工作没做好,一共没翻译几页,但奇怪的是大家素来没有埋怨过这个问题。起初察看发现,用户根本不看文档,更多的是看示例,示例没有的,会间接问咱们,文档其实只有咱们在看(捂脸)。
- 有人问问题时,尽量以示例的形式记录下来,后续大家在示例中能找到这个问题就不会再问了。
- 调用示例的名称目前是文字列表模式,文字毕竟有表白上的局限性,比照高德、百度地图 API,他们在示例列表的前一步,用动图的形式间接展现示例的最终成果,这样更加直观容易了解。
- 要尽量通过工具,让平台的保护变得简略,太简单本人就不爱保护,最初平台容易废掉。
第五版 2021 年
背景
这一版还没有实现,年前刚做完技术预研工作,这里先把整体的思路简略和大家分享一下。
总的来说,上一版曾经很好用了,当初曾经很少有来自用户的负面反馈。产品还曾在大我的项目中作为技术中台,提供给其余公司应用,同样成果很好。
但咱们本人还是有谋求的,和高德、百度地图 API 相比,咱们在上面几点上还须要改良:
- 地图好看度问题。地图的底图目前都是应用互联网地图瓦片,叠加上业务数据后,会遮蔽底图中的注记,业务数据间的注记也不容易实现主动避让,再加上没有好用的地图配图工具,导致地图在展现多样数据时就会显得很乱、很丑。
- 展现性能问题。地图有时须要一些动画成果,比方用动画成果表白管网中水的流动方向和快慢,在数据量较大时会呈现显著的卡顿。
- 地图配图问题。geoserver 配图不好用,这个问题后面曾经提到过,尽管应用 SLDEditor 能够生成配色文件,但一次只能生成一个图层,没有方法整体预览,效率太低,体验太差。高德、百度地图的自定义地图配图工具就很好用,美工能够间接上手,眼馋很久了。
这一版的指标是解决下面 3 个问题,并持续优化用户体验。
技术选型
前台改为应用 mapboxgl,不再应用 leaflet,起因有两个:
- 性能。leaflet 的下限在 10 万左右(详见:leaflet 如何加载 10 万数据),而 mapboxgl 基于 webgl 技术开发,最大数据量取决于显卡性能和网络传输速度,现实状况下能够轻松达到百万级别。
- 好看度。mapboxgl 对矢量瓦片反对特地好,再联合 maputnik 能够轻松实现高德、百度地图的自定义地图功能。
地图配图应用 maputnik,业务数据应用 geoserver 公布矢量瓦片,失常 maputnik 是不反对 geoserver 公布的矢量瓦片的,不过咱们曾经把这个问题解决了,详见:如何让矢量瓦片配图神器 maputnik 反对 geoserver
底图数据有两种计划:
- 持续应用互联网地图栅格瓦片,适宜对底图数据准确性要求较高的状况。
- 在本地公布 OSM 矢量瓦片地图,目前网上没有能够间接应用的收费矢量瓦片资源,只能本人把 OSM 数据下载到本地本人公布。OSM 地图在国内的数据品质比拟差,如果你的业务对底图数据的准确性要求不高,对款式要求比拟高,比方大屏展现零碎,能够选用这个计划。具体方法详见:如何实现 OSM 地图本地公布并自定义配图
地图可视化成果应用 deck.gl、L7 来实现。
经验总结
- 应用 maputnik 同时加载 geoserver 公布的业务图层和本地公布的 OSM 底图,能够实现业务数据和底图的深度交融,比方把业务数据中的河流放到底图路线图层的下方,并实现标签的主动避让性能,相似这样的体验还是十分爽的。
- OSM 地图的合规性存疑,倡议自行将中国的国界线校准一遍再用。
后续瞻望
-
解决 OSM 地图数据量少的问题。
第五版解决方案有一点不完满的中央是,OSM 地图在国内的数据量较少,这也是在我年初的 Flag 中,想要通过机器学习主动提取建筑物轮廓的起因。
-
钻研三维 GIS。
之前的工作始终是二维 GIS,三维 GIS 的业务比拟少,也钻研了 cesium、ArcGIS js API 4.x、three.js 等,并在我的项目上有过应用,但对三维 GIS 的整体了解还是不像二维 GIS 那样通透,不能像二维 GIS 那样信心十足的给出一个本人称心的开源解决方案,所以在这块儿须要持续致力。
总结
对于地图 API
在 toG 业务的公司中,想要通过开源 GIS,打造一套在易用性上比肩高德、百度地图的 API,须要留神以下几点:
- 解决地图资源问题。把网上的地图资源整顿好,把我的项目上的业务地图资源整顿好,对外让用户能够间接应用。
- 解决地图坐标系问题。要搞定互联网地图的偏移问题,和多种地图坐标间的转换问题,对外让用户只应用一种坐标。
- 根底地图功能通过用户教育的形式实现,也就是提供欠缺的调用示例和阐明文档。高级地图功能通过封装插件的形式实现,这样能够防止随着工夫的推迟,外围 API 越来越冗余。
- 场景丰盛的、能够间接应用的调用示例,比接口是否简介、文档是否具体更重要。
- 用户感觉地图 API 是否好用的影像因素,从高到低排序:能不能解决问题、有没有 bug、有没有丰盛的示例、技术支持是否到位、文档是否清晰。
- 己所不欲勿施于人。找一个实在的业务场景去应用本人的 API,并一直的从中发现问题,解决问题,欠缺性能,直到本人感觉十分好用为止,这样能够强制本人站在用户的角度去思考问题。如果本人都不违心去用,那就必定是不好用,最终不会走的久远。
- 要做好技术支持工作。开发地图 API 须要一个长期的、继续迭代的过程,这个过程中不免有这样那样的问题,如果你的用户反对好,它能帮你补救那些问题给用户带来的不好体验。
- 学会通过工具进步平台保护效率。多去想想平台保护的过程中,哪些环节能够通过自动化或半自动的形式实现,比方生成文档环节、更新部署环节等,节俭了工夫好去钻研更深层次的货色。
对于开源 GIS 解决方案
上面是我举荐的两种组合计划,其实都是后面提到过的,这里汇总一下。
轻量版:leaflet + geoserver + postGIS
这个组合网上的材料多,软件简略易用,普适性强,能满足绝大多数人对二维 GIS 的需要。
矢量瓦片版:mapboxgl + maputnik + geoserver + postGIS + openmaptiles + three.js
这个组合能够搭建出一套相似高德、百度地图的自定义地图,也能够实现白模三维地图,如果你比拟看重地图可视化成果,那么举荐你应用这一套。
好了,就到这里吧。如果感觉对你有帮忙,能够通过继续关注和多多分享来反对咱们。
原文地址:http://gisarmory.xyz/blog/index.html?blog=GISerSolution
关注《GIS 兵器库》,第一工夫取得更多高质量 GIS 文章。
本文章采纳 常识共享署名 - 非商业性应用 - 雷同形式共享 4.0 国内许可协定 进行许可。欢送转载、应用、从新公布,但务必保留文章署名《GIS 兵器库》(蕴含链接:http://gisarmory.xyz/blog/),不得用于商业目标,基于本文批改后的作品务必以雷同的许可公布。