Trying to perform a spatial selection on features in feature layer 1 and then copy/paste geometries to feature layer 2, using ApplyEdits.
I've grabbed some code from various samples and posts on GeoNet. I can get the application to select features but I am unable to apply edits to feature layer 2. See below. I have tried inserting ApplyEdits in two locations, one inside a button click event. See lines 164 and 174-180.
Console error: Unsupported geometry type: reshape
Source feature layer: (US States)
var featureLayer3 = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3"
Target feature layer:
var firePerimeterFL = new FeatureLayer("https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Fire/Sheep/FeatureServer/2",
Thanks.
<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">
<!--
ArcGIS API for JavaScript, https://js.arcgis.com
For more information about the graphics_add sample, read the original sample description at developers.arcgis.com.
https://developers.arcgis.com/javascript/3/jssamples/graphics_add.html
-->
<title>Shapes and Symbols</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.30/esri/css/esri.css">
<style>
#info {
top: 20px;
color: #444;
height: auto;
font-family: arial;
right: 20px;
margin: 5px;
padding: 10px;
position: absolute;
width: 115px;
z-index: 40;
border: solid 2px #666;
border-radius: 4px;
background-color: #fff;
}
html, body, #mapDiv {
padding:0;
margin:0;
height:100%;
}
button {
display: block;
}
</style>
<script src="https://js.arcgis.com/3.30/"></script>
<script>
var map, tb;
require([
"esri/map", "esri/toolbars/draw", "dojo/promise/all",
"esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol",
"esri/symbols/PictureFillSymbol", "esri/symbols/CartographicLineSymbol", "esri/layers/FeatureLayer",
"esri/graphic", "esri/tasks/query", "esri/tasks/QueryTask", "esri/InfoTemplate",
"esri/Color", "dojo/dom", "dojo/on", "dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane",
"dijit/layout/AccordionContainer", "dojo/domReady!"], function (
Map, Draw, All,
SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol,
PictureFillSymbol, CartographicLineSymbol, FeatureLayer,
Graphic, Query, QueryTask, InfoTemplate,
Color, dom, on, parser) {
parser.parse();
map = new Map("mapDiv", {
basemap: "streets",
center: [-85.82966, 33.666494],
zoom: 5
});
map.on("load", initToolbar);
var featureLayer1 = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/0", {
mode: FeatureLayer.MODE_SNAPSHOT,
infoTemplate: new InfoTemplate("Block: ${BLOCK}", "${*}"),
outFields: ["POP2000", "HOUSEHOLDS", "HSE_UNITS", "TRACT", "BLOCK"]
});
var featureLayer2 = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/1", {
mode: FeatureLayer.MODE_SNAPSHOT,
infoTemplate: new InfoTemplate("Block Group: ${BLKGRP}", "${*}"),
outFields: ["POP2000", "HOUSEHOLDS", "HSE_UNITS", "TRACT", "BLKGRP"]
});
var featureLayer3 = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3", {
mode: FeatureLayer.MODE_SNAPSHOT,
infoTemplate: new InfoTemplate("County Name: ${NAME}", "${*}"),
outFields: ["POP2000", "HOUSEHOLDS", "HSE_UNITS", "NAME"]
});
var firePerimeterFL = new FeatureLayer("https://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Fire/Sheep/FeatureServer/2", {
mode: FeatureLayer.MODE_SELECT,
outFields: ["*"],
});
map.addLayers([featureLayer1, featureLayer2, featureLayer3, firePerimeterFL]);
// markerSymbol is used for point and multipoint, see http://raphaeljs.com/icons/#talkq for more examples
var markerSymbol = new SimpleMarkerSymbol();
markerSymbol.setPath("M16,4.938c-7.732,0-14,4.701-14,10.5c0,1.981,0.741,3.833,2.016,5.414L2,25.272l5.613-1.44c2.339,1.316,5.237,2.106,8.387,2.106c7.732,0,14-4.701,14-10.5S23.732,4.938,16,4.938zM16.868,21.375h-1.969v-1.889h1.969V21.375zM16.772,18.094h-1.777l-0.176-8.083h2.113L16.772,18.094z");
markerSymbol.setColor(new Color("#00FFFF"));
// lineSymbol used for freehand polyline, polyline and line.
var lineSymbol = new CartographicLineSymbol(
CartographicLineSymbol.STYLE_SOLID,
new Color([255, 125, 0]), 10,
CartographicLineSymbol.CAP_ROUND,
CartographicLineSymbol.JOIN_MITER, 5);
// fill symbol used for extent, polygon and freehand polygon
var fillSymbol = new SimpleFillSymbol();
fillSymbol.setColor(new Color([255, 0, 255, 0.5]))
function initToolbar() {
tb = new Draw(map);
tb.on("draw-end", addGraphic);
// event delegation so a click handler is not
// needed for each individual button
on(dom.byId("info"), "click", function (evt) {
if (evt.target.id === "info") {
return;
}
var tool = evt.target.id.toLowerCase();
map.disableMapNavigation();
tb.activate(tool);
});
}
function addGraphic(evt) {
//deactivate the toolbar and clear existing graphics
tb.deactivate();
map.enableMapNavigation();
// figure out which symbol to use
var symbol;
if (evt.geometry.type === "point" || evt.geometry.type === "multipoint") {
symbol = markerSymbol;
} else if (evt.geometry.type === "line" || evt.geometry.type === "polyline") {
symbol = lineSymbol;
} else {
symbol = fillSymbol;
}
map.graphics.add(new Graphic(evt.geometry, symbol));
queryMapService(evt.geometry);
}
function queryMapService(Geom) {
var promises = [];
var query = new Query();
query.returnGeometry = false;
query.outFields = ["*"];
query.geometry = Geom;
//promises.push(featureLayer1.selectFeatures(query, FeatureLayer.SELECTION_NEW));
//promises.push(featureLayer2.selectFeatures(query, FeatureLayer.SELECTION_NEW));
promises.push(featureLayer3.selectFeatures(query, FeatureLayer.SELECTION_NEW));
firePerimeterFL.applyEdits([event.graphic], null, null);
var allPromises = new All(promises);
allPromises.then(function (r) {
showResults(r);
});
}
dojo.connect(dijit.byId("reshape"), "onClick", function() {
var targetGraphic = featureLayer3.getSelectedFeatures()[0].setGeometry(reshapedGeometry);
firePerimeterFL.applyEdits([targetGraphic],null, null);
});
function showResults(results) {
var resultCount = results.length;
console.log(resultCount);
}
});
</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="mapDiv" class="shadow roundedCorners" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"></div>
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'right'" class="roundedCorners" id="rightPane">
<div data-dojo-type="dijit.layout.AccordionContainer">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Graphics'" id='graphics'>
<div id="info">
<div>Select a shape then draw on map to add graphic</div>
<button id="Point">Point</button>
<button id="Multipoint">Multipoint</button>
<button id="Line">Line</button>
<button id="Polyline">Polyline</button>
<button id="FreehandPolyline">Freehand Polyline</button>
<button id="Triangle">Triangle</button>
<button id="Extent">Rectangle</button>
<button id="Circle">Circle</button>
<button id="Ellipse">Ellipse</button>
<button id="Polygon">Polygon</button>
<button id="FreehandPolygon">Freehand Polygon</button>
<button id="reshape" data-dojo-type="dijit.form.Button">ApplyEdits</button>
</div>
</div>
<div data-dojo-type="dijit/layout/ContentPane" id="legendPane" data-dojo-props="title:'Legend'">
<div id="legendDiv"></div>
</div>
</div>
</div>
</div>
</body>
</html>
Solved! Go to Solution.
Hi Will Hughes,
I haven't looked deeply into your example but there should not be a problem saving selected features from one service to another. You may run into issues if the feature type, m/z values, or spatial references of the services don't match and those may need a little extra handling. You would also need to handle the attribute field mapping as desired. There are ways to project features to the destination spatial reference if needed (e.g. GeometryService | API Reference | ArcGIS API for JavaScript 3.30).
I created an example that shows some basic workflows. https://jsfiddle.net/25g907ao/
Let me know if this helps answer your question.
Thanks!
Hi Will Hughes,
I haven't looked deeply into your example but there should not be a problem saving selected features from one service to another. You may run into issues if the feature type, m/z values, or spatial references of the services don't match and those may need a little extra handling. You would also need to handle the attribute field mapping as desired. There are ways to project features to the destination spatial reference if needed (e.g. GeometryService | API Reference | ArcGIS API for JavaScript 3.30).
I created an example that shows some basic workflows. https://jsfiddle.net/25g907ao/
Let me know if this helps answer your question.
Thanks!
Here are the changes to the original application. Thanks to Andrew, it is now passing the correct geometry and applying edits.
Added the following line: 174 destlayer.applyEdits(featureLayer3.getSelectedFeatures());
Select features on the map using graphic options, then click ApplyEdits.
<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">
<!--
ArcGIS API for JavaScript, https://js.arcgis.com
For more information about the graphics_add sample, read the original sample description at developers.arcgis.com.
https://developers.arcgis.com/javascript/3/jssamples/graphics_add.html
-->
<title>Shapes and Symbols</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.30/esri/css/esri.css">
<style>
#info {
top: 20px;
color: #444;
height: auto;
font-family: arial;
right: 20px;
margin: 5px;
padding: 10px;
position: absolute;
width: 115px;
z-index: 40;
border: solid 2px #666;
border-radius: 4px;
background-color: #fff;
}
html, body, #mapDiv {
padding:0;
margin:0;
height:100%;
}
button {
display: block;
}
</style>
<script src="https://js.arcgis.com/3.30/"></script>
<script>
var map, tb;
require([
"esri/map", "esri/toolbars/draw", "dojo/promise/all",
"esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol",
"esri/symbols/PictureFillSymbol", "esri/symbols/CartographicLineSymbol", "esri/layers/FeatureLayer",
"esri/graphic", "esri/tasks/query", "esri/tasks/QueryTask", "esri/InfoTemplate",
"esri/Color", "dojo/dom", "dojo/on", "dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane",
"dijit/layout/AccordionContainer", "dojo/domReady!"], function (
Map, Draw, All,
SimpleMarkerSymbol, SimpleLineSymbol, SimpleFillSymbol,
PictureFillSymbol, CartographicLineSymbol, FeatureLayer,
Graphic, Query, QueryTask, InfoTemplate,
Color, dom, on, parser) {
parser.parse();
map = new Map("mapDiv", {
basemap: "streets",
center: [-85.82966, 33.666494],
zoom: 5
});
map.on("load", initToolbar);
var featureLayer1 = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/0", {
mode: FeatureLayer.MODE_SNAPSHOT,
infoTemplate: new InfoTemplate("Block: ${BLOCK}", "${*}"),
outFields: ["POP2000", "HOUSEHOLDS", "HSE_UNITS", "TRACT", "BLOCK"]
});
var featureLayer2 = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/1", {
mode: FeatureLayer.MODE_SNAPSHOT,
infoTemplate: new InfoTemplate("Block Group: ${BLKGRP}", "${*}"),
outFields: ["POP2000", "HOUSEHOLDS", "HSE_UNITS", "TRACT", "BLKGRP"]
});
var featureLayer3 = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/3", {
mode: FeatureLayer.MODE_SELECTION,
infoTemplate: new InfoTemplate("County Name: ${NAME}", "${*}"),
outFields: ["POP2000", "HOUSEHOLDS", "HSE_UNITS", "NAME"]
});
//destination layer
var destlayer = new FeatureLayer(
"https://services.arcgis.com/Wl7Y1m92PbjtJs5n/arcgis/rest/services/geonetexamplepolygons/FeatureServer/0"
);
map.addLayers([featureLayer1, featureLayer2, featureLayer3, destlayer]);
// markerSymbol is used for point and multipoint, see http://raphaeljs.com/icons/#talkq for more examples
var markerSymbol = new SimpleMarkerSymbol();
markerSymbol.setPath("M16,4.938c-7.732,0-14,4.701-14,10.5c0,1.981,0.741,3.833,2.016,5.414L2,25.272l5.613-1.44c2.339,1.316,5.237,2.106,8.387,2.106c7.732,0,14-4.701,14-10.5S23.732,4.938,16,4.938zM16.868,21.375h-1.969v-1.889h1.969V21.375zM16.772,18.094h-1.777l-0.176-8.083h2.113L16.772,18.094z");
markerSymbol.setColor(new Color("#00FFFF"));
// lineSymbol used for freehand polyline, polyline and line.
var lineSymbol = new CartographicLineSymbol(
CartographicLineSymbol.STYLE_SOLID,
new Color([255, 125, 0]), 10,
CartographicLineSymbol.CAP_ROUND,
CartographicLineSymbol.JOIN_MITER, 5);
// fill symbol used for extent, polygon and freehand polygon
var fillSymbol = new SimpleFillSymbol();
fillSymbol.setColor(new Color([255, 0, 255, 0.5]))
function initToolbar() {
tb = new Draw(map);
tb.on("draw-end", addGraphic);
// event delegation so a click handler is not
// needed for each individual button
on(dom.byId("info"), "click", function (evt) {
if (evt.target.id === "info") {
return;
}
var tool = evt.target.id.toLowerCase();
map.disableMapNavigation();
tb.activate(tool);
});
}
function addGraphic(evt) {
//deactivate the toolbar and clear existing graphics
tb.deactivate();
map.enableMapNavigation();
// figure out which symbol to use
var symbol;
if (evt.geometry.type === "point" || evt.geometry.type === "multipoint") {
symbol = markerSymbol;
} else if (evt.geometry.type === "line" || evt.geometry.type === "polyline") {
symbol = lineSymbol;
} else {
symbol = fillSymbol;
}
map.graphics.add(new Graphic(evt.geometry, symbol));
queryMapService(evt.geometry);
}
function queryMapService(Geom) {
var promises = [];
var query = new Query();
query.returnGeometry = false;
query.outFields = ["*"];
query.geometry = Geom;
//promises.push(featureLayer1.selectFeatures(query, FeatureLayer.SELECTION_NEW));
//promises.push(featureLayer2.selectFeatures(query, FeatureLayer.SELECTION_NEW));
promises.push(featureLayer3.selectFeatures(query, FeatureLayer.SELECTION_NEW));
//destlayer.applyEdits(featureLayer3.getSelectedFeatures());
var allPromises = new All(promises);
allPromises.then(function (r) {
showResults(r);
});
}
document.getElementById("but").addEventListener("click",
function () {
// add feature to destination layer
destlayer.applyEdits(featureLayer3.getSelectedFeatures());
featureLayer3.clearSelection()
map.graphics.clear();
selectedpoint = null;
});
function showResults(results) {
var resultCount = results.length;
console.log(resultCount);
}
});
</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="mapDiv" class="shadow roundedCorners" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'center'"></div>
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'right'" class="roundedCorners" id="rightPane">
<div data-dojo-type="dijit.layout.AccordionContainer">
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Graphics'" id='graphics'>
<div id="info">
<div>Select a shape then draw on map to add graphic</div>
<button id="Point">Point</button>
<button id="Multipoint">Multipoint</button>
<button id="Line">Line</button>
<button id="Polyline">Polyline</button>
<button id="FreehandPolyline">Freehand Polyline</button>
<button id="Triangle">Triangle</button>
<button id="Extent">Rectangle</button>
<button id="Circle">Circle</button>
<button id="Ellipse">Ellipse</button>
<button id="Polygon">Polygon</button>
<button id="FreehandPolygon">Freehand Polygon</button>
<button id="but" data-dojo-type="dijit.form.Button">ApplyEdits</button>
</div>
</div>
<div data-dojo-type="dijit/layout/ContentPane" id="legendPane" data-dojo-props="title:'Legend'">
<div id="legendDiv"></div>
</div>
</div>
</div>
</div>
</body>
</html>