Skip to content
Draft
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b33c0b0
chore: implement very simple area measurement in drawstart handler
spectrachrome Oct 9, 2024
7c4f058
wip: try calculating circumference
spectrachrome Oct 9, 2024
d4d87dd
wip: use getLength method to calculate distances
spectrachrome Oct 10, 2024
24c44df
feat: properly implement area measurement with correct distances
spectrachrome Oct 14, 2024
d12d50e
fix: make sure overlays are cleaned up properly
spectrachrome Oct 21, 2024
8290727
feat: simplify calculation and provide area for polygons
spectrachrome Oct 21, 2024
66356ba
Merge branch 'main' into map/feature/area-measurements
spectrachrome Oct 21, 2024
c4eb290
fix: merge conflict
spectrachrome Oct 21, 2024
ed16f3f
chore: remove unnecessary method
spectrachrome Oct 21, 2024
241c41c
fix: only clear map overlays if applicable
spectrachrome Oct 21, 2024
b8932b9
chore: formatting
spectrachrome Oct 21, 2024
555a0c4
chore: add a `measure` attribute to map
spectrachrome Oct 30, 2024
e5b4ede
fix: a number of display issues, migrate to line string only
spectrachrome Oct 30, 2024
1bc5e09
feat: create a story for distance measurements
spectrachrome Oct 30, 2024
a4f5268
fix: linter errors
spectrachrome Oct 30, 2024
b44ea98
Merge branch 'main' into map/feature/area-measurements
spectrachrome Oct 30, 2024
5b6efad
chore: run prettier
spectrachrome Oct 30, 2024
51ca165
Merge branch 'map/feature/area-measurements' of github.com:EOX-A/EOxE…
spectrachrome Oct 30, 2024
0614d89
doc: update comments
spectrachrome Oct 30, 2024
389ebff
feat: define measure attribute on draw tools
spectrachrome Nov 11, 2024
90407ad
chore: move measuring from map into draw tools
spectrachrome Nov 11, 2024
a1acaa5
chore: remove old imports
spectrachrome Nov 11, 2024
cf617ad
chore: run prettier
spectrachrome Nov 11, 2024
43555b4
fix: merge conflicts
spectrachrome Nov 11, 2024
615589d
fix: linter issues, add more doc comments
spectrachrome Nov 11, 2024
ba9a55f
chore: provide single default export in measure helper
spectrachrome Nov 11, 2024
a3580d7
chore: cleanup
spectrachrome Nov 11, 2024
18a71eb
chore: run prettier (again?)
spectrachrome Nov 11, 2024
658516f
chore: replace mock-map reference
spectrachrome Nov 15, 2024
9c1c014
temp: work on tests
spectrachrome Nov 18, 2024
f9bc7fe
chore: add play function to fail e2e test deliberately
spectrachrome Nov 28, 2024
68014bc
chore: remove cypress file in favor of play fn test
spectrachrome Nov 28, 2024
ceae29c
Merge branch 'main' into map/feature/area-measurements
spectrachrome Nov 28, 2024
651442a
fix: linter errors and format
spectrachrome Nov 28, 2024
58ca335
chore: remove play function
spectrachrome Dec 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions elements/drawtools/src/methods/draw/discard-drawing.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ const discardDrawingMethod = (EoxDrawTool) => {
EoxDrawTool.drawLayer.getSource().clear();
//@ts-expect-error TODO
EoxDrawTool.geoJSON = null;

// Clear map overlays, if available
const map = EoxDrawTool.eoxMap.map;
if (map && map.getOverlays !== undefined) {
EoxDrawTool.eoxMap.map.getOverlays().clear();
}
};

// Function to trigger updates after discarding drawing
Expand Down
24 changes: 24 additions & 0 deletions elements/drawtools/stories/distance-measurement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { html } from "lit";
import { STORIES_MAP_STYLE, STORIES_LAYERS_ARRAY } from "../src/enums";

/**
* Component demonstrating how EOxMap and the draw tools can be used to measure distances on a map.
*/
export const DistanceMeasurement = {
render: () => html`
<eox-map
id="line-measurement"
style=${STORIES_MAP_STYLE}
.layers=${STORIES_LAYERS_ARRAY}
measure
/>
<eox-drawtools
for="eox-map#line-measurement"
multiple-features
allow-modify
type="LineString"
/>
`,
};

export default DistanceMeasurement;
7 changes: 7 additions & 0 deletions elements/drawtools/stories/drawtools.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
ImportFeaturesWithEditorStory,
SelectFeatureStory,
MultiFeaturesSelectStory,
DistanceMeasurementStory,
} from "./index";

export default {
Expand Down Expand Up @@ -77,3 +78,9 @@ export const CSSVariableOverride = CSSVariableOverrideStory;
* By setting the `unstyled` attribute or property, the element has no styling applied.
*/
export const Unstyled = UnstyledStory;

/**
* Setting the `measure` attribute on the map and drawing with `LineString`s will cause
* a tooltip to be displayed showing the distance of the line being drawn.
*/
export const DistanceMeasurement = DistanceMeasurementStory;
1 change: 1 addition & 0 deletions elements/drawtools/stories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export { default as UnstyledStory } from "./unstyled"; // Story demonstrating un
export { default as CSSVariableOverrideStory } from "./css-variable-override"; // Story demonstrating css override
export { default as SelectFeatureStory } from "./select-feature"; // Story demonstrating feature selection
export { default as MultiFeaturesSelectStory } from "./multi-feature-select"; // Story demonstrating multi feature selection with list
export { default as DistanceMeasurementStory } from "./distance-measurement"; // Story demonstrating distance measurements.
95 changes: 95 additions & 0 deletions elements/map/src/helpers/draw.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import Modify from "ol/interaction/Modify";
import Draw, { createBox } from "ol/interaction/Draw";
import { addNewFeature } from "../helpers";
import { getArea, getLength } from "ol/sphere";
import Overlay from "ol/Overlay";
import { LineString } from "ol/geom";
import { unByKey } from "ol/Observable";

/**
* @typedef {import("../../types").DrawOptions} DrawOptions
Expand Down Expand Up @@ -49,10 +53,69 @@ export function addDraw(EOxMap, drawLayer, options) {
drawInteraction.setActive(false);
}

// Create measure tooltip
let measureTooltipElement = document.createElement("div");

const measureTooltip = new Overlay({
element: measureTooltipElement,
offset: [16, 0],
positioning: "center-left",
stopEvent: false,
insertFirst: false,
});

measureTooltipElement.className = "ol-tooltip ol-tooltip-measure";
measureTooltipElement.style.padding = "3px 7px";
measureTooltipElement.style.borderRadius = "4px";
measureTooltipElement.style.backdropFilter = "blur(20px)";
measureTooltipElement.style.background = "#004180AA";
measureTooltipElement.style.fontFamily = "monospace, sans-serif";
measureTooltipElement.style.color = "#FFF";
measureTooltipElement.style.visibility = "hidden";
measureTooltipElement.style.pointerEvents = "none";

let sketch = null;
let listener;

// Initialize the measurement tooltip so that it displays the length of the line
// as a distance in kilometers while following the last point of the drawn line.
drawInteraction.on("drawstart", (evt) => {
if (EOxMap.measure) {
// Ensure the tooltip appears only in `measure` mode when drawing a line string.
if (options_.type === "LineString") {
measureTooltipElement.style.visibility = "visible";
measureTooltipElement.style.pointerEvents = "inherit";
}
sketch = evt.feature;
let tooltipCoord = evt.coordinate;

EOxMap.map.addOverlay(measureTooltip);

listener = sketch.getGeometry().on("change", function (evt) {
const geometry = evt.target;

if (geometry instanceof LineString) {
measureTooltipElement.innerHTML = formatLength(geometry);
tooltipCoord = geometry.getLastCoordinate();
}
tooltipCoord = geometry.getLastCoordinate();
measureTooltip.setPosition(tooltipCoord);
});
}
});

// Listen for the 'drawend' event to handle the addition of new features to the layer
drawInteraction.on("drawend", (e) => {
if (!drawLayer.get("isDrawingEnabled")) return;
addNewFeature(e, drawLayer, EOxMap, true);

// Tear down the measurement tooltip when the drawing is complete
if (EOxMap.measure) {
measureTooltipElement.className = "ol-tooltip ol-tooltip-static";
// unset sketch
sketch = null;
unByKey(listener);
}
});

// identifier to retrieve the interaction
Expand All @@ -77,3 +140,35 @@ export function addDraw(EOxMap, drawLayer, options) {
// Subscribe to the 'change' event on the layer group to detect when layers are removed
EOxMap.map.getLayerGroup().on("change", removeLayerListener);
}

/**
* Calculate real distance on the map and format the output.
* @param {Polygon} line The line string to calculate the distance for.
* @return {string} Formatted length.
*/
const formatLength = function (line) {
const length = getLength(line);
let output;
if (length > 100) {
output = Math.round((length / 1000) * 100) / 100 + " " + "km";
} else {
output = Math.round(length * 100) / 100 + " " + "m";
}
return output;
};

/**
* Format area output.
* @param {Polygon} polygon The polygon.
* @return {string} Formatted area.
*/
const _formatArea = function (polygon) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this used anywhere? It would be nice to support both lenght as well as area measurement.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, as currently implemented we would add it as a feature of the map, since that is where the OL interaction is created.

Currently this is not used, since the goal is mostly to determine distances in the GTIF apps. Question with two-dimensional measurements is also how the tooltip should behave (properly centered or stationary in a corner of the map).

const area = getArea(polygon);
let output;
if (area > 10000) {
output = Math.round((area / 1000000) * 100) / 100 + " " + "km<sup>2</sup>";
} else {
output = Math.round(area * 100) / 100 + " " + "m<sup>2</sup>";
}
return output;
};
1 change: 1 addition & 0 deletions elements/map/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ export class EOxMap extends LitElement {
intersections: { attribute: false, state: true, type: Object },
selectInteractions: { attribute: false, state: true, type: Object },
mapControls: { attribute: false, state: true, type: Object },
measure: { attribute: "measure", type: Boolean },
};
}

Expand Down