GeoDjango: как создать круг на основе точки и радиуса

У меня есть следующая (упрощенная) модель:

class Zone(gismodels.Model):
    name = gismodels.CharField()
    poly = gismodels.PolygonField()

Я хочу создать и сохранить многоугольник, представляющий круг, на основе заданной точки и радиуса.

Единственный способ, которым я могу понять, как этого добиться, - это вызвать функцию postgis ST_Buffer с использованием необработанного SQL. Я очень надеюсь, что есть другой способ.

Можно ли получить доступ к методам буфера GEOS?


person MattRowbum    schedule 13.02.2011    source источник


Ответы (2)


Да, можно использовать метод буфера geos< /а>:

>>> from django.contrib.gis import geos
>>> center = geos.Point(5, 5)
>>> radius = 2
>>> circle = center.buffer(radius)
>>> circle
<Polygon object at 0x1029d8370>

Радиус здесь в тех же единицах, что и координаты точек. Это будет работать для некоторых систем координат, таких как UTM, но не для других.

Кроме того, хотя это подходит для построения круговой геометрии, в документации PostGIS отмечается, что для выполнения поиск по радиусу ST_DWithin более эффективен.

person tcarobruce    schedule 15.02.2011
comment
Спасибо за Ваш ответ. У меня есть радиус в километрах, и моя точка создается с использованием пары долгота/широта в градусах. Нужно ли мне конвертировать радиус в градусы, чтобы получить полезный результат, или для этого есть встроенная функция? - person MattRowbum; 17.02.2011
comment
@MattRowbum - вам нужно преобразовать километры в градусы. Кроме того, это оставит вам овалы, которые становятся более растянутыми по мере удаления от экватора. PostGIS теперь позволяет тип географии, который вам больше нужен, но я не смог найти способ получить к нему доступ через API GEOS в GeoDjango. - person tcarobruce; 21.02.2011
comment
Как преобразовать километры в градусы: конвертировать километры в градусы в geodjango geos"> stackoverflow.com/questions/5217348/ - person fmalina; 16.06.2013

Я потратил смехотворное количество времени, пытаясь заставить это работать. Поскольку это результат поиска Google номер один, вот что сработало для меня:

radius_km = radius*1.609 # convert miles to km
point = target.geolocation # a django PointField using SRID 4326
# re-project point to a flat coordinate system 
# so we can use meters instead of degrees below, 
# AND get an actual circle instead of oval    
point.transform(6347) 
poly = point.buffer(radius_km*1000) # get a circular polygon from radius
poly.transform(4326)# re-project the resulting polygon back

Бонус: если вы делаете это, чтобы получить круг на статической карте Google, возьмите полилинию:

import polyline
import ast

geo = ast.literal_eval(poly.geojson) # turn the text into a dict
points = geo['coordinates'][0]
pl = polyline.encode(points, geojson=True, precision=5) # make a polyline out of the polygon for google
map_url += '&path=color:0x00000000%7Cfillcolor:0x0000AA33%7Cweight:1%7Cenc:' + pl
person Psyferre    schedule 17.12.2020