|
1 | | -import json |
2 | 1 | import logging |
3 | 2 | import urllib.parse |
4 | 3 | from typing import TYPE_CHECKING, Iterable, Union |
5 | 4 |
|
6 | 5 | from django.conf import settings |
7 | 6 | from django.contrib.gis.db import models |
8 | | -from django.contrib.gis.geos import GEOSGeometry, MultiPolygon, Polygon |
| 7 | +from django.contrib.gis.geos import MultiPolygon, Polygon |
9 | 8 | from django.contrib.postgres.fields import ArrayField |
10 | 9 | from django.utils.functional import cached_property |
11 | 10 | from django.utils.safestring import mark_safe |
@@ -112,67 +111,25 @@ def create_xyz_url(self) -> Union[str, None]: |
112 | 111 |
|
113 | 112 | @property |
114 | 113 | def multimask_extent(self): |
115 | | - """Calculate an extent based on all layers in this layerset's |
116 | | - multimask. If there is no multimask, return None.""" |
117 | | - extent = None |
118 | | - if self.multimask: |
119 | | - feature_polygons = [] |
120 | | - for v in self.multimask.values(): |
121 | | - poly = Polygon(v["geometry"]["coordinates"][0]) |
122 | | - feature_polygons.append(poly) |
123 | | - if len(feature_polygons) > 0: |
124 | | - extent = MultiPolygon(feature_polygons, srid=4326).extent |
125 | | - return extent |
| 114 | + """Calculate an extent based any existing masks of layers in this LayerSet. |
| 115 | + If no layer have masks then return None.""" |
| 116 | + feature_polygons = [] |
| 117 | + for feat in self.multimask_geojson["features"]: |
| 118 | + poly = Polygon(feat["geometry"]["coordinates"][0]) |
| 119 | + feature_polygons.append(poly) |
| 120 | + return ( |
| 121 | + MultiPolygon(feature_polygons, srid=4326).extent if len(feature_polygons) > 0 else None |
| 122 | + ) |
126 | 123 |
|
127 | 124 | @property |
128 | | - def multimask_geojson(self): |
129 | | - if self.multimask: |
130 | | - multimask_geojson = {"type": "FeatureCollection", "features": []} |
131 | | - for layer, geojson in self.multimask.items(): |
132 | | - geojson["properties"] = {"layer": layer} |
133 | | - multimask_geojson["features"].append(geojson) |
134 | | - return multimask_geojson |
135 | | - else: |
136 | | - return None |
137 | | - |
138 | | - def validate_multimask_geojson(self, multimask_geojson): |
139 | | - errors = [] |
140 | | - for feature in multimask_geojson["features"]: |
141 | | - lyr = feature["properties"]["layer"] |
142 | | - try: |
143 | | - geom_str = json.dumps(feature["geometry"]) |
144 | | - g = GEOSGeometry(geom_str) |
145 | | - if not g.valid: |
146 | | - logger.warning(f"{self} | invalid mask: {lyr} - {g.valid_reason}") |
147 | | - errors.append((lyr, g.valid_reason)) |
148 | | - except Exception as e: |
149 | | - logger.warning(f"{self} | improper GeoJSON in multimask") |
150 | | - errors.append((lyr, e)) |
151 | | - return errors |
152 | | - |
153 | | - def update_multimask_from_geojson(self, multimask_geojson): |
154 | | - from .layer import Layer |
155 | | - |
156 | | - errors = self.validate_multimask_geojson(multimask_geojson) |
157 | | - if errors: |
158 | | - return errors |
159 | | - |
160 | | - if multimask_geojson["features"]: |
161 | | - self.multimask = {} |
162 | | - for feature in multimask_geojson["features"]: |
163 | | - layer_slug = feature["properties"]["layer"] |
164 | | - self.multimask[feature["properties"]["layer"]] = feature |
165 | | - |
166 | | - ## future patch: save mask directly to layers |
167 | | - layer = Layer.objects.get(slug=layer_slug, region__document__map=self.map) |
168 | | - new_mask = GEOSGeometry(json.dumps(feature["geometry"])) |
169 | | - if new_mask != layer.mask: |
170 | | - logger.debug(f"updating mask on layer {layer.slug} ({layer.pk})") |
171 | | - layer.mask = new_mask |
172 | | - layer.save(skip_map_lookup_update=True, set_extent=False) |
173 | | - else: |
174 | | - self.multimask = None |
175 | | - self.save(update_fields=["multimask"]) |
| 125 | + def multimask_geojson(self) -> dict: |
| 126 | + """Collect all masks from layers in this layerset and return as GeoJSON Feature Collection""" |
| 127 | + fc = {"type": "FeatureCollection", "features": []} |
| 128 | + for layer in self.get_layers(): |
| 129 | + mask_geojson = layer.mask_geojson_feature |
| 130 | + if mask_geojson: |
| 131 | + fc["features"].append(mask_geojson) |
| 132 | + return fc |
176 | 133 |
|
177 | 134 | def save(self, set_tilejson: bool = False, *args, **kwargs): |
178 | 135 | if self._state.adding is False: |
|
0 commit comments