Python 3.X 从 GeoJSON 加载的形状多边形
Python 3.X Shapely Polygon loaded from GeoJSON
我想使用 Shapely 包来定义一个 Polygon 点来自 OpenStreetMap。让我们看一个例子。
我从 OpenStreetMap 下载了以下 export.geojson
,其中包含 NYC Hell's kitchen 街区的边界点。
{
"type": "FeatureCollection",
"generator": "overpass-ide",
"copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.",
"timestamp": "2018-12-05T21:48:03Z",
"features": [
{
"type": "Feature",
"properties": {
"@id": "relation/8398096",
"admin_level": "10",
"alt_name": "Midtown West",
"boundary": "administrative",
"name": "Hell's Kitchen",
"place": "neighbourhood",
"type": "boundary",
"wikidata": "Q840133"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-73.996317,
40.7533999
],
[
-73.9926276,
40.7584281
],
[
-73.9897925,
40.7572376
],
[
-73.9865711,
40.7616564
],
[
-73.9828759,
40.7667118
],
[
-73.9857128,
40.7679195
],
[
-73.9847606,
40.7692277
],
[
-73.993569,
40.7729369
],
[
-73.9939928,
40.7733086
],
[
-73.9941524,
40.7733787
],
[
-73.9960903,
40.7742003
],
[
-73.9963692,
40.7738002
],
[
-73.9940733,
40.7727927
],
[
-73.9942235,
40.7725956
],
[
-73.99616,
40.7733838
],
[
-73.9964068,
40.7730913
],
[
-73.9946607,
40.7723438
],
[
-73.9948565,
40.7720959
],
[
-73.9969674,
40.7729836
],
[
-73.9973322,
40.7725205
],
[
-73.9952078,
40.7716166
],
[
-73.995409,
40.7713606
],
[
-73.995975,
40.7716003
],
[
-73.9961976,
40.7712915
],
[
-73.9959508,
40.771188
],
[
-73.9959937,
40.771129
],
[
-73.9956531,
40.7709889
],
[
-73.9958328,
40.7707451
],
[
-73.9959213,
40.7707878
],
[
-73.9962056,
40.7704465
],
[
-73.996093,
40.7703896
],
[
-73.9963827,
40.7699692
],
[
-73.9987564,
40.7709279
],
[
-73.9991614,
40.7703917
],
[
-73.9968413,
40.769376
],
[
-73.9971685,
40.7689454
],
[
-73.9995879,
40.7699773
],
[
-74.0000251,
40.7694248
],
[
-73.9967179,
40.7680576
],
[
-73.9972463,
40.7673263
],
[
-74.0005133,
40.7687077
],
[
-74.0009397,
40.7681714
],
[
-73.9976245,
40.7667697
],
[
-73.998,
40.76627
],
[
-73.9982522,
40.766268
],
[
-74.0013501,
40.7675681
],
[
-74.0019402,
40.7668043
],
[
-73.9987242,
40.7654147
],
[
-73.9989388,
40.7652502
],
[
-73.9988717,
40.7649861
],
[
-73.9991775,
40.7649556
],
[
-74.0021253,
40.7661115
],
[
-74.0026027,
40.765498
],
[
-74.0024284,
40.7654066
],
[
-74.0025812,
40.7650897
],
[
-73.9995718,
40.7638444
],
[
-74.000001,
40.7636087
],
[
-74.0031847,
40.7649516
],
[
-74.0034664,
40.764594
],
[
-74.003225,
40.7644721
],
[
-74.0033671,
40.764273
],
[
-74.0012401,
40.7633487
],
[
-74.0014815,
40.7630358
],
[
-74.0036756,
40.7639541
],
[
-74.0040135,
40.7635214
],
[
-74.0018356,
40.7625787
],
[
-74.0023103,
40.7619571
],
[
-74.0045071,
40.7628672
],
[
-74.004837,
40.7624447
],
[
-74.0025732,
40.7614573
],
[
-74.0028682,
40.761051
],
[
-73.9964148,
40.7583347
],
[
-73.9979787,
40.7561892
],
[
-73.9991507,
40.754582
],
[
-73.996317,
40.7533999
]
]
]
},
"id": "relation/8398096"
},
{
"type": "Feature",
"properties": {
"@id": "node/158852213",
"@relations": [
{
"role": "label",
"rel": 8398096,
"reltags": {
"admin_level": "10",
"alt_name": "Midtown West",
"boundary": "administrative",
"name": "Hell's Kitchen",
"place": "neighbourhood",
"type": "boundary",
"wikidata": "Q840133"
}
}
]
},
"geometry": {
"type": "Point",
"coordinates": [
-73.9923918,
40.7644228
]
},
"id": "node/158852213"
}
]
}
基于 documentation and the page 89 of this book 的 Integration 部分,我得到以下 Python 片段来定义 Polygon
的形状地狱厨房:
from shapely.geometry import mapping, shape
I=shape(json.loads(open('/Users/MyUsername/Downloads/export.geojson').read()))
I.is_valid
但我收到以下错误:
Traceback (most recent call last): File "", line 1, in
I.is_valid() NameError: name 'I' is not defined
I.is_valid Traceback (most recent call last): File "", line 1, in
I.is_valid NameError: name 'I' is not defined
Does anybody have an idea on how to fix it?
我不认为这是一个重复的问题,因为 与 GeoJSON 格式的外部文件无关。
我确定有更好的方法,但这对我有用:
import json
from shapely.geometry import Polygon
your_json_file = json.loads(open('export.geojson').read())
p1 = Polygon(your_json_file['features'][0]['geometry']['coordinates'][0])
print(p1)
在分享我的答案之前,我需要指出这个 GeoJSON 有两个几何图形:一个多边形和一个点。因此,无论您提出什么解决方案,您都必须找到一种方法来解析 GeoJSON,并且只专门挑选出地狱厨房多边形。
读取 GeoJSON 的一种非常直接的方法是使用 geopandas
库。这会将 GeoJSON 的内容读入 GeoDataFrame,它类似于 Pandas DataFrame,但有一些用于地理操作的额外功能。它使用 shapely
库来绘制实际的几何图形,这正是您真正想要的。
代码如下所示:
import geopandas as gpd
# Reading in the whole GeoJSON into a GeoDataFrame
gdf = gpd.read_file('/Users/MyUsername/Downloads/export.geojson')
# Getting the row that contains the Hell's Kitchen polygon
hk = gdf.loc[gdf['name'] == "Hell's Kitchen"].iloc[0]
# Getting the actual shapely geometry
hk_poly = hk['geometry']
在上面的代码中,代码底部的变量 hk_poly
只包含请求的地狱厨房街区的 shapely
几何图形。
我想使用 Shapely 包来定义一个 Polygon 点来自 OpenStreetMap。让我们看一个例子。
我从 OpenStreetMap 下载了以下 export.geojson
,其中包含 NYC Hell's kitchen 街区的边界点。
{
"type": "FeatureCollection",
"generator": "overpass-ide",
"copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.",
"timestamp": "2018-12-05T21:48:03Z",
"features": [
{
"type": "Feature",
"properties": {
"@id": "relation/8398096",
"admin_level": "10",
"alt_name": "Midtown West",
"boundary": "administrative",
"name": "Hell's Kitchen",
"place": "neighbourhood",
"type": "boundary",
"wikidata": "Q840133"
},
"geometry": {
"type": "Polygon",
"coordinates": [
[
[
-73.996317,
40.7533999
],
[
-73.9926276,
40.7584281
],
[
-73.9897925,
40.7572376
],
[
-73.9865711,
40.7616564
],
[
-73.9828759,
40.7667118
],
[
-73.9857128,
40.7679195
],
[
-73.9847606,
40.7692277
],
[
-73.993569,
40.7729369
],
[
-73.9939928,
40.7733086
],
[
-73.9941524,
40.7733787
],
[
-73.9960903,
40.7742003
],
[
-73.9963692,
40.7738002
],
[
-73.9940733,
40.7727927
],
[
-73.9942235,
40.7725956
],
[
-73.99616,
40.7733838
],
[
-73.9964068,
40.7730913
],
[
-73.9946607,
40.7723438
],
[
-73.9948565,
40.7720959
],
[
-73.9969674,
40.7729836
],
[
-73.9973322,
40.7725205
],
[
-73.9952078,
40.7716166
],
[
-73.995409,
40.7713606
],
[
-73.995975,
40.7716003
],
[
-73.9961976,
40.7712915
],
[
-73.9959508,
40.771188
],
[
-73.9959937,
40.771129
],
[
-73.9956531,
40.7709889
],
[
-73.9958328,
40.7707451
],
[
-73.9959213,
40.7707878
],
[
-73.9962056,
40.7704465
],
[
-73.996093,
40.7703896
],
[
-73.9963827,
40.7699692
],
[
-73.9987564,
40.7709279
],
[
-73.9991614,
40.7703917
],
[
-73.9968413,
40.769376
],
[
-73.9971685,
40.7689454
],
[
-73.9995879,
40.7699773
],
[
-74.0000251,
40.7694248
],
[
-73.9967179,
40.7680576
],
[
-73.9972463,
40.7673263
],
[
-74.0005133,
40.7687077
],
[
-74.0009397,
40.7681714
],
[
-73.9976245,
40.7667697
],
[
-73.998,
40.76627
],
[
-73.9982522,
40.766268
],
[
-74.0013501,
40.7675681
],
[
-74.0019402,
40.7668043
],
[
-73.9987242,
40.7654147
],
[
-73.9989388,
40.7652502
],
[
-73.9988717,
40.7649861
],
[
-73.9991775,
40.7649556
],
[
-74.0021253,
40.7661115
],
[
-74.0026027,
40.765498
],
[
-74.0024284,
40.7654066
],
[
-74.0025812,
40.7650897
],
[
-73.9995718,
40.7638444
],
[
-74.000001,
40.7636087
],
[
-74.0031847,
40.7649516
],
[
-74.0034664,
40.764594
],
[
-74.003225,
40.7644721
],
[
-74.0033671,
40.764273
],
[
-74.0012401,
40.7633487
],
[
-74.0014815,
40.7630358
],
[
-74.0036756,
40.7639541
],
[
-74.0040135,
40.7635214
],
[
-74.0018356,
40.7625787
],
[
-74.0023103,
40.7619571
],
[
-74.0045071,
40.7628672
],
[
-74.004837,
40.7624447
],
[
-74.0025732,
40.7614573
],
[
-74.0028682,
40.761051
],
[
-73.9964148,
40.7583347
],
[
-73.9979787,
40.7561892
],
[
-73.9991507,
40.754582
],
[
-73.996317,
40.7533999
]
]
]
},
"id": "relation/8398096"
},
{
"type": "Feature",
"properties": {
"@id": "node/158852213",
"@relations": [
{
"role": "label",
"rel": 8398096,
"reltags": {
"admin_level": "10",
"alt_name": "Midtown West",
"boundary": "administrative",
"name": "Hell's Kitchen",
"place": "neighbourhood",
"type": "boundary",
"wikidata": "Q840133"
}
}
]
},
"geometry": {
"type": "Point",
"coordinates": [
-73.9923918,
40.7644228
]
},
"id": "node/158852213"
}
]
}
基于 documentation and the page 89 of this book 的 Integration 部分,我得到以下 Python 片段来定义 Polygon
的形状地狱厨房:
from shapely.geometry import mapping, shape
I=shape(json.loads(open('/Users/MyUsername/Downloads/export.geojson').read()))
I.is_valid
但我收到以下错误:
Traceback (most recent call last): File "", line 1, in I.is_valid() NameError: name 'I' is not defined
I.is_valid Traceback (most recent call last): File "", line 1, in I.is_valid NameError: name 'I' is not defined Does anybody have an idea on how to fix it?
我不认为这是一个重复的问题,因为
我确定有更好的方法,但这对我有用:
import json
from shapely.geometry import Polygon
your_json_file = json.loads(open('export.geojson').read())
p1 = Polygon(your_json_file['features'][0]['geometry']['coordinates'][0])
print(p1)
在分享我的答案之前,我需要指出这个 GeoJSON 有两个几何图形:一个多边形和一个点。因此,无论您提出什么解决方案,您都必须找到一种方法来解析 GeoJSON,并且只专门挑选出地狱厨房多边形。
读取 GeoJSON 的一种非常直接的方法是使用 geopandas
库。这会将 GeoJSON 的内容读入 GeoDataFrame,它类似于 Pandas DataFrame,但有一些用于地理操作的额外功能。它使用 shapely
库来绘制实际的几何图形,这正是您真正想要的。
代码如下所示:
import geopandas as gpd
# Reading in the whole GeoJSON into a GeoDataFrame
gdf = gpd.read_file('/Users/MyUsername/Downloads/export.geojson')
# Getting the row that contains the Hell's Kitchen polygon
hk = gdf.loc[gdf['name'] == "Hell's Kitchen"].iloc[0]
# Getting the actual shapely geometry
hk_poly = hk['geometry']
在上面的代码中,代码底部的变量 hk_poly
只包含请求的地狱厨房街区的 shapely
几何图形。