diff options
| -rw-r--r-- | ishtar_common/forms_common.py | 153 | ||||
| -rw-r--r-- | ishtar_common/models_common.py | 9 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/blocks/sheet_geographic.html | 3 | ||||
| -rw-r--r-- | ishtar_common/urls.py | 7 | ||||
| -rw-r--r-- | ishtar_common/views.py | 38 | 
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 | 
