andreaordonselli / qgis2o.gis

Make O.GIS - Open Source WebGIS
https://opengis.it
GNU General Public License v2.0
14 stars 0 forks source link

Link with popup and highlighting #17

Open jukos opened 1 day ago

jukos commented 1 day ago

With the “quick search” function, the result is

Question: Is it possible to generate links to individual content, with popup and color highlighting as with “quick search”?

Background to the question: A specific map content is to be linked in a text. If the user clicks on this link, they want to find out more about it straight away. An extra click to open the popup is an unnecessary step. And: If several points are close together, highlighting is required for quick visual recognition.

Greetings

andreaordonselli commented 1 day ago

You want permalinks external to the project that when clicked open the map at the correct zoom and queried the feature, right? The query will highlight the item and open the popup.

jukos commented 1 day ago

Yes.

andreaordonselli commented 4 minutes ago

I will bring the update in the next release, in the meantime I ask you to test the functionality and let me know if you have any problems. It was a good challenge. Thank you.

At the bottom of your index.html add this code before closing the </body>

<script>

            // permalink to query feature

            // Check if the 'find' parameter exists in the permalink
            if (permalink.hasUrlParam('find')) {
                // Extract the value of the 'find' parameter
                var urlFindParam = permalink.getUrlParam('find');

                // Break down the string 'find' by commas
                var findParams = urlFindParam.split(',');

                // The first element is always the layer (based on "popuplayertitle")
                var layerTitle = findParams[0].trim(); 

                // The following elements represent the fields for searching for the feature
                var searchCriteria = {};
                findParams.slice(1).forEach(function(param) {
                    var keyValue = param.split(':');
                    if (keyValue.length === 2) {
                        searchCriteria[keyValue[0].trim()] = keyValue[1].trim();
                    }
                });

                // Find the layer corresponding to the 'popuplayertitle' property
                var selectedLayer;
                allLayers.forEach(function(layer) {
                    if (layer.get('popuplayertitle') === layerTitle) { 
                        selectedLayer = layer;
                    }
                });

                if (selectedLayer) {        
                    // Get alias mapping from layer
                    var fieldAliases = selectedLayer.get('fieldAliases') || {};

                    // Convert defined search fields based on aliases
                    var convertedSearchCriteria = {};
                    for (var alias in searchCriteria) {
                        var valueCriteria = searchCriteria[alias];
                        // If the alias is present in the aliases, find the corresponding effective field
                        var actualField = getKeyByValue(fieldAliases, alias) || alias;
                        convertedSearchCriteria[actualField] = valueCriteria;
                    }   

                    // Find the matching feature using the converted search criteria
                    var features = selectedLayer.getSource().getFeatures();

                    var featureFound = features.find(function(f) {              
                        var match = true;

                        for (var field in convertedSearchCriteria) {
                            var valueCriteria = convertedSearchCriteria[field];
                            var valueFeature = f.get(field);

                            // If the feature value is a number, compare as a number
                            if (!isNaN(valueFeature)) {
                                // Remove any units of measurement from the search criterion (e.g. '125.32m' -> '125.32')
                                valueCriteria = parseFloat(valueCriteria.replace(/[^0-9.-]/g, ''));

                                // Compare numerically
                                if (parseFloat(valueFeature) !== valueCriteria) {
                                    match = false;
                                    break;
                                }
                            } else {
                                // Compare as string
                                if (valueFeature !== valueCriteria) {
                                    match = false;
                                    break;
                                }
                            }
                        }

                        /* if (match) {
                            console.log('Find feature:', f);
                        } else {
                            console.log('No match fot this feature.');
                        } */

                        return match;
                    });

                    if (featureFound) {         
                        // Simulate selection to activate SearchFeature's 'select' function
                        // The selection is configured in the base code with search.on...
                        search.dispatchEvent({
                            type: 'select',
                            search: featureFound
                        });
                    }/* else {
                        console.log('No feature found with this criteria:', searchCriteria);
                    }*/
                }/* else {
                    console.log('Layer not found with popuplayertitle:', layerTitle);
                }*/

                // Remove the "find" parameter from the URL using setUrlParam without specifying the value
                permalink.setUrlParam('find');
            }

            // Funzione per ottenere la chiave in base al valore (invertire gli alias)
            function getKeyByValue(object, value) {
                return Object.keys(object).find(key => object[key] === value);
            }
</scrpit>

Now write the permalink to your feature by following these steps: 1) open your webgis as you did for the first time 2) add to the bottom of the link you see in the address bar &find=layerTitle,field1:value1,field2:value1 etc..

where:

You can add "n" criteria to find your feature The ideal would be to add an "id" field in qgis with a progressive number so as to search only for this

You can test this link: ORIGINAL LINK: https://www.opengis.it/ente/qgis2o.gis/?lon=12.956319&lat=43.705298&z=13.3&l=ComuniLimitrofi:1|Confini:1|Edifici:1|Stradario:1

LINK WITH FIND WITH 2 CRITERIA: https://www.opengis.it/ente/qgis2o.gis/?lon=12.956319&lat=43.705298&z=13.3&l=ComuniLimitrofi:1|Confini:1|Edifici:1|Stradario:1&find=Particelle+Censuario,FOGLIO:15,PARTICELLA:17

ANOTHER LINK WITH FIND WITH 1 CRITERIA: https://www.opengis.it/ente/qgis2o.gis/?lon=12.956319&lat=43.705298&z=13.3&l=ComuniLimitrofi:1|Confini:1|Edifici:1|Stradario:1&find=Edifici,QuotaGronda:207.04