How Do You Filter on a Property in a GEO JSON Layer?

1557
6
Jump to solution
02-04-2021 01:00 PM
developerarce
New Contributor III

I have a property within my GEO JSON that I would like to add a feature widget to the map in order to filter on those values. I see examples for FeatureLayers, but none for GeoJson Layers.

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
developerarce
New Contributor III

Solution:

    view.whenLayerView(geoJSONLayer).then(function(layerView: any) {
        // set up UI items
        if (filterElement) {
          filterElement.addEventListener("click", function(event) {
            filterLayer(event.target, layerView);
          });
          filterElement.style.visibility = "visible";
          const filterExpand = new Expand({
            view: view,
            content: filterElement,
            expandIconClass: "esri-icon-filter",
            group: "top-left"
          });
          //clear the filters when user closes the expand widget
          filterExpand.watch("expanded", function () {
            if (!filterExpand.expanded) {
              layerView.filter = null;
            }
          });
          view.ui.add(filterExpand, "top-left");
        }
      });

...

const filterLayer = (layer:any, view:any) => {
    const data = layer.getAttribute("data-layer");
    view.filter = new FeatureFilter({
      where: `layer='${data}'`
    })
}

 

View solution in original post

0 Kudos
6 Replies
jcarlson
MVP Notable Contributor

I suspect that is because a GeoJSON will not behave in a consistent way like tabular datasets do.

You can read the GeoJSON docs for all the nitty-gritty, but the short version is that it's not as structured a data format. In your FeatureLayers, you can only have a single geometry type, and every feature has the same fields, whether they have values entered or not.

In GeoJSON, however, it's perfectly acceptable to violate those norms. Here's a slightly modified example GeoJSON from Wikipedia:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [102.0, 0.5]
      },
      "properties": {
        "name": "my_house"
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
        ]
      },
      "properties": {
        "ref": "Main Street",
        "speed_limit": 35
      }
    },
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [100.0, 0.0], [101.0, 0.0], [101.0, 1.0],
            [100.0, 1.0], [100.0, 0.0]
          ]
        ]
      },
      "properties": {
        "kind": "barrier",
        "prop": { "this": "that" }
      }
    }
  ]
}

Even though the objects have entirely different schema and geometry types, this is a valid GeoJSON.

It's probably pretty straightforward to make a custom widget that looks first for the existence of a key in properties, then for a certain value based on that key, but it's going to look pretty different from the built-in filter widget, and will depend a lot on your particular data, I would think.

- Josh Carlson
Kendall County GIS
0 Kudos
developerarce
New Contributor III

So, while you can have different geometries, the GeoJSONLayer documentation states this limitation:

  • Each GeoJSONLayer will only accept one geometry type. If there are multiple types of geometries, only the type specified in geometryType will be loaded. If geometryType is not specified, it will default to the geometry type of the first geometry.

It is true that many different objects could have different properties.

However, the reason I raise this question is due to the excerpt at the bottom of the Core Concepts in the documentation:
https://developers.arcgis.com/javascript/latest/query-filter/

--------------------------

Just happened to find this in the documentation: GeoJSONLayerView

developerarce
New Contributor III

I will post a solution after I solve this last issue. How do I clear a filter? I cannot set the filter to null.

0 Kudos
JeffK
by MVP Regular Contributor
MVP Regular Contributor

I think you could reassign the variable to the original dataset source?  Kind of hard to tell what you mean without seeing your code though.

0 Kudos
developerarce
New Contributor III

I was able to fortunately set it back to `null` which is the original value. Had to do something different due to Typescript.


0 Kudos
developerarce
New Contributor III

Solution:

    view.whenLayerView(geoJSONLayer).then(function(layerView: any) {
        // set up UI items
        if (filterElement) {
          filterElement.addEventListener("click", function(event) {
            filterLayer(event.target, layerView);
          });
          filterElement.style.visibility = "visible";
          const filterExpand = new Expand({
            view: view,
            content: filterElement,
            expandIconClass: "esri-icon-filter",
            group: "top-left"
          });
          //clear the filters when user closes the expand widget
          filterExpand.watch("expanded", function () {
            if (!filterExpand.expanded) {
              layerView.filter = null;
            }
          });
          view.ui.add(filterExpand, "top-left");
        }
      });

...

const filterLayer = (layer:any, view:any) => {
    const data = layer.getAttribute("data-layer");
    view.filter = new FeatureFilter({
      where: `layer='${data}'`
    })
}

 

0 Kudos