You need to do what you say. For that, you will need to use a library that handles projections (pyproj
is the choice here). There is a similar question in Geodesic buffering in python
import pyproj
from shapely.geometry import MultiPolygon, Polygon, Point
from shapely.ops import transform as sh_transform
from functools import partial
wgs84_globe = pyproj.Proj(proj='latlong', ellps='WGS84')
def point_buff_on_globe(lat, lon, radius):
#First, you build the Azimuthal Equidistant Projection centered in the
# point given by WGS84 lat, lon coordinates
aeqd = pyproj.Proj(proj='aeqd', ellps='WGS84', datum='WGS84',
lat_0=lat, lon_0=lon)
#You then transform the coordinates of that point in that projection
project_coords = pyproj.transform(wgs84_globe, aeqd, lon, lat)
# Build a shapely point with that coordinates and buffer it in the aeqd projection
aeqd_buffer = Point(project_coords).buffer(radius)
# Transform back to WGS84 each coordinate of the aeqd buffer.
# Notice the clever use of sh_transform with partial functor, this is
# something that I learned here in SO. A plain iteration in the coordinates
# will do the job too.
projected_pol = sh_transform(partial(pyproj.transform, aeqd, wgs84_globe),
aeqd_buffer)
return projected_pol
The function point_buff_on_globe
will give you a polygon in lat lon that is the result of buffering the given point in the Azimuthal Equidistant Projection centered in that point (the best you can do with your requirements. Two observations:
- I don't remember the units of the
radius
argument. I think is in meters, so if you need a 10 km buffer, you will need to pass it 10e3. But please, check it!
- Beware of using this with radius to wide or points that are to far away from each other. Projections work well when the points are near to the point you are centering the projection.