From 24d64e840aa0742761b17af4372bebbd195da113 Mon Sep 17 00:00:00 2001 From: Jessica McInchak Date: Mon, 26 Aug 2024 12:53:29 +0200 Subject: [PATCH] fix: update `featuresGeojsonChange` event to match new `geojsonChange` behavior (#479) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dafydd Llŷr Pearson --- index.html | 2 -- src/components/my-map/index.ts | 58 +++++++++++++++++++--------------- src/components/my-map/utils.ts | 23 +++++++------- 3 files changed, 45 insertions(+), 38 deletions(-) diff --git a/index.html b/index.html index 54680e3..7683f46 100644 --- a/index.html +++ b/index.html @@ -50,10 +50,8 @@

ariaLabelOlFixedOverlay="Interactive example map" zoom="20" maxZoom="23" - basemap="MapboxSatellite" drawMode drawMany - drawType="Polygon" osCopyright="© Crown copyright and database rights 2024 OS (0)100024857" osProxyEndpoint="https://api.editor.planx.dev/proxy/ordnance-survey" /> diff --git a/src/components/my-map/index.ts b/src/components/my-map/index.ts index 3d20d3b..7fed3a8 100644 --- a/src/components/my-map/index.ts +++ b/src/components/my-map/index.ts @@ -54,7 +54,7 @@ import styles from "./styles.scss?inline"; import { AreaUnitEnum, fitToData, - formatArea, + calculateArea, hexToRgba, makeGeoJSON, } from "./utils"; @@ -234,6 +234,9 @@ export class MyMap extends LitElement { @property({ type: Boolean }) staticMode = false; + /** + * @deprecated - both `area.squareMetres` & `area.hectares` are calculated by default now in applicable `geojsonChange` events + */ @property({ type: String }) areaUnit: AreaUnitEnum = "m2"; @@ -389,16 +392,7 @@ export class MyMap extends LitElement { if (this.drawMode) { drawingSource.clear(); - this.dispatch("geojsonChange", {}); - - if (this.drawType === "Polygon") { - this.dispatch( - "areaChange", - `0 ${this.areaUnit === "m2" ? "m²" : this.areaUnit}`, - ); - } - map.addInteraction(draw); map.addInteraction(snap); } @@ -507,7 +501,7 @@ export class MyMap extends LitElement { // log total area of static geojson data (assumes single polygon for now) const data = geojsonSource.getFeatures()[0].getGeometry(); if (data) { - this.dispatch("geojsonDataArea", formatArea(data, this.areaUnit)); + this.dispatch("geojsonDataArea", calculateArea(data, this.areaUnit)); } } @@ -542,7 +536,7 @@ export class MyMap extends LitElement { } map.addInteraction(modify); - // XXX: snap must be added after draw and modify + // Snap must be added after draw and modify map.addInteraction(snap); // 'change' listens for 'drawend' and modifications @@ -556,10 +550,15 @@ export class MyMap extends LitElement { if (sketches.length > 0) { if (this.drawType === "Polygon") { + // Calculate the "area" and set on geojson `properties` sketches.forEach((sketch) => { const sketchGeom = sketch.getGeometry(); if (sketchGeom) { - sketch.set("area", formatArea(sketchGeom, this.areaUnit)); + sketch.set( + "area.squareMetres", + calculateArea(sketchGeom, "m2"), + ); + sketch.set("area.hectares", calculateArea(sketchGeom, "ha")); } }); } @@ -640,29 +639,38 @@ export class MyMap extends LitElement { ); map.addLayer(outlineLayer); - // ensure getFeaturesAtPoint has fetched successfully + // Ensure getFeaturesAtPoint has fetched successfully outlineSource.on("change", () => { if ( outlineSource.getState() === "ready" && outlineSource.getFeatures().length > 0 ) { - // fit map to extent of features + // Fit map to extent of features fitToData(map, outlineSource, this.featureBuffer); - // write the geojson representation of the feature or merged features + // Calculate the total area of the feature or merged features and set on geojson `properties` + const osFeatures = outlineSource.getFeatures(); + if (osFeatures.length > 0) { + osFeatures.forEach((osFeature) => { + const osFeatureGeom = osFeature.getGeometry(); + if (osFeatureGeom) { + osFeature.set( + "area.squareMetres", + calculateArea(osFeatureGeom, "m2"), + ); + osFeature.set( + "area.hectares", + calculateArea(osFeatureGeom, "ha"), + ); + } + }); + } + + // Dispatch the geojson of the feature or merged features this.dispatch("featuresGeojsonChange", { "EPSG:3857": makeGeoJSON(outlineSource, "EPSG:3857"), "EPSG:27700": makeGeoJSON(outlineSource, "EPSG:27700"), }); - - // calculate the total area of the feature or merged features - const data = outlineSource.getFeatures()[0].getGeometry(); - if (data) { - this.dispatch( - "featuresAreaChange", - formatArea(data, this.areaUnit), - ); - } } }); } diff --git a/src/components/my-map/utils.ts b/src/components/my-map/utils.ts index ddf3eb6..6c8f70b 100644 --- a/src/components/my-map/utils.ts +++ b/src/components/my-map/utils.ts @@ -13,25 +13,26 @@ import { ProjectionEnum } from "./projections"; export type AreaUnitEnum = "m2" | "ha"; /** - * Calculate & format the area of a polygon + * Calculate the area of a polygon * @param polygon * @param unit - defaults to square metres ("m2"), or supports "ha" for hectares - * @returns - the total area formatted with unit as a string + * @returns - the total area */ -export function formatArea(polygon: Geometry, unit: AreaUnitEnum) { +export function calculateArea( + polygon: Geometry, + unit: AreaUnitEnum = "m2", +): number { const area = getArea(polygon); const squareMetres = Math.round(area * 100) / 100; - const hectares = squareMetres / 10000; // 0.0001 hectares in 1 square metre + const hectares = squareMetres / 10000; // 1 square metre = 0.0001 hectare - let output; - if (unit === "m2") { - output = squareMetres + " m²"; - } else if (unit === "ha") { - output = hectares + " ha"; + switch (unit) { + case "m2": + return squareMetres; + case "ha": + return hectares; } - - return output; } /**