Shapely单个Polygon有效但构造MultiPolygon报错原因
问题描述
正在尝试将多边形坐标集合转换为WKT格式,该集合应当被识别为MultiPolygon类型,对应数据结构如下:
'geometry': [[[129093.87770000007, 6638201.563100001], [129145.82270000037, 6638246.0934], [129170.66339999996, 6638267.387800001], [129234.25879999995, 6638194.9081], [129263.13030000031, 6638162.0021], [129256.51460000034, 6638153.420600001], [129264.29519999959, 6638144.4186], [129227.29739999957, 6638111.6921], [129198.93099999987, 6638086.598099999], [129197.43379999977, 6638085.2764], [129189.4422000004, 6638094.0996], [129176.43039999995, 6638108.3499], [129159.07469999976, 6638127.3638], [129151.15539999958, 6638136.5965], [129133.93259999994, 6638156.149599999], [129159.67819999997, 6638179.257999999], [129154.22589999996, 6638185.2235], [129151.20010000002, 6638188.5338], [129146.49629999977, 6638193.680299999], [129143.46549999993, 6638196.9956], [129136.80140000023, 6638191.0813], [129117.92229999974, 6638174.326099999], [129101.88219999988, 6638192.5428], [129100.7592000002, 6638193.8189], [129093.87770000007, 6638201.563100001]], [[128941.56969999988, 6638372.659700001], [128943.42590000015, 6638374.3345], [128960.41220000014, 6638389.665999999], [128973.69660000037, 6638401.5129], [128996.57529999968, 6638375.679], [128987.46860000025, 6638367.0911], [128983.83999999985, 6638363.6691], [128972.29009999987, 6638376.4816], [128953.31819999963, 6638359.575999999], [128943.23959999997, 6638370.7996], [128941.56969999988, 6638372.659700001]], [[129090.9358000001, 6638503.8179], [129097.49689999968, 6638510.4618], [129097.59499999974, 6638513.236199999], [129134.7444000002, 6638546.606799999], [129147.49670000002, 6638558.0616], [129149.08770000003, 6638558.060900001], [129150.47169999965, 6638558.0603], [129176.9729000004, 6638534.216700001], [129176.96339999977, 6638531.551899999], [129160.03479999956, 6638516.535], [129124.70949999988, 6638485.1993], [129121.82320000045, 6638485.3100000005], [129115.54370000027, 6638479.5166], [129090.9358000001, 6638503.8179]], [[129158.46559999976, 6638281.2897], [129181.3964999998, 6638301.693600001], [129202.42819999997, 6638320.4079], [129222.96760000009, 6638338.684900001], [129228.84059999976, 6638332.3202], [129164.44720000029, 6638274.4724], [129158.46559999976, 6638281.2897]], [[129129.06099999975, 6638386.475199999], [129155.41009999998, 6638410.2303], [129169.55939999968, 6638422.9824], [129172.49909999967, 6638422.9364], [129180.67559999973, 6638429.6515], [129180.72410000023, 6638433.040999999], [129214.33800000045, 6638463.1961], [129235.7324000001, 6638482.398399999], [129238.75250000041, 6638482.4419], [129272.70870000031, 6638453.891899999], [129276.91830000002, 6638450.3521], [129311.60599999968, 6638421.1872000005], [129313.13900000043, 6638419.8989], [129312.24859999958, 6638419.095799999], [129319.1475999998, 6638413.4484], [129256.64639999997, 6638357.3002], [129250.38129999954, 6638363.2841], [129248.93879999965, 6638364.661900001], [129224.56620000023, 6638387.8639], [129203.5848000003, 6638407.837400001], [129202.72339999955, 6638408.6601], [129195.30989999976, 6638401.2228999995], [129179.70480000041, 6638385.5688000005], [129178.5390999997, 6638384.5253], [129160.28000000026, 6638368.1357], [129151.56759999972, 6638360.3236], [129129.06099999975, 6638386.475199999]]], 'type': 'MultiPolygon'}
执行如下构造代码时触发错误:
from shapely.geometry import Point, Polygon, MultiPolygon MultiPolygon(jk['geometry'])
报错信息如下,先后抛出TypeError与AttributeError:
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) File /usr/local/lib/python3.10/dist-packages/shapely/geometry/multipolygon.py:189, in geos_multipolygon_from_polygons(arg) 188 try: --> 189 N = len(exemplar[0][0]) 190 except TypeError: TypeError: object of type 'float' has no len() During handling of the above exception, another exception occurred: AttributeError Traceback (most recent call last) Input In [68], in <cell line: 1>() ----> 1 MultiPolygon(jk['geometry']) File /usr/local/lib/python3.10/dist-packages/shapely/geometry/multipolygon.py:60, in MultiPolygon.__init__(self, polygons, context_type) 58 return 59 elif context_type == 'polygons': ---> 60 geom, n = geos_multipolygon_from_polygons(polygons) 61 elif context_type == 'geojson': 62 geom, n = geos_multipolygon_from_py(polygons) File /usr/local/lib/python3.10/dist-packages/shapely/geometry/multipolygon.py:191, in geos_multipolygon_from_polygons(arg) 189 N = len(exemplar[0][0]) 190 except TypeError: --> 191 N = exemplar._ndim 193 assert N == 2 or N == 3 195 subs = (c_void_p * L)() AttributeError: 'list' object has no attribute '_ndim'
经测试,集合内的单个多边形坐标均有效,如下代码可正常执行,成功输出每个Polygon的WKT内容:
import shapely for item in jk['geometry']: print(shapely.wkt.dumps(Polygon(item)))
问题原因
报错的核心原因是传入MultiPolygon构造函数的参数嵌套层级不符合要求:
- 你传入的
jk['geometry']是3层嵌套结构,结构为[多边形1外环坐标点列表, 多边形2外环坐标点列表, ...],每个元素是单个多边形的外环坐标数组,刚好符合单个Polygon对象的构造输入要求,这也是为什么循环构造单个Polygon可以正常运行。 - Shapely的
MultiPolygon构造函数在默认polygons上下文下,只接受两类输入:- 已经实例化完成的
Polygon对象组成的序列 - 4层嵌套的纯坐标结构,格式为
[[[多边形1外环坐标点], [多边形1内环1坐标点], [多边形1内环2坐标点]...], [多边形2结构], ...],每个多边形对应一个外层元素,元素内部第一个数组是外环,后续数组是可选的内环(洞)坐标。
- 已经实例化完成的
- 你传入3层坐标列表时,构造函数误将第一个多边形的外环数组当成单个多边形的完整结构,继续向下解析时拿到的是
[x, y]形式的浮点数坐标对,尝试对浮点数取长度触发第一个TypeError;后续异常处理逻辑将当前输入当成Shapely内置几何对象读取_ndim属性,因为输入是普通Python列表,触发第二个AttributeError。
解决方法
两种方案均可正常构造MultiPolygon并转换为WKT:
- 方案1:先逐个
相关产品推荐
相关产品推荐

