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.
Solved! Go to Solution.
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}'`
})
}
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.
So, while you can have different geometries, the GeoJSONLayer documentation states this limitation:
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
I will post a solution after I solve this last issue. How do I clear a filter? I cannot set the filter to null.
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.
I was able to fortunately set it back to `null` which is the original value. Had to do something different due to Typescript.
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}'`
})
}