Python: 如何检查形状区域是否包含点?
Python: how to check if shape areas contain points?
我有一个 shapefile
的新加坡,我是这样想象的:
import shapefile
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
### Plot shapefile
sf = shapefile.Reader("myShape.shp")
recs = sf.records()
shapes = sf.shapes()
Nshp = len(shapes)
cns = []
for nshp in xrange(Nshp):
cns.append(recs[nshp][1])
cns = array(cns)
cm = get_cmap('Dark2')
cccol = cm(1.*arange(Nshp)/Nshp)
# -- plot --
fig,ax = plt.subplots(figsize=(20,10))
for nshp in xrange(Nshp):
ptchs = []
pts = array(shapes[nshp].points)
prt = shapes[nshp].parts
par = list(prt) + [pts.shape[0]]
for pij in xrange(len(prt)):
ptchs.append(Polygon(pts[par[pij]:par[pij+1]]))
ax.add_collection(PatchCollection(ptchs,facecolor=cccol[nshp,:],edgecolor='k', linewidths=.1))
ax.set_xlim(103.6,104.1)
ax.set_ylim(1.15,1.48)
现在我有一个坐标在 dataframe
中的点列表,我想检查这些点在 shapefile 的哪个区域。
mypoints
lon lat
0 103.619740 1.280485
1 103.622632 1.268944
2 103.622632 1.274714
3 103.622632 1.277600
4 103.622632 1.280485
特别是从 shapefile
我可以提取特定区域的信息,例如 name
。事实上,在 recs
我有这个信息。例如:
recs[0]:
[42,
1,
'STRAITS VIEW',
'SVSZ01',
'Y',
'STRAITS VIEW',
'SV',
'CENTRAL REGION',
'CR',
'21451799CA1AB6EF',
datetime.date(2016, 5, 11),
30832.9017,
28194.0843,
5277.76082729,
1127297.23737]
在这种情况下,STRAITS VIEW
是区域的名称。最后我想要一个 dataframe
像:
mypoints
lon lat name
0 103.619740 1.280485 STRAITS VIEW
1 103.622632 1.268944 STRAITS VIEW
2 103.622632 1.274714 DOWNTOWN
3 103.622632 1.277600 BEDOK
4 103.622632 1.280485 CHANGI
要检查坐标是否位于某个多边形内,您可以使用 GDAL 中的 Intersects 方法。此方法比较两个 OGRGeometry
对象和 return 指示它们是否拦截的布尔值。
有了这个,您可以遍历您的点,并针对每个点测试它是否 Intersects()
与您的所有多边形区域。它应该看起来像:
for point_geom in your_points:
#iterate over your area polygons and check
for area_geom in your_areas:
if area_geom.Intersects(point_geom):
#then you have a match, save or do as you want
注意: 如果您的观点是 而不是 OGRGeometry
(您的多边形很可能与您正在阅读的一样来自 Shapefile),您可以按照建议创建此类几何体 here:
from osgeo import ogr
point = ogr.Geometry(ogr.wkbPoint)
point.AddPoint(1198054.34, 648493.09)
对于多边形:
ring = ogr.Geometry(ogr.wkbLinearRing)
ring.AddPoint(1179091.1646903288, 712782.8838459781)
ring.AddPoint(1161053.0218226474, 667456.2684348812)
#etc...add all your points, in a loop would be better
# Create polygon
poly = ogr.Geometry(ogr.wkbPolygon)
poly.AddGeometry(ring)
我有一个 shapefile
的新加坡,我是这样想象的:
import shapefile
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
### Plot shapefile
sf = shapefile.Reader("myShape.shp")
recs = sf.records()
shapes = sf.shapes()
Nshp = len(shapes)
cns = []
for nshp in xrange(Nshp):
cns.append(recs[nshp][1])
cns = array(cns)
cm = get_cmap('Dark2')
cccol = cm(1.*arange(Nshp)/Nshp)
# -- plot --
fig,ax = plt.subplots(figsize=(20,10))
for nshp in xrange(Nshp):
ptchs = []
pts = array(shapes[nshp].points)
prt = shapes[nshp].parts
par = list(prt) + [pts.shape[0]]
for pij in xrange(len(prt)):
ptchs.append(Polygon(pts[par[pij]:par[pij+1]]))
ax.add_collection(PatchCollection(ptchs,facecolor=cccol[nshp,:],edgecolor='k', linewidths=.1))
ax.set_xlim(103.6,104.1)
ax.set_ylim(1.15,1.48)
现在我有一个坐标在 dataframe
中的点列表,我想检查这些点在 shapefile 的哪个区域。
mypoints
lon lat
0 103.619740 1.280485
1 103.622632 1.268944
2 103.622632 1.274714
3 103.622632 1.277600
4 103.622632 1.280485
特别是从 shapefile
我可以提取特定区域的信息,例如 name
。事实上,在 recs
我有这个信息。例如:
recs[0]:
[42,
1,
'STRAITS VIEW',
'SVSZ01',
'Y',
'STRAITS VIEW',
'SV',
'CENTRAL REGION',
'CR',
'21451799CA1AB6EF',
datetime.date(2016, 5, 11),
30832.9017,
28194.0843,
5277.76082729,
1127297.23737]
在这种情况下,STRAITS VIEW
是区域的名称。最后我想要一个 dataframe
像:
mypoints
lon lat name
0 103.619740 1.280485 STRAITS VIEW
1 103.622632 1.268944 STRAITS VIEW
2 103.622632 1.274714 DOWNTOWN
3 103.622632 1.277600 BEDOK
4 103.622632 1.280485 CHANGI
要检查坐标是否位于某个多边形内,您可以使用 GDAL 中的 Intersects 方法。此方法比较两个 OGRGeometry
对象和 return 指示它们是否拦截的布尔值。
有了这个,您可以遍历您的点,并针对每个点测试它是否 Intersects()
与您的所有多边形区域。它应该看起来像:
for point_geom in your_points:
#iterate over your area polygons and check
for area_geom in your_areas:
if area_geom.Intersects(point_geom):
#then you have a match, save or do as you want
注意: 如果您的观点是 而不是 OGRGeometry
(您的多边形很可能与您正在阅读的一样来自 Shapefile),您可以按照建议创建此类几何体 here:
from osgeo import ogr
point = ogr.Geometry(ogr.wkbPoint)
point.AddPoint(1198054.34, 648493.09)
对于多边形:
ring = ogr.Geometry(ogr.wkbLinearRing)
ring.AddPoint(1179091.1646903288, 712782.8838459781)
ring.AddPoint(1161053.0218226474, 667456.2684348812)
#etc...add all your points, in a loop would be better
# Create polygon
poly = ogr.Geometry(ogr.wkbPolygon)
poly.AddGeometry(ring)