矢量数据在数据采集过程中由于数据处理导致出现局部狭窄的面状部分,如下图
1. 定义和解决方法
狭长结构是指图斑几何形态上窄而长的部分,符号化后出现图形粘连压盖现象,导致难以在图面上清晰地表达出来。因此,依据地图表达比例尺因素需要对狭长结构进行融解处理。在遥感影像提取的地物图斑中,既存在单个图斑整体上呈现狭长形态,也存在图斑的局部结构呈狭长状分布。针对图斑狭长结构的探测与一致性处理问题已经引起相关学者的注意,并提出了相应的算法模型。例如,艾廷华等人利用约束德劳奈(Delaunay)三角网提取狭长图斑的骨架结构,结合 空间上的全覆盖、无重叠特点,设计了狭长图斑的无缝剖分与一致性融解方法。 相关学者对 狭长图斑提取的骨架线进行修正,优化狭长图斑区 域的剖分结构与融解结果。 江宝得等人运用Delaunay三角网对图斑局部狭长结构进行分析探测,并建立了专门的一致性剖分策略。
1. 历史判断方法
使用图斑的周长/面积<0.5便是狭长图斑
但是上述方法存在一定的问题,没有严谨的数学逻辑,所以存在非常大的漏洞
2. 图形变化消除狭长部分
设:
- 狭长阈值:图斑中狭长部分的宽度阈值
- S(原有):原有面状图斑
解:
- S(内缩): 将
S(原有)
数据通过Buffer
算法内缩狭长阈值
/2 - S(恢复):将
S(内缩)
外扩狭长阈值
/2 - S(结果):使用
S(恢复)
擦除S(原有)
的面,得到的结果 - 判断
S(结果)
的面积是否大于面积阈值>0
3. 解决方法的细节
- 不能使用ArcGIS的buffer算法,ArcGIS的buffer算法在拐点处会生成为弧线。
- 面积阈值需要做一些调整,由于Buffer算法的特殊性会存在小范围的丢失
S(结果)
就是错误结果。
3.1. PostGIS的Buffer函数参数
st_buffer(geometry,5,'endcap=square join=mitre');
具体可以参见笔者博客:PostGIS的Geometry Processing 几何处理_1 ST_Buffer&&ST_BuildArea
4. 解决方法
4.1. PostGIS
- 原有图斑
--原始图斑
select st_geomfromgeojson('
{"type":"MultiPolygon","crs":{"type":"name","properties":{"name":"EPSG:4526"}},"coordinates":[[[[38526197.78691587,3946082.078275221],[38526239.096389465,3946081.883067248],[38526238.06191367,3946036.096619079],[38526272.53906836,3946035.789329056],[38526273.51750401,3946081.464537357],[38526318.149973966,3946079.913959388],[38526314.70475503,3945983.071421279],[38526269.72318699,3945985.068052262],[38526271.88954763,3946029.693470535],[38526238.0934658,3946029.695052562],[38526237.20585602,3945985.275129035],[38526191.99821754,3945985.892739444],[38526191.99821754,3945985.892739444],[38526197.78691587,3946082.078275221]]]]}
');
- 内缩图斑
--内缩图斑
select st_buffer(st_setsrid(st_geomfromtext ('
MULTIPOLYGON (((38526197.78691587 3946082.078275221, 38526239.096389465 3946081.883067248, 38526238.06191367 3946036.096619079, 38526272.53906836 3946035.789329056, 38526273.51750401 3946081.464537357, 38526318.149973966 3946079.913959388, 38526314.70475503 3945983.071421279, 38526269.72318699 3945985.068052262, 38526271.88954763 3946029.693470535, 38526238.0934658 3946029.695052562, 38526237.20585602 3945985.275129035, 38526191.99821754 3945985.892739444, 38526191.99821754 3945985.892739444, 38526197.78691587 3946082.078275221)))
'),4526),-5,'endcap=square join=mitre');
- 还原图斑
--外扩图斑
select st_buffer(st_setsrid(st_geomfromtext('
MULTIPOLYGON (((38526202.49370748 3946077.055977445, 38526233.9826907 3946076.9071762124, 38526232.94869538 3946031.14199388, 38526233.12135005 3946031.140455033, 38526232.306116015 3945990.34253409, 38526197.30384319 3945990.820722484, 38526202.49370748 3946077.055977445)), ((38526276.946718015 3946030.749845702, 38526277.432169005 3946030.745518946, 38526278.40783909 3946076.291625642, 38526312.97522189 3946075.090719166, 38526309.88725189 3945988.290182704, 38526274.96075535 3945989.840491601, 38526276.946718015 3946030.749845702)))
'),4526),5,'endcap=square join=mitre');
- 结果图斑
select ST_MakeValid(ST_Difference(st_setsrid(st_geomfromtext ('
MULTIPOLYGON (((38526197.78691587 3946082.078275221, 38526239.096389465 3946081.883067248, 38526238.06191367 3946036.096619079, 38526272.53906836 3946035.789329056, 38526273.51750401 3946081.464537357, 38526318.149973966 3946079.913959388, 38526314.70475503 3945983.071421279, 38526269.72318699 3945985.068052262, 38526271.88954763 3946029.693470535, 38526238.0934658 3946029.695052562, 38526237.20585602 3945985.275129035, 38526191.99821754 3945985.892739444, 38526191.99821754 3945985.892739444, 38526197.78691587 3946082.078275221)))
'),4526),st_setsrid(st_geomfromtext ('
MULTIPOLYGON (((38526272.18562671 3946035.79247923, 38526272.53906836 3946035.7893290548, 38526273.51750401 3946081.464537357, 38526318.149973966 3946079.913959388, 38526314.70475503 3945983.071421279, 38526269.72318699 3945985.068052262, 38526272.18562671 3946035.79247923)), ((38526197.78691587 3946082.078275221, 38526239.096389465 3946081.883067248, 38526238.06191367 3946036.096619083, 38526238.221355066 3946036.0951980045, 38526237.20585602 3945985.2751290346, 38526191.99821754 3945985.892739444, 38526197.78691587 3946082.078275221)))
'),4526)))
4.2. Java解决方案
- Buffer算法
使用Java中JTS的算法,其中有部分可以实现上述Buffer效果
bufferDistance=-5
BufferParameters bufferParameters = new BufferParameters();
bufferParameters.setEndCapStyle(BufferParameters.CAP_SQUARE);
bufferParameters.setJoinStyle(BufferParameters.JOIN_MITRE);
bufferParameters.setMitreLimit(8.0);
bufferParameters.setQuadrantSegments(8);
BufferOp bufferOp = new BufferOp(geometry, bufferParameters);
Geometry resultGeometry = bufferOp.getResultGeometry(bufferDistance);
- 图形计算使用JTS算法即可
序号 | 关系名称 | 关系说明 | JTS接口 |
---|---|---|---|
1 | 相等(Equals): | 几何形状拓扑上相等。 | equals(geometry) |
2 | 脱节(Disjoint): | 几何形状没有共有的点。 | disjoint(geometry) |
3 | 相交(Intersects): | 几何形状至少有一个共有点(区别于脱节) | intersects(geometry) |
4 | 接触(Touches): | 几何形状有至少一个公共的边界点,但是没有内部点。 | disjoint(geometry) |
5 | 交叉(Crosses): | 几何形状共享一些但不是所有的内部点。 | crosses(geometry) |
6 | 内含(Within): | 几何形状A的线都在几何形状B内部。 | within(geometry) |
7 | 包含(Contains): | 几何形状B的线都在几何形状A内部(区别于内含) | contains(geometry) |
8 | 重叠(Overlaps): | 几何形状共享一部分但不是所有的公共点,而且相交处有他们自己相同的区域。 | overlaps(geometry) |
4.3. C#中的解决方法
使用JTS的C#版本的NTS就可以。