GeoDjango: определить площадь многоугольника

В моей модели у меня есть полигональное поле, определенное через

polygon = models.PolygonField(srid=4326, geography=True, null=True, blank=True)

Когда я хочу определить площадь многоугольника, я вызываю

area_square_degrees = object.polygon.area

Но как я могу преобразовать результат в квадратных градусах в m2 с помощью GeoDjango? Этот ответ не работает, так как area не имеет метода sq_m . Есть ли встроенная конвертация?


person neurix    schedule 10.11.2013    source источник
comment
Вы нашли нативное решение django, которое также может сохранять область в базе данных при создании объекта?   -  person Charalamm    schedule 01.07.2021


Ответы (4)


Вам необходимо преобразовать ваши данные в правильную систему пространственной привязки.

area_square_local_units = object.polygon.transform(srid, clone=False).area

В Великобритании вы можете использовать SRID британской национальной сети 27700, в котором используются счетчики.

area_square_meters = object.polygon.transform(27700, clone=False).area

Вы можете клонировать или не клонировать геометрию в зависимости от того, нужно ли вам делать с ней что-то еще в ее непреобразованном состоянии.

Документы находятся здесь https://docs.djangoproject.com/en/1.8/ref/contrib/gis/geos/

person Alexander    schedule 23.08.2015
comment
Обратите внимание, что приведенный ниже ответ Гийома является лучшим решением при использовании 4326 и типа географии в поле геометрии вашей модели. - person Alexander; 26.03.2021

Я много боролся с этим, так как я не мог найти чистое решение. Хитрость в том, что вы должны использовать возможности postgis (и, следовательно, работать только с postgis..):

from django.contrib.gis.db.models.functions import Area
loc_obj = Location.objects.annotate(area_=Area("poly")).get(pk=??)  
# put the primary key of the object

print(loc_obj.area_)  # distance object, result should be in meters, but you can change to the unit you want, e.g  .mi for miles etc..

Модели.py:

class Location(models.Model):
    poly = gis_models.PolygonField(srid=4326, geography=True)

Я думаю, что это лучший способ сделать это, если вам приходится иметь дело с географическими координатами, а не с проекциями. Он обрабатывает расчет кривой земли, и результат является точным даже при большом расстоянии/площади.

person Guillaume Lebreton    schedule 01.09.2017
comment
Есть ли способ сделать расчет площади при создании объекта или хотя бы сделать расчет для одной строки, а не для всей таблицы? - person Charalamm; 02.07.2021
comment
Я думаю, это что-то вроде Location.objects.filter(pk=XXX) .annotate(area_=Area("poly")). Тогда расчеты производятся только на подмножестве таблицы. - person Guillaume Lebreton; 09.07.2021

Мне нужно было приложение, чтобы получить площадь многоугольников по всему миру, и если я использовал недопустимую проекцию страны/региона, я получал ошибку OGRException: OGR failure

Я закончил с использованием реализации OpenLayers, используя проекция 4326 (проекция по умолчанию), чтобы не беспокоиться о прогнозе для каждой страны/региона. Вот мой код:

import math

def getCoordsM2(coordinates):
    d2r = 0.017453292519943295  # Degrees to radiant
    area = 0.0
    for coord in range(0, len(coordinates)):
        point_1 = coordinates[coord]
        point_2 = coordinates[(coord + 1) % len(coordinates)]
        area += ((point_2[0] - point_1[0]) * d2r) *\
            (2 + math.sin(point_1[1] * d2r) + math.sin(point_2[1] * d2r))
    area = area * 6378137.0 * 6378137.0 / 2.0
    return math.fabs(area)

def getGeometryM2(geometry):
    area = 0.0
    if geometry.num_coords > 2:
        # Outer ring
        area += getCoordsM2(geometry.coords[0])
        # Inner rings
        for counter, coordinates in enumerate(geometry.coords):
            if counter > 0:
                area -= getCoordsM2(coordinates)
    return area

Просто передайте свою геометрию в функцию getGeometryM2, и все готово! Я использую эту функцию в своей модели GeoDjango как свойство. Надеюсь, поможет!

person castledom04    schedule 16.11.2015

Если площадь поверхности земли, о которой вы говорите, 1 квадратный градус составляет 12 365,1613 квадратных километров. Итак, умножьте свой квадратный градус и умножьте на 10 ^ 6, чтобы преобразовать в метры.

person Sri    schedule 22.01.2014