Django - получить центроид многоугольника в формате geoJSON

Я создаю REST API для управления гео-данными.
Мой разработчик внешнего интерфейса хочет получить центроид многоугольников, в зависимости от уровня масштабирования, в geoJSON формат.

Моя модель многоугольника выглядит следующим образом:

...
from django.contrib.gis.db import models as geomodels
class Polygon(geomodels.Model):
    fk_owner = models.ForeignKey(User, on_delete=models.DO_NOTHING, blank=True)
    external_id = models.CharField(max_length=25, unique=True) 
    func_type = models.CharField(max_length=15)
    coordinates = geomodels.PolygonField(srid=3857)
    properties = JSONField(default={}) 

API в настоящее время возвращает такие вещи:

"type": "FeatureCollection",
"features": [
 {
     "type": "Feature",
     "geometry": {
         "type": "Polygon",
         "coordinates": [[[..]]]
      }
  }]

И я пользуюсь rest_framework_gis.serializers.GeoFeatureModelSerializer сериализовать мои данные.

Я вижу следующие способы получить центроид:

  1. Добавить центроид колонки к моей модели: я не хочу этого делать
  2. Создайте представление базы данных моей модели: Django не управляет представлениями базы данных, и я не хочу писать пользовательскую миграцию
  3. Используйте ту же модель и добавьте extra(...) на мое утверждение orm: я пытался, но все становится трудно в или до сериализации, потому что в модели тип Polygon и центроид Point , Ошибка заключается в следующем:

    TypeError: 
        Cannot set Polygon SpatialProxy (POLYGON) with value of type:
        <class 'django.contrib.gis.geos.point.Point'>
    

Ожидаемый результат должен быть:

"type": "FeatureCollection",
"features": [
 {
     "type": "Feature",
     "geometry": {
         "type": "Point",
         "coordinates": [..]
      }
  }]

Каково твое мнение?

1 ответ

Решение

Вы можете использовать комбинацию следующих методов:

  1. AsGeoJSON, который

    Принимает одно географическое поле или выражение и возвращает представление геометрии GeoJSON.

  2. Centroid() который

    Принимает одно географическое поле или выражение и возвращает значение центроида геометрии.

  3. .annotate() который

    Аннотирует каждый объект в QuerySet с предоставленным списком выражений запроса.
    [...]
    Каждый аргумент annotate() это аннотация, которая будет добавлена ​​к каждому возвращаемому объекту в QuerySet.


Пример:

Следующий запрос:

Polygon.objects.annotate(geometry=AsGeoJSON(Centroid('coordinates')))

добавит поле с именем 'geometry' к Polygon набор запросов, который будет содержать центроид, рассчитанный из coordinates поле каждого Polygon объект вашей данной модели.

Другие вопросы по тегам