我想计算shapefile和多边形之间的重叠百分比。我使用了Cartopy和Matplotlib并创建了这里显示的地图:
显示欧洲的一部分(使用shapefile下载here)和任意矩形。让我们说我想计算矩形覆盖的比利时百分比。我该怎么做?下面显示了到目前为止的代码。
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.shapereader as shapereader
from shapely.geometry import Polygon
from descartes import PolygonPatch
#create figure
fig1 = plt.figure(figsize=(10,10))
PLT = plt.axes(projection=ccrs.PlateCarree())
PLT.set_extent([-10,10,45,55])
PLT.gridlines()
#import and display shapefile
fname = r'C:\Users\Me\ne_50m_admin_0_countries.shp'
adm1_shapes = list(shapereader.Reader(fname).geometries())
PLT.add_geometries(adm1_shapes, ccrs.PlateCarree(),
edgecolor='black', facecolor='gray', alpha=0.5)
#create arbitrary polygon
x3 = 4
x4 = 5
y3 = 50
y4 = 52
poly = Polygon([(x3,y3),(x3,y4),(x4,y4),(x4,y3)])
PLT.add_patch(PolygonPatch(poly, fc='#cc00cc', ec='#555555', alpha=0.5,
zorder=5))
答案 0 :(得分:2)
嗯,您需要某种方式来获取整个地图的区域以及该国家/地区的区域。多边形的区域可能是最简单的部分。
我建议从更基本的东西开始,也许只是一个网格和两个简单的形状,这可以帮助你设想如何在更复杂的层面上完成它。
答案 1 :(得分:2)
如果你有两个多边形的形状。您可以执行以下操作:
from shapely.geometry import Polygon
p1=Polygon([(0,0),(1,1),(1,0)])
p2=Polygon([(0,1),(1,0),(1,1)])
p3=p1.intersection(p2)
print(p3) # result: POLYGON ((0.5 0.5, 1 1, 1 0, 0.5 0.5))
print(p3.area) # result: 0.25
当然,我过分简化问题,结果很可能是欧几里得地区,这可能不是你需要的。如上所述,对于球体表面上的多边形区域,您可以验证following reference中的代码。为了获得灵感,您还可以验证matlab函数areaint n。我不知道它是否直接存在于python中的类似函数。
答案 2 :(得分:2)
基于其他人发布的所有答案/评论,最终我在最后添加这些行时起作用了。没有受访者的帮助,我无法做到:
#find the Belgium polygon.
for country in shapereader.Reader(fname).records():
if country.attributes['SOV_A3'] == 'BEL':
Belgium = country.geometry
break
PLT.add_patch(PolygonPatch(poly.intersection(Belgium), fc='#009900', alpha=1))
#calculate coverage
x = poly.intersection(Belgium)
print ('Coverage: ', x.area/Belgium.area*100,'%')
答案 3 :(得分:0)
我正在利用给出的答案来找到两个旋转的矩形的交集(请找到原始答案here)。如果您觉得它有用,请不要回答这个答案,但请继续投票给原始海报。我不赞成这一点。此外,这个答案必须适应您的具体情况。
TL:DR答案涉及使用shapely。
import shapely.geometry
import shapely.affinity
class RotatedRect:
def __init__(self, cx, cy, w, h, angle):
self.cx = cx
self.cy = cy
self.w = w
self.h = h
self.angle = angle
def get_contour(self):
w = self.w
h = self.h
c = shapely.geometry.box(-w/2.0, -h/2.0, w/2.0, h/2.0)
rc = shapely.affinity.rotate(c, self.angle)
return shapely.affinity.translate(rc, self.cx, self.cy)
def intersection(self, other):
return self.get_contour().intersection(other.get_contour())
r1 = RotatedRect(10, 15, 15, 10, 30)
r2 = RotatedRect(15, 15, 20, 10, 0)
from matplotlib import pyplot
from descartes import PolygonPatch
fig = pyplot.figure(1, figsize=(10, 4))
ax = fig.add_subplot(121)
ax.set_xlim(0, 30)
ax.set_ylim(0, 30)
ax.add_patch(PolygonPatch(r1.get_contour(), fc='#990000', alpha=0.7))
ax.add_patch(PolygonPatch(r2.get_contour(), fc='#000099', alpha=0.7))
ax.add_patch(PolygonPatch(r1.intersection(r2), fc='#009900', alpha=1))
pyplot.show()