summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2023-01-16 16:43:21 +0100
committerÉtienne Loks <etienne.loks@iggdrasil.net>2023-01-16 16:43:21 +0100
commit608532dfcde97a984ed10ad60a01e0210be65d0d (patch)
treee4093e8e80bce90b2388696a48005687766fbf80 /ishtar_common
parent71d726991b1577ea06aa96ee769e63a83422a814 (diff)
downloadIshtar-608532dfcde97a984ed10ad60a01e0210be65d0d.tar.bz2
Ishtar-608532dfcde97a984ed10ad60a01e0210be65d0d.zip
GeoVectorData: method to update from a geojson
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/models_common.py49
1 files changed, 48 insertions, 1 deletions
diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py
index 151ab5650..a6f9ac0e8 100644
--- a/ishtar_common/models_common.py
+++ b/ishtar_common/models_common.py
@@ -8,6 +8,7 @@ Generic models and tools for models
import copy
from collections import OrderedDict
import datetime
+import fiona
import json
import logging
import os
@@ -25,7 +26,7 @@ from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.db import migrations as db_migrations
from django.contrib.gis.db import models
-from django.contrib.gis.geos import Point
+from django.contrib.gis.geos import GEOSGeometry, Point
from django.contrib.gis.gdal.error import GDALException
from django.contrib.postgres.fields import JSONField
from django.contrib.postgres.search import SearchVectorField, SearchVector
@@ -2117,6 +2118,17 @@ GEOMETRY_TYPE_LBL = {
}
+GEOTYPE_TO_GEOVECTOR = {
+ # key: (geom attr, need list convert)
+ "Point": ("point_2d", False),
+ "LineString": ("multi_line", True),
+ "Polygon": ("multi_polygon", True),
+ "MultiPoint": ("multi_points", False),
+ "MultiLineString": ("multi_line", False),
+ "MultiPolygon": ("multi_polygon", False),
+}
+
+
class GeoVectorData(Imported, OwnPerms):
SLUG = "geovectordata"
RELATED_MODELS = [
@@ -2589,6 +2601,41 @@ class GeoVectorData(Imported, OwnPerms):
return self._geojson_serialize("multi_polygon")
return "{}"
+ def update_from_geojson(self, geojson: str, save=False) -> bool:
+ """
+ Update geometry from a geojson string
+ :param geojson: geojson
+ :param save: save the object if set to True
+ :return: True if update
+ """
+ if not geojson: # no data provided
+ return False
+
+ with fiona.open(geojson) as src:
+ if len(src) != 1:
+ # ambiguous -> need only one feature
+ return False
+ feature = src[0]
+ geom = feature["geometry"]
+ if geom["type"] not in GEOTYPE_TO_GEOVECTOR:
+ # unknown geometry type
+ return False
+ feature_attr, need_list_convert = GEOTYPE_TO_GEOVECTOR[geom["type"]]
+ if need_list_convert:
+ geom["coordinates"] = [geom["coordinates"]]
+ geom = json.dumps(geom)
+ setattr(self, feature_attr, GEOSGeometry(geom))
+ if save:
+ self.save()
+ geo_attrs = ["point_2d", "point_3d", "x", "y", "z", "multi_line",
+ "multi_points", "multi_polygon"]
+ geo_attrs.pop(geo_attrs.index(feature_attr))
+ for geo_attr in geo_attrs:
+ setattr(self, geo_attr, None)
+ if save:
+ self.save()
+ return True
+
@classmethod
def migrate_srid(cls, new_srid):
fields = (