Is there a way to extend the Measurement Widget's Location function to allow for multiple pin locations on a map, and for those pins to be removed individually by the user? I've got a pin function that I'm using for another part of some code that I'm developing against and, before I try to try and leverage it similarly on this part, I wanted to ask.
I'm using v 3.16 & Dojo for this.
B
Solved! Go to Solution.
Bart,
Here is a sample. Don't forget to mark this question as answered by clicking on the "Mark Correct" link on the reply that answered your question.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--The viewport meta tag is used to improve the presentation and behavior of the samples
on iOS devices-->
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Measure Tool</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.21/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.21/esri/css/esri.css">
<style>
html,
body {
height: 100%;
width: 100%;
margin: 0;
}
body {
background-color: #FFF;
overflow: hidden;
font-family: "Trebuchet MS";
}
#map {
border: solid 2px #808775;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
margin: 5px;
padding: 0px;
}
#titlePane {
width: 240px;
}
.claro .dijitTitlePaneTitle {
background: #fff;
font-weight: 600;
border: none;
border-bottom: solid 1px #29201A;
border-top: solid 1px #29201A;
}
.claro .dijitTitlePaneTitleHover {
background: #eee;
}
.claro .dijitTitlePaneTitleActive {
background: #808775;
}
.claro .dijitTitlePaneContentOuter {
border-right: none;
border-bottom: none;
border-left: none;
}
</style>
<script src="http://js.arcgis.com/3.21/"></script>
<script>
var map, deleteMGra;
require([
"dojo/dom",
"esri/Color",
"dojo/keys",
"dojo/parser",
"dojo/query",
"dojo/on",
"dojo/dom-construct",
"dojo/_base/array",
"dojo/dom-style",
"esri/config",
"esri/sniff",
"esri/map",
"esri/SnappingManager",
"esri/dijit/Measurement",
"esri/layers/FeatureLayer",
"esri/layers/GraphicsLayer",
"esri/graphic",
"esri/renderers/SimpleRenderer",
"esri/tasks/GeometryService",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/PictureMarkerSymbol",
"esri/dijit/Scalebar",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dijit/TitlePane",
"dijit/form/CheckBox",
"dojo/domReady!"
], function (
dom, Color, keys, parser, query, on, domConstruct, array, domStyle,
esriConfig, has, Map, SnappingManager, Measurement, FeatureLayer, GraphicsLayer, Graphic,
SimpleRenderer, GeometryService, SimpleLineSymbol, SimpleFillSymbol, PictureMarkerSymbol
) {
parser.parse();
//This sample may require a proxy page to handle communications with the ArcGIS Server services. You will need to
//replace the url below with the location of a proxy on your machine. See the 'Using the proxy page' help topic
//for details on setting up a proxy page.
esriConfig.defaults.io.proxyUrl = "/proxy/";
esriConfig.defaults.io.alwaysUseProxy = false;
//This service is for development and testing purposes only. We recommend that you create your own geometry service for use within your applications
esriConfig.defaults.geometryService = new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
map = new Map("map", {
basemap: "satellite",
center: [-85.743, 38.256],
zoom: 17
});
var sfs = new SimpleFillSymbol(
"solid",
new SimpleLineSymbol("solid", new Color([195, 176, 23]), 2),
null
);
var parcelsLayer = new FeatureLayer("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Louisville/LOJIC_LandRecords_Louisville/MapServer/0", {
mode: FeatureLayer.MODE_ONDEMAND,
outFields: ["*"]
});
parcelsLayer.setRenderer(new SimpleRenderer(sfs));
map.addLayers([parcelsLayer]);
//dojo.keys.copyKey maps to CTRL on windows and Cmd on Mac., but has wrong code for Chrome on Mac
var snapManager = map.enableSnapping({
snapKey: has("mac") ? keys.META : keys.CTRL
});
var layerInfos = [{
layer: parcelsLayer
}];
snapManager.setLayerInfos(layerInfos);
var measureGL = new GraphicsLayer();
var pms = new PictureMarkerSymbol('http://js.arcgis.com/3.21/esri/dijit/images/esriGreenPin16x26.png', 16, 26);
pms.setOffset(0, 12);
map.addLayers([measureGL]);
var measurement = new Measurement({
map: map,
}, dom.byId("measurementDiv"));
measurement.startup();
measurement.on("tool-change", function (evt) {
if (evt.toolName !== "location") {
//If a tool other than the location tool or the location tool has been toggled off
//Clear the graphics layer
measureGL.clear();
//Remove all the rows of locations added by the code
var rows = query(".myMeasurementTableRow");
array.forEach(rows, function (row) {
domConstruct.destroy(row);
});
//Hide the Graphics Layer
measureGL.hide();
} else {
//Hide the Graphics Layer
measureGL.show();
//show the standard location measure row that was hidden
var mRows = query(".esriMeasurementTableRow");
domStyle.set(mRows[1], "display", "");
}
});
measurement.on("measure", function (evt) {
switch (evt.toolName) {
case "location":
break;
default:
var resultDiv = query(".dijitContentPane .esriMeasurementResultValue")[0];
console.info(measurement);
var result = domConstruct.toDom("<div class='result'>" + evt.values[0] + "<div>");
domConstruct.place(resultDiv, result);
break;
}
});
deleteMGra = function (){
var rowId = this.event.target.id;
domConstruct.destroy(this.event.target.id);
//loop trough the graphics and delete this graphic by ID
measureGL.graphics.some(function(g){
if(g.attributes.Id === rowId){
measureGL.remove(g);
if(measureGL.graphics.length == 0){
measurement.clearResult();
}
return true;
}
})
}
measurement.on("measure-end", function (evt) {
switch (evt.toolName) {
case "location":
//console.log("Lat: " + evt.values[0] + " Lng: " + evt.values[1]);
var tbl = query(".esriMeasurementResultTable tbody")[0];
var eRows = query(".esriMeasurementTableRow");
var mRows = query(".myMeasurementTableRow");
var rowId = "mrowid" + (mRows.length + 1 ).toString();
var row = domConstruct.toDom("<tr class='myMeasurementTableRow' id='" + rowId + "'>" +
"<td><img src='http://js.arcgis.com/3.14/esri/dijit/images/esriGreenPin16x26.png' style='vertical-align:middle'></td>" +
"<td class='esriMeasurementTableCell'>" + evt.values[0] + "</td><td class='esriMeasurementTableCell'>" + evt.values[1] +
"</td><td><span style='cursor:pointer;color:red;font-weight:bold;padding:0 2px;' id='" + rowId + "'" +
" onClick='deleteMGra()'>X</span></td></tr>");
//Hide the standard measure loaction row so that there is not two identical measures
domStyle.set(eRows[1], "display", "none");
domConstruct.place(row, tbl);
//Add the measure to the Graphics Layer
measureGL.add(new Graphic(evt.geometry, pms, {
"Lat": evt.values[0],
"Lon": evt.values[1],
"Id": rowId
}));
measurement._measureGraphics[0]._graphicsLayer.clear();
break;
default:
var resultDiv = query(".esriMeasurementResultValue")[0];
var result = domConstruct.toDom("<div class='result'>" + evt.values[0] + "<div>");
domConstruct.place(resultDiv, result);
break;
}
});
});
</script>
</head>
<body class="claro">
<div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline',gutters:false" style="width:100%; height:100%;">
<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'">
<div style="position:absolute; right:20px; top:10px; z-Index:999;">
<div id="titlePane" data-dojo-type="dijit/TitlePane" data-dojo-props="title:'Measurement', closable:'false', open:'false'">
<div id="measurementDiv"></div>
<span style="font-size:smaller;padding:5px 5px;">Press <b>CTRL</b> to enable snapping.</span>
</div>
</div>
</div>
</div>
</body>
</html>
Bart,
Something like this? You can place multiple points on the map and right click a point to delete it.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Measure Tool</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.29/esri/themes/calcite/dijit/calcite.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.29/esri/themes/calcite/esri/esri.css">
<style>
html,body {
height:100%;
width:100%;
margin:0;
}
body {
background-color:#FFF;
overflow:hidden;
font-family:"Trebuchet MS";
}
#map {
border:solid 2px #808775;
-moz-border-radius:4px;
-webkit-border-radius:4px;
border-radius:4px;
margin:5px;
padding:0px;
}
#titlePane{
width:280px;
}
</style>
<script src="https://js.arcgis.com/3.29/"></script>
<script>
var map;
require([
"dojo/dom",
"esri/Color",
"dojo/keys",
"dojo/parser",
"esri/config",
"esri/sniff",
"esri/map",
"esri/SnappingManager",
"esri/dijit/Measurement",
"esri/layers/FeatureLayer",
"esri/renderers/SimpleRenderer",
"esri/tasks/GeometryService",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/layers/GraphicsLayer",
"esri/graphic",
"dijit/Menu", "dijit/MenuItem", "dijit/MenuSeparator",
"esri/dijit/Scalebar",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dijit/TitlePane",
"dijit/form/CheckBox",
"dojo/domReady!"
], function(
dom, Color, keys, parser,
esriConfig, has, Map, SnappingManager, Measurement, FeatureLayer, SimpleRenderer, GeometryService, SimpleLineSymbol, SimpleFillSymbol, GraphicsLayer, Graphic,
Menu, MenuItem, MenuSeparator
) {
parser.parse();
//This sample may require a proxy page to handle communications with the ArcGIS Server services. You will need to
//replace the url below with the location of a proxy on your machine. See the 'Using the proxy page' help topic
//for details on setting up a proxy page.
esriConfig.defaults.io.proxyUrl = "/proxy/";
esriConfig.defaults.io.alwaysUseProxy = false;
//This service is for development and testing purposes only. We recommend that you create your own geometry service for use within your applications
esriConfig.defaults.geometryService = new GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
map = new Map("map", {
basemap: "satellite",
center: [-85.743, 38.256],
zoom: 17
});
var mGL = new GraphicsLayer();
map.on("load", createGraphicsMenu);
function createGraphicsMenu() {
map.addLayer(mGL);
// Creates right-click context menu for GRAPHICS
ctxMenuForGraphics = new Menu({});
ctxMenuForGraphics.addChild(new MenuItem({
label: "Delete",
onClick: function() {
mGL.remove(selected);
}
}));
ctxMenuForGraphics.startup();
mGL.on("mouse-over", function(evt) {
// We'll use this "selected" graphic to enable editing tools
// on this graphic when the user click on one of the tools
// listed in the menu.
selected = evt.graphic;
// Let's bind to the graphic underneath the mouse cursor
ctxMenuForGraphics.bindDomNode(evt.graphic.getDojoShape().getNode());
});
mGL.on("mouse-out", function(evt) {
ctxMenuForGraphics.unBindDomNode(evt.graphic.getDojoShape().getNode());
});
}
var sfs = new SimpleFillSymbol(
"solid",
new SimpleLineSymbol("solid", new Color([195, 176, 23]), 2),
null
);
var parcelsLayer = new FeatureLayer("https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Louisville/LOJIC_LandRecords_Louisville/MapServer/0", {
mode: FeatureLayer.MODE_ONDEMAND,
outFields: ["*"]
});
parcelsLayer.setRenderer(new SimpleRenderer(sfs));
map.addLayers([parcelsLayer]);
//dojo.keys.copyKey maps to CTRL on windows and Cmd on Mac., but has wrong code for Chrome on Mac
var snapManager = map.enableSnapping({
snapKey: has("mac") ? keys.META : keys.CTRL
});
var layerInfos = [{
layer: parcelsLayer
}];
snapManager.setLayerInfos(layerInfos);
var measurement = new Measurement({
map: map
}, dom.byId("measurementDiv"));
measurement.startup();
measurement.on('measure-end', function(evt){
var geom = evt.geometry;
console.info(measurement);
var gra = new Graphic(geom, measurement._pointSymbol)
measurement.clearResult();
mGL.add(gra);
});
});
</script>
</head>
<body class="calcite">
<div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline',gutters:false"
style="width:100%; height:100%;">
<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'">
<div style="position:absolute; right:20px; top:10px; z-Index:999;">
<div id="titlePane" data-dojo-type="dijit/TitlePane" data-dojo-props="title:'Measurement', closable:false">
<div id="measurementDiv"></div>
<span style="font-size:smaller;padding:5px 5px;">Press <b>CTRL</b> to enable snapping.</span>
</div>
</div>
</div>
</div>
</body>
</html>
Robert,
That's along the lines of what I was trying to do. I'm needing to add the points to a list which I was going to put below where the green pin marker was located. From there, they would have the option to remove individual ones or clear the list.
Bart
Yet totally possible.
Bart,
Here is a sample. Don't forget to mark this question as answered by clicking on the "Mark Correct" link on the reply that answered your question.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--The viewport meta tag is used to improve the presentation and behavior of the samples
on iOS devices-->
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Measure Tool</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.21/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.21/esri/css/esri.css">
<style>
html,
body {
height: 100%;
width: 100%;
margin: 0;
}
body {
background-color: #FFF;
overflow: hidden;
font-family: "Trebuchet MS";
}
#map {
border: solid 2px #808775;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
border-radius: 4px;
margin: 5px;
padding: 0px;
}
#titlePane {
width: 240px;
}
.claro .dijitTitlePaneTitle {
background: #fff;
font-weight: 600;
border: none;
border-bottom: solid 1px #29201A;
border-top: solid 1px #29201A;
}
.claro .dijitTitlePaneTitleHover {
background: #eee;
}
.claro .dijitTitlePaneTitleActive {
background: #808775;
}
.claro .dijitTitlePaneContentOuter {
border-right: none;
border-bottom: none;
border-left: none;
}
</style>
<script src="http://js.arcgis.com/3.21/"></script>
<script>
var map, deleteMGra;
require([
"dojo/dom",
"esri/Color",
"dojo/keys",
"dojo/parser",
"dojo/query",
"dojo/on",
"dojo/dom-construct",
"dojo/_base/array",
"dojo/dom-style",
"esri/config",
"esri/sniff",
"esri/map",
"esri/SnappingManager",
"esri/dijit/Measurement",
"esri/layers/FeatureLayer",
"esri/layers/GraphicsLayer",
"esri/graphic",
"esri/renderers/SimpleRenderer",
"esri/tasks/GeometryService",
"esri/symbols/SimpleLineSymbol",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/PictureMarkerSymbol",
"esri/dijit/Scalebar",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dijit/TitlePane",
"dijit/form/CheckBox",
"dojo/domReady!"
], function (
dom, Color, keys, parser, query, on, domConstruct, array, domStyle,
esriConfig, has, Map, SnappingManager, Measurement, FeatureLayer, GraphicsLayer, Graphic,
SimpleRenderer, GeometryService, SimpleLineSymbol, SimpleFillSymbol, PictureMarkerSymbol
) {
parser.parse();
//This sample may require a proxy page to handle communications with the ArcGIS Server services. You will need to
//replace the url below with the location of a proxy on your machine. See the 'Using the proxy page' help topic
//for details on setting up a proxy page.
esriConfig.defaults.io.proxyUrl = "/proxy/";
esriConfig.defaults.io.alwaysUseProxy = false;
//This service is for development and testing purposes only. We recommend that you create your own geometry service for use within your applications
esriConfig.defaults.geometryService = new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
map = new Map("map", {
basemap: "satellite",
center: [-85.743, 38.256],
zoom: 17
});
var sfs = new SimpleFillSymbol(
"solid",
new SimpleLineSymbol("solid", new Color([195, 176, 23]), 2),
null
);
var parcelsLayer = new FeatureLayer("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Louisville/LOJIC_LandRecords_Louisville/MapServer/0", {
mode: FeatureLayer.MODE_ONDEMAND,
outFields: ["*"]
});
parcelsLayer.setRenderer(new SimpleRenderer(sfs));
map.addLayers([parcelsLayer]);
//dojo.keys.copyKey maps to CTRL on windows and Cmd on Mac., but has wrong code for Chrome on Mac
var snapManager = map.enableSnapping({
snapKey: has("mac") ? keys.META : keys.CTRL
});
var layerInfos = [{
layer: parcelsLayer
}];
snapManager.setLayerInfos(layerInfos);
var measureGL = new GraphicsLayer();
var pms = new PictureMarkerSymbol('http://js.arcgis.com/3.21/esri/dijit/images/esriGreenPin16x26.png', 16, 26);
pms.setOffset(0, 12);
map.addLayers([measureGL]);
var measurement = new Measurement({
map: map,
}, dom.byId("measurementDiv"));
measurement.startup();
measurement.on("tool-change", function (evt) {
if (evt.toolName !== "location") {
//If a tool other than the location tool or the location tool has been toggled off
//Clear the graphics layer
measureGL.clear();
//Remove all the rows of locations added by the code
var rows = query(".myMeasurementTableRow");
array.forEach(rows, function (row) {
domConstruct.destroy(row);
});
//Hide the Graphics Layer
measureGL.hide();
} else {
//Hide the Graphics Layer
measureGL.show();
//show the standard location measure row that was hidden
var mRows = query(".esriMeasurementTableRow");
domStyle.set(mRows[1], "display", "");
}
});
measurement.on("measure", function (evt) {
switch (evt.toolName) {
case "location":
break;
default:
var resultDiv = query(".dijitContentPane .esriMeasurementResultValue")[0];
console.info(measurement);
var result = domConstruct.toDom("<div class='result'>" + evt.values[0] + "<div>");
domConstruct.place(resultDiv, result);
break;
}
});
deleteMGra = function (){
var rowId = this.event.target.id;
domConstruct.destroy(this.event.target.id);
//loop trough the graphics and delete this graphic by ID
measureGL.graphics.some(function(g){
if(g.attributes.Id === rowId){
measureGL.remove(g);
if(measureGL.graphics.length == 0){
measurement.clearResult();
}
return true;
}
})
}
measurement.on("measure-end", function (evt) {
switch (evt.toolName) {
case "location":
//console.log("Lat: " + evt.values[0] + " Lng: " + evt.values[1]);
var tbl = query(".esriMeasurementResultTable tbody")[0];
var eRows = query(".esriMeasurementTableRow");
var mRows = query(".myMeasurementTableRow");
var rowId = "mrowid" + (mRows.length + 1 ).toString();
var row = domConstruct.toDom("<tr class='myMeasurementTableRow' id='" + rowId + "'>" +
"<td><img src='http://js.arcgis.com/3.14/esri/dijit/images/esriGreenPin16x26.png' style='vertical-align:middle'></td>" +
"<td class='esriMeasurementTableCell'>" + evt.values[0] + "</td><td class='esriMeasurementTableCell'>" + evt.values[1] +
"</td><td><span style='cursor:pointer;color:red;font-weight:bold;padding:0 2px;' id='" + rowId + "'" +
" onClick='deleteMGra()'>X</span></td></tr>");
//Hide the standard measure loaction row so that there is not two identical measures
domStyle.set(eRows[1], "display", "none");
domConstruct.place(row, tbl);
//Add the measure to the Graphics Layer
measureGL.add(new Graphic(evt.geometry, pms, {
"Lat": evt.values[0],
"Lon": evt.values[1],
"Id": rowId
}));
measurement._measureGraphics[0]._graphicsLayer.clear();
break;
default:
var resultDiv = query(".esriMeasurementResultValue")[0];
var result = domConstruct.toDom("<div class='result'>" + evt.values[0] + "<div>");
domConstruct.place(resultDiv, result);
break;
}
});
});
</script>
</head>
<body class="claro">
<div id="mainWindow" data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline',gutters:false" style="width:100%; height:100%;">
<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'">
<div style="position:absolute; right:20px; top:10px; z-Index:999;">
<div id="titlePane" data-dojo-type="dijit/TitlePane" data-dojo-props="title:'Measurement', closable:'false', open:'false'">
<div id="measurementDiv"></div>
<span style="font-size:smaller;padding:5px 5px;">Press <b>CTRL</b> to enable snapping.</span>
</div>
</div>
</div>
</div>
</body>
</html>