Is it possible to filter based on an extent?

2787
9
01-20-2021 04:27 AM
sandrooco
New Contributor II

After regularly using this forum as silent reader, I finally came to the point that I had to create my own post (thanks for all your help in the past! 😊).

I'm trying to filter a layer based on an extent. Every feature that is in the extent should be loaded/displayed, the rest shouldn't.
Example from the screenshot below: Only the labels with the "origin" point inside the orange polygon should be displayed. "Richtung Pfäffikon SZ" and "Richtung Zürich / Meilen" should not be displayed. 

Screenshot 2021-01-20 at 13.26.26.png

I think this would be possible with adding an attribute on these items' table, right? My problem is that this should be dynamic and I don't really want to go add this attribute/add a value for around 1M items in total.

This is why I thought about a possibility to tell the layer "load only the stuff in the given geometry". I coulnd't find anything like this in the docs and reference - maybe I'm just looking for the wrong words.
Any ideas?

Thanks in advance!

Tags (3)
0 Kudos
9 Replies
BlakeTerhune
MVP Regular Contributor

Welcome! When executing a query, you can specify geometry to use as a spatial extent (intersect) for the results. Here's a sample.

0 Kudos
sandrooco
New Contributor II

Thanks @BlakeTerhune - I was able to only get the features I really need.
Though, the other features still show up. As far as I understand I already receive them in the "map image". How can I filter it before it even renders in the gis service?

As you might guess, I'm kind of a gis newbie - so it's possible that I'm missing a core concept.

0 Kudos
BlakeTerhune
MVP Regular Contributor

Check out this sample. The quakesLayer FeatureLayer is defined with visible: false so it doesn't display in the map. Then, the section at the end with the last three functions section of code is what queries the quakes and displays them.

// query for earthquakes with the specified magnitude
// within the buffer geometry when the query button
// is clicked
queryQuakes.addEventListener("click", function () {
  queryEarthquakes().then(displayResults);
});

function queryEarthquakes() {
  var query = quakesLayer.createQuery();
  query.where = "mag >= " + magSlider.values[0];
  query.geometry = wellBuffer;
  query.spatialRelationship = "intersects";

  return quakesLayer.queryFeatures(query);
}

// display the earthquake query results in the
// view and print the number of results to the DOM
function displayResults(results) {
  resultsLayer.removeAll();
  var features = results.features.map(function (graphic) {
    graphic.symbol = {
      type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
      style: "diamond",
      size: 6.5,
      color: "darkorange"
    };
    return graphic;
  });
  var numQuakes = features.length;
  document.getElementById("results").innerHTML =
    numQuakes + " earthquakes found";
  resultsLayer.addMany(features);
}

Notice the results are added to a GraphicsLayer called resultsLayer. That is defined earlier as

var resultsLayer = new GraphicsLayer();
0 Kudos
sandrooco
New Contributor II

Thank you @BlakeTerhune - this works really nice.

Follow up question: Isn't it bad practice to let the GIS server render the features when they won't even be displayed? Or won't they be included anyways if they are on visible: false?

Do you have an idea how to style the simple marker (prefferably even with an icon)?

0 Kudos
BlakeTerhune
MVP Regular Contributor

I'm not really sure how visible: false works on the back end of the API. I just tested this with the Query features from a FeatureLayer sample by taking out visible: false where the quakesLayer FeatureLayer was defined and removing the quakesLayer from the layers property where the map was initialized. The app still seemed to function normally. Do some experiments with your own app to be sure.

As for creating a symbol, check out the Symbol Playground.

JohnGrayson
Esri Regular Contributor

Do you have a very simple codpen showing what you've tried so far?  What type of layer are we dealing with?  If the points are in a FeatureLayer (or MapImageLayer Sublayer) you can use the definitionExpression property to define which features to retrieve and display.  If the filtering extent is defined dynamically you can use queryObjectIds to help you find the relevant features to show/hide.

0 Kudos
sandrooco
New Contributor II

I don't have a codepen, the project is already quite large - sorry.
It's a Sublayer of a MapImageLayer. You mentioned definitionExpression - this only works for the table attributes, but not geometries right?

0 Kudos
EspinBowder
New Contributor

Hi Sandrooco, 

I'm trying to do the same as you - filter a massive data set to only load the features in the extent I'm interested in. Did you have any success with using a definitionExpression to define the extent?

Many thanks, Espin

 

0 Kudos
post4k_dev
New Contributor

I've kind of "solved" this by making another map in another div, that takes the position of a "hidden" graphical rectangle created by a SketchViewModel create function, and then overlaying it on top of my "main" map.

It's not particularly pretty, but it works, untill we can query a featureservice for polygons only within an extent.

This works because "an app" by default only shows features within an "app extent", which is defined by the map container, as I understand it.

0 Kudos