Skip to content

Commit

Permalink
Merge pull request #487 from ka-pr/map-geoserver-and-multigeometries
Browse files Browse the repository at this point in the history
Map geoserver and multigeometries
  • Loading branch information
xzzy committed Jul 24, 2024
2 parents 23cf06a + ae644f5 commit d8e252c
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 11 deletions.
50 changes: 39 additions & 11 deletions boranga/components/spatial/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def invert_xy_coordinates(geometries):


def intersect_geometry_with_layer(geometry, intersect_layer, geometry_name="SHAPE"):
"""Query a geoserver WFS layer with a geometry and return the intersecting features as JSON."""

geoserver_url = intersect_layer.geoserver_url
intersect_layer_name = intersect_layer.layer_name
invert_xy = intersect_layer.invert_xy
Expand All @@ -58,6 +60,22 @@ def intersect_geometry_with_layer(geometry, intersect_layer, geometry_name="SHAP
if invert_xy:
test_geom = invert_xy_coordinates([geometry])[0]

if test_geom.geom_type in ["MultiPoint"]:
# For some unknown silly reason, geoserver's jts cannot handle valid single-bracketed multipoint geometries,
# e.g. MULTIPOINT (3 1, 4 1, 5 2), and rather throws unintelligible java class exceptions at me, so we
# have to convert them to a double-bracket notation in the form of MULTIPOINT ((3 1), (4 1), (5 2)). Even
# though both forms are (topologically) valid by OGC definition, the jts (java topology suite) library only
# seems to except singleton lists (https://www.tsusiatsoftware.net/jts/javadoc/com/vividsolutions/jts/io/WKTReader.html)
logger.warn(
f"Converting MultiPoint geometry {test_geom} to double-bracket notation"
)
test_geom_wkt = (
f'MULTIPOINT ({", ".join([f"({c[0]} {c[1]})" for c in test_geom.coords])})'
)
else:
test_geom_wkt = test_geom.wkt

wkt.loads(test_geom.wkt)
params = {
"service": "WFS",
"version": "2.0.0",
Expand All @@ -67,7 +85,7 @@ def intersect_geometry_with_layer(geometry, intersect_layer, geometry_name="SHAP
"srsName": "EPSG:4326", # using the default projection for open layers and geodjango
"outputFormat": "application/json",
"propertyName": f"{geometry_name},CAD_OWNER_NAME,CAD_OWNER_COUNT",
"CQL_FILTER": f"INTERSECTS({geometry_name}, {test_geom.wkt})",
"CQL_FILTER": f"INTERSECTS({geometry_name}, {test_geom_wkt})",
}

request_path = (
Expand Down Expand Up @@ -142,16 +160,15 @@ def populate_occurrence_tenure_data(geometry_instance, features, request):
else:
occurrence_tenures = OccurrenceTenure.objects.filter(
tenure_area_id=feature_id
).exclude(occurrence_geometry=None,tenure_area_id=None)
).exclude(occurrence_geometry=None, tenure_area_id=None)

occurrence_tenures_current = occurrence_tenures.filter(
occurrence_geometry=geometry_instance,
status="current"
occurrence_geometry=geometry_instance, status="current"
)

occurrence_tenures_historical = occurrence_tenures.filter(
historical_occurrence=geometry_instance.occurrence.id,
status="historical"
status="historical",
)

if occurrence_tenures_current.exists():
Expand Down Expand Up @@ -298,7 +315,7 @@ def save_geometry(
InstanceCopiedFrom
)

opacity = feature.get("properties", {}).get("opacity", .5)
opacity = feature.get("properties", {}).get("opacity", 0.5)

geom_4326 = feature_json_to_geosgeometry(feature)

Expand Down Expand Up @@ -454,9 +471,20 @@ def save_geometry(
# or have been drawn by another user
geometry_ids = list(geometry_id_intersect_data.keys())
if instance_fk_field_name == "occurrence":
affected_tenure_ids = list(OccurrenceTenure.objects.filter(occurrence_geometry__in=(InstanceGeometry.objects.filter(**{instance_fk_field_name: instance})
.exclude(Q(id__in=geometry_ids) | Q(locked=True) | ~Q(drawn_by=request.user.id)))).values_list("id",flat=True))

affected_tenure_ids = list(
OccurrenceTenure.objects.filter(
occurrence_geometry__in=(
InstanceGeometry.objects.filter(
**{instance_fk_field_name: instance}
).exclude(
Q(id__in=geometry_ids)
| Q(locked=True)
| ~Q(drawn_by=request.user.id)
)
)
).values_list("id", flat=True)
)

deleted_geometries = (
InstanceGeometry.objects.filter(**{instance_fk_field_name: instance})
.exclude(Q(id__in=geometry_ids) | Q(locked=True) | ~Q(drawn_by=request.user.id))
Expand All @@ -466,9 +494,9 @@ def save_geometry(
logger.info(
f"Deleted {instance_model_name} geometries: {deleted_geometries} for {instance}"
)

if instance_fk_field_name == "occurrence":
#we save affected tenures to record the historical change
# we save affected tenures to record the historical change
affected_tenures = OccurrenceTenure.objects.filter(id__in=affected_tenure_ids)
for i in affected_tenures:
i.save(version_user=request.user)
Expand Down
50 changes: 50 additions & 0 deletions boranga/frontend/boranga/src/components/common/component_map.vue
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,53 @@
stroke-width="2"
/>
</svg>
<svg
v-else-if="
isMultiPolygonFeature(
feature
)
"
class="svg-object"
width="24"
height="24"
xmlns="http://www.w3.org/2000/svg"
>
<!-- Two intersecting rectangles -->
<path
d="M2 2 16 2 16 16 2 16 z"
:fill="
feature.getProperties()
.color
"
:stroke="
selectedFeatureIds.includes(
feature.getProperties()
.id
)
? 'red'
: feature.getProperties()
.stroke
"
stroke-width="2"
/>
<path
d="M9 9 22 9 22 22 9 22 z"
:fill="
feature.getProperties()
.color
"
:stroke="
selectedFeatureIds.includes(
feature.getProperties()
.id
)
? 'red'
: feature.getProperties()
.stroke
"
stroke-width="2"
/>
</svg>
<svg
v-else
class="svg-object"
Expand Down Expand Up @@ -5211,6 +5258,9 @@ export default {
feature.getGeometry().getType()
);
},
isMultiPolygonFeature: function (feature) {
return feature.getGeometry().getType() === 'MultiPolygon';
},
isPolygonLikeFeature: function (feature) {
return ['Polygon', 'MultiPolygon'].includes(
feature.getGeometry().getType()
Expand Down
1 change: 1 addition & 0 deletions docs/sql-scripts/OccurrenceCommunity.sql
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ geom AS (
CASE
ST_GeometryType(geometry)
WHEN 'ST_Point' THEN ST_Buffer(geometry, 0.00001)
WHEN 'ST_MultiPoint' THEN ST_Buffer(geometry, 0.00001)
ELSE geometry
END AS geometry,
ST_GeometryType(geometry) AS geometry_type,
Expand Down
1 change: 1 addition & 0 deletions docs/sql-scripts/OccurrenceFauna.sql
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ geom AS (
CASE
ST_GeometryType(geometry)
WHEN 'ST_Point' THEN ST_Buffer(geometry, 0.00001)
WHEN 'ST_MultiPoint' THEN ST_Buffer(geometry, 0.00001)
ELSE geometry
END AS geometry,
ST_GeometryType(geometry) AS geometry_type,
Expand Down
1 change: 1 addition & 0 deletions docs/sql-scripts/OccurrenceFlora.sql
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ geom AS (
CASE
ST_GeometryType(geometry)
WHEN 'ST_Point' THEN ST_Buffer(geometry, 0.00001)
WHEN 'ST_MultiPoint' THEN ST_Buffer(geometry, 0.00001)
ELSE geometry
END AS geometry,
ST_GeometryType(geometry) AS geometry_type,
Expand Down
1 change: 1 addition & 0 deletions docs/sql-scripts/OccurrenceReportCommunity.sql
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ geom AS (
CASE
ST_GeometryType(geometry)
WHEN 'ST_Point' THEN ST_Buffer(geometry, 0.00001)
WHEN 'ST_MultiPoint' THEN ST_Buffer(geometry, 0.00001)
ELSE geometry
END AS geometry,
ST_GeometryType(geometry) AS geometry_type,
Expand Down
1 change: 1 addition & 0 deletions docs/sql-scripts/OccurrenceReportFauna.sql
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ geom AS (
CASE
ST_GeometryType(geometry)
WHEN 'ST_Point' THEN ST_Buffer(geometry, 0.00001)
WHEN 'ST_MultiPoint' THEN ST_Buffer(geometry, 0.00001)
ELSE geometry
END AS geometry,
ST_GeometryType(geometry) AS geometry_type,
Expand Down
1 change: 1 addition & 0 deletions docs/sql-scripts/OccurrenceReportFlora.sql
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ geom AS (
CASE
ST_GeometryType(geometry)
WHEN 'ST_Point' THEN ST_Buffer(geometry, 0.00001)
WHEN 'ST_MultiPoint' THEN ST_Buffer(geometry, 0.00001)
ELSE geometry
END AS geometry,
ST_GeometryType(geometry) AS geometry_type,
Expand Down

0 comments on commit d8e252c

Please sign in to comment.