I am trying to select all the features which are present in the current extent of map i.e which are visible on screen. I find this link helpful but it iterates through all the graphics and check if that graphic is present in the current extent and adds to result set as shown in code below
dojo.forEach(map.graphics.graphics,function(graphic){
if (extent.contains(graphic.geometry)) {
graphic.setSymbol(highlightSymbol);
results.push(graphic.getContent());
}
The feature layer of my map consists of thousands of features and I might need selecting very few based on map extent and zoom level. I feel the above code takes lot of time as it needs to iterate through thousands for the few features. I am trying to update the result set whenever the user drags the screen as the map extent change.
Is there any other better way to select features based on the map extent?
-
What are you doing with the selection? Perhaps one workaround would be to not do the selection but instead just make your downstream action aware of the current extent.GavinR– GavinR2019年08月08日 19:40:02 +00:00Commented Aug 8, 2019 at 19:40
-
@GavinR I am actually trying to display a table with all features present on the screen. When the user drags screen, the table should be updated with the list of latest features on the screenuser147504– user1475042019年08月08日 19:45:04 +00:00Commented Aug 8, 2019 at 19:45
2 Answers 2
In version 4 of a ArcGIS API for JavaScript, you can utilize the FeatureLayerView (sample). I'm not aware of a better way to do what you're wanting to do in the v3 API.
That sample first puts the queried items in a graphics layer, which have to be iterated to get the cities that are within the extent that the user draw.
For your application, add the layer as a featurelayer and run a selectFeatures on it using the extent whenever the extent changes. Here's a way to do that (updating the original sample, using modern dojo)
<!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>Points in Extent</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.29/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.29/esri/css/esri.css">
<script src="https://js.arcgis.com/3.29/"></script>
<script>
require([
"esri/map",
"esri/layers/FeatureLayer",
"esri/tasks/query",
"dojo/dom",
"dojo/domReady!"
],
function (
Map,
FeatureLayer,
Query,
dom
) {
var map = new Map("map", {
basemap: "streets",
center: [-120.275, 47.485],
zoom: 6,
slider: false,
showInfoWindowOnClick: false
});
var featureLayer = new FeatureLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/0", {
definitionExpression: "st = 'WA'",
outFields: ['areaname'],
mode: FeatureLayer.MODE_SNAPSHOT
});
map.addLayer(featureLayer);
var query = new Query();
map.on('extent-change', function (evt) {
console.log(evt.extent);
query.geometry = evt.extent;
featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function (features) {
dom.byId("inextent").innerHTML = features.length;
var results = "";
for (var i = 0; i < features.length; i++) {
results += "<tr><td>" + features[i].attributes.areaname + "</tr></td>";
}
dom.byId("results").innerHTML = "<table><tbody>" + results + "</tbody></table>";
});
});
});
</script>
</head>
<body class="claro">
Draw an Extent on the map to find all points within this extent
<div id="map" style="width:800px; height:400px; border:1px solid #000;"></div>
<br />
<b># of points in extent = <span id="inextent">0</span></b>
<div id="results" style="width:400px; height:200px; border:1px solid #000; overflow:auto;">
</div>
</body>
</html>
-
Thanks a lot. I am new to GIS. I tried looking at the documentation for featurelayer.selectedfeatures() but unable to understand how FeatureLayer.SELECTION_NEW works. Could you help me please?user147504– user1475042019年08月09日 19:06:05 +00:00Commented Aug 9, 2019 at 19:06
-
That means it's making a new selection from the feature layer every time. SELECTION_ADD and SELECTION_SUBTRACT will add or remove the items found from the current selectionkenbuja– kenbuja2019年08月09日 19:29:17 +00:00Commented Aug 9, 2019 at 19:29
-
Need small help. How can I attach events for doing same job? Like doing same job for 'extent-change' and 'zoom-end' without rewriting code when using dojo on() function?user147504– user1475042019年09月20日 18:17:28 +00:00Commented Sep 20, 2019 at 18:17
-
You can write a separate function [myFunction(evt), for example] and have both events reference that function
map.on('extent-change', myFunction)
. The evt argument will get automatically passed using this syntaxkenbuja– kenbuja2019年09月24日 16:08:46 +00:00Commented Sep 24, 2019 at 16:08