qgis / qwc2-demo-app

QWC2 demo application
Other
243 stars 155 forks source link

New feature QGIS Filters #263

Closed dmestudent closed 4 months ago

dmestudent commented 3 years ago

Hello,

I would like to implement the possibility to use the QGIS url "FILTER" parameter to only return a specific set of features back to the QWC2 app.

Could you point me to the right location where I can add support for an addition attribute in the QWC2 app url? From there I would parse it and push it to the redux store. Then I will also implement a new plugin to manually configure the values and layers to be filtered.

I thought about implementing another service that has an axios interceptor to add additional information to the qgis server request url called by the qwc2 app before the request is actually send.

Any thoughts or ideas on how this can be implemented in a better way? QGIS Docs regarding this functionallity https://docs.qgis.org/3.16/en/docs/server_manual/services.html#filter

Thanks again for this great software. 👍 Best regards

nigr0nyx commented 3 years ago

In your app.jsx add code below

import React from 'react';
import ReactDOM from 'react-dom';
import StandardApp from 'qwc2/components/StandardApp';
import appConfig from './appConfig';
import '../icons/build/qwc2-icons.css';

ReactDOM.render(
    <StandardApp appConfig={appConfig}/>,
    document.getElementById('container')
);

// REQUEST=GetMAP
const getImage = ImageWrapper.prototype.load;
ImageWrapper.prototype.load = function () {
    const dateFilter = document.getElementById('dateFilter');
    const src = this.src_.split('&FILTER=')[0];
    this.src_ = `${src}&FILTER=layerName:"date" >= '${encodeURIComponent(dateFilter.valueAsDate.toLocaleString().slice(0,10))}'`;
    return getImage.call(this);
};

// REQUEST=GetFeatureInfo
import axios from 'axios';
axios.interceptors.request.use((config) => {
    if(config?.params?.request === 'GetFeatureInfo') {
        const dateFilter = document.getElementById('dateFilter');
        config.params.FILTER = `layerName:"date" >= '${dateFilter.valueAsDate.toLocaleString().slice(0,10)}'`;
    }
    return config;
}, (error) => {
    return Promise.reject(error);
});

In api_example.js add

apiFrame.innerHTML = "....
<div>\
    <span>Filter date:</span>\
    <input type='date' id='dateFilter' onchange='dateFilterChanged(event);'/>\
</div>
"

function dateFilterChanged(ev){
    let myCanvasElement = document.querySelector('#map canvas');
}

But I do not know, how refresh the map inside dateFilterChanged.

nigr0nyx commented 3 years ago

If you have any ideas to improve my code, let me know pls.

dmestudent commented 3 years ago

Hello just responding back to this issue. So the whole filtering in my project became much more complex than expected when writing this issue I moved to writing a complete backend service for this. It is not in a state to share this one public at the moment so I will quickly explain what I did.

My microservice works as a proxy which manipulates all requests the QWC2 would normally directly send to the QGIS server. I do this by configuring the url of the proxy inside the themes config and do some little adjustments inside the WMSLayer.js to route all requests to my proxy.

I also manipulate the first response from the qgis server so that all urls in the xml response that would normally point directly to the qgis server are pointed to my proxy. From this point QWC2 works as it would if you would just configure normal qgis server urls for your themes.

Inside my microservice (proxy) I have some business logic that does the following:

  1. Extract target layers from request url
  2. Check if there are filters configured for this layer (I have a filters.json file that contains a structure with an object for each layer with an array of filter objects.
  3. If there are any filters for this layer create the filters query part
  4. Append the filters query part to the initial query
  5. Send everything to the qgis server
  6. Return the result of the qgis server to the backend

It was some work but the idea works like charm. Will give further information about that once I can make a public release.

Best regards

pka commented 3 years ago

Sounds very interesting! I think, the server side functionality should be integrated into https://github.com/qwc-services/qwc-ogc-service or https://github.com/qwc-services/qwc-feature-info-service

raynerhoward commented 2 years ago

+1 The ability to filter via qwc2 url parameter (and pass it along to getmap) would be a HUGE benefit.

gug-developer commented 2 years ago

+1 I have to satisfy a mandatory user requirement and I would need to filter the features of a layer with QWC2.

raynerhoward commented 2 years ago

As per the QGIS docs https://docs.qgis.org/3.22/en/docs/server_manual/services/wms.html#filter

It is possible to FILTER features via a query:

&FILTER=countries_shapeburst,countries:"name" = 'France';places: "name" = 'Paris'

It would be useful, especially those of us working with features stored in database tables, if we could specify a new qwc2 url parameter f = some filter or some such - see https://github.com/qgis/qwc2-demo-app/blob/master/doc/QWC2_Documentation.md#url-parameters

It could perhaps look something like this:

http://myqwc2webmap.somewhere.com/?t=my_theme&l=countries_shapeburst,countries,places&f=countries_shapeburst,countries:"name" = 'France';places: "name" = 'Paris'

Being able to filter in this manner (passing the filter url parameter to the GETMAP request) would be very useful.

Best Regards

raynerhoward commented 2 years ago

So this is my attempt at implementing a new url parameter f that simply gets passed to the wms getmap and getfeatureinfo requests: https://github.com/raynerhoward/qwc2

When used in conjunction with the url parameter l (layers), it filters features in the qwc2 map, in the print plugin, and in the identify (Feature Info) window. No error checking or anything fancy. A badly formatted f param will most likely prevent the qwc2 map from loading correctly, so use with caution.

raynerhoward commented 2 years ago

To implement this new qwc2 'f' filter url parameter, I added these 3 lines to these 3 qwc2 files:

https://github.com/raynerhoward/qwc2/commit/fb699e31b5515aaa494ddf1939dbe7765a5e53d7

Hope it helps someone.

danceb commented 1 year ago

@raynerhoward as this is very usefull for other qwc2 users aswell, could you provide a pull request for this to get this function in the main qwc2 app? Would be nice. An other possibility would be to copy your changes as an own commit (@manisandro).

raynerhoward commented 1 year ago

@danceb I did a pull request and it was not accepted by the developers. Unable to find it now, may have been removed. Anyway, it's simple enough to add those 3 lines to those 3 files as per https://github.com/raynerhoward/qwc2/commit/fb699e31b5515aaa494ddf1939dbe7765a5e53d7

manisandro commented 4 months ago

The filtering functionality has since been implemented, see https://qwc-services.github.io/master/topics/MapFilter/