简体   繁体   中英

How to translate a polygon in GeoDjango?

I have a Place model which has a polygon field:

from django.contrib.gis.db import models

class Place(models.Model):
    area = models.PolygonField()

I want to translate the area field of an instance of this Place model.

Here is how I am doing it right now:

from django.contrib.gis.db.models.functions import Translate

place = Place.objects.get(pk=1)
place.area = Place.objects.filter(pk=place.pk).annotate(new_area=Translate('area', 0.001, 0.001)).first().new_area
place.save()

This seems very hacky. I think that there should be a way of doing this in the following way:

place = Place.objects.get(pk=1)
place.area = Translate(place.area, 0.001, 0.001)
place.save()

But this throws an exception.

Should I be using some library? Which one works well with GeoDjango and its models/fields?

What is the better way of doing it?

Note the "db" in django.contrib.gis.db.models.functions . There aren't Python functions, these are classes (thus the initial capital in the names) that allow you to access the database system's spatial functions (usually provided by a spatial database extension like spatialite of SQLite or PostGIS for PostgreSQL). See the GeoDjango documentation

The functions documented on this page allow users to access geographic database functions to be used in annotations , aggregations , or filters in Django.

(Emphasis mine.)

That is, these can only be used in queries , as the spatial calculation work of offloaded to the database.

So what can you do instead of doing several queries?

update query

If you'd do this directly in SQL, you'd probably write an UPDATE query. The Django ORM allows you to do the same from Django, with the update() method .

It'd probably look something like this (untested):

Place.objects.filter(pk=1).update(area=Translate('area', 0.001, 0.001))

If you're using GeoDjango anyway, this is probably the preferred way.

external (Python) library

As you suggested, you can use an external library instead of GeoDjango's Translate , eg shapely.affinity.translate from the shapely library . However, I doubt it will accept GeoDjango's django.contrib.gis.geos.GEOSGeometry as input, so you might have to go through GeoJSON or WKT to convert back and forth.

Use this approach if you need your spatial calculations to be independent of the underlying database system.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM