javascriptgisopenlayersgeoserverweb-feature-service

How to filter feature using OpenLayer and WFS?


I'm able to extract data from geojson file (produced from GeoServer WFS layer type) and display it on browser using OpenLayer. But I'm facing problem when I only want to display the data with certain features aka filtering.

My JSON filename -> gpr.geojson
GeoServer layername -> visualization:GPR
Attribute filter -> branchCode = N01821 and routeCode = 0650

I followed filtering tutorial from https://www.giserdqy.com/wp-content/guids/ol-v4.6.5/examples/vector-wfs-getfeature.html and I also have tried using CQL_FILTER but no luck at all

Below is my code and the filtering doesn't work

var mymap = new ol.Map({
    target: 'mapid',
    layers: [
          new ol.layer.Tile({
            source: new ol.source.XYZ({
                //Vworld Tile 변경
                url: 'http://xdworld.vworld.kr:8080/2d/Base/201802/{z}/{x}/{y}.png'
            })
          })
    ],
    view: new ol.View({
        center: ol.proj.transform([128.1591, 36.4109], 'EPSG:4326', 'EPSG:3857'),
        zoom: 8,
        minZoom: 6,
        maxZoom: 19
    }),
    logo:false
});

var vectorSource = new ol.source.Vector({
    url: './data/GPR.geojson,
    format: new ol.format.GeoJSON()
})

var layer = new ol.layer.VectorImage({
    source: vectorSource,
    visible: true,
})

// generate a GetFeature request
var featureRequest = new ol.format.WFS().writeGetFeature({
    srsName: 'EPSG:3857',
    featureNS: 'visualization',
    featurePrefix: 'osm',
    featureTypes: ['GPR'],
    outputFormat: 'application/json',
    filter: ol.format.filter.and(
        ol.format.filter.like('branchCode', 'N01821'),
        ol.format.filter.equalTo('routeCode', '0650')
    )
});

// then post the request and add the received features to a layer
fetch('http://localhost:8080/geoserver/visualization/wfs', {
    method: 'POST',
    body: new XMLSerializer().serializeToString(featureRequest)
}).then(function (response) {
    return response.json();
}).then(function (json) {
    var features = new ol.format.GeoJSON().readFeatures(json);
    vectorSource.addFeatures(features);
    mymap.getView().fit(vectorSource.getExtent());
});

Using Leaflet, WMS and CQL Filter is very simple as below. How to do it using OpenLayer and WFS?

var wmsLayer= L.tileLayer.wms("http://localhost:8080/geoserver/visualization/wms", {
layers: 'visualization:GPR',
format: 'image/png',
transparent: true,
CQL_FILTER:  "branchCode='N01821'"

Solution

  • You can still use a request and CQL_FILTER in OL just like your leaflet example, something like this,

    $.ajax({
        method: 'POST',
        url: 'http://localhost:8080/geoserver/visualization/wfs',
        data: {
            "service": "WFS",
            "request": "GetFeature",
            "typename": "visualization:GPR",
            "outputFormat": "application/json",
            "srsname": "EPSG:3857",
            "maxFeatures": 50,
            "CQL_FILTER": "branchCode='N01821'"
        },
        success: function (response) {
            var features = new ol.format.GeoJSON().readFeatures(response);
            vectorSource.addFeatures(features);
            mymap.getView().fit(vectorSource.getExtent());
        },
        fail: function (jqXHR, textStatus) {
            console.log("Request failed: " + textStatus);
        }
    });
    

    If you prefer to use fetch, I think this should work,

    let featureRequest  = {
        "service": "WFS",
        "request": "GetFeature",
        "typename": "visualization:GPR",
        "outputFormat": "application/json",
        "srsname": "EPSG:3857",
        "maxFeatures": 50,
        "CQL_FILTER": "branchCode='N01821'"
    };
    fetch('http://localhost:8080/geoserver/visualization/wfs', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(featureRequest)
    }).then(function (json) {
        var features = new ol.format.GeoJSON().readFeatures(reponse);
        vectorSource.addFeatures(features);
        mymap.getView().fit(vectorSource.getExtent());
    });