如何使用 geopandas 或 shapely 提取内部多边形的坐标?
How can I extract the coordinates of an interior polygon using geopandas or shapely?
我有一个英国 county/unitary 当局 (UTLA) 的 geojson 文件,我已经使用 geopandas 阅读了该文件。我试图获得每个 UTLA 的匀称多边形,但我 运行 遇到包含其他 UTLA(即内部多边形)的 UTLA 的问题,例如德比郡。
我正在尝试提取内部多边形的坐标:
import geopandas as gpd
utla_polygons = gpd.read_file('https://opendata.arcgis.com/datasets/244b257482da4778995cf11ff99e9997_0.geojson')
derbs = utla_polygons[utla_polygons['CTYUA21NM']=='Derbyshire']
derbs_int = derbs.explode().geometry.interiors
derbs_int
derbs_int 是我期望的样子,基于 geopandas documentation:
130 0 [LINEARRING (-1.484521649999976 52.96638748100...
dtype: object
但是,当我尝试从 derbs_int 中提取坐标时,出现以下错误:
derbs_int.coords
AttributeError: 'Series' object has no attribute 'coords'
如何提取这些坐标以便使用它们来创建形状优美的多边形?
从多边形中移除内部多边形的一种方法是访问 JSON 并获取多边形元素的第一个环。
from shapely.geometry import shape
import requests
url = 'https://opendata.arcgis.com/datasets/244b257482da4778995cf11ff99e9997_0.geojson'
r = requests.get(url)
data = r.json()
for f in data['features']:
if f['properties']['CTYUA21NM'] == 'Derbyshire':
geom = f['geometry']
if geom.get('type') == 'MultiPolygon':
print("BEFORE:")
for p in shape(geom).geoms:
print(len(p.interiors))
geom = [g[0] for g in geom['coordinates']]
geom = shape({
'type': 'MultiPolygon',
'coordinates': [geom]
})
# geom is a MultiPolygon instance with polygons only having an exterior ring
print("AFTER:")
for p in geom.geoms:
print(len(p.interiors))
break
输出:
BEFORE:
1
AFTER:
0
0 表示多边形没有内环。
需要系统化。多边形包含多边形,多边形包含内部,内部有坐标
import geopandas as gpd
import requests
res = requests.get(
"https://opendata.arcgis.com/datasets/244b257482da4778995cf11ff99e9997_0.geojson"
)
gdf = gpd.GeoDataFrame.from_features(res.json()).set_crs("epsg:4326")
gdfd = gdf.loc[gdf["CTYUA21NM"].str.contains("Derbyshire")].copy()
gdfd["geometry"].apply(
lambda g: [g3.coords for g2 in g.geoms for g3 in g2.interiors]
).explode().explode()
输出
130 (-1.484521649999976, 52.96638748100003)
130 (-1.484809956999925, 52.96630955400008)
130 (-1.484938351999972, 52.96627955300005)
130 (-1.485184568999955, 52.96623118800005)
130 (-1.48530681099993, 52.96621284400004)
...
130 (-1.483622200999946, 52.96727346400007)
130 (-1.483387032999929, 52.96689850300004)
130 (-1.483327163999945, 52.966792199000054)
130 (-1.483532068999978, 52.966718497000045)
130 (-1.484521649999976, 52.96638748100003)
Name: geometry, Length: 1587, dtype: object
我有一个英国 county/unitary 当局 (UTLA) 的 geojson 文件,我已经使用 geopandas 阅读了该文件。我试图获得每个 UTLA 的匀称多边形,但我 运行 遇到包含其他 UTLA(即内部多边形)的 UTLA 的问题,例如德比郡。
我正在尝试提取内部多边形的坐标:
import geopandas as gpd
utla_polygons = gpd.read_file('https://opendata.arcgis.com/datasets/244b257482da4778995cf11ff99e9997_0.geojson')
derbs = utla_polygons[utla_polygons['CTYUA21NM']=='Derbyshire']
derbs_int = derbs.explode().geometry.interiors
derbs_int
derbs_int 是我期望的样子,基于 geopandas documentation:
130 0 [LINEARRING (-1.484521649999976 52.96638748100...
dtype: object
但是,当我尝试从 derbs_int 中提取坐标时,出现以下错误:
derbs_int.coords
AttributeError: 'Series' object has no attribute 'coords'
如何提取这些坐标以便使用它们来创建形状优美的多边形?
从多边形中移除内部多边形的一种方法是访问 JSON 并获取多边形元素的第一个环。
from shapely.geometry import shape
import requests
url = 'https://opendata.arcgis.com/datasets/244b257482da4778995cf11ff99e9997_0.geojson'
r = requests.get(url)
data = r.json()
for f in data['features']:
if f['properties']['CTYUA21NM'] == 'Derbyshire':
geom = f['geometry']
if geom.get('type') == 'MultiPolygon':
print("BEFORE:")
for p in shape(geom).geoms:
print(len(p.interiors))
geom = [g[0] for g in geom['coordinates']]
geom = shape({
'type': 'MultiPolygon',
'coordinates': [geom]
})
# geom is a MultiPolygon instance with polygons only having an exterior ring
print("AFTER:")
for p in geom.geoms:
print(len(p.interiors))
break
输出:
BEFORE:
1
AFTER:
0
0 表示多边形没有内环。
需要系统化。多边形包含多边形,多边形包含内部,内部有坐标
import geopandas as gpd
import requests
res = requests.get(
"https://opendata.arcgis.com/datasets/244b257482da4778995cf11ff99e9997_0.geojson"
)
gdf = gpd.GeoDataFrame.from_features(res.json()).set_crs("epsg:4326")
gdfd = gdf.loc[gdf["CTYUA21NM"].str.contains("Derbyshire")].copy()
gdfd["geometry"].apply(
lambda g: [g3.coords for g2 in g.geoms for g3 in g2.interiors]
).explode().explode()
输出
130 (-1.484521649999976, 52.96638748100003)
130 (-1.484809956999925, 52.96630955400008)
130 (-1.484938351999972, 52.96627955300005)
130 (-1.485184568999955, 52.96623118800005)
130 (-1.48530681099993, 52.96621284400004)
...
130 (-1.483622200999946, 52.96727346400007)
130 (-1.483387032999929, 52.96689850300004)
130 (-1.483327163999945, 52.966792199000054)
130 (-1.483532068999978, 52.966718497000045)
130 (-1.484521649999976, 52.96638748100003)
Name: geometry, Length: 1587, dtype: object