版权声明:转载请注明作者(独孤尚良dugushangliang)出处:https://blog.csdn.net/dugushangliang/article/details/100572453
先贴上本人相关文章:
Arcpy读取写入线的几何和属性https://blog.csdn.net/dugushangliang/article/details/93305277
arcgis的arcpy写入几何怎么创建一个空心面要素并读取几何和属性信息https://blog.csdn.net/dugushangliang/article/details/83861447
arcpy生成点、线、面层并同时增加形状shape和属性字段fieldhttps://blog.csdn.net/dugushangliang/article/details/89677348
以上已有提到一些操作,但对于多个空心,多部件的容易出现一些预料之外的问题,所以另开一篇来叙述。
重点先放在这里:
上图是一个多空心面,读取这个几何发现:
这个面是单部件的,不是多个部件,共有24个点(可是为什么我查了查是19个点?)。
我们读取下看看,如下图所示:
为什么19个点构成的几何面,为什么含有24个点呢?None来分隔环,第一个是外环,后面的都是面里的空心所使用的环。
我们可以看到,这每个环都是有始有终的,所以每个环都需要添加一个额外的点来保证闭环。
读取几何好说,写可能有问题。我们下面谈一下写的问题。
#创建一个简单的点
pt=arcpy.Point(123.45,32.1)
#用于创建几何的点序列
lst=[[123.1, 32.1], [123.5, 32.1], [123.5, 32.5]]
#根据一个点序列来创建一条简单的线
pln=arcpy.Polyline(arcpy.Array([arcpy.Point(*cd)for cd in lst]))
#根据一个点序列来创建一个简单的面
plgn=arcpy.Polygon(arcpy.Array([arcpy.Point(*cd)for cd in lst]))
上述的简单的点线面一般都不会有什么问题,各位可以自行把这些几何写入到一个shp文件或数据库的要素类中,具体操作请参阅本文开篇提到的其他链接。
下面论述多个空心面的操作:
coords_list = [
[[1, 123.1, 32.1],
[1, 123.5, 32.1],
[1, 123.5, 32.5],
[1, 123.1, 32.5],
[1, 123.1, 32.1]],
[[1, 123.2, 32.2],
[1, 123.3, 32.3],
[1, 123.2, 32.3],
[1, 123.2, 32.2]],
[[1, 123.4, 32.4],
[1, 123.3, 32.4],
[1, 123.4, 32.3],
[1, 123.4, 32.4]],
[[1, 123.30, 32.13],
[1, 123.44, 32.12],
[1, 123.38, 32.23],
[1, 123.30, 32.13]]
]
pnt=arcpy.Polygon(arcpy.Array([arcpy.Array([arcpy.Point(coords[1],coords[2],ID=coords[0]) for coords in coords_list[i]]) for i in range(len(coords_list))]))
将上面的这个pnt写入到shp文件里,得到结果如左下图。而如果https://blog.csdn.net/dugushangliang/article/details/83861447这样只是根据点序构成闭环的则是右下图所示。
这表明,对于多个空心的面,因为几何比较复杂,所以适合使用Array的Array来构建几何面。
Array的Array中点序列有什么要求吗?点序列可以主动构成闭环,但也不必有始有终,因为:
除了Array的Array来构建,还有没有其他办法呢?
https://pro.arcgis.com/zh-cn/pro-app/arcpy/get-started/reading-geometries.htm提到使用空点对象来作为环之间的分隔符,但并不能创建空点对象,因为Point有xy的默认值。Array也不能含有None,所以有一个不以列表、Array为元素的Array看起来是实现不了了。那么不用Array用别的怎样?Polygon的初始化要么Array对象要么Point。
再看看下面的情况:
ar=arcpy.Array([arcpy.Array([arcpy.Point(coords[1],coords[2],ID=coords[0]) for coords in coords_list[i]]) for i in range(len(coords_list))])
ar.add(arcpy.Array([arcpy.Point(*co) for co in [[122.9,31.9],[122.8,31.9],[122.8,31.8]]]))
pnt=arcpy.Polygon(ar)
这得到了一个多部件的面。这是含有4个Array元素的Array对象所构成的Polygon。其中前三个环构成一个多空心面,后一个构成一个简单面。下面的代码是含有3个Array元素的Array对象构成了三个简单面。
a0,a1,a2,a3=[arcpy.Array([arcpy.Point(coords[1],coords[2],ID=coords[0]) for coords in coords_list[i]]) for i in range(len(coords_list))]
ar=arcpy.Array([a2,a3])
ar.add(arcpy.Array([arcpy.Point(*co) for co in [[122.9,31.9],[122.8,31.9],[122.8,31.8]]]))
pnt=arcpy.Polygon(ar)
由此可以看出,由Array构成的Array也不一定能保证符合我们的预期。为什么呢?
我给你两个环,你说这应该生成一个空心面呢?还是两个单独的面呢?
下面开始论述多部件几何创建的问题。
先看官方文档:
然后我们创建线,这个线是多部件的线。这个是怎么创建的呢?Array的Array。
输出后查看,发现这个多部件的线构建成功。
那么多部件的点怎么办呢?
对不起,我找不到怎么做,因为ArcMap选择两个单点并不能像线或面那样可以合并成多部件要素。
别慌,这个Point不支持,但MultiPoint支持啊。
那么多部件的面呢?
上文我们也看到了,如果是两个不相干的环,则生成一个多部件的面。
a0是外环,a1,a2,a3都是a0内的环,但不论顺序如何,即:arr=arcpy.Array([a0,a2])或arr=arcpy.Array([a2,a0])都会出现下图所示的结果。
由上图可知,即使两个环叠加在一起,也会构成一个多部件要素。但如果某个环完全包含或包含于另一个环,则这两个环将构成一个空心面。
什么?你还要这一部分完全包含另一部分的多部件几何?如果这样,你来教教我吧。
独孤尚良dugushangliang——著