I would like to calculate the percentage of overlap between a shapefile and a polygon. I'm using Cartopy and Matplotlib and created the map shown here:
A part of Europe (using a shapefile downloaded here) and an arbitrary rectangle are shown. Let's say I would like to calculate the percentage of Belgium that is covered by the rectangle. How would I do this? Below, the code so far is shown.
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))
You can use the GDAL/OGR Python bindings for that. It returns None if they don't intersect. If they intersect it returns the geometry were both intersect. Also you can find further infos in the GDAL/OGR Cookbook .
A LineString has zero area and non-zero length. >>> from shapely.geometry import LineString >>> line = LineString([(0, 0), (1, 1)]) >>> line. area 0.0 >>> line. length 1.4142135623730951. Its x-y bounding box is a (minx, miny, maxx, maxy) tuple.
To import shapefiles you use the geopandas function read_file() . Notice that you call the read_file() function using gpd. read_file() to tell python to look for the function within the geopandas library.
Based on all the answers/comments posted by others, eventually it worked when I added these lines at the end. I could not have done it without the help of the respondees:
#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,'%')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With