如何FME中使用QGIS算法

目录

前言

二、在FME中配置QGIS环境

1.引入QGIS的python环境

2.在pythoncaller转换器中调用qgis环境

三、PYQGIS介绍

1、core中的各种基础类

2、FMEfeature和Qgsfeature的相互转换

 3、qgis要素如何在fme中聚合为图层类。

4、调用QGIS算法

四、几个简单的案例展示

一、buffer

二、两个图层取交集

总结


前言

QGIS作为开源gis软件的主流,拥有大量的C++编写的优质算法,支持九交模型,具有功能齐全、高性能等特点,且所有算法都有对应的Python api,FME作为目前最好用的gisETL工具之一,如果能在FME模板流程中调用QGIS算法,那么FME能解决的事情就会更多了。


一、QGIS和arcpy

fme也能调用arcpy的算法,但是为什么我没有选择arcpy路线主要有这几大原因:

1、arcgis闭源,算法封装的较为上层,只支持调用,不支持修改。

2、arcpy和fme耦合性低,所有调用都基于写出文件,然后传递路径给arcpy算法,计算完成后写出文件,再用fme读取,导致了浪费大量的性能在文件写入写出上面。

3、arcgis大部分是用户目前都是用的32位arcgis,与之对应则需要使用32位FME才能调用arcpy,这就导致32位软件调度内存能力不足,性能就大打折扣。

4、arcpy使用的python 27 很多py库并不兼容,例如新版的pandas、TensorFlow等优秀的python库都不支持python2了,则导致了在fme调用arcpy的局限性。

5、外部调用arcpy需要认证,而认证则需要浪费大量的时间,导致模板执行效率进一步下降。

而QGIS则完全不同,QGIS完全避免了上述的缺陷,并且QGIS的类封装的逻辑非常契合FME的思维,可以实现不用写入写出任何文件,将FME要素直接在内存中调用qgis算法,计算完毕后转换为FME要素继续进入下一工作流。而且QGIS最新版本支持python39,不兼容的python第三方库可以说几乎没有。而且QGIS算法封装的比较底层,支持传入各种类进行计算,性能比arcgis要快上不少。

二、在FME中配置QGIS环境

1.引入QGIS的python环境

在fme设置中把python环境和python解释器换为qgis环境。

2.在pythoncaller转换器中调用qgis环境

需要在pythoncaller中写入如下代码,在python环境中加入qgis的dll。写入以下代码后就可以愉快的调用的QGIS的所有算法了。

import sys
sys.path.append(r"C:\Program Files\QGIS 3.18\apps\qgis\python")
sys.path.append(r"C:\Program Files\QGIS 3.18\apps\qgis\python\plugins")

三、PYQGIS介绍

1、core中的各种基础类

参考官方文档core

(1)几大基础元素类:QgsPointQgsPolygonQgsMeshQgsRaster QgsLineString

(2)几何特征类:QgsGeometry

(3)字段类:QgsFieldQgsFields

(4)要素类:QgsFeature

(5)图层类:QgsMapLayerQgsMeshLayer QgsPointCloudLayerQgsRasterLayer

如果是默认安装则qgis源码路径C:\Program Files\QGIS 3.18\apps\qgis\python\qgis,

 可以发现所有类都是基于C++编写,但是这个是编译好的dll,所以我们需要了解类的本质需要通过查看未编译的QGIS C++源码Index of /downloads

首先找到QgsGeometry也就是几何类部分,该类能储存qgis的所有几何信息。

 打开源码qgsgeometry.cpp文件

 可以看到各种类方法。同时悟空也发现了QGIS的几何类的特性,可以直接加载wkb几何

 那么FME输入的几何要素也可以转为wkb数据(参考FMEpython官网fmeobjects.FMEFeature — Python FME API FME 2021.2 b21812 documentation

 这样则可以实现FME要素和qgis要素的几何信息的互相转换。

通过查看qgsfeature.cpp源码,发现qgsfeature类属性包含了qgsgeometry和qgsfield两大核心属性。

 

2、FMEfeature和Qgsfeature的相互转换

通过对两个类的构造的了解,发现两个类在底层的构造逻辑基本一致,那么实现转换也就可以实现了。创建qistofme.py外部py文件,将转换函数封装在该文件类,杂fme的pythoncaller中import函数,则就能轻松实现fme和qgis数据的互相转换。

 

 可以看到这里我调用了两个函数,先把fmefeature转换为qgisfeature,然后再将qgisfeature转换为fmefeature。最后再抛出转换后的fmefeature。如下图所示,导入fme的shp数据的转换非常成功。

同时几何和属性数据没有任何丢失。

 

 3、qgis要素如何在fme中聚合为图层类。

qgis的很多算法最终需要传递的数据,都是图层类数据,比如矢量数据则是QgsVectorLayer类,该类可以理解为qgis要素的集合。根据FME中pythoncaller的FeatureProcessor类中的input函数的特性,我们可以将qgisfeature聚合为qgisfeatures,在close函数中,建立一个空QgsVectorLayer变量,将qgisfeatures导入到QgsVectorLayer中,实现qgis图层类的转换。

4、调用QGIS算法

参考官网文档,25.1.19. Vector overlay — QGIS Documentation documentation

用python调用qgis算法非常简单,比如我们要实现两个图层的相交。

 找到算法位置

找到具体参数,记得inputlayer最好为图层类,当然这输入层也可以选择文件本身。

 找到算法ID

 将参数以json格式传入,建立一个result变量来接受计算后的数据

        result=processing.run("qgis:intersection", {"INPUT":layer1,
        "OVERLAY":layer2,
        "OUTPUT":"TEMPORARY_OUTPUT"})["OUTPUT"]

拿到变量后,将变量转换为fme要素导出。

        count=result.featureCount()
        for i in range(1,count+1):
            qgisfea=result.getFeature(i)
            newfeature=qgistofme(qgisfea)
            self.pyoutput(newfeature)

四、几个简单的案例展示

一、buffer

 可以看到图形被缓冲了,并且属性没有任何丢失,同时也没有任何数据写入写出,完全把所有计算都放在内存,同时计算速度也是非常的快,对比各类python开源gis库和arcpy ,qgis的执行基本是瞬间响应。

二、两个图层取交集

首先我们先用fme实现看看需要花多少时间。模板如下

 可以发现执行一共耗时1分52秒,接下来我们开QGIS的执行速度,可以看到只耗费了44.5秒,性能是大幅度提升并且和fme是高耦合度。

 


总结

结合QGIS,fme还能做的事更多,QGIS基于gdal和geos开发,因此我们还能直接调用gdal库和geos库的各种算法,可以说是算法拉满。同时还能在QGIS中加载别人开发的插件,在fme用插件的算法。还能结合QGIS的三维模块做更多的扩展,当然这一切都需要静下心来研究,没有不能解决的问题,只有不去思考研究扩展的人。之前我并没有接触过QGIS,通过这几天的研究,让我对这个开源gis软件产生非常浓厚的兴趣,希望对开源gis有研究的小伙伴联系我qq1131698384,一起研究gis技术,有对上文的详细代码或者功能集有需求的小伙伴也可以联系我,付费获取FME模板。

猜你喜欢

转载自blog.csdn.net/weixin_57664381/article/details/126619544
今日推荐