hajkmap / Hajk

A modern, full-featured OpenLayers based map viewer and editor
MIT License
123 stars 47 forks source link

Multiple filters on same layer #1325

Open FredrikEkstrom79 opened 1 year ago

FredrikEkstrom79 commented 1 year ago

_Edit: this issue regards Hajk's vector layers, which is the layer type that currently supports some CQL functionality._

Edit 2: I (@jacobwod) just realised that this is related to #498. This new functionality should produce a filter that looks the same and is written to the same f parameter as #498. Note however that #498 is about WMS layers. This issue was originally about WFS/GML (Hajk's vector) layers. So what shall we do?

The ability to filter on several attributes and not just on one as it is now. This would mean that many times you could avoid publishing the same layer several times in geoserver / Hajk admin.

You set predefined filters for the layer in admin that the user can then use. Dropdown lists that filter what the user selected.

skiss

jacobwod commented 1 year ago

We won't probably be building it in current Admin UI, but here's a snippet of proposed JSON configuration that would make it possible to construct the dropdown(s) in LayerSwitcher. (Sorry about the use of Swedish but that how our data and column definitions look like…)

{
    // Inside Hajk's layer definition
    "vectorlayers": [
        // Here's one random vector layer
        {
            "name": "a8f0g", // The ID
            "caption": "Aktiviteter", // The label
            "foo": "bar", // And the rest of...
            // ... current options.

            // HERE STARTS THE PROPOSED SYNTAX
            "predefinedCQLFilter": { // FIXME: Better name?
                "filterType": "AND", // If we show multiple dropdowns: should it be an AND or an OR?
                "dropdowns": [ // Array of objects that holds our dropdown definitions
                    {
                        "column": "forening", // One dropdown should filter the 'forening' column
                        "label": "Föreningar", // It should have a nice looking label
                        "possibleValues": [ // Here start the possible drowdown values
                            {
                                "key": "halmia_hstd", // Here's the value as it looks in the tabel
                                "label": "Halmia" // And here's a nice looking label
                            },
                            {
                                "key": "vapnoif",
                                "label": "Vapnö IF"
                            }
                        ]
                    },
                    {
                        "column": "aktivitet", // Another dropdown on another DB column
                        "label": "Aktiviteter",
                        "possibleValues": [
                            {
                                "key": "1",
                                "label": "Basket"
                            },
                            {
                                "key": "2",
                                "label": "Fotboll"
                            }
                        ]
                    }
                ]
            }
        }
    ]
}

The above configuration would result in two dropdowns with two values each. If user selects first options in each of the dropdowns, here's how the pseudo-CQL would look like:

WHERE forening = 'halmia_hstd' AND 'aktivitet' = '1'

Questions

Hallbergs commented 1 year ago

Very interesting! Regarding the comparer, it depends on how/if we want to handle more inputs than dropdowns (in your example the = would be sufficient, but if we would allow for a text-field, IS-LIKE would be needed obviously).

Instead of dropdowns in the configuration, would it be feasible with something like inputs instead? In that case, we could add an input-type on every object in that array, maybe DROPDOWN and TEXTFIELD. Most of the input configuration would stay the same, but in the text-field type we wouldn't need the possible values.

In our setup, we use the CQL-filters daily, mainly filtering contracts by their contract-id. I can see a use case for us where we would use both dropdown and textfield, somethink like:

"inputs": [  // Earlier `dropdowns`
                {
                    "type": "DROPDOWN",
                    "column": "status", 
                    "label": "Contract status", 
                    "possibleValues": [ 
                        {
                            "key": "A",
                            "label": "Approved"
                        },
                        {
                            "key": "R",
                            "label": "Rejected"
                        }
                    ],
                   "comparer": "EQUALS"
                },
                {
                    "type": "TEXTFIELD",
                    "column": "id", 
                    "label": "Contract ID",
                    "possibleValues": [ ],
                    "comparer": "ISLIKE"
                }
            ]

The above would allow us to show all contracts that were created 1990 and has been approved if we would allow for wildcards, something like:

WHERE status = 'A' AND 'id' LIKE 'AL1990%'
FredrikEkstrom79 commented 1 year ago

It doesn't have to be locked to just the dropdown.

The idea in my example is perhaps that the user starts typing and the list matches against that and then shows the available options.

I think this can be really good if we get it right.

Hallbergs commented 1 year ago

It's gonna be a great addition! Would love to help with the implementation, just let me know when you're gonna have a go at it!

jacobwod commented 1 year ago

Hmm… the latest posts got me thinking: what is the benefit of doing this (filtering layers with CQL) vs. setting up the relevant data table as a search source in Hajk and using the Search tool instead? 🤔 For instance, in @Hallbergs example: wouldn't you get the same results if you searched the contract IDs in Search? It already has these features and more (e.g. wildcard options, possibility to limit by geographic area).

Hallbergs commented 1 year ago

They want different styles on different layers. To make that solution work we would have to allow for changing the highlight style in search on the fly/ have separate styling for each search-source.

FredrikEkstrom79 commented 1 year ago

I don't see that the search and this function are the same for the user. To make the search show everything you have to type * then? (if you don't want any filter). If the user only wants to get results from this layer, they need to be quite experienced with Hajk and change the settings of the search tool. Instead of just using the drop down menu/lists presented for the specific layer in the layer manager.