I tried to merge two of the ArcGis Javascript API widgets in sandbox and those are the basemap gallery and the measurement, however, the measurement widget does not work. The measurement widget does not function in the sense that i am simply unable to measure on the map. Cannot select any points or I do not see any lines come up. What could the problem be and how do I go about fixing it?
<html lang="en">
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1, maximum-scale=1,user-scalable=no"
/>
<title>
BasemapGallery widget | Sample | ArcGIS Maps SDK for JavaScript 4.26
</title>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.26/esri/themes/light/main.css"
/>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script src="https://js.arcgis.com/4.26/"></script>
<script>
require([
"esri/Map",
"esri/views/SceneView",
"esri/widgets/Expand",
"esri/widgets/BasemapGallery",
"esri/widgets/DistanceMeasurement2D",
"esri/widgets/AreaMeasurement2D"
], (Map, SceneView, Expand, BasemapGallery, DistanceMeasurement2D, AreaMeasurement2D) => {
const map = new Map({
basemap: "topo-vector"
});
const view = new SceneView({
container: "viewDiv",
map: map,
center: [-77.2627, 18.0927],
zoom: 10
});
const basemapGallery = new BasemapGallery({
view: view,
});
// Create an Expand instance and set the content
// property to the DOM node of the basemap gallery widget
// Use an Esri icon font to represent the content inside
// of the Expand widget
const bgExpand = new Expand({
view: view,
content: basemapGallery
});
// close the expand whenever a basemap is selected
basemapGallery.watch("activeBasemap", () => {
const mobileSize =
view.heightBreakpoint === "xsmall" ||
view.widthBreakpoint === "xsmall";
if (mobileSize) {
bgExpand.collapse();
}
});
// Add the expand instance to the ui
view.ui.add(bgExpand, "top-left");
// add the toolbar for the measurement widgets
view.ui.add("topbar", "top-right");
document
.getElementById("distanceButton")
.addEventListener("click", function () {
setActiveWidget(null);
if (!this.classList.contains("active")) {
setActiveWidget("distance");
} else {
setActiveButton(null);
}
});
document
.getElementById("areaButton")
.addEventListener("click", function () {
setActiveWidget(null);
if (!this.classList.contains("active")) {
setActiveWidget("area");
} else {
setActiveButton(null);
}
});
function setActiveWidget(type) {
switch (type) {
case "distance":
activeWidget = new DistanceMeasurement2D({
view: view
});
// skip the initial 'new measurement' button
activeWidget.viewModel.start();
view.ui.add(activeWidget, "top-right");
setActiveButton(document.getElementById("distanceButton"));
break;
case "area":
activeWidget = new AreaMeasurement2D({
view: view
});
// skip the initial 'new measurement' button
activeWidget.viewModel.start();
view.ui.add(activeWidget, "top-right");
setActiveButton(document.getElementById("areaButton"));
break;
case null:
if (activeWidget) {
view.ui.remove(activeWidget);
activeWidget.destroy();
activeWidget = null;
}
break;
}
}
function setActiveButton(selectedButton) {
// focus the view to activate keyboard shortcuts for sketching
view.focus();
let elements = document.getElementsByClassName("active");
for (let i = 0; i < elements.length; i++) {
elements[i].classList.remove("active");
}
if (selectedButton) {
selectedButton.classList.add("active");
}
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="topbar">
<button
class="action-button esri-icon-measure-line"
id="distanceButton"
type="button"
title="Measure distance between two or more points"
></button>
<button
class="action-button esri-icon-measure-area"
id="areaButton"
type="button"
title="Measure area"
></button>
</div>
</body>
</html>
You have two problems in your code,
activeWidget
variableMapView
, which is the view for two dimensionsHere is the fixed code,
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" />
<title>
BasemapGallery widget | Sample | ArcGIS Maps SDK for JavaScript 4.26
</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.26/esri/themes/light/main.css" />
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script src="https://js.arcgis.com/4.26/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/widgets/Expand",
"esri/widgets/BasemapGallery",
"esri/widgets/DistanceMeasurement2D",
"esri/widgets/AreaMeasurement2D"
], (Map, MapView, Expand, BasemapGallery, DistanceMeasurement2D, AreaMeasurement2D) => {
let activeWidget = null; // <- YOU WERE MISSING
const map = new Map({
basemap: "topo-vector"
});
const view = new MapView({
container: "viewDiv",
map: map,
center: [-77.2627, 18.0927],
zoom: 10
});
const basemapGallery = new BasemapGallery({
view: view,
});
// Create an Expand instance and set the content
// property to the DOM node of the basemap gallery widget
// Use an Esri icon font to represent the content inside
// of the Expand widget
const bgExpand = new Expand({
view: view,
content: basemapGallery
});
// close the expand whenever a basemap is selected
basemapGallery.watch("activeBasemap", () => {
const mobileSize =
view.heightBreakpoint === "xsmall" ||
view.widthBreakpoint === "xsmall";
if (mobileSize) {
bgExpand.collapse();
}
});
// Add the expand instance to the ui
view.ui.add(bgExpand, "top-left");
// add the toolbar for the measurement widgets
view.ui.add("topbar", "top-right");
document
.getElementById("distanceButton")
.addEventListener("click", function () {
setActiveWidget(null);
if (!this.classList.contains("active")) {
setActiveWidget("distance");
} else {
setActiveButton(null);
}
});
document
.getElementById("areaButton")
.addEventListener("click", function () {
setActiveWidget(null);
if (!this.classList.contains("active")) {
setActiveWidget("area");
} else {
setActiveButton(null);
}
});
function setActiveWidget(type) {
switch (type) {
case "distance":
activeWidget = new DistanceMeasurement2D({
view: view
});
// skip the initial 'new measurement' button
activeWidget.viewModel.start();
view.ui.add(activeWidget, "top-right");
setActiveButton(document.getElementById("distanceButton"));
break;
case "area":
activeWidget = new AreaMeasurement2D({
view: view
});
// skip the initial 'new measurement' button
activeWidget.viewModel.start();
view.ui.add(activeWidget, "top-right");
setActiveButton(document.getElementById("areaButton"));
break;
case null:
if (activeWidget) {
view.ui.remove(activeWidget);
activeWidget.destroy();
activeWidget = null;
}
break;
}
}
function setActiveButton(selectedButton) {
// focus the view to activate keyboard shortcuts for sketching
view.focus();
let elements = document.getElementsByClassName("active");
for (let i = 0; i < elements.length; i++) {
elements[i].classList.remove("active");
}
if (selectedButton) {
selectedButton.classList.add("active");
}
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="topbar">
<button class="action-button esri-icon-measure-line" id="distanceButton" type="button"
title="Measure distance between two or more points"></button>
<button class="action-button esri-icon-measure-area" id="areaButton" type="button"
title="Measure area"></button>
</div>
</body>
</html>