summaryrefslogtreecommitdiff
path: root/ishtar_common/admin.py
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common/admin.py')
-rw-r--r--ishtar_common/admin.py165
1 files changed, 98 insertions, 67 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py
index 50dbbe25a..36331e2f7 100644
--- a/ishtar_common/admin.py
+++ b/ishtar_common/admin.py
@@ -229,7 +229,7 @@ def export_as_csv_action(
def export_as_geojson_action(
geometry_field,
- description=_("Export selected as GeoJSON file"),
+ description=_("Export selected as GeoJSON/JSON file"),
fields=None,
exclude=None,
):
@@ -243,24 +243,29 @@ def export_as_geojson_action(
Generic zipped geojson export admin action.
"""
opts = modeladmin.model._meta
- field_names = set(
- [field.name for field in opts.fields if field.name != geometry_field]
- )
- if fields:
- fieldset = set(fields)
- field_names = field_names & fieldset
- if exclude:
- excludeset = set(exclude)
- field_names = field_names - excludeset
+ if hasattr(modeladmin.model, "geodata_export"):
+ geojson = []
+ for item in queryset.order_by("pk").all():
+ geojson += item.geodata_export
+ geojson = json.dumps(geojson, indent=4)
+ else:
+ field_names = set(
+ [field.name for field in opts.fields if field.name != geometry_field]
+ )
+ if fields:
+ fieldset = set(fields)
+ field_names = field_names & fieldset
+ if exclude:
+ excludeset = set(exclude)
+ field_names = field_names - excludeset
+ geojson = serialize(
+ "geojson",
+ queryset.order_by("pk"),
+ geometry_field=geometry_field,
+ fields=field_names,
+ ).encode("utf-8")
basename = str(opts).replace(".", "_")
-
- geojson = serialize(
- "geojson",
- queryset.order_by("pk"),
- geometry_field=geometry_field,
- fields=field_names,
- ).encode("utf-8")
in_memory = BytesIO()
czip = zipfile.ZipFile(in_memory, "a")
czip.writestr(basename + ".geojson", geojson)
@@ -1234,7 +1239,7 @@ class ImportActionAdmin(admin.ModelAdmin):
class ImportGeoJsonForm(forms.Form):
json_file = forms.FileField(
- label=_("Geojson file"),
+ label=_("Geojson/JSON file"),
help_text=_(
"Only unicode encoding is managed - convert your"
" file first. The file must be a geojson file or a zip "
@@ -1312,11 +1317,11 @@ class ImportGEOJSONActionAdmin(object):
self.message_user(request, error, level=messages.ERROR)
return False
if geom.geom_type == "Point":
- values["center"] = geom
+ values["point_2d"] = geom
elif geom.geom_type == "MultiPolygon":
- values["limit"] = geom
+ values["multi_polygon"] = geom
elif geom.geom_type == "Polygon":
- values["limit"] = MultiPolygon(geom)
+ values["multi_polygon"] = MultiPolygon(geom)
else:
if trace_error:
error = str(_("Geometry {} not managed for towns - feature {}")).format(
@@ -1355,7 +1360,8 @@ class ImportGEOJSONActionAdmin(object):
if form.is_valid():
json_file_obj = request.FILES["json_file"]
- base_dct = {"file_form": form, "current_action": "import_geojson"}
+ base_dct = {"file_form": form, "current_action": "import_geojson",
+ "is_town": True}
tempdir = tempfile.mkdtemp()
tmpfilename = tempdir + os.sep + "dest_file"
@@ -1389,53 +1395,78 @@ class ImportGEOJSONActionAdmin(object):
"insee_prefix": request.POST.get("numero_insee_prefix", None) or "",
"surface_unit": int(request.POST.get("surface_unit")),
}
+ town_content_type = ContentType.objects.get(
+ app_label="ishtar_common", model="town"
+ )
+ town_data_type, __ = models.GeoDataType.objects.get_or_create(
+ txt_idx="town-limit", defaults={"label": _("Town limit")}
+ )
with open(json_filename) as json_file_obj:
json_file = json_file_obj.read()
- try:
- dct = json.loads(json_file)
- if "features" not in dct or not dct["features"]:
- raise ValueError()
- except (ValueError, AssertionError):
- error = _("Bad geojson file")
- return self.import_geojson_error(
- request, error, base_dct, tempdir
- )
-
- error_count = 0
- created = 0
- updated = 0
- for idx, feat in enumerate(dct["features"]):
- trace_error = True
- if error_count == 6:
- self.message_user(
- request, _("Too many errors..."), level=messages.ERROR
+ dct = json.loads(json_file)
+ if "features" not in dct or not dct["features"]:
+ # probably Ishtar JSON
+ created, __, updated, __ = models.Town.geodata_import(dct)
+ else:
+ error_count = 0
+ created = 0
+ updated = 0
+ for idx, feat in enumerate(dct["features"]):
+ trace_error = True
+ if error_count == 6:
+ self.message_user(
+ request, _("Too many errors..."), level=messages.ERROR
+ )
+ if error_count > 5:
+ trace_error = False
+ values = self.geojson_values(
+ request, idx + 1, feat, keys, trace_error
)
- if error_count > 5:
- trace_error = False
- values = self.geojson_values(
- request, idx + 1, feat, keys, trace_error
- )
- if not values:
- error_count += 1
- continue
- num_insee = values.pop("numero_insee")
- year = values.pop("year") or None
- t, c = models_common.Town.objects.get_or_create(
- numero_insee=num_insee, year=year, defaults=values
- )
- if c:
- created += 1
- else:
- modified = False
- for k in values:
- if keys["update"] and k not in ["center", "limit"]:
- continue
- if values[k] != getattr(t, k):
- setattr(t, k, values[k])
- modified = True
- if modified:
- updated += 1
- t.save()
+ if not values:
+ error_count += 1
+ continue
+ num_insee = values.pop("numero_insee")
+ year = values.pop("year") or None
+ geo_values = {}
+ for k in ["point_2d", "multi_polygon"]:
+ if k in values:
+ geo_values[k] = values.pop(k)
+ t, c = models_common.Town.objects.get_or_create(
+ numero_insee=num_insee, year=year, defaults=values
+ )
+ if c:
+ created += 1
+ else:
+ modified = False
+ if not keys["update"]:
+ for k in values:
+ if not getattr(t, k) or \
+ values[k] != getattr(t, k):
+ setattr(t, k, values[k])
+ modified = True
+ if modified:
+ updated += 1
+ t.save()
+ if geo_values:
+ if t.main_geodata: # update
+ for k in geo_values:
+ c_value = getattr(t.main_geodata, k)
+ if not c_value or \
+ geo_values[k] != c_value.wkt:
+ setattr(t.main_geodata, k, geo_values[k])
+ t.main_geodata.save()
+ else:
+ gd, __ = models.GeoVectorData.objects.get_or_create(
+ source_id=t.pk,
+ source_content_type=town_content_type,
+ data_type=town_data_type,
+ defaults={"name": t.cached_label}
+ )
+ for k in geo_values:
+ setattr(gd, k, geo_values[k])
+ gd.save()
+ t.main_geodata = gd
+ t.save()
if created:
self.message_user(
request, str(_("%d item(s) created.")) % created
@@ -1455,7 +1486,7 @@ class ImportGEOJSONActionAdmin(object):
return render(
request,
"admin/import_from_file.html",
- {"file_form": form, "current_action": "import_geojson"},
+ {"file_form": form, "current_action": "import_geojson", "is_town": True},
)