In the 4.32 SDK, the 3D measurement components have both clear and start methods - along with componentReady and destroy methods. But the 2D measurement components (both Area and Distance) only have the latter two methods - I do not see a clear or a start method. I am looking for a way to clear the graphics that are created when measuring distance/area in 2D. In the 3D sample code, it uses components; the 2D sample code is still using widgets (rather than arcgis-distance-measurement-2d or arcgis-area-measurement-2d). I already have a way to remove graphics when 2D widgets are used; I'm looking for a way to clear when using components. I already have a button in place that could do the clearing (vs clearing when the tools are no longer expanded). But I'm just not seeing the methods for the actual action.
Solved! Go to Solution.
Thank you again @Edvinas_S - you definitely helped get me on my way. I additionally want to thank a Penn State University instructor - Jim Detwiler - who taught me web mapping some years ago (and still proves to be a valuable resource when I am stuck). These users' insights helped immensely, as did this Esri page regarding watching for component changes:
https://developers.arcgis.com/javascript/latest/watch-for-changes/
There is in fact a specific example of the 2D measurement tool. Ultimately, I look for any property change in the tool's state. Once that happens - eg. with a push of the 'New measurement' button - the state will change ("measuring", "measured", etc.). Regardless, as soon as that happens, I can set an EventListener on my calcite-button that allows me to clear the measurement graphics:
// ****** MEASUREMENT TOOLS ******
const expandMeasurement_line = document.getElementById("line-measure");
const expandMeasurement_area = document.getElementById("area-measure");
const measureLine = document.querySelector("arcgis-distance-measurement-2d");
const measureArea = document.querySelector("arcgis-area-measurement-2d");
const trashCan = document.querySelector("calcite-button");
measureLine.addEventListener("arcgisPropertyChange", (e) => {
if (e.detail.name === "state") {
console.log("Measurement state:", e.target[e.detail.name]);
trashCan.addEventListener("click", () => {
e.target._store.viewModel.clear();
if (expandMeasurement_line.expanded === true) {
expandMeasurement_line.collapse();
}
});
}
});
measureArea.addEventListener("arcgisPropertyChange", (e) => {
if (e.detail.name === "state") {
console.log("Measurement state:", e.target[e.detail.name]);
trashCan.addEventListener("click", () => {
e.target._store.viewModel.clear();
if (expandMeasurement_area.expanded === true) {
expandMeasurement_area.collapse();
}
});
}
});
// ****** MEASUREMENT TOOLS ******
Until the clear and start methods are exposed for 2D measurement as they are with 3D measurement, this should do the trick.
For 2D widgets it used to be distanceMeasurement2D.viewModel.start() and distanceMeasurement2D.viewModel.clear()
Equivalent web components do not have these methods or the viewModel exposed. I think it's best to use widgets in this case. These specific web components use widgets behind the scenes anyway.
If you are interested, you can see current (4.32) web component implementation for Distance Measurement 2D here: js.arcgis.com/map-components/4.32/6XQYH356.js
Note that it imports the widget from widgets/DistanceMeasurement2D. The component has this.widget.viewModel in it, but it is not exposed as an external attribute that you could change/read.
Thank you for responding. Though I am not inclined to use a widget when - it would seem - it should be unnecessary. I have already worked through migrating 4.22 widgets to 4.32 components, and in every single instance I was successful - except for this situation. I find it strange that in the 3D measurement component example, both clear and start methods are exposed. And they work as expected:
https://developers.arcgis.com/javascript/latest/sample-code/sandbox/?sample=measurement-3d
Moreover, check out the 2D measurement component Demo:
Each click of the New measurement button clears the first measurement graphic, allowing the user to start a new measurement. In my case, I'd like to fire the same action as that button - at least in so far as clearing the graphics. If I could see how that action is carried out with the push of the New measurement button, I could easily enough set up my calcite button to clear those same graphics.
It seems odd that clear and start methods would exist for 3D measurement but not 2D measurement.
It should be there, but I think they just forgot to expose those methods. The reason they exist in 3D components is probably because those were used in live demos, so they got more attention.
Anyway, here is a workaround. Get a reference to the loaded component and access viewModel via _store
const arcgisMeasure = document.querySelector("arcgis-distance-measurement-2d");
arcgisMeasure.addEventListener("arcgisReady", (event) => {
event.target._store.viewModel.start()
// this also works
// arcgisMeasure._store.viewModel.start()
// clearing
// event.target._store.viewModel.clear()
})
This automatically starts drawing when component is loaded. viewModel doesn't exist before component fully loads.
I appreciate the tip. Unfortunately, I have not been able to get the result I'm looking for. Not certain if I have your code in the right place or not. Honestly, it would be infinitely easier and more elegant if Esri simply exposed the clear and start methods for 2D measurement. In the 3D sample code sandbox, I've actually tested these methods successfully. I grouped the measurement tools together with a calcite-button into the <arcgis-placement> component:
<arcgis-placement position="top-right">
<arcgis-expand id="expand-line" position="top-right" group="top-right">
<arcgis-directline-measurement-3d>
</arcgis-directline-measurement-3d>
</arcgis-expand>
<arcgis-expand id="expand-area" position="top-right" group="top-right">
<arcgis-area-measurement-3d>
</arcgis-area-measurement-3d>
</arcgis-expand>
<calcite-button icon-start="trash"></calcite-button>
</arcgis-placement>
Then I added a very simple event listener within the arcScene.arcgisViewReadyChange even listener. Works like a charm - I can clear both linear and area measurements with the click of my calcite-button:
arcgisScene.addEventListener("arcgisViewReadyChange", () => {
trash.addEventListener("click", () => {
// If I want to clear only on a specific state
/*if(areaMeasurement3d.state == "measured") {
areaMeasurement3d.clear();
}*/
directlineMeasurement3d.clear();
areaMeasurement3d.clear();
});
Hopefully those methods get exposed for 2D - and before SDK v4.33 is release (~June 2025)
Thank you again @Edvinas_S - you definitely helped get me on my way. I additionally want to thank a Penn State University instructor - Jim Detwiler - who taught me web mapping some years ago (and still proves to be a valuable resource when I am stuck). These users' insights helped immensely, as did this Esri page regarding watching for component changes:
https://developers.arcgis.com/javascript/latest/watch-for-changes/
There is in fact a specific example of the 2D measurement tool. Ultimately, I look for any property change in the tool's state. Once that happens - eg. with a push of the 'New measurement' button - the state will change ("measuring", "measured", etc.). Regardless, as soon as that happens, I can set an EventListener on my calcite-button that allows me to clear the measurement graphics:
// ****** MEASUREMENT TOOLS ******
const expandMeasurement_line = document.getElementById("line-measure");
const expandMeasurement_area = document.getElementById("area-measure");
const measureLine = document.querySelector("arcgis-distance-measurement-2d");
const measureArea = document.querySelector("arcgis-area-measurement-2d");
const trashCan = document.querySelector("calcite-button");
measureLine.addEventListener("arcgisPropertyChange", (e) => {
if (e.detail.name === "state") {
console.log("Measurement state:", e.target[e.detail.name]);
trashCan.addEventListener("click", () => {
e.target._store.viewModel.clear();
if (expandMeasurement_line.expanded === true) {
expandMeasurement_line.collapse();
}
});
}
});
measureArea.addEventListener("arcgisPropertyChange", (e) => {
if (e.detail.name === "state") {
console.log("Measurement state:", e.target[e.detail.name]);
trashCan.addEventListener("click", () => {
e.target._store.viewModel.clear();
if (expandMeasurement_area.expanded === true) {
expandMeasurement_area.collapse();
}
});
}
});
// ****** MEASUREMENT TOOLS ******
Until the clear and start methods are exposed for 2D measurement as they are with 3D measurement, this should do the trick.
Thank you so much for sharing this conversation @LMFGeospatial and @Edvinas_S. We are looking at enhancing the 2D measurement components for this workflow.
Excellent, @Noah-Sager - looking forward to the enhancement.