From 33c02443db7f28d40428042f86f4312abf922a26 Mon Sep 17 00:00:00 2001 From: nboisteault Date: Tue, 22 Oct 2024 11:04:45 +0200 Subject: [PATCH 1/9] API: expose a `zoomToGeometryOrExtent` function like OL fit() function Ref: https://openlayers.org/en/latest/apidoc/module-ol_View-View.html#fit --- assets/src/modules/map.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/assets/src/modules/map.js b/assets/src/modules/map.js index 707290d84d..99ee54f294 100644 --- a/assets/src/modules/map.js +++ b/assets/src/modules/map.js @@ -1074,4 +1074,13 @@ export default class map extends olMap { removeToolLayer(layer) { this._toolsGroup.getLayers().remove(layer); } + + /** + * Zoom to given geometry or extent + * @param {import("ol/geom/SimpleGeometry.js").default|import("ol/extent.js").Extent} geometryOrExtent The geometry or extent to zoom to. + * @param {object} [options] Options. + */ + zoomToGeometryOrExtent(geometryOrExtent, options) { + this.getView().fit(geometryOrExtent, options); + } } From 2bae8f176b48a20ec5a664f46018d986bac55031 Mon Sep 17 00:00:00 2001 From: nboisteault Date: Tue, 22 Oct 2024 11:06:04 +0200 Subject: [PATCH 2/9] Refactor LocateByLayer in a module --- assets/src/legacy/map.js | 458 --------------------------- assets/src/modules/Lizmap.js | 2 + assets/src/modules/LocateByLayer.js | 471 ++++++++++++++++++++++++++++ 3 files changed, 473 insertions(+), 458 deletions(-) create mode 100644 assets/src/modules/LocateByLayer.js diff --git a/assets/src/legacy/map.js b/assets/src/legacy/map.js index 31f6da366b..81afa13189 100644 --- a/assets/src/legacy/map.js +++ b/assets/src/legacy/map.js @@ -772,59 +772,6 @@ window.lizMap = function() { window.addEventListener('resize', updateContentSize); } - /** - * Get features for locate by layer tool - * @param aName - */ - function updateLocateFeatureList(aName) { - var locate = config.locateByLayer[aName]; - // clone features reference - var features = {}; - for ( var fid in locate.features ) { - features[fid] = locate.features[fid]; - } - // filter by filter field name - if ('filterFieldName' in locate) { - var filterValue = $('#locate-layer-'+cleanName(aName)+'-'+locate.filterFieldName).val(); - if ( filterValue != '-1' ) { - for (var fid in features) { - var feat = features[fid]; - if (feat.properties[locate.filterFieldName] != filterValue) - delete features[fid]; - } - } else - features = {} - } - // filter by vector joins - if ( 'vectorjoins' in locate && locate.vectorjoins.length != 0 ) { - var vectorjoins = locate.vectorjoins; - for ( var i=0, len =vectorjoins.length; i< len; i++) { - var vectorjoin = vectorjoins[i]; - var jName = vectorjoin.joinLayer; - if ( jName in config.locateByLayer ) { - var jLocate = config.locateByLayer[jName]; - var jVal = $('#locate-layer-'+cleanName(jName)).val(); - if ( jVal == '-1' ) continue; - var jFeat = jLocate.features[jVal]; - for (var fid in features) { - var feat = features[fid]; - if ( feat.properties[vectorjoin.targetFieldName] != jFeat.properties[vectorjoin.joinFieldName] ) - delete features[fid]; - } - } - } - } - // create the option list - const placeHolder = config.layers[aName].title; - var options = ''; - for (var fid in features) { - var feat = features[fid]; - options += ''; - } - // add option list - $('#locate-layer-'+cleanName(aName)).html(options); - } - /** * * @param layer_name @@ -837,401 +784,6 @@ window.lizMap = function() { layer[0].destroyFeatures(); } - /** - * Zoom to locate feature - * @param aName - */ - function zoomToLocateFeature(aName) { - // clear highlight layer - lizMap.mainLizmap.map.clearHighlightFeatures(); - - // get locate by layer val - var locate = config.locateByLayer[aName]; - var layerName = cleanName(aName); - var proj = new OpenLayers.Projection(locate.crs); - var val = $('#locate-layer-'+layerName).val(); - if (val == '-1') { - - // Trigger event - lizMap.events.triggerEvent('lizmaplocatefeaturecanceled', - { - 'featureType': aName - } - ); - } else { - // zoom to val - var feat = locate.features[val]; - var format = new OpenLayers.Format.GeoJSON({ - ignoreExtraDims: true - }); - feat = format.read(feat)[0]; - - if( feat.geometry != null){ - feat.geometry.transform(proj, map.getProjection()); - // Show geometry if asked - if (locate.displayGeom == 'True') { - var getFeatureUrlData = getVectorLayerWfsUrl( aName, null, null, null ); - getFeatureUrlData['options']['PROPERTYNAME'] = ['geometry',locate.fieldName].join(','); - getFeatureUrlData['options']['FEATUREID'] = val; - // Get data - $.post( getFeatureUrlData['url'], getFeatureUrlData['options'], function(data) { - if ( !data.features ){ - data = JSON.parse(data); - } - lizMap.mainLizmap.map.setHighlightFeatures(data.features[0], "geojson"); - }).fail(function(){ - lizMap.mainLizmap.map.setHighlightFeatures(feat, "geojson"); - }); - } - // zoom to extent - map.zoomToExtent(feat.geometry.getBounds()); - } - - var fid = val.split('.')[1]; - - // Trigger event - lizMap.events.triggerEvent('lizmaplocatefeaturechanged', - { - 'featureType': aName, - 'featureId': fid - } - ); - } - } - - /** - * Get features for locate by layer tool - * @param aName - */ - function getLocateFeature(aName) { - var locate = config.locateByLayer[aName]; - - // get fields to retrieve - var fields = ['geometry',locate.fieldName]; - // if a filter field is defined - if ('filterFieldName' in locate) - fields.push( locate.filterFieldName ); - // check for join fields - if ( 'filterjoins' in locate ) { - var filterjoins = locate.filterjoins; - for ( var i=0, len=filterjoins.length; i b - } - } else { - if (isNaN(bProperty)) { // a number and b string - return -1; // a < b - } else { // a and b are numbers - return parseFloat(aProperty) - parseFloat(bProperty); - } - } - }); - var filterPlaceHolder = ''; - if ( 'filterFieldAlias' in locate && locate.filterFieldAlias!='') - filterPlaceHolder += locate.filterFieldAlias+' '; - else - filterPlaceHolder += locate.filterFieldName; - filterPlaceHolder +=' ('+ lConfig.title + ')'; - var fOptions = ''; - var fValue = '-1'; - for (var i=0, len=features.length; i'+fValue+''; - } - } - - - // add filter values list - $('#locate-layer-'+layerName).parent().before('

'); - // listen to filter select changes - $('#locate-layer-'+layerName+'-'+locate.filterFieldName).change(function(){ - var filterValue = $(this).children(':selected').val(); - updateLocateFeatureList( aName ); - if (filterValue == '-1') - $('#locate-layer-'+layerName+'-'+locate.filterFieldName+' ~ span > input').val(''); - $('#locate-layer-'+layerName+' ~ span > input').val(''); - $('#locate-layer-'+layerName).val('-1'); - zoomToLocateFeature(aName); - }); - // add combobox to the filter select - $('#locate-layer-'+layerName+'-'+locate.filterFieldName).combobox({ - position: { my : "right top", at: "right bottom" }, - "selected": function(evt, ui){ - if ( ui.item ) { - var self = $(this); - var uiItem = $(ui.item); - window.setTimeout(function(){ - self.val(uiItem.val()).change(); - }, 1); - } - } - }); - - // add place holder to the filter combobox input - $('#locate-layer-'+layerName+'-'+locate.filterFieldName+' ~ span > input').attr('placeholder', filterPlaceHolder).val(''); - $('#locate-layer-'+layerName+'-'+locate.filterFieldName+' ~ span > input').autocomplete('close'); - } - - // create combobox for the layer - features.sort(function(a, b) { - var aProperty = a.properties[locate.fieldName]; - var bProperty = b.properties[locate.fieldName]; - if (isNaN(aProperty)) { - if (isNaN(bProperty)) { // a and b are strings - return aProperty.localeCompare(bProperty); - } else { // a string and b number - return 1; // a > b - } - } else { - if (isNaN(bProperty)) { // a number and b string - return -1; // a < b - } else { // a and b are numbers - return parseFloat(aProperty) - parseFloat(bProperty); - } - } - }); - var placeHolder = ''; - if ('filterFieldName' in locate) { - if ( 'fieldAlias' in locate && locate.fieldAlias!='' ) - placeHolder += locate.fieldAlias+' '; - else - placeHolder += locate.fieldName+' '; - placeHolder += '('+lConfig.title+')'; - } else { - placeHolder = lConfig.title; - } - var options = ''; - for (var i=0, len=features.length; i' + DOMPurify.sanitize(feat.properties[locate.fieldName]) + ''; - } - // listen to select changes - $('#locate-layer-'+layerName).html(options).change(function() { - var val = $(this).children(':selected').val(); - if (val == '-1') { - $('#locate-layer-'+layerName+' ~ span > input').val(''); - // update to join layer - if ( 'filterjoins' in locate && locate.filterjoins.length != 0 ) { - var filterjoins = locate.filterjoins; - for (var i=0, len=filterjoins.length; i input').val(''); - } - } - } - } - $(this).blur(); - return; - }); - $('#locate-layer-'+layerName).combobox({ - "minLength": ('minLength' in locate) ? locate.minLength : 0, - "position": { my : "right top", at: "right bottom" }, - "selected": function(evt, ui){ - if ( ui.item ) { - var self = $(this); - var uiItem = $(ui.item); - window.setTimeout(function(){ - self.val(uiItem.val()).change(); - }, 1); - } - } - }); - $('#locate-layer-'+layerName+' ~ span > input').attr('placeholder', placeHolder).val(''); - $('#locate-layer-'+layerName+' option[value=-1]').attr('label', placeHolder); - $('#locate-layer-'+layerName+' ~ span > input').autocomplete('close'); - if ( ('minLength' in locate) && locate.minLength > 0 ) - $('#locate-layer-'+layerName).parent().addClass('no-toggle'); - if(mCheckMobile()){ - // autocompletion items for locatebylayer feature - $('div.locate-layer select').show(); - $('span.custom-combobox').hide(); - } - },'json'); - } - - function addLocateByLayer(){ - var locateByLayerList = []; - for (var lname in config.locateByLayer) { - if ('order' in config.locateByLayer[lname]) - locateByLayerList[config.locateByLayer[lname].order] = lname; - else - locateByLayerList.push(lname); - } - var locateContent = []; - for (var l in locateByLayerList) { - var lname = locateByLayerList[l]; - var lConfig = config.layers[lname]; - var html = '
'; - html += ''; - html += '
'; - //constructing the select - locateContent.push(html); - } - $('#locate .menu-content').html(locateContent.join('
')); - - var featureTypes = lizMap.mainLizmap.initialConfig.vectorLayerFeatureTypeList; - if (featureTypes.length == 0) { - config.locateByLayer = {}; - $('#button-locate').parent().remove(); - $('#locate-menu').remove(); - } else { - for (const featureType of featureTypes) { - var typeName = featureType.Name; - var lname = lizMap.getNameByTypeName(typeName); - if (!lname) { - if (typeName in config.locateByLayer) - lname = typeName - else if ((typeName in shortNameMap) && (shortNameMap[typeName] in config.locateByLayer)) - lname = shortNameMap[typeName]; - else { - for (var lbl in config.locateByLayer) { - if (lbl.split(' ').join('_') == typeName) { - lname = lbl; - break; - } - } - } - } - - if (!(lname in config.locateByLayer)) - continue; - - var locate = config.locateByLayer[lname]; - locate['crs'] = featureType.SRS; - loadProjDefinition(locate.crs, function () { - new OpenLayers.Projection(locate.crs); - }); - locate['bbox'] = featureType.LatLongBoundingBox; - } - - // get joins - for (var lName in config.locateByLayer) { - var locate = config.locateByLayer[lName]; - if ('vectorjoins' in locate && locate['vectorjoins'].length != 0) { - var vectorjoin = locate['vectorjoins'][0]; - locate['joinFieldName'] = vectorjoin['targetFieldName']; - for (var jName in config.locateByLayer) { - var jLocate = config.locateByLayer[jName]; - if (jLocate.layerId == vectorjoin.joinLayerId) { - vectorjoin['joinLayer'] = jName; - locate['joinLayer'] = jName; - jLocate['joinFieldName'] = vectorjoin['joinFieldName']; - jLocate['joinLayer'] = lName; - jLocate['filterjoins'] = [{ - 'targetFieldName': vectorjoin['joinFieldName'], - 'joinFieldName': vectorjoin['targetFieldName'], - 'joinLayerId': locate.layerId, - 'joinLayer': lName - }]; - } - } - } - } - - // get locate by layers features - for (var lname in config.locateByLayer) { - getLocateFeature(lname); - } - $('.btn-locate-clear').click(function () { - lizMap.mainLizmap.map.clearHighlightFeatures(); - $('#locate select').val('-1'); - $('div.locate-layer span > input').val(''); - - if (lizMap.lizmapLayerFilterActive) { - lizMap.events.triggerEvent('lizmaplocatefeaturecanceled', - { 'featureType': lizMap.lizmapLayerFilterActive } - ); - } - return false; - - }); - $('#locate-close').click(function () { - $('.btn-locate-clear').click(); // deactivate locate and filter - $('#button-locate').click(); - return false; - }); - } - } - /** * PRIVATE function: createToolbar * create the tool bar (collapse switcher, etc) @@ -3828,10 +3380,6 @@ window.lizMap = function() { })); } - if ('locateByLayer' in config) { - addLocateByLayer(); - } - /** * Event when layers have been added * @event layersadded @@ -3887,12 +3435,6 @@ window.lizMap = function() { return false; }); - // Show locate by layer - if (!('locateByLayer' in config)) - $('#button-locate').parent().hide(); - else - $('#button-locate').click(); - // hide mini-dock if no tool is active if ($('#mapmenu ul li.nav-minidock.active').length == 0) { $('#mini-dock-content > .tab-pane.active').removeClass('active'); diff --git a/assets/src/modules/Lizmap.js b/assets/src/modules/Lizmap.js index 456b332ffb..6152432872 100644 --- a/assets/src/modules/Lizmap.js +++ b/assets/src/modules/Lizmap.js @@ -25,6 +25,7 @@ import Legend from './Legend.js'; import Permalink from './Permalink.js'; import Search from './Search.js'; import Tooltip from './Tooltip.js'; +import LocateByLayer from './LocateByLayer.js'; import WMSCapabilities from 'ol/format/WMSCapabilities.js'; import WFSCapabilities from 'ol-wfs-capabilities'; @@ -167,6 +168,7 @@ export default class Lizmap { this.legend = new Legend(this.state.layerTree); this.search = new Search(this.map, this.lizmap3); this.tooltip = new Tooltip(); + this.locateByLayer = new LocateByLayer(); // Removed unusable button if (!this.config['printTemplates'] || this.config.printTemplates.length == 0 ) { diff --git a/assets/src/modules/LocateByLayer.js b/assets/src/modules/LocateByLayer.js new file mode 100644 index 0000000000..53f69bf834 --- /dev/null +++ b/assets/src/modules/LocateByLayer.js @@ -0,0 +1,471 @@ +/** + * @module modules/LocateByLayer.js + * @name LocateByLayer + * @copyright 2024 3Liz + * @author BOISTEAULT Nicolas + * @license MPL-2.0 + */ + +import { mainLizmap } from '../modules/Globals.js'; +import DOMPurify from 'dompurify'; + +import GeoJSON from 'ol/format/GeoJSON.js'; + +/** + * @class + * @name LocateByLayer + */ +export default class LocateByLayer { + constructor() { + this._locateByLayerConfig = lizMap.config.locateByLayer; + const locateBtn = document.getElementById('button-locate'); + if (mainLizmap.initialConfig.locateByLayer) { + this.addLocateByLayer(); + locateBtn?.click(); + } else { + locateBtn?.parentNode.classList.add('hide'); + } + } + + addLocateByLayer() { + var locateByLayerList = []; + for (var lname in this._locateByLayerConfig) { + if ('order' in this._locateByLayerConfig[lname]) + locateByLayerList[this._locateByLayerConfig[lname].order] = lname; + else + locateByLayerList.push(lname); + } + var locateContent = []; + for (var l in locateByLayerList) { + var lname = locateByLayerList[l]; + var lConfig = lizMap.config.layers[lname]; + var html = '
'; + html += ''; + html += '
'; + //constructing the select + locateContent.push(html); + } + $('#locate .menu-content').html(locateContent.join('
')); + + var featureTypes = lizMap.mainLizmap.initialConfig.vectorLayerFeatureTypeList; + if (featureTypes.length == 0) { + this._locateByLayerConfig = {}; + $('#button-locate').parent().remove(); + $('#locate-menu').remove(); + } else { + for (const featureType of featureTypes) { + var typeName = featureType.Name; + var lname = lizMap.getNameByTypeName(typeName); + if (!lname) { + if (typeName in this._locateByLayerConfig) + lname = typeName + else if ((typeName in shortNameMap) && (shortNameMap[typeName] in this._locateByLayerConfig)) + lname = shortNameMap[typeName]; + else { + for (var lbl in this._locateByLayerConfig) { + if (lbl.split(' ').join('_') == typeName) { + lname = lbl; + break; + } + } + } + } + + if (!(lname in this._locateByLayerConfig)) + continue; + + var locate = this._locateByLayerConfig[lname]; + locate['crs'] = featureType.SRS; + // loadProjDefinition(locate.crs, function () { + // new OpenLayers.Projection(locate.crs); + // }); + locate['bbox'] = featureType.LatLongBoundingBox; + } + + // get joins + for (var lName in this._locateByLayerConfig) { + var locate = this._locateByLayerConfig[lName]; + if ('vectorjoins' in locate && locate['vectorjoins'].length != 0) { + var vectorjoin = locate['vectorjoins'][0]; + locate['joinFieldName'] = vectorjoin['targetFieldName']; + for (var jName in this._locateByLayerConfig) { + var jLocate = this._locateByLayerConfig[jName]; + if (jLocate.layerId == vectorjoin.joinLayerId) { + vectorjoin['joinLayer'] = jName; + locate['joinLayer'] = jName; + jLocate['joinFieldName'] = vectorjoin['joinFieldName']; + jLocate['joinLayer'] = lName; + jLocate['filterjoins'] = [{ + 'targetFieldName': vectorjoin['joinFieldName'], + 'joinFieldName': vectorjoin['targetFieldName'], + 'joinLayerId': locate.layerId, + 'joinLayer': lName + }]; + } + } + } + } + + // get locate by layers features + for (var lname in this._locateByLayerConfig) { + this.getLocateFeature(lname); + } + $('.btn-locate-clear').click(function () { + lizMap.mainLizmap.map.clearHighlightFeatures(); + $('#locate select').val('-1'); + $('div.locate-layer span > input').val(''); + + if (lizMap.lizmapLayerFilterActive) { + lizMap.events.triggerEvent('lizmaplocatefeaturecanceled', + { 'featureType': lizMap.lizmapLayerFilterActive } + ); + } + return false; + + }); + $('#locate-close').click(function () { + $('.btn-locate-clear').click(); // deactivate locate and filter + document.getElementById('button-locate')?.click(); + return false; + }); + } + } + + /** + * Get features for locate by layer tool + * @param aName + */ + getLocateFeature(aName) { + var locate = this._locateByLayerConfig[aName]; + + // get fields to retrieve + var fields = ['geometry',locate.fieldName]; + // if a filter field is defined + if ('filterFieldName' in locate) + fields.push( locate.filterFieldName ); + // check for join fields + if ( 'filterjoins' in locate ) { + var filterjoins = locate.filterjoins; + for ( var i=0, len=filterjoins.length; i { + var lConfig = lizMap.config.layers[aName]; + locate['features'] = {}; + if ( !data.features ) + data = JSON.parse(data); + var features = data.features; + // if( locate.crs != 'EPSG:4326' && features.length != 0) { + // // load projection to be sure to have the definition + // loadProjDefinition( locate.crs, function() { + // locate.crs = 'EPSG:4326'; + // }); + // } + + if ('filterFieldName' in locate) { + // create filter combobox for the layer + features.sort(function(a, b) { + var aProperty = a.properties[locate.filterFieldName]; + var bProperty = b.properties[locate.filterFieldName]; + if (isNaN(aProperty)) { + if (isNaN(bProperty)) { // a and b are strings + return aProperty.localeCompare(bProperty); + } else { // a string and b number + return 1; // a > b + } + } else { + if (isNaN(bProperty)) { // a number and b string + return -1; // a < b + } else { // a and b are numbers + return parseFloat(aProperty) - parseFloat(bProperty); + } + } + }); + var filterPlaceHolder = ''; + if ( 'filterFieldAlias' in locate && locate.filterFieldAlias!='') + filterPlaceHolder += locate.filterFieldAlias+' '; + else + filterPlaceHolder += locate.filterFieldName; + filterPlaceHolder +=' ('+ lConfig.title + ')'; + var fOptions = ''; + var fValue = '-1'; + for (var i=0, len=features.length; i'+fValue+''; + } + } + + // add filter values list + $('#locate-layer-'+layerName).parent().before('

'); + // listen to filter select changes + document.getElementById('locate-layer-'+layerName+'-'+locate.filterFieldName).addEventListener("change", () => { + var filterValue = $(this).children(':selected').val(); + this.updateLocateFeatureList( aName ); + if (filterValue == '-1') + $('#locate-layer-'+layerName+'-'+locate.filterFieldName+' ~ span > input').val(''); + $('#locate-layer-'+layerName+' ~ span > input').val(''); + $('#locate-layer-'+layerName).val('-1'); + this.zoomToLocateFeature(aName); + }); + // add combobox to the filter select + $('#locate-layer-'+layerName+'-'+locate.filterFieldName).combobox({ + position: { my : "right top", at: "right bottom" }, + "selected": function(evt, ui){ + if ( ui.item ) { + const self = this; + var uiItem = $(ui.item); + window.setTimeout(function(){ + self.value = uiItem.val(); + self.dispatchEvent(new Event('change')); + }, 1); + } + } + }); + + // add place holder to the filter combobox input + $('#locate-layer-'+layerName+'-'+locate.filterFieldName+' ~ span > input').attr('placeholder', filterPlaceHolder).val(''); + $('#locate-layer-'+layerName+'-'+locate.filterFieldName+' ~ span > input').autocomplete('close'); + } + + // create combobox for the layer + features.sort(function(a, b) { + var aProperty = a.properties[locate.fieldName]; + var bProperty = b.properties[locate.fieldName]; + if (isNaN(aProperty)) { + if (isNaN(bProperty)) { // a and b are strings + return aProperty.localeCompare(bProperty); + } else { // a string and b number + return 1; // a > b + } + } else { + if (isNaN(bProperty)) { // a number and b string + return -1; // a < b + } else { // a and b are numbers + return parseFloat(aProperty) - parseFloat(bProperty); + } + } + }); + var placeHolder = ''; + if ('filterFieldName' in locate) { + if ( 'fieldAlias' in locate && locate.fieldAlias!='' ) + placeHolder += locate.fieldAlias+' '; + else + placeHolder += locate.fieldName+' '; + placeHolder += '('+lConfig.title+')'; + } else { + placeHolder = lConfig.title; + } + var options = ''; + for (var i=0, len=features.length; i' + DOMPurify.sanitize(feat.properties[locate.fieldName]) + ''; + } + document.getElementById('locate-layer-'+layerName).innerHTML = options; + // listen to select changes + document.getElementById('locate-layer-'+layerName).addEventListener("change", (event) => { + var val = event.target.value; + if (val == '-1') { + $('#locate-layer-'+layerName+' ~ span > input').val(''); + // update to join layer + if ( 'filterjoins' in locate && locate.filterjoins.length != 0 ) { + var filterjoins = locate.filterjoins; + for (var i=0, len=filterjoins.length; i input').val(''); + } + } + } + } + $(this).blur(); + return; + }); + $('#locate-layer-'+layerName).combobox({ + "minLength": ('minLength' in locate) ? locate.minLength : 0, + "position": { my : "right top", at: "right bottom" }, + "selected": function(evt, ui){ + if ( ui.item ) { + const self = this; + var uiItem = $(ui.item); + window.setTimeout(function(){ + self.value = uiItem.val(); + self.dispatchEvent(new Event('change')); + }, 1); + } + } + }); + $('#locate-layer-'+layerName+' ~ span > input').attr('placeholder', placeHolder).val(''); + $('#locate-layer-'+layerName+' option[value=-1]').attr('label', placeHolder); + $('#locate-layer-'+layerName+' ~ span > input').autocomplete('close'); + if ( ('minLength' in locate) && locate.minLength > 0 ) + $('#locate-layer-'+layerName).parent().addClass('no-toggle'); + if(lizMap.checkMobile()){ + // autocompletion items for locatebylayer feature + $('div.locate-layer select').show(); + $('span.custom-combobox').hide(); + } + },'json'); + } + + /** + * Zoom to locate feature + * @param aName + */ + zoomToLocateFeature(aName) { + // clear highlight layer + lizMap.mainLizmap.map.clearHighlightFeatures(); + + // get locate by layer val + var locate = this._locateByLayerConfig[aName]; + var layerName = lizMap.cleanName(aName); + var val = $('#locate-layer-'+layerName).val(); + if (val == '-1') { + // Trigger event + lizMap.events.triggerEvent('lizmaplocatefeaturecanceled', {'featureType': aName }); + } else { + // zoom to val + const featGeoJSON = locate.features[val]; + if( featGeoJSON.geometry){ + const geom = (new GeoJSON()).readGeometry(featGeoJSON.geometry, { + dataProjection: 'EPSG:4326', + featureProjection: lizMap.mainLizmap.projection + }); + // Show geometry if asked + if (locate.displayGeom == 'True') { + var getFeatureUrlData = getVectorLayerWfsUrl( aName, null, null, null ); + getFeatureUrlData['options']['PROPERTYNAME'] = ['geometry',locate.fieldName].join(','); + getFeatureUrlData['options']['FEATUREID'] = val; + // Get data + $.post( getFeatureUrlData['url'], getFeatureUrlData['options'], function(data) { + if ( !data.features ){ + data = JSON.parse(data); + } + lizMap.mainLizmap.map.setHighlightFeatures(data.features[0], "geojson"); + }).fail(function(){ + lizMap.mainLizmap.map.setHighlightFeatures(feat, "geojson"); + }); + } + // zoom to extent + lizMap.mainLizmap.map.zoomToGeometryOrExtent(geom); + } + + var fid = val.split('.')[1]; + + // Trigger event + lizMap.events.triggerEvent('lizmaplocatefeaturechanged', + { + 'featureType': aName, + 'featureId': fid + } + ); + } + } + + /** + * Get features for locate by layer tool + * @param aName + */ + updateLocateFeatureList(aName) { + var locate = this._locateByLayerConfig[aName]; + // clone features reference + var features = {}; + for ( var fid in locate.features ) { + features[fid] = locate.features[fid]; + } + // filter by filter field name + if ('filterFieldName' in locate) { + var filterValue = $('#locate-layer-' + lizMap.cleanName(aName) + '-'+locate.filterFieldName).val(); + if ( filterValue != '-1' ) { + for (var fid in features) { + var feat = features[fid]; + if (feat.properties[locate.filterFieldName] != filterValue) + delete features[fid]; + } + } else + features = {} + } + // filter by vector joins + if ( 'vectorjoins' in locate && locate.vectorjoins.length != 0 ) { + var vectorjoins = locate.vectorjoins; + for ( var i=0, len =vectorjoins.length; i< len; i++) { + var vectorjoin = vectorjoins[i]; + var jName = vectorjoin.joinLayer; + if ( jName in this._locateByLayerConfig ) { + var jLocate = this._locateByLayerConfig[jName]; + var jVal = $('#locate-layer-' + lizMap.cleanName(jName)).val(); + if ( jVal == '-1' ) continue; + var jFeat = jLocate.features[jVal]; + for (var fid in features) { + var feat = features[fid]; + if ( feat.properties[vectorjoin.targetFieldName] != jFeat.properties[vectorjoin.joinFieldName] ) + delete features[fid]; + } + } + } + } + // create the option list + const placeHolder = lizMap.config.layers[aName].title; + var options = ''; + for (var fid in features) { + var feat = features[fid]; + options += ''; + } + // add option list + $('#locate-layer-'+ lizMap.cleanName(aName)).html(options); + } +}; From 545ca86e4cff95d5dad001be52639c95d2c066a9 Mon Sep 17 00:00:00 2001 From: nboisteault Date: Wed, 23 Oct 2024 10:01:50 +0200 Subject: [PATCH 3/9] Apply max scale constraint in `zoomToGeometryOrExtent` function --- assets/src/modules/config/Options.js | 20 +++++++++++++ assets/src/modules/map.js | 42 +++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/assets/src/modules/config/Options.js b/assets/src/modules/config/Options.js index cde838a777..0710016077 100644 --- a/assets/src/modules/config/Options.js +++ b/assets/src/modules/config/Options.js @@ -29,6 +29,8 @@ const optionalProperties = { 'wmsMaxHeight': {type: 'number', default: 3000}, 'wmsMaxWidth': {type: 'number', default: 3000}, 'fixed_scale_overview_map': {type: 'boolean', default: true}, + 'max_scale_points': {type: 'number', default: 5000}, + 'max_scale_lines_polygons': {type: 'number', default: 5000}, 'use_native_zoom_levels': {type: 'boolean', nullable: true, default: null}, 'hide_numeric_scale_value': {type: 'boolean', default: false}, 'hideGroupCheckbox': { type: 'boolean', default: false }, @@ -62,6 +64,8 @@ export class OptionsConfig extends BaseObjectConfig { * @param {number} [cfg.wmsMaxHeight] - the image max height for WMS GetMap request * @param {number} [cfg.wmsMaxWidth] - the image max width for WMS GetMap request * @param {boolean} [cfg.fixed_scale_overview_map] - does the Overview map have fixed scale ? + * @param {number} [cfg.max_scale_points] - maximum scale when zooming on points + * @param {boolean} [cfg.max_scale_lines_polygons] - maximum scale when zooming on lines or polygons * @param {boolean} [cfg.use_native_zoom_levels] - does the map use native zoom levels ? * @param {boolean} [cfg.hide_numeric_scale_value] - does the scale line hide numeric scale value ? * @param {boolean} [cfg.hideGroupCheckbox] - are groups checkbox hidden ? @@ -207,6 +211,22 @@ export class OptionsConfig extends BaseObjectConfig { return this._fixed_scale_overview_map; } + /** + * Maximum scale when zooming on points + * @type {boolean} + */ + get max_scale_points() { + return this._max_scale_points; + } + + /** + * Maximum scale when zooming on lines or polygons + * @type {boolean} + */ + get max_scale_lines_polygons() { + return this._max_scale_lines_polygons; + } + /** * The map uses native zoom levels * @type {boolean} diff --git a/assets/src/modules/map.js b/assets/src/modules/map.js index 99ee54f294..8e43e0f85d 100644 --- a/assets/src/modules/map.js +++ b/assets/src/modules/map.js @@ -1077,10 +1077,50 @@ export default class map extends olMap { /** * Zoom to given geometry or extent - * @param {import("ol/geom/SimpleGeometry.js").default|import("ol/extent.js").Extent} geometryOrExtent The geometry or extent to zoom to. + * @param {geometry|extent} geometryOrExtent The geometry or extent to zoom to. * @param {object} [options] Options. */ zoomToGeometryOrExtent(geometryOrExtent, options) { + const geometryType = geometryOrExtent.getType?.(); + if (geometryType && (mainLizmap.initialConfig.options.max_scale_lines_polygons || mainLizmap.initialConfig.options.max_scale_lines_polygons)) { + let maxScale; + if (['Polygon', 'Linestring'].includes(geometryType)){ + maxScale = mainLizmap.initialConfig.options.max_scale_lines_polygons; + } else if (geometryType === 'Point'){ + maxScale = mainLizmap.initialConfig.options.max_scale_points; + } + const resolution = mainLizmap.utils.getResolutionFromScale( + maxScale, + mainLizmap.map.getView().getProjection().getMetersPerUnit() + ); + if (!options?.minResolution) { + if (!options) { + options = { minResolution: resolution }; + } else { + options.minResolution = resolution; + } + } + } this.getView().fit(geometryOrExtent, options); } + + /** + * Zoom to given feature id + * @param {string} featureTypeDotId The string as `featureType.fid` to zoom to. + * @param {object} [options] Options. + */ + zoomToFid(featureTypeDotId, options) { + const [featureType, fid] = featureTypeDotId.split('.'); + if (!featureType || !fid) { + console.log('Wrong string for featureType.fid'); + return; + } + lizMap.getLayerFeature(featureType, fid, feat => { + const olFeature = (new GeoJSON()).readFeature(feat, { + dataProjection: 'EPSG:4326', + featureProjection: mainLizmap.projection + }); + this.zoomToGeometryOrExtent(olFeature.getGeometry(), options); + }); + } } From e51aed2078395e7dcef02865ce2305c1147d1d3f Mon Sep 17 00:00:00 2001 From: nboisteault Date: Tue, 12 Nov 2024 10:35:32 +0100 Subject: [PATCH 4/9] Refactor to use `zoomToGeometryOrExtent` and `zoomToFid` --- assets/src/components/FeatureToolbar.js | 23 ++++++++----- assets/src/legacy/atlas.js | 18 ++++------ assets/src/legacy/filter.js | 3 +- assets/src/legacy/map.js | 35 -------------------- assets/src/legacy/switcher-layers-actions.js | 24 -------------- assets/src/modules/map.js | 4 +-- 6 files changed, 23 insertions(+), 84 deletions(-) diff --git a/assets/src/components/FeatureToolbar.js b/assets/src/components/FeatureToolbar.js index 8b7ee8aa15..b1597485cf 100644 --- a/assets/src/components/FeatureToolbar.js +++ b/assets/src/components/FeatureToolbar.js @@ -15,6 +15,8 @@ import { getCenter } from 'ol/extent.js'; import GeoJSON from 'ol/format/GeoJSON.js'; import GPX from 'ol/format/GPX.js'; import KML from 'ol/format/KML.js'; +import Point from 'ol/geom/Point.js'; +import {fromExtent} from 'ol/geom/Polygon.js'; import '../images/svg/map-print.svg'; @@ -397,12 +399,6 @@ export default class FeatureToolbar extends HTMLElement { } zoom() { - // FIXME: necessary? - // Remove map popup to avoid confusion - if (lizMap.map.popups.length != 0){ - lizMap.map.removePopup(lizMap.map.popups[0]); - } - if (this.getAttribute('crs')){ const featureExtent = [ parseFloat(this.getAttribute('bbox-minx')), @@ -415,9 +411,18 @@ export default class FeatureToolbar extends HTMLElement { this.getAttribute('crs'), lizMap.mainLizmap.projection ); - lizMap.mainLizmap.extent = targetMapExtent; - }else{ - lizMap.zoomToFeature(this.featureType, this.fid, 'zoom'); + + let geom; + // The geom is a Point + if (targetMapExtent[0] == targetMapExtent[2] && targetMapExtent[1] == targetMapExtent[3]) { + geom = new Point([targetMapExtent[0], targetMapExtent[1]]) + } else { + geom = fromExtent(targetMapExtent); + } + + mainLizmap.map.zoomToGeometryOrExtent(geom); + } else { + mainLizmap.map.zoomToFid(this.featureType + '.' + this.fid); } } diff --git a/assets/src/legacy/atlas.js b/assets/src/legacy/atlas.js index 09d0babd50..864fb75243 100644 --- a/assets/src/legacy/atlas.js +++ b/assets/src/legacy/atlas.js @@ -6,6 +6,8 @@ */ import DOMPurify from 'dompurify'; +import GeoJSON from 'ol/format/GeoJSON.js'; +import { getCenter } from 'ol/extent.js'; (function () { @@ -531,26 +533,18 @@ import DOMPurify from 'dompurify'; * @param feature */ function runAtlasItem(feature) { - - // Use OL tools to reproject feature geometry - var format = new OpenLayers.Format.GeoJSON({ - ignoreExtraDims: true - }); - var feat = format.read(feature)[0]; - var f = feat.clone(); - var proj = lizMap.config.layers[lizAtlasConfig.layername]['featureCrs']; - f.geometry.transform(proj, lizMap.map.getProjection()); + const olFeature = (new GeoJSON()).readFeature(feature); // Zoom to feature if (lizAtlasConfig['zoom']) { if (lizAtlasConfig['zoom'].toLowerCase() == 'center') { // center - var lonlat = f.geometry.getBounds().getCenterLonLat(); - lizMap.map.setCenter(lonlat); + const center = getCenter(olFeature.getGeometry().getExtent()); + lizMap.map.setCenter(center); } else { // zoom - lizMap.map.zoomToExtent(f.geometry.getBounds()); + lizMap.mainLizmap.map.zoomToGeometryOrExtent(olFeature.getGeometry()); } } diff --git a/assets/src/legacy/filter.js b/assets/src/legacy/filter.js index f3f7b64ead..f87a680252 100644 --- a/assets/src/legacy/filter.js +++ b/assets/src/legacy/filter.js @@ -1462,8 +1462,7 @@ var lizLayerFilterTool = function () { if (!bounds || abounds.length != 4) { return false; } - var extent = new OpenLayers.Bounds(abounds[0], abounds[1], abounds[2], abounds[3]); - lizMap.map.zoomToExtent(extent); + lizMap.mainLizmap.map.zoomToGeometryOrExtent(abounds); return false; } diff --git a/assets/src/legacy/map.js b/assets/src/legacy/map.js index 81afa13189..1e535b2990 100644 --- a/assets/src/legacy/map.js +++ b/assets/src/legacy/map.js @@ -2260,37 +2260,6 @@ window.lizMap = function() { },'json'); } }); - - // $.post( getFeatureUrlData['url'], getFeatureUrlData['options'], function(incomingData) { - // const data = DOMPurify.sanitize(incomingData); - - // aConfig['featureCrs'] = 'EPSG:4326'; - - // if (aConfig?.['alias'] && aConfig?.['types']) { - // callFeatureDataCallBacks(poolId, data.features); - // $('body').css('cursor', 'auto'); - // } else { - // $.post(globalThis['lizUrls'].service, { - // 'SERVICE':'WFS' - // ,'VERSION':'1.0.0' - // ,'REQUEST':'DescribeFeatureType' - // ,'TYPENAME': ('typename' in aConfig) ? aConfig.typename : aName - // ,'OUTPUTFORMAT':'JSON' - // }, function(describe) { - - // aConfig['alias'] = describe.aliases; - // aConfig['types'] = describe.types; - // aConfig['columns'] = describe.columns; - - // callFeatureDataCallBacks(poolId, data.features); - - // $('body').css('cursor', 'auto'); - - // },'json'); - // } - - // },'json'); - return true; } @@ -2418,10 +2387,6 @@ window.lizMap = function() { if( !feat ) return false; - // Remove map popup to avoid confusion - if (lizMap.map.popups.length != 0) - lizMap.map.removePopup( lizMap.map.popups[0] ); - // Get popup content by FILTER and not with virtual click on map var filter = ''; var qgisName = aName; diff --git a/assets/src/legacy/switcher-layers-actions.js b/assets/src/legacy/switcher-layers-actions.js index f4dff57c10..06b96aad11 100644 --- a/assets/src/legacy/switcher-layers-actions.js +++ b/assets/src/legacy/switcher-layers-actions.js @@ -413,20 +413,6 @@ var lizLayerActionButtons = function() { if(mapProjection == 'EPSG:900913') mapProjection = 'EPSG:3857'; - /*if( !( 'bbox' in itemConfig ) || !( mapProjection in itemConfig['bbox'] ) ){ - console.log('The layer bbox information has not been found in config'); - console.log(itemConfig); - return false; - }*/ - - /*var lex = itemConfig['bbox'][mapProjection]['bbox']; - var lBounds = new OpenLayers.Bounds( - lex[0], - lex[1], - lex[2], - lex[3] - );*/ - if ( !('extent' in itemConfig) ) { console.log('The layer extent information has not been found in config'); console.log(itemConfig); @@ -440,16 +426,6 @@ var lizLayerActionButtons = function() { var lBounds = OpenLayers.Bounds.fromArray(itemConfig['extent']); lBounds = lBounds.transform(itemConfig['crs'],mapProjection); - // Reverse axis - /*if (OpenLayers.Projection.defaults[mapProjection] && - OpenLayers.Projection.defaults[mapProjection].yx) { - lBounds = new OpenLayers.Bounds( - lex[1], - lex[0], - lex[3], - lex[2] - ); - }*/ lizMap.map.zoomToExtent( lBounds ); return false; diff --git a/assets/src/modules/map.js b/assets/src/modules/map.js index 8e43e0f85d..307b24d3a7 100644 --- a/assets/src/modules/map.js +++ b/assets/src/modules/map.js @@ -1077,14 +1077,14 @@ export default class map extends olMap { /** * Zoom to given geometry or extent - * @param {geometry|extent} geometryOrExtent The geometry or extent to zoom to. + * @param {geometry|extent} geometryOrExtent The geometry or extent to zoom to. CRS is 4326 by default. * @param {object} [options] Options. */ zoomToGeometryOrExtent(geometryOrExtent, options) { const geometryType = geometryOrExtent.getType?.(); if (geometryType && (mainLizmap.initialConfig.options.max_scale_lines_polygons || mainLizmap.initialConfig.options.max_scale_lines_polygons)) { let maxScale; - if (['Polygon', 'Linestring'].includes(geometryType)){ + if (['Polygon', 'Linestring', 'MultiPolygon', 'MultiLinestring'].includes(geometryType)){ maxScale = mainLizmap.initialConfig.options.max_scale_lines_polygons; } else if (geometryType === 'Point'){ maxScale = mainLizmap.initialConfig.options.max_scale_points; From 4dffc445dc196bc4ad11d4deee761dfa96b10074 Mon Sep 17 00:00:00 2001 From: nboisteault Date: Tue, 12 Nov 2024 11:06:19 +0100 Subject: [PATCH 5/9] Finish locateByLayer refactoring --- assets/src/modules/LocateByLayer.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/src/modules/LocateByLayer.js b/assets/src/modules/LocateByLayer.js index 53f69bf834..08cb23c613 100644 --- a/assets/src/modules/LocateByLayer.js +++ b/assets/src/modules/LocateByLayer.js @@ -21,7 +21,8 @@ export default class LocateByLayer { const locateBtn = document.getElementById('button-locate'); if (mainLizmap.initialConfig.locateByLayer) { this.addLocateByLayer(); - locateBtn?.click(); + document.querySelector('#mapmenu .locate').classList.add('active') + document.getElementById('locate').classList.remove('hide') } else { locateBtn?.parentNode.classList.add('hide'); } @@ -387,7 +388,7 @@ export default class LocateByLayer { }); // Show geometry if asked if (locate.displayGeom == 'True') { - var getFeatureUrlData = getVectorLayerWfsUrl( aName, null, null, null ); + var getFeatureUrlData = lizMap.getVectorLayerWfsUrl( aName, null, null, null ); getFeatureUrlData['options']['PROPERTYNAME'] = ['geometry',locate.fieldName].join(','); getFeatureUrlData['options']['FEATUREID'] = val; // Get data From 5e35aa62b6f419232b8bad2799d1b19a34754126 Mon Sep 17 00:00:00 2001 From: nboisteault Date: Thu, 14 Nov 2024 10:49:25 +0100 Subject: [PATCH 6/9] Refactor `zoomToOlFeature` to use OL10 map --- assets/src/legacy/map.js | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/assets/src/legacy/map.js b/assets/src/legacy/map.js index 1e535b2990..83440acb7d 100644 --- a/assets/src/legacy/map.js +++ b/assets/src/legacy/map.js @@ -13,7 +13,6 @@ import { extend } from 'ol/extent.js'; import WFS from '../modules/WFS.js'; import WMS from '../modules/WMS.js'; import Utils from '../modules/Utils.js'; -import DOMPurify from 'dompurify'; window.lizMap = function() { /** @@ -2269,8 +2268,7 @@ window.lizMap = function() { * @param proj * @param zoomAction */ - function zoomToOlFeature( feature, proj, zoomAction ){ - zoomAction = typeof zoomAction !== 'undefined' ? zoomAction : 'zoom'; + function zoomToOlFeature( feature, proj, zoomAction = 'action' ){ var format = new OpenLayers.Format.GeoJSON({ ignoreExtraDims: true }); @@ -2279,11 +2277,11 @@ window.lizMap = function() { feat.geometry.transform( proj, lizMap.map.getProjection() ); // Zoom or center to selected feature - if( zoomAction == 'zoom' ) - map.zoomToExtent(feat.geometry.getBounds()); - if( zoomAction == 'center' ){ - var lonlat = feat.geometry.getBounds().getCenterLonLat() - map.setCenter(lonlat); + if( zoomAction == 'zoom' ){ + lizMap.mainLizmap.map.zoomToGeometryOrExtent(feat.geometry.getBounds().toArray()); + } else if( zoomAction == 'center' ){ + const lonlat = feat.geometry.getBounds().getCenterLonLat(); + lizMap.mainLizmap.map.getView().setCenter([lonlat.lon, lonlat.lat]); } } } @@ -2294,9 +2292,7 @@ window.lizMap = function() { * @param fid * @param zoomAction */ - function zoomToFeature( featureType, fid, zoomAction ){ - zoomAction = typeof zoomAction !== 'undefined' ? zoomAction : 'zoom'; - + function zoomToFeature( featureType, fid, zoomAction = 'zoom' ){ getLayerFeature(featureType, fid, function(feat) { var proj = new OpenLayers.Projection(config.layers[featureType].crs); if( config.layers[featureType].featureCrs ) From ad8813377daa68451eaec43bd6501772ccfc93b1 Mon Sep 17 00:00:00 2001 From: nboisteault Date: Thu, 5 Dec 2024 16:12:46 +0100 Subject: [PATCH 7/9] Refactoring --- assets/src/modules/Lizmap.js | 7 +- assets/src/modules/LocateByLayer.js | 135 ++++++++++++++-------------- 2 files changed, 75 insertions(+), 67 deletions(-) diff --git a/assets/src/modules/Lizmap.js b/assets/src/modules/Lizmap.js index 6152432872..9ec4b55517 100644 --- a/assets/src/modules/Lizmap.js +++ b/assets/src/modules/Lizmap.js @@ -168,7 +168,12 @@ export default class Lizmap { this.legend = new Legend(this.state.layerTree); this.search = new Search(this.map, this.lizmap3); this.tooltip = new Tooltip(); - this.locateByLayer = new LocateByLayer(); + this.locateByLayer = new LocateByLayer( + this.initialConfig.locateByLayer, + this.initialConfig.vectorLayerFeatureTypeList, + this.map, + this._lizmap3 + ); // Removed unusable button if (!this.config['printTemplates'] || this.config.printTemplates.length == 0 ) { diff --git a/assets/src/modules/LocateByLayer.js b/assets/src/modules/LocateByLayer.js index 08cb23c613..85ba22f236 100644 --- a/assets/src/modules/LocateByLayer.js +++ b/assets/src/modules/LocateByLayer.js @@ -6,7 +6,6 @@ * @license MPL-2.0 */ -import { mainLizmap } from '../modules/Globals.js'; import DOMPurify from 'dompurify'; import GeoJSON from 'ol/format/GeoJSON.js'; @@ -16,10 +15,22 @@ import GeoJSON from 'ol/format/GeoJSON.js'; * @name LocateByLayer */ export default class LocateByLayer { - constructor() { - this._locateByLayerConfig = lizMap.config.locateByLayer; + /** + * Build the lizmap LocateByLayer instance + * @param {LocateByLayerConfig} locateByLayer - The lizmap locateByLayer config + * @param {WfsFeatureType[]} vectorLayerFeatureTypeList - The list of WFS feature type + * @param {Map} map - OpenLayers map + * @param {object} lizmap3 - The old lizmap object + */ + constructor(locateByLayer, vectorLayerFeatureTypeList, map, lizmap3) { + this._map = map; + this._vectorLayerFeatureTypeList = vectorLayerFeatureTypeList; + + this._lizmap3 = lizmap3; + this._lizmap3LocateByLayerConfig = lizmap3.config.locateByLayer; + const locateBtn = document.getElementById('button-locate'); - if (mainLizmap.initialConfig.locateByLayer) { + if (locateByLayer) { this.addLocateByLayer(); document.querySelector('#mapmenu .locate').classList.add('active') document.getElementById('locate').classList.remove('hide') @@ -30,18 +41,19 @@ export default class LocateByLayer { addLocateByLayer() { var locateByLayerList = []; - for (var lname in this._locateByLayerConfig) { - if ('order' in this._locateByLayerConfig[lname]) - locateByLayerList[this._locateByLayerConfig[lname].order] = lname; - else + for (var lname in this._lizmap3LocateByLayerConfig) { + if ('order' in this._lizmap3LocateByLayerConfig[lname]){ + locateByLayerList[this._lizmap3LocateByLayerConfig[lname].order] = lname; + } else { locateByLayerList.push(lname); + } } var locateContent = []; for (var l in locateByLayerList) { var lname = locateByLayerList[l]; - var lConfig = lizMap.config.layers[lname]; + var lConfig = this._lizmap3.config.layers[lname]; var html = '
'; - html += ''; html += ''; html += ''; html += '
'; @@ -50,22 +62,22 @@ export default class LocateByLayer { } $('#locate .menu-content').html(locateContent.join('
')); - var featureTypes = lizMap.mainLizmap.initialConfig.vectorLayerFeatureTypeList; + var featureTypes = this._vectorLayerFeatureTypeList; if (featureTypes.length == 0) { - this._locateByLayerConfig = {}; + this._lizmap3LocateByLayerConfig = {}; $('#button-locate').parent().remove(); $('#locate-menu').remove(); } else { for (const featureType of featureTypes) { var typeName = featureType.Name; - var lname = lizMap.getNameByTypeName(typeName); + var lname = this._lizmap3.getNameByTypeName(typeName); if (!lname) { - if (typeName in this._locateByLayerConfig) + if (typeName in this._lizmap3LocateByLayerConfig) lname = typeName - else if ((typeName in shortNameMap) && (shortNameMap[typeName] in this._locateByLayerConfig)) + else if ((typeName in shortNameMap) && (shortNameMap[typeName] in this._lizmap3LocateByLayerConfig)) lname = shortNameMap[typeName]; else { - for (var lbl in this._locateByLayerConfig) { + for (var lbl in this._lizmap3LocateByLayerConfig) { if (lbl.split(' ').join('_') == typeName) { lname = lbl; break; @@ -74,25 +86,22 @@ export default class LocateByLayer { } } - if (!(lname in this._locateByLayerConfig)) + if (!(lname in this._lizmap3LocateByLayerConfig)) continue; - var locate = this._locateByLayerConfig[lname]; + var locate = this._lizmap3LocateByLayerConfig[lname]; locate['crs'] = featureType.SRS; - // loadProjDefinition(locate.crs, function () { - // new OpenLayers.Projection(locate.crs); - // }); locate['bbox'] = featureType.LatLongBoundingBox; } // get joins - for (var lName in this._locateByLayerConfig) { - var locate = this._locateByLayerConfig[lName]; + for (var lName in this._lizmap3LocateByLayerConfig) { + var locate = this._lizmap3LocateByLayerConfig[lName]; if ('vectorjoins' in locate && locate['vectorjoins'].length != 0) { var vectorjoin = locate['vectorjoins'][0]; locate['joinFieldName'] = vectorjoin['targetFieldName']; - for (var jName in this._locateByLayerConfig) { - var jLocate = this._locateByLayerConfig[jName]; + for (var jName in this._lizmap3LocateByLayerConfig) { + var jLocate = this._lizmap3LocateByLayerConfig[jName]; if (jLocate.layerId == vectorjoin.joinLayerId) { vectorjoin['joinLayer'] = jName; locate['joinLayer'] = jName; @@ -110,23 +119,23 @@ export default class LocateByLayer { } // get locate by layers features - for (var lname in this._locateByLayerConfig) { + for (var lname in this._lizmap3LocateByLayerConfig) { this.getLocateFeature(lname); } - $('.btn-locate-clear').click(function () { - lizMap.mainLizmap.map.clearHighlightFeatures(); + document.getElementById('locate-clear').addEventListener('click', () => { + this._lizmap3.mainLizmap.map.clearHighlightFeatures(); $('#locate select').val('-1'); $('div.locate-layer span > input').val(''); - if (lizMap.lizmapLayerFilterActive) { - lizMap.events.triggerEvent('lizmaplocatefeaturecanceled', - { 'featureType': lizMap.lizmapLayerFilterActive } + if (this._lizmap3.lizmapLayerFilterActive) { + this._lizmap3.events.triggerEvent('lizmaplocatefeaturecanceled', + { 'featureType': this._lizmap3.lizmapLayerFilterActive } ); } return false; }); - $('#locate-close').click(function () { + document.getElementById('locate-close').addEventListener('click', () => { $('.btn-locate-clear').click(); // deactivate locate and filter document.getElementById('button-locate')?.click(); return false; @@ -139,7 +148,7 @@ export default class LocateByLayer { * @param aName */ getLocateFeature(aName) { - var locate = this._locateByLayerConfig[aName]; + var locate = this._lizmap3LocateByLayerConfig[aName]; // get fields to retrieve var fields = ['geometry',locate.fieldName]; @@ -163,24 +172,18 @@ export default class LocateByLayer { } // Get WFS url and options - var getFeatureUrlData = lizMap.getVectorLayerWfsUrl( aName, null, null, 'extent' ); + var getFeatureUrlData = this._lizmap3.getVectorLayerWfsUrl( aName, null, null, 'extent' ); getFeatureUrlData['options']['PROPERTYNAME'] = fields.join(','); - var layerName = lizMap.cleanName(aName); + var layerName = this._lizmap3.cleanName(aName); // Get data - $.post( getFeatureUrlData['url'], getFeatureUrlData['options'], (data) => { - var lConfig = lizMap.config.layers[aName]; + $.post( getFeatureUrlData['url'], getFeatureUrlData['options'], data => { + var lConfig = this._lizmap3.config.layers[aName]; locate['features'] = {}; if ( !data.features ) data = JSON.parse(data); var features = data.features; - // if( locate.crs != 'EPSG:4326' && features.length != 0) { - // // load projection to be sure to have the definition - // loadProjDefinition( locate.crs, function() { - // locate.crs = 'EPSG:4326'; - // }); - // } if ('filterFieldName' in locate) { // create filter combobox for the layer @@ -296,7 +299,7 @@ export default class LocateByLayer { for (var i=0, len=filterjoins.length; i input').autocomplete('close'); if ( ('minLength' in locate) && locate.minLength > 0 ) $('#locate-layer-'+layerName).parent().addClass('no-toggle'); - if(lizMap.checkMobile()){ + if (this._lizmap3.checkMobile()) { // autocompletion items for locatebylayer feature $('div.locate-layer select').show(); $('span.custom-combobox').hide(); @@ -369,46 +372,46 @@ export default class LocateByLayer { */ zoomToLocateFeature(aName) { // clear highlight layer - lizMap.mainLizmap.map.clearHighlightFeatures(); + this._map.clearHighlightFeatures(); // get locate by layer val - var locate = this._locateByLayerConfig[aName]; - var layerName = lizMap.cleanName(aName); + var locate = this._lizmap3LocateByLayerConfig[aName]; + var layerName = this._lizmap3.cleanName(aName); var val = $('#locate-layer-'+layerName).val(); if (val == '-1') { // Trigger event - lizMap.events.triggerEvent('lizmaplocatefeaturecanceled', {'featureType': aName }); + this._lizmap3.events.triggerEvent('lizmaplocatefeaturecanceled', {'featureType': aName }); } else { // zoom to val const featGeoJSON = locate.features[val]; if( featGeoJSON.geometry){ const geom = (new GeoJSON()).readGeometry(featGeoJSON.geometry, { dataProjection: 'EPSG:4326', - featureProjection: lizMap.mainLizmap.projection + featureProjection: this._lizmap3.mainLizmap.projection }); // Show geometry if asked if (locate.displayGeom == 'True') { - var getFeatureUrlData = lizMap.getVectorLayerWfsUrl( aName, null, null, null ); + var getFeatureUrlData = this._lizmap3.getVectorLayerWfsUrl( aName, null, null, null ); getFeatureUrlData['options']['PROPERTYNAME'] = ['geometry',locate.fieldName].join(','); getFeatureUrlData['options']['FEATUREID'] = val; // Get data - $.post( getFeatureUrlData['url'], getFeatureUrlData['options'], function(data) { + $.post( getFeatureUrlData['url'], getFeatureUrlData['options'], data => { if ( !data.features ){ data = JSON.parse(data); } - lizMap.mainLizmap.map.setHighlightFeatures(data.features[0], "geojson"); - }).fail(function(){ - lizMap.mainLizmap.map.setHighlightFeatures(feat, "geojson"); + this._map.setHighlightFeatures(data.features[0], "geojson"); + }).fail(() => { + this._.map.setHighlightFeatures(feat, "geojson"); }); } // zoom to extent - lizMap.mainLizmap.map.zoomToGeometryOrExtent(geom); + this._map.zoomToGeometryOrExtent(geom); } var fid = val.split('.')[1]; // Trigger event - lizMap.events.triggerEvent('lizmaplocatefeaturechanged', + this._lizmap3.events.triggerEvent('lizmaplocatefeaturechanged', { 'featureType': aName, 'featureId': fid @@ -422,7 +425,7 @@ export default class LocateByLayer { * @param aName */ updateLocateFeatureList(aName) { - var locate = this._locateByLayerConfig[aName]; + var locate = this._lizmap3LocateByLayerConfig[aName]; // clone features reference var features = {}; for ( var fid in locate.features ) { @@ -430,7 +433,7 @@ export default class LocateByLayer { } // filter by filter field name if ('filterFieldName' in locate) { - var filterValue = $('#locate-layer-' + lizMap.cleanName(aName) + '-'+locate.filterFieldName).val(); + var filterValue = $('#locate-layer-' + this._lizmap3.cleanName(aName) + '-'+locate.filterFieldName).val(); if ( filterValue != '-1' ) { for (var fid in features) { var feat = features[fid]; @@ -446,9 +449,9 @@ export default class LocateByLayer { for ( var i=0, len =vectorjoins.length; i< len; i++) { var vectorjoin = vectorjoins[i]; var jName = vectorjoin.joinLayer; - if ( jName in this._locateByLayerConfig ) { - var jLocate = this._locateByLayerConfig[jName]; - var jVal = $('#locate-layer-' + lizMap.cleanName(jName)).val(); + if ( jName in this._lizmap3LocateByLayerConfig ) { + var jLocate = this._lizmap3LocateByLayerConfig[jName]; + var jVal = $('#locate-layer-' + this._lizmap3.cleanName(jName)).val(); if ( jVal == '-1' ) continue; var jFeat = jLocate.features[jVal]; for (var fid in features) { @@ -460,13 +463,13 @@ export default class LocateByLayer { } } // create the option list - const placeHolder = lizMap.config.layers[aName].title; + const placeHolder = this._lizmap3.config.layers[aName].title; var options = ''; for (var fid in features) { var feat = features[fid]; options += ''; } // add option list - $('#locate-layer-'+ lizMap.cleanName(aName)).html(options); + $('#locate-layer-'+ this._lizmap3.cleanName(aName)).html(options); } }; From 5078c0d0f3e39b92624d7654e91a0412bec3d420 Mon Sep 17 00:00:00 2001 From: nboisteault Date: Fri, 6 Dec 2024 11:41:11 +0100 Subject: [PATCH 8/9] Revert "Refactoring" This reverts commit 4cc973c9c91925cdb13bf303b60597b7e02ca527. --- assets/src/modules/Lizmap.js | 7 +- assets/src/modules/LocateByLayer.js | 135 ++++++++++++++-------------- 2 files changed, 67 insertions(+), 75 deletions(-) diff --git a/assets/src/modules/Lizmap.js b/assets/src/modules/Lizmap.js index 9ec4b55517..6152432872 100644 --- a/assets/src/modules/Lizmap.js +++ b/assets/src/modules/Lizmap.js @@ -168,12 +168,7 @@ export default class Lizmap { this.legend = new Legend(this.state.layerTree); this.search = new Search(this.map, this.lizmap3); this.tooltip = new Tooltip(); - this.locateByLayer = new LocateByLayer( - this.initialConfig.locateByLayer, - this.initialConfig.vectorLayerFeatureTypeList, - this.map, - this._lizmap3 - ); + this.locateByLayer = new LocateByLayer(); // Removed unusable button if (!this.config['printTemplates'] || this.config.printTemplates.length == 0 ) { diff --git a/assets/src/modules/LocateByLayer.js b/assets/src/modules/LocateByLayer.js index 85ba22f236..08cb23c613 100644 --- a/assets/src/modules/LocateByLayer.js +++ b/assets/src/modules/LocateByLayer.js @@ -6,6 +6,7 @@ * @license MPL-2.0 */ +import { mainLizmap } from '../modules/Globals.js'; import DOMPurify from 'dompurify'; import GeoJSON from 'ol/format/GeoJSON.js'; @@ -15,22 +16,10 @@ import GeoJSON from 'ol/format/GeoJSON.js'; * @name LocateByLayer */ export default class LocateByLayer { - /** - * Build the lizmap LocateByLayer instance - * @param {LocateByLayerConfig} locateByLayer - The lizmap locateByLayer config - * @param {WfsFeatureType[]} vectorLayerFeatureTypeList - The list of WFS feature type - * @param {Map} map - OpenLayers map - * @param {object} lizmap3 - The old lizmap object - */ - constructor(locateByLayer, vectorLayerFeatureTypeList, map, lizmap3) { - this._map = map; - this._vectorLayerFeatureTypeList = vectorLayerFeatureTypeList; - - this._lizmap3 = lizmap3; - this._lizmap3LocateByLayerConfig = lizmap3.config.locateByLayer; - + constructor() { + this._locateByLayerConfig = lizMap.config.locateByLayer; const locateBtn = document.getElementById('button-locate'); - if (locateByLayer) { + if (mainLizmap.initialConfig.locateByLayer) { this.addLocateByLayer(); document.querySelector('#mapmenu .locate').classList.add('active') document.getElementById('locate').classList.remove('hide') @@ -41,19 +30,18 @@ export default class LocateByLayer { addLocateByLayer() { var locateByLayerList = []; - for (var lname in this._lizmap3LocateByLayerConfig) { - if ('order' in this._lizmap3LocateByLayerConfig[lname]){ - locateByLayerList[this._lizmap3LocateByLayerConfig[lname].order] = lname; - } else { + for (var lname in this._locateByLayerConfig) { + if ('order' in this._locateByLayerConfig[lname]) + locateByLayerList[this._locateByLayerConfig[lname].order] = lname; + else locateByLayerList.push(lname); - } } var locateContent = []; for (var l in locateByLayerList) { var lname = locateByLayerList[l]; - var lConfig = this._lizmap3.config.layers[lname]; + var lConfig = lizMap.config.layers[lname]; var html = '
'; - html += ''; html += ''; html += ''; html += '
'; @@ -62,22 +50,22 @@ export default class LocateByLayer { } $('#locate .menu-content').html(locateContent.join('
')); - var featureTypes = this._vectorLayerFeatureTypeList; + var featureTypes = lizMap.mainLizmap.initialConfig.vectorLayerFeatureTypeList; if (featureTypes.length == 0) { - this._lizmap3LocateByLayerConfig = {}; + this._locateByLayerConfig = {}; $('#button-locate').parent().remove(); $('#locate-menu').remove(); } else { for (const featureType of featureTypes) { var typeName = featureType.Name; - var lname = this._lizmap3.getNameByTypeName(typeName); + var lname = lizMap.getNameByTypeName(typeName); if (!lname) { - if (typeName in this._lizmap3LocateByLayerConfig) + if (typeName in this._locateByLayerConfig) lname = typeName - else if ((typeName in shortNameMap) && (shortNameMap[typeName] in this._lizmap3LocateByLayerConfig)) + else if ((typeName in shortNameMap) && (shortNameMap[typeName] in this._locateByLayerConfig)) lname = shortNameMap[typeName]; else { - for (var lbl in this._lizmap3LocateByLayerConfig) { + for (var lbl in this._locateByLayerConfig) { if (lbl.split(' ').join('_') == typeName) { lname = lbl; break; @@ -86,22 +74,25 @@ export default class LocateByLayer { } } - if (!(lname in this._lizmap3LocateByLayerConfig)) + if (!(lname in this._locateByLayerConfig)) continue; - var locate = this._lizmap3LocateByLayerConfig[lname]; + var locate = this._locateByLayerConfig[lname]; locate['crs'] = featureType.SRS; + // loadProjDefinition(locate.crs, function () { + // new OpenLayers.Projection(locate.crs); + // }); locate['bbox'] = featureType.LatLongBoundingBox; } // get joins - for (var lName in this._lizmap3LocateByLayerConfig) { - var locate = this._lizmap3LocateByLayerConfig[lName]; + for (var lName in this._locateByLayerConfig) { + var locate = this._locateByLayerConfig[lName]; if ('vectorjoins' in locate && locate['vectorjoins'].length != 0) { var vectorjoin = locate['vectorjoins'][0]; locate['joinFieldName'] = vectorjoin['targetFieldName']; - for (var jName in this._lizmap3LocateByLayerConfig) { - var jLocate = this._lizmap3LocateByLayerConfig[jName]; + for (var jName in this._locateByLayerConfig) { + var jLocate = this._locateByLayerConfig[jName]; if (jLocate.layerId == vectorjoin.joinLayerId) { vectorjoin['joinLayer'] = jName; locate['joinLayer'] = jName; @@ -119,23 +110,23 @@ export default class LocateByLayer { } // get locate by layers features - for (var lname in this._lizmap3LocateByLayerConfig) { + for (var lname in this._locateByLayerConfig) { this.getLocateFeature(lname); } - document.getElementById('locate-clear').addEventListener('click', () => { - this._lizmap3.mainLizmap.map.clearHighlightFeatures(); + $('.btn-locate-clear').click(function () { + lizMap.mainLizmap.map.clearHighlightFeatures(); $('#locate select').val('-1'); $('div.locate-layer span > input').val(''); - if (this._lizmap3.lizmapLayerFilterActive) { - this._lizmap3.events.triggerEvent('lizmaplocatefeaturecanceled', - { 'featureType': this._lizmap3.lizmapLayerFilterActive } + if (lizMap.lizmapLayerFilterActive) { + lizMap.events.triggerEvent('lizmaplocatefeaturecanceled', + { 'featureType': lizMap.lizmapLayerFilterActive } ); } return false; }); - document.getElementById('locate-close').addEventListener('click', () => { + $('#locate-close').click(function () { $('.btn-locate-clear').click(); // deactivate locate and filter document.getElementById('button-locate')?.click(); return false; @@ -148,7 +139,7 @@ export default class LocateByLayer { * @param aName */ getLocateFeature(aName) { - var locate = this._lizmap3LocateByLayerConfig[aName]; + var locate = this._locateByLayerConfig[aName]; // get fields to retrieve var fields = ['geometry',locate.fieldName]; @@ -172,18 +163,24 @@ export default class LocateByLayer { } // Get WFS url and options - var getFeatureUrlData = this._lizmap3.getVectorLayerWfsUrl( aName, null, null, 'extent' ); + var getFeatureUrlData = lizMap.getVectorLayerWfsUrl( aName, null, null, 'extent' ); getFeatureUrlData['options']['PROPERTYNAME'] = fields.join(','); - var layerName = this._lizmap3.cleanName(aName); + var layerName = lizMap.cleanName(aName); // Get data - $.post( getFeatureUrlData['url'], getFeatureUrlData['options'], data => { - var lConfig = this._lizmap3.config.layers[aName]; + $.post( getFeatureUrlData['url'], getFeatureUrlData['options'], (data) => { + var lConfig = lizMap.config.layers[aName]; locate['features'] = {}; if ( !data.features ) data = JSON.parse(data); var features = data.features; + // if( locate.crs != 'EPSG:4326' && features.length != 0) { + // // load projection to be sure to have the definition + // loadProjDefinition( locate.crs, function() { + // locate.crs = 'EPSG:4326'; + // }); + // } if ('filterFieldName' in locate) { // create filter combobox for the layer @@ -299,7 +296,7 @@ export default class LocateByLayer { for (var i=0, len=filterjoins.length; i input').autocomplete('close'); if ( ('minLength' in locate) && locate.minLength > 0 ) $('#locate-layer-'+layerName).parent().addClass('no-toggle'); - if (this._lizmap3.checkMobile()) { + if(lizMap.checkMobile()){ // autocompletion items for locatebylayer feature $('div.locate-layer select').show(); $('span.custom-combobox').hide(); @@ -372,46 +369,46 @@ export default class LocateByLayer { */ zoomToLocateFeature(aName) { // clear highlight layer - this._map.clearHighlightFeatures(); + lizMap.mainLizmap.map.clearHighlightFeatures(); // get locate by layer val - var locate = this._lizmap3LocateByLayerConfig[aName]; - var layerName = this._lizmap3.cleanName(aName); + var locate = this._locateByLayerConfig[aName]; + var layerName = lizMap.cleanName(aName); var val = $('#locate-layer-'+layerName).val(); if (val == '-1') { // Trigger event - this._lizmap3.events.triggerEvent('lizmaplocatefeaturecanceled', {'featureType': aName }); + lizMap.events.triggerEvent('lizmaplocatefeaturecanceled', {'featureType': aName }); } else { // zoom to val const featGeoJSON = locate.features[val]; if( featGeoJSON.geometry){ const geom = (new GeoJSON()).readGeometry(featGeoJSON.geometry, { dataProjection: 'EPSG:4326', - featureProjection: this._lizmap3.mainLizmap.projection + featureProjection: lizMap.mainLizmap.projection }); // Show geometry if asked if (locate.displayGeom == 'True') { - var getFeatureUrlData = this._lizmap3.getVectorLayerWfsUrl( aName, null, null, null ); + var getFeatureUrlData = lizMap.getVectorLayerWfsUrl( aName, null, null, null ); getFeatureUrlData['options']['PROPERTYNAME'] = ['geometry',locate.fieldName].join(','); getFeatureUrlData['options']['FEATUREID'] = val; // Get data - $.post( getFeatureUrlData['url'], getFeatureUrlData['options'], data => { + $.post( getFeatureUrlData['url'], getFeatureUrlData['options'], function(data) { if ( !data.features ){ data = JSON.parse(data); } - this._map.setHighlightFeatures(data.features[0], "geojson"); - }).fail(() => { - this._.map.setHighlightFeatures(feat, "geojson"); + lizMap.mainLizmap.map.setHighlightFeatures(data.features[0], "geojson"); + }).fail(function(){ + lizMap.mainLizmap.map.setHighlightFeatures(feat, "geojson"); }); } // zoom to extent - this._map.zoomToGeometryOrExtent(geom); + lizMap.mainLizmap.map.zoomToGeometryOrExtent(geom); } var fid = val.split('.')[1]; // Trigger event - this._lizmap3.events.triggerEvent('lizmaplocatefeaturechanged', + lizMap.events.triggerEvent('lizmaplocatefeaturechanged', { 'featureType': aName, 'featureId': fid @@ -425,7 +422,7 @@ export default class LocateByLayer { * @param aName */ updateLocateFeatureList(aName) { - var locate = this._lizmap3LocateByLayerConfig[aName]; + var locate = this._locateByLayerConfig[aName]; // clone features reference var features = {}; for ( var fid in locate.features ) { @@ -433,7 +430,7 @@ export default class LocateByLayer { } // filter by filter field name if ('filterFieldName' in locate) { - var filterValue = $('#locate-layer-' + this._lizmap3.cleanName(aName) + '-'+locate.filterFieldName).val(); + var filterValue = $('#locate-layer-' + lizMap.cleanName(aName) + '-'+locate.filterFieldName).val(); if ( filterValue != '-1' ) { for (var fid in features) { var feat = features[fid]; @@ -449,9 +446,9 @@ export default class LocateByLayer { for ( var i=0, len =vectorjoins.length; i< len; i++) { var vectorjoin = vectorjoins[i]; var jName = vectorjoin.joinLayer; - if ( jName in this._lizmap3LocateByLayerConfig ) { - var jLocate = this._lizmap3LocateByLayerConfig[jName]; - var jVal = $('#locate-layer-' + this._lizmap3.cleanName(jName)).val(); + if ( jName in this._locateByLayerConfig ) { + var jLocate = this._locateByLayerConfig[jName]; + var jVal = $('#locate-layer-' + lizMap.cleanName(jName)).val(); if ( jVal == '-1' ) continue; var jFeat = jLocate.features[jVal]; for (var fid in features) { @@ -463,13 +460,13 @@ export default class LocateByLayer { } } // create the option list - const placeHolder = this._lizmap3.config.layers[aName].title; + const placeHolder = lizMap.config.layers[aName].title; var options = ''; for (var fid in features) { var feat = features[fid]; options += ''; } // add option list - $('#locate-layer-'+ this._lizmap3.cleanName(aName)).html(options); + $('#locate-layer-'+ lizMap.cleanName(aName)).html(options); } }; From b6a567b21ef24e1601b6b2a6dcaae807c928f50e Mon Sep 17 00:00:00 2001 From: nboisteault Date: Fri, 6 Dec 2024 12:54:57 +0100 Subject: [PATCH 9/9] Activate locateByLayer by default in Lizmap 3.9 Activation is different than is master as we now use CSS --- assets/src/modules/LocateByLayer.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/src/modules/LocateByLayer.js b/assets/src/modules/LocateByLayer.js index 08cb23c613..45337eaee9 100644 --- a/assets/src/modules/LocateByLayer.js +++ b/assets/src/modules/LocateByLayer.js @@ -21,8 +21,9 @@ export default class LocateByLayer { const locateBtn = document.getElementById('button-locate'); if (mainLizmap.initialConfig.locateByLayer) { this.addLocateByLayer(); - document.querySelector('#mapmenu .locate').classList.add('active') - document.getElementById('locate').classList.remove('hide') + document.querySelector('#mini-dock-content .active').classList.remove('active'); + document.querySelector('#mapmenu .locate').classList.add('active'); + document.getElementById('locate').classList.add('active'); } else { locateBtn?.parentNode.classList.add('hide'); }