QGIS C++ 3. 地图工程 与 SLD geoserver
上文谈到了QGIS将自身的SLD通过组图层文件夹的方式来实现SLD的工程实现。那这一节我们马上讲解如何将SLD整体作用到跨平台的Geoserver上,其中遇见了很多具体的工程实现问题,尤其是不同厂商对OGC-SLD的理解与偏差 。
数据导入
我们先看看geoserver支持那些数据格式
再看看QGIS支持的数据格式
可以发现交集分为三类
以下表格都是实际测试过,都建立了对应的R树/**GIST**索引加速读写。
| 分类 | 格式 | 备注 | 优缺点 |
|---|---|---|---|
| 本地 | 商业shapefile | ArcGIS本地文件/行业事实标准 | 文档注释行业霸主标杆绝大多平台都支持该格式属性名10大小的限制单个文件2G限制 |
| 本地数据库 | 开源geopackage/mbtiles-ectortile | sqliete改造的本地数据库 支持矢量/[矢量瓦片]/栅格瓦片 | 文档质量一般,很多api居然有种让我联想到我司的api。Orz服了。虽然理论上支持The maximum size of a GeoPackage file is about 140TB [K4a].。实际测试中同向对比很多友商,一旦超过2G也是很慢。我自己在按照OGC官方标准实现一个C++的实现的时候,发现有33Requirement,然后我一个个实现了下,发现很多的细节必须要实际参考已有的实现才行,最尴尬的是我把官方默认的库下下来在qgis平台里面打不开。 |
| 在线数据库] | 开源postgis/postgis-XL | 数据库(分布式) | 文档不输arcgis,质量极高,近千页的cookbook,我遇见问题几乎都是看该文档解决的。生态很好,很多商业/开源的实现分布式存储,支持海量数据的存储,使用OSM的全球数据测试过,确实在数据的迁移和节点的添加删除上很方便,经得起实际大数据的考验几乎主流平台都支持,然后qgis上大数据浏览是相对能够接受的。(其实有点慢,需要人手动的作一些制图综合处理提升速度) |
参考资料
[OGC GeoPackage] 需要很多很繁琐,必须严格遵循。这个标准的文档真心还是写的很不错的。认真阅读执行是可以走通的。标准制定的很严谨,点赞,不愧是定标准的。
[SpatiaLite: Introduction] 实际实现api文档,官方的example极其简单,针对GBK GB2312的批量数据插入盲试了很多才找到正确的方法。很多用法直接看代码的注释完全不明白具体的使用的方式,官方示例也缺失,很多都是在stackflow上别人踩过坑才能明白具体的用法。这个文档我感觉我的的确确认真看了,但是还是不清楚具体的用法,这种感觉让我深深的联想到我司的api,不问特定的研发压根不清楚怎么实际使用,真心是梦回10年前读书时代的机房老师门用破解狗mapgis-k9教学的时代,累并快乐着。
网上很多对比 [shapefile]和geopackage的文章,都说使用geopackage来替换shapefile,但是怎么能够用一个数据库和文件类型的格式进行对比呢,类型都不一样。就从我的实际从业经验,我感觉geopackage真正对手反而是[arcgis]的文件数据库filegdb,从各种对比上除了开源的优势,感觉geopackage都是处于劣势。很多生产单位都是使用的filegdb来作为实际的数据库。
对比上面的表格,搜索开源,生态,稳定,几乎是只有[postgis]一个选项了。因此我们采取该方式实现数据源。
QGIS导出
在导入的时候遇见的问题主要是QGIS的默认异常要素的处理规则
GeoServer导入
SLD样式导入
在上面众多图层中,随便点一个图层进行发布,这里我选择了有符号、文字、图形的图层World_Cites,按照geoserver的官方说明直接进行发布,果然无法显示,其余简单的点线面颜色图层可以预览。
首先看看不能成功显示的原因,主要分为下面3类:语义规则(当前版本2.21.1不支持所有特性),符号规则(当前版本2.21.1只支持png),图层顺序压盖导致看不见
语义规则
删除svg中无法解析的fill params参数即可
符号规则
geoserver 2.21.1中只支持png等图片符号,不支持svg符号。这里我想了下,可能是因为Geoserver使用的引擎是ol3的版本过低导致其无法支持svg符号,可能和geoserver本身的关系不大。
将se中的svg替换成png即可
图层顺序
geoserver的图层顺序和qgis是反着的,和mapbox是保持一致的这一点我感觉geoserver和mapbox的设计是比较符号人的认识的,顺序在下的后加载到地图画布中。这个见仁见智了。
filter规则
[gis.stackexchange.com/questions/1…]
属性大小写
PostGIS里面的属性geoserver默认处理成统一小写,导致原本大小写敏感的问题出现了
需要将原本大写的字段替换成小写的字段
批量导入
整体操作一个图层,我发现如果我使用geoserver默认的人机交互,我居然需要切换4个界面,并且在不同的界面里面不停的数据点击拖拽上传操作。光是一个图层的发布就很繁琐。因此需要批量操作。之前我将生成sld放到了一个文件夹中,对应的geoserver也有工作空间进行文件夹对应。
因此我们建立一个geoserver的工作空间PostGIS(geoserver/data_dir/workspaces/PostGIS/styles/),并把SLD和符号拷贝到对应的目录下即可。
或者是放到默认[全局路径]下geoserver/data_dir/styles/,建议不要这么处理,后期不好维护
然后再耐心点一步步发布sld-style就可以使用了(这里的图层鼠标人机交互还是挺多挺麻烦的,虽然说是批处理,但是我感觉geoserver的人机交互还是很原始不友好的)
最后我们把所有的单个图层组织成一个LayerGroup就可以实现类似QGIS的地图工程的效果了。
整个批量处理中,我感觉只是节省了上传大量符号和sld文件的过程,其余的图层发布和融合成一个组图层的工作是一点也不少的。这点感觉需要针对geoserver的代码进行定制开发了。
最后的显示效果是
总结
一句话 事非经过不知难 ,只有简单的样式才能无缝的跨平台进行转换,否则需要大量的定制开发工作配合。
尤其是符号问题上,QGIS桌面支持SVG符号,Geoserver支持Png符号,Mapbox支持Sprite符号。因此需要自己实现一个工具实现svg符号到png/sprite的转换。
这里我实现了一个SVG Sprite来串联这些问题的。
<figcaption style="color: rgb(145, 150, 161); font-size: 0.9em; line-height: 1.5; margin-top: calc(0.666667em); padding: 0px 1em; text-align: center;">qgis geoserver openlayer3 mapbox-gl 多端跨平台相同风格显示</figcaption>
最后,可能会觉得我现在展示的这个例子还是过于简单,但是实际上笔者已经在很严格很严谨的制图综合的项目中(几乎很难有比该项目更苛刻的制图规则了)实战落地了。由于一些客观原因无法直接贴图。但是我要强调的是这条路线是完全可以支撑很复杂的制图综合的需求的。就是需要额外很多定制开发工作。
后期我会上传一些相对弱一点的行业模板 如 国土、地矿、公安的例子来详细的支撑这一条路线的可行性。