summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2022-06-01 17:39:10 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2022-12-12 12:21:00 +0100
commit1bc40bcbc0792abe3686f5a09eeb7a229ab18a95 (patch)
tree78d25ed0a224c5a87af078f12a0bffe9a64c04f2
parente435a4929b8d315f13184ea65086fc032c1fbea6 (diff)
downloadIshtar-1bc40bcbc0792abe3686f5a09eeb7a229ab18a95.tar.bz2
Ishtar-1bc40bcbc0792abe3686f5a09eeb7a229ab18a95.zip
Geodata - geo forms: create item form
-rw-r--r--ishtar_common/forms_common.py153
-rw-r--r--ishtar_common/models_common.py9
-rw-r--r--ishtar_common/templates/ishtar/blocks/sheet_geographic.html3
-rw-r--r--ishtar_common/urls.py7
-rw-r--r--ishtar_common/views.py38
5 files changed, 164 insertions, 46 deletions
diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py
index e764077be..b6a36ff03 100644
--- a/ishtar_common/forms_common.py
+++ b/ishtar_common/forms_common.py
@@ -2615,7 +2615,7 @@ class GISForm(forms.ModelForm, CustomForm, ManageOldType):
class Meta:
model = models.GeoVectorData
exclude = ["need_update", "imports", "cached_x", "cached_y", "cached_z",
- "point_3d"]
+ "source_content_type"]
HEADERS = {
"related_items_ishtar_common_town": FormHeader(
@@ -2630,68 +2630,44 @@ class GISForm(forms.ModelForm, CustomForm, ManageOldType):
GEO_FIELDS = (
("point_2d",),
+ ("point_3d",),
("multi_points",),
("multi_line",),
("multi_polygon",),
- ("x", "z")
+ ("x", "z"),
)
+ GEOM_TYPES = {
+ "point_2d": "Point",
+ "point_3d": "Point",
+ "multi_points": "MultiPoint",
+ "multi_line": "MultiLineString",
+ "multi_polygon": "MultiPolygon",
+ }
+
def __init__(self, *args, **kwargs):
main_items_fields = {}
if "main_items_fields" in kwargs:
main_items_fields = kwargs.pop("main_items_fields")
self.user = None
+ self.geom_type = kwargs.pop("geom_type") \
+ if kwargs.get("geom_type", None) else None
if kwargs.get("user", None):
self.user = kwargs.pop("user")
instance = kwargs.get("instance", False)
self.is_instancied = bool(instance)
+ self.source_content_type = kwargs.pop("source_content_type", None)
+ self.source_id = kwargs.pop("source_id", None)
super(GISForm, self).__init__(*args, **kwargs)
if not self.fields["import_key"].initial:
self.fields.pop("import_key")
- self.source_content_type = kwargs.pop("source_content_type", None)
- self.source_id = kwargs.pop("source_id", None)
if not self.source_content_type:
self.fields.pop("source_content_type_id")
self.fields.pop("source_id")
else:
self.fields["source_content_type_id"].initial = self.source_content_type
self.fields["source_id"].initial = self.source_id
- self.geo_keys = []
- if instance:
- for keys in self.GEO_FIELDS:
- if any(getattr(instance, key) for key in keys):
- if keys[0] != "x":
- geom = getattr(instance, keys[0])
- map_srid = geom.srid or 4326
- widget = gis_forms.OSMWidget
- if map_srid == 4326:
- widget = widgets.ReversedOSMWidget
- self.fields[keys[0]].widget = widget(
- attrs={"map_srid": map_srid,
- "geom_type": geom.geom_type})
- self.fields.pop("spatial_reference_system")
- self.geo_keys = keys[:]
- else:
- self.geo_keys = [
- "x", "estimated_error_x",
- "y", "estimated_error_y",
- "z", "estimated_error_z",
- "spatial_reference_system",
- ]
- for geo_fields in self.GEO_FIELDS:
- if geo_fields != keys:
- for geo_field in geo_fields:
- self.fields.pop(geo_field)
- if geo_field == "x":
- self.fields.pop("estimated_error_x")
- self.fields.pop("y")
- self.fields.pop("estimated_error_y")
- if geo_field == "z":
- self.fields.pop("estimated_error_z")
- break
- if not self.geo_keys:
- # TODO....
- pass
+ self.geo_keys = self.get_geo_keys(instance)
fields = OrderedDict()
for related_key in models.GeoVectorData.RELATED_MODELS:
@@ -2703,6 +2679,7 @@ class GISForm(forms.ModelForm, CustomForm, ManageOldType):
required=False,
style="width: 100%",
)
+ for related_key in models.GeoVectorData.RELATED_MODELS:
if related_key in main_items_fields:
for field_key, label in main_items_fields[related_key]:
disabled = False
@@ -2720,6 +2697,85 @@ class GISForm(forms.ModelForm, CustomForm, ManageOldType):
fields[k] = self.fields[k]
self.fields = fields
+ def get_geo_keys(self, instance):
+ if instance:
+ return self._get_instance_geo_keys(instance)
+ else:
+ return self._get_base_geo_keys()
+
+ def _get_base_geo_keys(self):
+ geo_keys = []
+ if self.geom_type == "coordinates":
+ geo_keys = [
+ "x", "estimated_error_x",
+ "y", "estimated_error_y",
+ "z", "estimated_error_z",
+ "spatial_reference_system",
+ ]
+ for keys in self.GEO_FIELDS:
+ if any(key == self.geom_type for key in keys):
+ map_srid = 4326
+ widget = gis_forms.OSMWidget
+ self.fields[keys[0]].widget = widget(
+ attrs={"map_srid": map_srid,
+ "cols": True,
+ "geom_type": self.GEOM_TYPES[self.geom_type]})
+ self.fields.pop("spatial_reference_system")
+ geo_keys = keys[:]
+ self.fields.pop("x")
+ self.fields.pop("y")
+ if self.geom_type != "point_3d":
+ self.fields.pop("z")
+ self.fields.pop("estimated_error_x")
+ self.fields.pop("estimated_error_y")
+ self.fields.pop("estimated_error_z")
+ break
+ for geo_fields in self.GEO_FIELDS[:-1]:
+ # -1 -> do not get x - already managed
+ if geo_fields != geo_keys:
+ for geo_field in geo_fields:
+ self.fields.pop(geo_field)
+ if self.geom_type == "point_3d":
+ geo_keys = list(geo_keys) + ["z"]
+ return geo_keys
+
+ def _get_instance_geo_keys(self, instance):
+ # geo keys for an instanced item
+ geo_keys = []
+ for keys in self.GEO_FIELDS:
+ if any(getattr(instance, key) for key in keys):
+ if keys[0] != "x":
+ geom = getattr(instance, keys[0])
+ map_srid = geom.srid or 4326
+ widget = gis_forms.OSMWidget
+ if map_srid == 4326:
+ widget = widgets.ReversedOSMWidget
+ self.fields[keys[0]].widget = widget(
+ attrs={"map_srid": map_srid,
+ "geom_type": geom.geom_type,
+ "cols": True})
+ self.fields.pop("spatial_reference_system")
+ geo_keys = keys[:]
+ else:
+ geo_keys = [
+ "x", "estimated_error_x",
+ "y", "estimated_error_y",
+ "z", "estimated_error_z",
+ "spatial_reference_system",
+ ]
+ for geo_fields in self.GEO_FIELDS:
+ if geo_fields != keys:
+ for geo_field in geo_fields:
+ self.fields.pop(geo_field)
+ if geo_field == "x":
+ self.fields.pop("estimated_error_x")
+ self.fields.pop("y")
+ self.fields.pop("estimated_error_y")
+ if geo_field == "z":
+ self.fields.pop("estimated_error_z")
+ break
+ return geo_keys
+
def get_headers(self):
headers = self.HEADERS.copy()
if self.geo_keys:
@@ -2769,3 +2825,20 @@ class GISForm(forms.ModelForm, CustomForm, ManageOldType):
item.skip_history_when_saving = True
item.save() # resave to regen the attached items
return item
+
+
+class PreGISForm(IshtarForm):
+ geom_type = forms.ChoiceField(
+ label=_("Geometry type"),
+ choices=(
+ ("coordinates", _("Coordinates")),
+ ("point_2d", _("Point")),
+ ("point_3d", _("Point 3D")),
+ ("multi_points", _("Multi-points")),
+ ("multi_line", _("Multi-lines")),
+ ("multi_polygon", _("Multi-polygons")),
+ )
+ )
+ HEADERS = {
+ "geom_type": FormHeader(_("Type")),
+ }
diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py
index 0c2d67140..3fcf4aea9 100644
--- a/ishtar_common/models_common.py
+++ b/ishtar_common/models_common.py
@@ -3973,6 +3973,15 @@ class MainItem(ShortMenuItem, SerializeItem):
"""
QUICK_ACTIONS = []
+ SLUG = ""
+
+ @classmethod
+ def app_label(cls):
+ return cls._meta.app_label
+
+ @classmethod
+ def model_name(cls):
+ return cls._meta.model_name
@classmethod
def class_verbose_name(cls):
diff --git a/ishtar_common/templates/ishtar/blocks/sheet_geographic.html b/ishtar_common/templates/ishtar/blocks/sheet_geographic.html
index e1a8a1200..709186c1e 100644
--- a/ishtar_common/templates/ishtar/blocks/sheet_geographic.html
+++ b/ishtar_common/templates/ishtar/blocks/sheet_geographic.html
@@ -27,3 +27,6 @@
</tr>
{% endfor %}
</table>
+{% if permission_change_geo %}
+<a href="{% url 'create-pre-geo' item.app_label item.model_name item.pk %}"><i class="fa fa-pencil"></i></a>
+{% endif %}
diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py
index 60a2d8767..b6ac71a9e 100644
--- a/ishtar_common/urls.py
+++ b/ishtar_common/urls.py
@@ -577,6 +577,13 @@ urlpatterns += [
url(
r"geo/create/(?P<app_source>[-\w]+)/(?P<model_source>[-\w]+)/(?P<source_pk>\d+)/$",
check_rights(["add_geovectordata", "add_own_geovectordata"])(
+ views.GeoPreCreateView.as_view()
+ ),
+ name="create-pre-geo",
+ ),
+ url(
+ r"geo/create/(?P<app_source>[-\w]+)/(?P<model_source>[-\w]+)/(?P<source_pk>\d+)/(?P<geom_type>[-\w]+)/$",
+ check_rights(["add_geovectordata", "add_own_geovectordata"])(
views.GeoCreateView.as_view()
),
name="create-geo",
diff --git a/ishtar_common/views.py b/ishtar_common/views.py
index f79ad25ee..9d5256df5 100644
--- a/ishtar_common/views.py
+++ b/ishtar_common/views.py
@@ -2713,6 +2713,24 @@ class DisplayItemView(IshtarMixin, TemplateView):
return data
+class GeoPreCreateView(IshtarMixin, LoginRequiredMixin, FormView):
+ page_name = _("Geo item creation")
+ form_class = forms.PreGISForm
+ template_name = "ishtar/forms/base_form.html"
+
+ def form_valid(self, form):
+ success_url = reverse(
+ "create-geo",
+ kwargs={
+ "app_source": self.kwargs.get("app_source"),
+ "model_source": self.kwargs.get("model_source"),
+ "source_pk": self.kwargs.get("source_pk"),
+ "geom_type": form.cleaned_data.get("geom_type"),
+ }
+ )
+ return HttpResponseRedirect(success_url)
+
+
class GeoFormMixin(IshtarMixin, LoginRequiredMixin):
form_class = forms.GISForm
template_name = "ishtar/forms/base_related_items.html"
@@ -2776,15 +2794,10 @@ class GeoEditView(GeoFormMixin, UpdateView):
kwargs["initial"] = initial
kwargs["user"] = self.request.user
- self.geo = geo
- return kwargs
-
- def get_context_data(self, **kwargs):
- kwargs = super(GeoEditView, self).get_context_data(**kwargs)
return kwargs
-class GeoCreateView(GeoFormMixin, UpdateView):
+class GeoCreateView(GeoFormMixin, CreateView):
page_name = _("Geo item creation")
def get_form_kwargs(self):
@@ -2813,6 +2826,19 @@ class GeoCreateView(GeoFormMixin, UpdateView):
or not obj.is_own(ishtaruser):
# check permission to view own attached item
raise Http404()
+ kwargs["main_items_fields"] = {}
+ for k in models.GeoVectorData.RELATED_MODELS:
+ kwargs["main_items_fields"][k] = []
+ if k.endswith(obj.SLUG):
+ kwargs["initial"][k] = [obj.pk]
+ key = f"{k}_{obj.pk}_main_item"
+ kwargs["main_items_fields"][k].append(
+ (key, "{} - {}".format(_("Main geo item for"), obj))
+ )
+
+ kwargs["source_content_type"] = content_type.pk
+ kwargs["source_id"] = obj.pk
+ kwargs["geom_type"] = self.kwargs.get("geom_type")
kwargs["user"] = self.request.user
return kwargs