Given land polygons as a Shapely MultiPolygon
, I want to find the (Multi-)Polygon that represents the e.g. 12 nautical mile buffer around the coastlines.
Using the Shapely buffer
method does not work since it uses euclidean calculations.
Can somebody tell me how to calculate geodesic buffers in python?
Geodesic buffers account for the earth's actual shape in the calculation of the buffers. The earth is an ellipsoid (or, more properly, a geoid), and when the Buffer tool generates geodesic buffers, distances are measured between two points on a globe.
Geodesic buffers were generated by buffering a point feature class with a geographic coordinate system, and Euclidean buffers were generated by buffering a point feature class with a projected coordinate system (in both the projected and unprojected datasets the points represent the same cities).
You can use the Buffer tool to identify or define an area within a specified distance around a feature. For example, you may create a buffer to define an area around a river to identify land that can't be developed, or you may want to create a buffer to select features within a specified distance of a feature.
This is not a shapely problem, since shapely explicitly tells in its documentation that the library is for planar computation only. Nevertheless, in order to answer your question, you should specify the coordinate systems you are using for your multipolygons.
Assuming you are using WGS84 projection (lat,lon), this is a recipe I found in another SO question (fix-up-shapely-polygon-object-when-discontinuous-after-map-projection). You will need pyproj
library.
import pyproj
from shapely.geometry import MultiPolygon, Polygon
from shapely.ops import transform as sh_transform
from functools import partial
wgs84_globe = pyproj.Proj(proj='latlong', ellps='WGS84')
def pol_buff_on_globe(pol, radius):
_lon, _lat = pol.centroid.coords[0]
aeqd = pyproj.Proj(proj='aeqd', ellps='WGS84', datum='WGS84',
lat_0=_lat, lon_0=_lon)
project_pol = sh_transform(partial(pyproj.transform, wgs84_globe, aeqd), pol)
return sh_transform( partial(pyproj.transform, aeqd, wgs84_globe),
project_pol.buffer(radius))
def multipol_buff_on_globe(multipol, radius):
return MultiPolygon([pol_buff_on_globe(g, radius) for g in multipol])
pol_buff_on_globe
function does the following. First, build an azimuthal equidistant projection centered in the polygon centroid. Then, change the coordinate system of the polygon to that projection. After that, builds the buffer there, and then change the coordinate system of the buffered polygon to WGS84 coordinate system.
Some special care is needed:
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