Creative crypter
Creative crypter

Reputation: 1496

Django / GeoDjango / PostGis - Filter FeatureCollection

Currently i have a very basic django model containing a PointField:

from django.contrib.gis.db import models
from django.utils.translation import gettext_lazy as _

from api.models import AbstractModel

class SampleEntity(AbstractModel):
    point = models.PointField(_('point'))

My goal is to filter all rows and check if the point is in a certain polygon...

In order to create a polygon i receive the following payload (FeatureCollection):

{
    "type": "FeatureCollection",
    "crs": {
        "type": "name",
        "properties": {
            "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
        }
    },
    "source": "© GeoBasis-DE / BKG 2013",
    "features": [{
        "type": "Feature",
        "properties": {},
        "geometry": {
            "type": "Polygon",
            "coordinates": [
                [
                    [10.453980128926366, 47.55557895879648],
                    [10.438876535127962, 47.52349211089603],
                    [10.44055084477551, 47.5135694350795],
                    [10.431323512106337, 47.5036776164676],
                    [10.442767953986108, 47.4846168990274],
                    [10.45131095387671, 47.485685093946636],
                    [10.463220692620368, 47.48277492286606],
                    [10.468022327337152, 47.47691846929882],
                    etc..
                ]
            ]
        }
    }, {
        "type": "Feature",
        "properties": {},
        "geometry": {
            "type": "Polygon",
            "coordinates": [
                [
                    [9.617342617593987, 47.568803310179476],
                    [9.628007474077956, 47.570911279233016],
                    [9.628870213746309, 47.56638028461108],
                    [9.638605938479984, 47.56693417152559],
                    [9.653552559008789, 47.55698746615904],
                    [9.679038885003902, 47.55702134414172],
                    [9.682804387548277, 47.55244003193477],
                    [9.675623645853232, 47.54522412435771],
                    etc..
                ]
            ]
        }
    }]
}

Next i need to somehow convert my FeatureCollection to a valid "GeoDjango" Polygon in order to filter in the database:

geoms = []
for feature in payload["features"]:
    geoms.append(GEOSGeometry(str(feature["geometry"])))
geometry = GeometryCollection(geoms)

rows = SampleEntity.objects.filter(point__within=geometry)
print(rows) # <- Error

Raises:

django.db.utils.InternalError: Relate Operation called with a LWGEOMCOLLECTION type.  This is unsupported.
HINT:  Change argument 1: 'GEOMETRYCOLLECTION(MULTIPOLYGON(((13.8005705219365 53.5582546199631,13.798463...'

Probably some internal error...

Can anybody help me out with this issue? I have literally no idea what to do here..

Thanks and Greetings!

EDIT 1:

Query:

SELECT "api_table"."id", "api_event"."point"::bytea FROM "api_table" WHERE ST_Within("api_event"."point", ST_GeomFromEWKB('\001\007\000\000 \346\020\000\000\002\000\000\etc

Upvotes: 0

Views: 983

Answers (1)

Deniz
Deniz

Reputation: 321

In order to filter points within a valid geodjango geometry, you have to convert geojson into appropriate geometry types. In you case, geojson polygons will be combined to create a multipolygon object, not a geometry collection.

from django.contrib.gis.geos import  MultiPolygon, GEOSGeometry
import json
polygonlist = [GEOSGeometry(json.dumps(feature["geometry"])) \
               for feature in  payload["features"]]

mpoly = MultiPolygon(*polygonlist)
rows = SampleEntity.objects.filter(point__within=mpoly )

Upvotes: 1

Related Questions