基于FME的海量数据点高效率抽稀技术及实现

作者:暂时匿名

 

摘要:POI(兴趣点)是电子地图的重要组成部分,而海量密集的兴趣点显示,则常常需要先进行抽稀处理,怎样使其分布均匀合理,并要顾及其要素特征(如优先级)值得深入研究。本文借鉴了ArcGIS的SubPoints的实现思路,并对算法进行了优化,实现了FME版的SubPoints功能,运行效率上得到了很大的提升。同时,在此基础上,还实现了另外5种抽稀方法,分别为简单法、SQL查询法、点云法,格网中心法和聚合重心法。本文研究,不但弥补了FME缺乏有效的点抽稀方法的不足,还支持在不同比例尺下进行抽稀,为多比例尺海量数据点的抽稀工作带来了便利。

1. 引言

SubPoints工具是ESRI中国自主开发的一个插件,该工具优先考虑点在空间分布上的均匀合理性,并结合点数据中包含的“优先级”属性进行筛选。其中优先级用来设置数据的重要性,在抽稀过程中综合考虑数据的优先级别。通过获取每个点在一定范围内拥有的相邻点的数目信息,得到地图中点密度的分布状况。抽稀时在若干相临近的点中首先比较优先级,保留优先级高的;优先级相同时比较name字段,保留name长度短的;两者都相同时随机选择。

前段时间,在使用SubPoints工具处理数据时,体验上不是很便利。主要有3点:

1)数据的处理过程稍微繁杂,需要分三步走。一是需要进行点距离分析(即生成邻近点的OD矩阵),二是进行实际的SubPoints的抽稀标记计算,最后再把标记状态(status)大于-99的点提取出来。本来想使用ModelBuilder把这三步整合起来,却并不能正常运行(无报错,也无结果),最后放弃掉。

2)处理效率一般。2W的数据点,也需要处理个三分钟作业的样子,数据量大时会有假死情况。

3)缺乏灵活性。必须要包含“优先级”和“name”两个字段,如果没有这两个字段,则要先定义好(即使为空)。

基于以上种种原因,就冒出了想要使用FME实现类似功能的想法。

2. 总体流程

本文借鉴了SubPoints的思路,进行了一定程度的优化处理,实现了FME版的SubPoints功能,并且运行效率也远远高于ArcGIS。

同时,在此基础上,还实现了另外5种抽稀方法,分别为简单法、SQL查询法、点云法、格网中心法和聚合重心法。

最后,把以上6种方法进行了整合,定制了一个自定义转换器(PointsThinner),并且把“优先级”和“name”改为可选输入,灵活性更好一些。

本文点抽稀自定义转换器的实现流程和参数设置分别为:

基于FME的海量数据点高效率抽稀技术及实现

                                                                          图1 总体流程图

图中虚线用于对跨线进行区分。

基于FME的海量数据点高效率抽稀技术及实现

                                                                                图2 参数设置

转换器的参数共有4个,说明如下:

1)Mode:为抽稀模式,分别对应SubPoints工具法、简单法(Simple)、SQL查询法、点云法(Cloud)、格网中心法(Grid)和聚合重心法(Aggregation)。

2)Resolution(Cell Size):必选,指分辨率或者网格大小,也可以理解为搜索直径(即2*Radius),单位与地图单位一致。这里设置为分辨率,而不是搜索半径,主要是考虑到NeighborhoodAggregator只能接收用户参数,而不能使用算术编辑器的情况。下文中提到的内切圆半径和外接圆半径都与此有关。

3)Priority:优先级,可选,范围在[0,999999],数值越低优先级越高。

4)Name:名称字段,可选,用字符长度来计算优先级,字符长度越短,优先级越高。

注:以防属性冲突,转换器里的所有内置变量(属性)均为大写,且以THINNER_作为前缀。

3. 模型分解

3.1 初始化

基于FME的海量数据点高效率抽稀技术及实现

                                                                           图3 初始化流程

初始化主要是先计算点的优先等级(THINNER_PRIORITY),再根据选择的抽稀方法分配流程。

这里提前使用了StringLengthCalculator转换器来计算Name字段的字符长度,是由于AttributeManager里的Length方法计算的则是字节长度(一个中文字符等于两字节)。具体选用哪一种,结果上可能会有些差异。

AttributeManager的主要工作是计算点的优先等级:Priority * 10000 + Length(Name)。先把Priority放大10000倍,是为了避免Name字段长度的影响。这样,后面运算只需要进行一次排序即可,而不需要先进行Priority排序再进行Name字段长度排序,以提高运行效率。

TestFilter根据抽稀方法选择流程。其中简单法和SQL查询法的输出端口增加了THINNER_NO属性,是用于计算其所在网格编号。

3.2 SubPoints

借鉴ArcGIS里SubPoints抽稀的思路,对代码进行了优化改善。

先用NeighborFinder计算点的邻近距离表(OD矩阵),搜索距离取内切圆半径,即分辨率的一半。

由于提前计算了优先等级(THINNER_PRIORITY),把Priority和Name两个字段整合到一起了,SubPoints的处理代码也少了一些判断,相对比较简单。

虽然运行效率上相比于ArcGIS的SubPoints工具有了很大的提升,但是,当数据量越来越大,尤其是数据点密集程度越来越高时,其所构建邻近距离表所需的空间和运行时间也将成倍的增加。因此,为了解决这个问题,也就有了后面的几种抽稀方法。

基于FME的海量数据点高效率抽稀技术及实现

                                                                             图4 SubPoints法流程

3.3 简单法

顾名思义,简单粗暴,是在WebGIS和数据库中较为常用的一种方法,效率很高。其核心思想是先计算数据点所在的网格编号(THINNER_NO),格子大小为分辨率参数(Cell Size),然后再取落在同一个格子中的第一个元素。另外,还可根据优先等级对落在格子里的点进行排序。

网格编号计算方法是,分别以点的X、Y坐标除以Size,再取整,最后拼接起来即可。

基于FME的海量数据点高效率抽稀技术及实现

                                                                             图5 简单法流程

3.4 SQL查询法

SQL查询法思路跟简单法类似,只不过是使用了InlineQuerier进行SQL(具体的SQL语法会跟数据库里的有些出入)的方式来实现。但由于其排序逻辑跟Sorter有些差异,输出结果也可能会不一样。

其网格编号计算方法同简单法。

基于FME的海量数据点高效率抽稀技术及实现

                                                                       图6 SQL查询代码

3.5 点云法

点云法的核心思想跟简单法一样,只不过是使用了点云的方式来实现,输出结果也是跟简单法一模一样,使用了较多的转换器,但执行效率反而是提高了。

基于FME的海量数据点高效率抽稀技术及实现

                                                                          图7 点云法流程

1)先把数据点合成点云,THINNER_ID和THINNER_PRIORITY作为点云的组成部分。

2)根据给定分辨率,重新计算各点的x,y值,即把x,y转换为其所在的网格行列号。

3)按优先等级(THINNER_PRIORITY)排序后去重,再根据THINNER_ID与源数据进行属性挂接。

3.6 格网中心法与聚合重心法

格网中心法是先根据分辨率大小生成一系列大小相同的网格,再找到离网格中心最近且优先等级最高的一个点。

聚合中心法则是先根据分辨率大小来生成一系列的聚合块,再找到离聚合重心最近且优先等级最高的一个点。

两种方法大同小异,效率相差不太大。

基于FME的海量数据点高效率抽稀技术及实现

                                                                图8 格网中心法和聚合重心法流程

这里的NeighborFinder的搜索距离取外接圆半径。

两种方法在进行邻近分析前,都要先对优先等级进行降序排序,这是因为NeighborFinder会把其搜索范围内找到的最后的一个最近点作为最终输出。

值得注意的是,需要用VertexCreator把网格中心或聚合重心替换为真实的数据点坐标。另外,可能还会存在点的THINNER_ID重复的情况,可用DuplicateFilter按THINNER_ID去重。

3.7 二次过滤

除SubPoints法外,其他5种抽稀方法都可能存在部分点离的较近的情况(小于搜索距离),因此还需要进行二次过滤,以排除那些在搜索距离以内的点,即都要经过SubPoints法进行二次过滤再输出。

当然,简单一点的话,可以直接用NeighborFinder进行过滤,搜索距离取内切圆半径。

4. 结果分析

本文抽取了深圳和香港两地的POI数据进行测试,为国家2000投影坐标系(这里取EPSG:4547),分辨率取1000米,即搜索半径为500米。

                                                      表1  抽稀方法运行时间对比              单位:秒(s)

基于FME的海量数据点高效率抽稀技术及实现

运行效率上,点云法最快,格网中心法和聚合重心法次之,简单法比SQL查询法稍快(当然,简单法在数据库查询里应该是最快的),SubPoints法最慢。但无论是哪种方法,都要比在ArcGIS里的SubPoints工具法要快得多。

注:带“——”的地方是由于运行时间太长,没有进行统计。如ArcGIS的SubPoints工具在生成10万条数据点的邻近距离表时,就花了6分多钟,而FME里的SubPoints法在处理40万数据点时,也超过了10分钟,就没有再进行下去。

                                                     表2  抽稀方法抽稀后保留点数对比           单位:个

基于FME的海量数据点高效率抽稀技术及实现

运行结果上,SubPoints法保留的点数最多,也相对均匀。简单法和点云法结果一样,保留的点数也最少,而SQL查询法由于排序逻辑不一样,结果与简单法和点云法有些出入但也相差不大,这三种方法抽稀后的点也比较均匀,但随机性会比SubPoints高一些。网格中心法和聚合重心法保留的点更趋向于呈网格化分布。格网中心法剩余点数接近SubPoints法。

基于FME的海量数据点高效率抽稀技术及实现

                                                                  图9 数据点抽稀处理后分布情况

以下是2万数据点抽稀后的点距离分布直方图,可以看出大部分点的距离都集中在500~1000之间,符合抽稀预期。

基于FME的海量数据点高效率抽稀技术及实现

                                                                  图10 抽稀处理后点距离分布直方图

5. 结语

本文借鉴了ArcGIS的SubPoints工具的点抽稀思路,进行优化和拓展,实现了多种基于FME的海里数据点抽稀技术。运行效率上,相比于ArcGIS的SubPoints工具得到了极大的提升,同时还弥补了FME缺乏有效的海量点抽稀方法的不足,也为多比例尺海量数据点的抽稀工作带来了便利。本文中的每种抽稀方法都有其特点,实现思路也不一样,在运行效率上和输出结果上也有差异,但都顾及了数据点的要素特征(优先等级)。具体使用哪种方法,可根据实际的应用场景和需要进行选择。多比例下电子地图数据点抽稀,只需要设定不同比例尺下的对应的分辨率(搜索半径的2倍)即可。后面将再做一个直接支持多比例尺抽稀的转换器。

当然,本文模型还有优化空间,这就留待后面再继续深挖了。

最后,感谢FME带来的工作便利!

参考资料

1) 侯辉娇子, 林旭芳, 赵海强. 电子地图中POI数据抽稀方法研究[J]. 北京测绘, 2017(S1):236-239.

2) 王屏, 宋昊, 刘淑红. 基于点距离的点抽稀算法在电子地图符号化中的应用[J]. 科技与企业,  2014(17):311-311.

3) OneMap. 常用点抽稀方法之三——SubPoints点抽稀[EB/OL]. http://blog.sina.com.cn/s/blog_ba3ace5f0101i8cb.html, 2013-02-25