5

I'm using openlayers (v3.20.0) in an angular 2 project. I have a vector layer which has its source bound to a geoserver.

My task is to filter the features displayed in this layer. I have a collection Ids (which are in features' attributes) representing the features needed to be shown. But I can't find how to filter the layer. There seems to have been an easy way to do this in openlayers v2, but not in v3.

What am I missing ?

7
  • You want to filter the layer on the client side rather on the server side?
    – artwork21
    Commented Oct 12, 2017 at 12:23
  • The best would server-side I guess. The Ids list is build on client side though
    – Shimrod
    Commented Oct 12, 2017 at 12:25
  • If server side/geoserver you may use the sld Filters option, docs.geoserver.org/stable/en/user/styling/sld/reference/…
    – artwork21
    Commented Oct 12, 2017 at 12:27
  • Could be interresting but a rapid research shows that openlayers doesn't support SLD yet. Do you have a working example to use it ?
    – Shimrod
    Commented Oct 12, 2017 at 12:33
  • The sld is just the styling on the server, openlayers is just pulling in the WMS. I know in older versions it supports SLD styled WMS.
    – artwork21
    Commented Oct 12, 2017 at 12:45

3 Answers 3

2

If you want to filter the features on client side, the style parameter of your layer should be defined as style function. In the style function you filter the features and return a valid or a empty style depending if features with that id want to be shown.

Assuming you have the ids you want to show in an array called collectionList, you could do it like that:

var styleFunction = function(feature, resolution) {
    var style = new ol.style.Style({});
    var id = feature.get('collection_id');
    if (id && collectionList.includes(id) {
        style = new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: #000,
                width: 1
            })
        });
    }
    return style;
}
1

This question is old but I was looking for a similar solution and found one. I am using OpenLayers v5+ and Angular 6, but this shouldn't make a difference for older versions, the idea is the same regardless of the versions.

What you can do is define 2 layers, one hidden and one visible with styling. You can then load your data into the hidden layer. When the user triggers a filter action, you take the filter parameters and select the appropriate features from the source of the hidden layer, collect them and add them to the source of the visible layer.

The following code demonstrates the idea, is simplified and should be adjusted to the used version and language(JavaScript/TypeScript).

export class MyGeoApp implements OnInit {

    private map = new Map();
    private hiddenSource = new VectorSource();
    private hiddenLayer = new VectorLayer({
        source: this.hiddenSource,
        visible: false
    });
    private visibleSource = new VectorSource();
    private visibleLayer = new VectorLayer({
        source: this.visibleSource,
        visible: true
    });

    constructor() { }

    ngOnInit() {
        this.map.addLayer(this.hiddenLayer);
        this.map.addLayer(this.visibleLayer);
        this.loadData();
    }

    loadData() {
        // load data in your hiddenSource
    }

    updateVisibleLayer(filterCriteria) {
        // Clear the source before adding data
        this.visibleSource.clear();

        // Your filter
        const myFilter = (query) => {
            return this.hiddenSource.getFeatures()
                                    .filter(feature =>
                feature.get('country').toLowerCase()
                       .indexOf(query.toLowerCase()) > -1
        );

        // Add the features to your visible layer, using myFilter
        this.visibleSource.addFeatures(myFilter(filterCriteria));
    }
}

I am assuming you know how to load your data into the hiddenSource. The example above can be applied to any type of user based selection, e.g.: a drop down list, checkbox, radio button, link, etc.

The filtering is based on the fact that the method getFeatures() returns an Array of Feature objects. Arrays have many methods to use and one of them is the filter() method. Check this link for more details: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

0

If you need just to hide certain features is possible to set the visibility like this answer (my OL version 6.14.1): https://gis.stackexchange.com/a/270829

updateLayerVisibility() {
            const myLayer = map.getLayers().getArray()
                .find((layer) => layer.get('id') === 'myLayer');

            myLayer.getSource().forEachFeature((feature) => {
                // your filter logic
             myLayer.setStyle(new ol.style.Style({})); // hide feature
             // myLayer.setStyle(null); // show feature
            });
        }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.