Вы можете использовать библиотеку proj4, чтобы описать круг, используя расстояние большого круга.
Например, вот радиус 3000 км от Эдинбурга, Токио, Кейптауна и Кито в wgs84 / Equirectangular. Только Кито смутно «круглый» из-за его близости к экватору. Я также добавил в единую уплотненную спицевую линию с азимутом 36 градусов (приблизительно к северо-востоку)
Если мы перейдем к азимутальной эквидистантной проекции с центром в Эдинбурге, вы увидите, что радиус вокруг Эдинбурга переходит в круг ...
В Mercator (как и в вашем веб-приложении) вы видите больше искажений по мере удаления от экватора, но буферы более эллиптические.
Следующий код Python делает это (требует pyproj и shapely )
import pyproj
from shapely.geometry import Polygon, MultiPoint, LineString
import math
def geodesicpointbuffer(longitude, latitude,
segments, distance_m,
geom_type=MultiPoint):
"""
Creates a buffer in meters around a point given as long, lat in WGS84
Uses the geodesic, so should be more accurate over larger distances
:param longitude: center point longitude
:param latitude: center point latitude
:param segments: segments to approximate (more = smoother)
:param distance_m: distance in meters
:param geom_type: shapely type (e.g. Multipoint, Linestring, Polygon)
:return: tuple (proj4 string, WKT of buffer geometry)
"""
geodesic = pyproj.Geod(ellps='WGS84')
coords = []
for i in range(0, segments):
angle = (360.0 / segments) * float(i)
x1, y1, z1 = geodesic.fwd(lons=longitude,
lats=latitude,
az=angle,
dist=distance_m,
radians=False)
coords.append((x1, y1))
# makes a great circle for one spoke.
if i==200:
example = geodesic.npts(longitude,latitude,x1,y1,1000)
coords2 = []
for xx,yy in example:
coords2.append((xx,yy))
coords2.append((x1,y1)) # make sure we include endpoint ;-)
flight = LineString(coords2)
print(flight.wkt)
ring = geom_type(coords)
return "+init=EPSG:4326", ring.wkt
def main():
# example : Cape Town. 3000km buffer.
spec, wkt = geodesicpointbuffer(18.4637082653, -33.8496404007, 2000, 3000000.0, Polygon)
print(spec)
print(wkt)
if __name__ == "__main__":
main()
Вы можете вставить вывод WKT в QGIS, используя полезный плагин QuickWKT .
Вы можете использовать другие методы - как упоминалось в coneypylon, вы можете создать круг на собственной эквидистантной проекции в метрах, центрированной по вашей начальной точке. Я обнаружил, что на больших расстояниях появляется ошибка (всего несколько километров на 2000 км, но на межконтинентальных расстояниях эти ошибки могут возрасти)
По памяти плагин mmqgis позволяет буферизовать в км. Я не уверен, какой метод он использует, хотя.
Обратите внимание, что у вас могут возникнуть проблемы с рендерингом полигонов в QGIS, которые пересекают антимеридиан, если вы начинаете в Азии - здесь может помочь ogr2ogr с опцией -wrapdateline . Вы можете обнаружить, что это меньше проблем с открытыми слоями / листовкой, IIRC они позволяют долготы больше 180 и меньше -180.
В блоге esri есть хорошая статья о геодезической буферизации .