From 5c39ba0096f157e60d6d5a6ebb0953f13dd98f4f Mon Sep 17 00:00:00 2001 From: rldhont Date: Sat, 26 Aug 2023 15:39:03 +0200 Subject: [PATCH 1/5] JSDoc: The lizmap Map State --- assets/src/modules/state/Map.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/src/modules/state/Map.js b/assets/src/modules/state/Map.js index 2101825e89..a768ea358a 100644 --- a/assets/src/modules/state/Map.js +++ b/assets/src/modules/state/Map.js @@ -116,14 +116,14 @@ const mapStateProperties = { */ /** - * Class representing the map state + * Class representing the lizmap Map State * @class * @augments EventDispatcher */ export class MapState extends EventDispatcher { /** - * Creating the map state + * Create a lizmap Map State instance * @param {OptionsConfig} [options] - main configuration options * @param {string|undefined} [startupFeatures] - The features to highlight at startup in GeoJSON */ From 5a0cd6178efe95400711ff83d4e31e30a14b36e9 Mon Sep 17 00:00:00 2001 From: rldhont Date: Sat, 26 Aug 2023 15:46:00 +0200 Subject: [PATCH 2/5] [JavaScript] Remove mainLizmap from Map module --- assets/src/modules/Lizmap.js | 2 +- assets/src/modules/map.js | 141 +++++++++++++++++++---------------- 2 files changed, 79 insertions(+), 64 deletions(-) diff --git a/assets/src/modules/Lizmap.js b/assets/src/modules/Lizmap.js index e930e1ce98..e18c81387f 100644 --- a/assets/src/modules/Lizmap.js +++ b/assets/src/modules/Lizmap.js @@ -150,7 +150,7 @@ export default class Lizmap { // Create Lizmap modules this.permalink = new Permalink(); - this.map = new map(); + this.map = new map('newOlMap', this.initialConfig, this.serviceURL, this.state.map, this.state.baseLayers, this.state.rootMapGroup, this.lizmap3); this.edition = new Edition(this._lizmap3); this.featuresTable = new FeaturesTable(this.initialConfig, this.lizmap3); this.geolocation = new Geolocation(this.map, this.lizmap3); diff --git a/assets/src/modules/map.js b/assets/src/modules/map.js index 307b24d3a7..6696e24df5 100644 --- a/assets/src/modules/map.js +++ b/assets/src/modules/map.js @@ -5,10 +5,12 @@ * @license MPL-2.0 */ -import { mainLizmap, mainEventDispatcher } from './Globals.js'; +import { mainEventDispatcher } from './Globals.js'; import Utils from './Utils.js'; -import { BaseLayerTypes } from './config/BaseLayer.js'; -import { MapLayerLoadStatus, MapLayerState } from './state/MapLayer.js'; +import { Config } from './Config.js'; +import { MapState } from './state/Map.js'; +import { BaseLayersState, BaseLayerTypes } from './config/BaseLayer.js'; +import { MapLayerLoadStatus, MapLayerState, MapRootState } from './state/MapLayer.js'; import olMap from 'ol/Map.js'; import View from 'ol/View.js'; import { ADJUSTED_DPI } from '../utils/Constants.js'; @@ -41,15 +43,24 @@ import SingleWMSLayer from './SingleWMSLayer.js'; * @augments olMap */ export default class map extends olMap { - - constructor() { - const qgisProjectProjection = mainLizmap.projection; + /** + * Create the OpenLayers Map + * @param {string} mapTarget - The id of the container element for the OpenLayers Map + * @param {Config} initialConfig - The lizmap initial config instance + * @param {string} serviceURL - The lizmap service URL + * @param {MapState} mapState - The lizmap map state + * @param {BaseLayersState} baseLayersState - The lizmap base layers state + * @param {MapRootState} rootMapGroup - The lizmap root map group + * @param {object} lizmap3 - The old lizmap object + */ + constructor(mapTarget, initialConfig, serviceURL, mapState, baseLayersState, rootMapGroup, lizmap3) { + const qgisProjectProjection = lizmap3.map.getProjection(); const mapProjection = getProjection(qgisProjectProjection); // Get resolutions from OL2 map - let resolutions = mainLizmap.lizmap3.map.resolutions ? mainLizmap.lizmap3.map.resolutions : mainLizmap.lizmap3.map.baseLayer.resolutions; + let resolutions = lizmap3.map.resolutions ? lizmap3.map.resolutions : lizmap3.map.baseLayer.resolutions; if (resolutions == undefined) { - resolutions= [mainLizmap.lizmap3.map.resolution]; + resolutions= [lizmap3.map.resolution]; } // Remove duplicated values resolutions = [... new Set(resolutions)]; @@ -63,14 +74,16 @@ export default class map extends olMap { view: new View({ resolutions: resolutions, constrainResolution: true, - center: [mainLizmap.lizmap3.map.getCenter().lon, mainLizmap.lizmap3.map.getCenter().lat], + center: [lizmap3.map.getCenter().lon, lizmap3.map.getCenter().lat], projection: mapProjection, - extent: mainLizmap.lizmap3.map.restrictedExtent.toArray(), + extent: lizmap3.map.restrictedExtent.toArray(), constrainOnlyCenter: true // allow view outside the restricted extent when zooming }), - target: 'newOlMap' + target: mapTarget }); + this._lizmap3 = lizmap3; + this._initialConfig = initialConfig; this._newOlMap = true; // Zoom to box @@ -91,7 +104,7 @@ export default class map extends olMap { const pointResolution = getPointResolution(projection, view.getResolution(), view.getCenter(), projection.getUnits()); const pointScaleDenominator = pointResolution * inchesPerMeter * dpi; - mainLizmap.state.map.update({ + mapState.update({ 'type': 'map.state.changing', 'projection': projection.getCode(), 'center': [...view.getCenter()], @@ -113,8 +126,8 @@ export default class map extends olMap { // Respecting WMS max size const wmsMaxSize = [ - mainLizmap.initialConfig.options.wmsMaxWidth, - mainLizmap.initialConfig.options.wmsMaxHeight, + initialConfig.options.wmsMaxWidth, + initialConfig.options.wmsMaxHeight, ]; // Get pixel ratio, if High DPI is disabled do not use device pixel ratio @@ -126,7 +139,7 @@ export default class map extends olMap { ); this._customTileGrid = this._useCustomTileWms ? new TileGrid({ - extent: mainLizmap.lizmap3.map.restrictedExtent.toArray(), + extent: lizmap3.map.restrictedExtent.toArray(), resolutions: resolutions, tileSize: this.getSize().map((x, i) => { // Get the min value between the map size and the max size @@ -153,7 +166,7 @@ export default class map extends olMap { // Mapping between layers name and states used to construct the singleWMSLayer, if needed this._statesSingleWMSLayers = new Map(); - const layersCount = mainLizmap.state.rootMapGroup.countExplodedMapLayers(); + const layersCount = rootMapGroup.countExplodedMapLayers(); // Returns a layer or a layerGroup depending of the node type const createNode = (node, statesOlLayersandGroupsMap, overlayLayersAndGroups, metersPerUnit, WMSRatio) => { @@ -192,8 +205,8 @@ export default class map extends olMap { } /* Sometimes throw an Error and extent is not used let extent = node.layerConfig.extent; - if(node.layerConfig.crs !== "" && node.layerConfig.crs !== mainLizmap.projection){ - extent = transformExtent(extent, node.layerConfig.crs, mainLizmap.projection); + if(node.layerConfig.crs !== "" && node.layerConfig.crs !== qgisProjectProjection){ + extent = transformExtent(extent, node.layerConfig.crs, qgisProjectProjection); } */ @@ -212,7 +225,7 @@ export default class map extends olMap { if (result['Contents']['Layer']) { options = optionsFromCapabilities(result, { layer: node.wmsName, - matrixSet: mainLizmap.projection, + matrixSet: qgisProjectProjection, }); } @@ -226,7 +239,7 @@ export default class map extends olMap { }); } } else { - if(mainLizmap.state.map.singleWMSLayer){ + if(mapState.singleWMSLayer){ this._statesSingleWMSLayers.set(node.name,node); node.singleWMSLayer = true; return @@ -238,7 +251,7 @@ export default class map extends olMap { minResolution: minResolution, maxResolution: maxResolution, source: new TileWMS({ - url: useExternalAccess ? itemState.externalAccess.url : mainLizmap.serviceURL, + url: useExternalAccess ? itemState.externalAccess.url : serviceURL, serverType: 'qgis', tileGrid: this._customTileGrid, params: { @@ -264,7 +277,7 @@ export default class map extends olMap { minResolution: minResolution, maxResolution: maxResolution, source: new TileWMS({ - url: useExternalAccess ? itemState.externalAccess.url : mainLizmap.serviceURL, + url: useExternalAccess ? itemState.externalAccess.url : serviceURL, serverType: 'qgis', params: { LAYERS: useExternalAccess ? decodeURIComponent(itemState.externalAccess.layers) : node.wmsName, @@ -281,7 +294,7 @@ export default class map extends olMap { minResolution: minResolution, maxResolution: maxResolution, source: new ImageWMS({ - url: useExternalAccess ? itemState.externalAccess.url : mainLizmap.serviceURL, + url: useExternalAccess ? itemState.externalAccess.url : serviceURL, serverType: 'qgis', ratio: WMSRatio, hidpi: this._hidpi, @@ -345,9 +358,9 @@ export default class map extends olMap { const metersPerUnit = this.getView().getProjection().getMetersPerUnit(); - if(mainLizmap.state.layerTree.children.length){ + if(rootMapGroup.children.length){ this._overlayLayersGroup = createNode( - mainLizmap.state.rootMapGroup, + rootMapGroup, this._statesOlLayersandGroupsMap, this._overlayLayersAndGroups, metersPerUnit, @@ -380,7 +393,7 @@ export default class map extends olMap { this._hasEmptyBaseLayer = false; const baseLayers = []; - for (const baseLayerState of mainLizmap.state.baseLayers.getBaseLayers()) { + for (const baseLayerState of baseLayersState.getBaseLayers()) { let baseLayer; let layerMinResolution; let layerMaxResolution; @@ -477,7 +490,7 @@ export default class map extends olMap { const result = parser.read(lizMap.wmtsCapabilities); const options = optionsFromCapabilities(result, { layer: baseLayerState.itemState.wmsName, - matrixSet: mainLizmap.projection, + matrixSet: qgisProjectProjection, }); baseLayer = new TileLayer({ @@ -486,7 +499,7 @@ export default class map extends olMap { source: new WMTS(options) }); } else { - if(mainLizmap.state.map.singleWMSLayer){ + if(mapState.singleWMSLayer){ baseLayerState.singleWMSLayer = true; this._statesSingleWMSLayers.set(baseLayerState.name, baseLayerState); } else { @@ -496,7 +509,7 @@ export default class map extends olMap { minResolution: layerMinResolution, maxResolution: layerMaxResolution, source: new TileWMS({ - url: mainLizmap.serviceURL, + url: serviceURL, projection: qgisProjectProjection, serverType: 'qgis', tileGrid: this._customTileGrid, @@ -516,7 +529,7 @@ export default class map extends olMap { minResolution: layerMinResolution, maxResolution: layerMaxResolution, source: new ImageWMS({ - url: mainLizmap.serviceURL, + url: serviceURL, projection: qgisProjectProjection, serverType: 'qgis', ratio: this._WMSRatio, @@ -551,7 +564,7 @@ export default class map extends olMap { baseLayer.getSource().setAttributions(attribution); } - const visible = mainLizmap.initialConfig.baseLayers.startupBaselayerName === baseLayerState.name; + const visible = initialConfig.baseLayers.startupBaselayerName === baseLayerState.name; baseLayer.setProperties({ name: baseLayerState.name, @@ -565,7 +578,7 @@ export default class map extends olMap { baseLayers.push(baseLayer); if (visible && baseLayer.getSource().getProjection().getCode() !== qgisProjectProjection) { - this.getView().getProjection().setExtent(mainLizmap.lizmap3.map.restrictedExtent.toArray()); + this.getView().getProjection().setExtent(lizmap3.map.restrictedExtent.toArray()); } } @@ -609,7 +622,7 @@ export default class map extends olMap { })); // Sync new OL view with OL2 view - mainLizmap.lizmap3.map.events.on({ + lizmap3.map.events.on({ move: () => { this.syncNewOLwithOL2View(); } @@ -618,7 +631,7 @@ export default class map extends olMap { this.on('moveend', () => { this._dispatchMapStateChanged(); - if (!mainLizmap.newOlMap) { + if (!this._newOlMap) { lizMap.map.setCenter(undefined,this.getView().getZoom(), false, false); } }); @@ -650,34 +663,34 @@ export default class map extends olMap { if (source instanceof ImageWMS) { source.on('imageloadstart', event => { - const mapLayer = mainLizmap.state.rootMapGroup.getMapLayerByName(event.target.get('name')) + const mapLayer = rootMapGroup.getMapLayerByName(event.target.get('name')) mapLayer.loadStatus = MapLayerLoadStatus.Loading; }); source.on('imageloadend', event => { - const mapLayer = mainLizmap.state.rootMapGroup.getMapLayerByName(event.target.get('name')) + const mapLayer = rootMapGroup.getMapLayerByName(event.target.get('name')) mapLayer.loadStatus = MapLayerLoadStatus.Ready; }); source.on('imageloaderror', event => { - const mapLayer = mainLizmap.state.rootMapGroup.getMapLayerByName(event.target.get('name')) + const mapLayer = rootMapGroup.getMapLayerByName(event.target.get('name')) mapLayer.loadStatus = MapLayerLoadStatus.Error; }); } else if (source instanceof WMTS) { source.on('tileloadstart', event => { - const mapLayer = mainLizmap.state.rootMapGroup.getMapLayerByName(event.target.get('name')) + const mapLayer = rootMapGroup.getMapLayerByName(event.target.get('name')) mapLayer.loadStatus = MapLayerLoadStatus.Loading; }); source.on('tileloadend', event => { - const mapLayer = mainLizmap.state.rootMapGroup.getMapLayerByName(event.target.get('name')) + const mapLayer = rootMapGroup.getMapLayerByName(event.target.get('name')) mapLayer.loadStatus = MapLayerLoadStatus.Ready; }); source.on('tileloaderror', event => { - const mapLayer = mainLizmap.state.rootMapGroup.getMapLayerByName(event.target.get('name')) + const mapLayer = rootMapGroup.getMapLayerByName(event.target.get('name')) mapLayer.loadStatus = MapLayerLoadStatus.Error; }); } } - mainLizmap.state.rootMapGroup.addListener( + rootMapGroup.addListener( evt => { // if the layer is loaded ad single WMS, the visibility events are managed by the dedicated class if (this.isSingleWMSLayer(evt.name)) return; @@ -692,7 +705,7 @@ export default class map extends olMap { ['layer.visibility.changed', 'group.visibility.changed'] ); - mainLizmap.state.layersAndGroupsCollection.addListener( + rootMapGroup.addListener( evt => { // conservative control since the opacity events should not be fired for single WMS layers if (this.isSingleWMSLayer(evt.name)) return; @@ -707,7 +720,7 @@ export default class map extends olMap { ['layer.opacity.changed', 'group.opacity.changed'] ); - mainLizmap.state.rootMapGroup.addListener( + rootMapGroup.addListener( evt => { const stateOlLayerAndMap = this._statesOlLayersandGroupsMap.get(evt.name); if (!stateOlLayerAndMap) return; @@ -727,16 +740,16 @@ export default class map extends olMap { ['layer.symbol.checked.changed', 'layer.style.changed', 'layer.selection.token.changed', 'layer.filter.token.changed'] ); - mainLizmap.state.baseLayers.addListener( + baseLayersState.addListener( evt => { this.changeBaseLayer(evt.name); }, ['baselayers.selection.changed'] ); - mainLizmap.state.rootMapGroup.addListener( + rootMapGroup.addListener( evt => { - const extGroup = mainLizmap.state.rootMapGroup.children[0]; + const extGroup = rootMapGroup.children[0]; if (evt.name != extGroup.name) return; const extLayerGroup = new LayerGroup({ @@ -776,7 +789,7 @@ export default class map extends olMap { }, ['ext-group.added'] ); - mainLizmap.state.rootMapGroup.addListener( + rootMapGroup.addListener( evt => { const groups = this._overlayLayersGroup .getLayers() @@ -807,12 +820,12 @@ export default class map extends olMap { this.addToolLayer(this._highlightLayer); // Add startup features to map if any - const startupFeatures = mainLizmap.state.map.startupFeatures; + const startupFeatures = mapState.startupFeatures; if (startupFeatures) { this.setHighlightFeatures(startupFeatures, "geojson"); } - mainLizmap.state.map.addListener( + mapState.addListener( evt => { const view = this.getView(); const updateCenter = ('center' in evt && view.getCenter().filter((v, i) => {return evt['center'][i] != v}).length != 0); @@ -909,16 +922,17 @@ export default class map extends olMap { * @param {string|undefined} projection optional features projection */ addHighlightFeatures(features, format, projection) { + const qgisProjectProjection = this._lizmap3.map.getProjection(); let olFeatures; if (format === "geojson") { olFeatures = (new GeoJSON()).readFeatures(features, { dataProjection: projection, - featureProjection: mainLizmap.projection + featureProjection: qgisProjectProjection }); } else if (format === "wkt") { olFeatures = (new WKT()).readFeatures(features, { dataProjection: projection, - featureProjection: mainLizmap.projection + featureProjection: qgisProjectProjection }); } else { return; @@ -949,17 +963,17 @@ export default class map extends olMap { * @memberof Map */ syncNewOLwithOL2View(){ - const center = mainLizmap.lizmap3.map.getCenter() + const center = this._lizmap3.map.getCenter(); this.getView().animate({ center: [center.lon, center.lat], - zoom: mainLizmap.lizmap3.map.getZoom(), + zoom: this._lizmap3.map.getZoom(), duration: 50 }); } refreshOL2View() { // This refresh OL2 view and layers - mainLizmap.lizmap3.map.setCenter( + this._lizmap3.map.setCenter( this.getView().getCenter(), this.getView().getZoom() ); @@ -981,10 +995,11 @@ export default class map extends olMap { // If base layer projection is different from project projection // We must set the project extent to the View to reproject nicely - if (selectedBaseLayer?.getSource().getProjection().getCode() !== mainLizmap.projection) { - this.getView().getProjection().setExtent(mainLizmap.lizmap3.map.restrictedExtent.toArray()); + const qgisProjectProjection = this._lizmap3.map.getProjection(); + if (selectedBaseLayer?.getSource().getProjection().getCode() !== qgisProjectProjection) { + this.getView().getProjection().setExtent(this._lizmap3.map.restrictedExtent.toArray()); } else { - this.getView().getProjection().setExtent(getProjection(mainLizmap.projection).getExtent()); + this.getView().getProjection().setExtent(getProjection(qgisProjectProjection).getExtent()); } // Trigger legacy event @@ -1082,16 +1097,16 @@ export default class map extends olMap { */ zoomToGeometryOrExtent(geometryOrExtent, options) { const geometryType = geometryOrExtent.getType?.(); - if (geometryType && (mainLizmap.initialConfig.options.max_scale_lines_polygons || mainLizmap.initialConfig.options.max_scale_lines_polygons)) { + if (geometryType && (this._initialConfig.options.max_scale_lines_polygons || this._initialConfig.options.max_scale_lines_polygons)) { let maxScale; if (['Polygon', 'Linestring', 'MultiPolygon', 'MultiLinestring'].includes(geometryType)){ - maxScale = mainLizmap.initialConfig.options.max_scale_lines_polygons; + maxScale = this._initialConfig.options.max_scale_lines_polygons; } else if (geometryType === 'Point'){ - maxScale = mainLizmap.initialConfig.options.max_scale_points; + maxScale = this._initialConfig.options.max_scale_points; } - const resolution = mainLizmap.utils.getResolutionFromScale( + const resolution = Utils.getResolutionFromScale( maxScale, - mainLizmap.map.getView().getProjection().getMetersPerUnit() + this.getView().getProjection().getMetersPerUnit() ); if (!options?.minResolution) { if (!options) { @@ -1118,7 +1133,7 @@ export default class map extends olMap { lizMap.getLayerFeature(featureType, fid, feat => { const olFeature = (new GeoJSON()).readFeature(feat, { dataProjection: 'EPSG:4326', - featureProjection: mainLizmap.projection + featureProjection: this.getView().getProjection() }); this.zoomToGeometryOrExtent(olFeature.getGeometry(), options); }); From f12a95710051277d712d140fa367a3ff9840bd7e Mon Sep 17 00:00:00 2001 From: rldhont Date: Wed, 31 Jul 2024 18:20:16 +0200 Subject: [PATCH 3/5] [JavaScript] Remove mainLizmap from Digitizing module --- assets/src/modules/Digitizing.js | 85 +++++++++++++++++--------------- assets/src/modules/Lizmap.js | 2 +- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/assets/src/modules/Digitizing.js b/assets/src/modules/Digitizing.js index 42d87af71c..395855a1f3 100644 --- a/assets/src/modules/Digitizing.js +++ b/assets/src/modules/Digitizing.js @@ -4,7 +4,7 @@ * @copyright 2023 3Liz * @license MPL-2.0 */ -import { mainLizmap, mainEventDispatcher } from '../modules/Globals.js'; +import { mainEventDispatcher } from '../modules/Globals.js'; import { deepFreeze } from './config/Tools.js'; import { createEnum } from './utils/Enums.js'; import Utils from '../modules/Utils.js'; @@ -74,7 +74,10 @@ export const DigitizingTools = createEnum({ */ export class Digitizing { - constructor() { + constructor(map, lizmap3) { + + this._map = map; + this._lizmap3 = lizmap3; // defined a context to separate drawn features this._context = 'draw'; @@ -280,7 +283,7 @@ export class Digitizing { name: 'LizmapDigitizingDrawLayer' }); - mainLizmap.map.addToolLayer(this._drawLayer); + this._map.addToolLayer(this._drawLayer); // Constraint layer this._constraintLayer = new VectorLayer({ @@ -307,7 +310,7 @@ export class Digitizing { this._constraintLayer.setProperties({ name: 'LizmapDigitizingConstraintLayer' }); - mainLizmap.map.addToolLayer(this._constraintLayer); + this._map.addToolLayer(this._constraintLayer); // Constraints values this._distanceConstraint = 0; @@ -317,7 +320,7 @@ export class Digitizing { this.loadFeatureDrawnToMap(); // Disable drawing tool when measure tool is activated - mainLizmap.lizmap3.events.on({ + this._lizmap3.events.on({ minidockopened: (e) => { if (e.id == 'measure') { this.toolSelected = this._tools[0]; @@ -397,8 +400,8 @@ export class Digitizing { } this._isSaved = (localStorage.getItem(this._repoAndProjectString + '_' + this._context + '_drawLayer') !== null); this._measureTooltips.forEach((measureTooltip) => { - mainLizmap.map.removeOverlay(measureTooltip[0]); - mainLizmap.map.removeOverlay(measureTooltip[1]); + this._map.removeOverlay(measureTooltip[0]); + this._map.removeOverlay(measureTooltip[1]); this._measureTooltips.delete(measureTooltip); }); this._drawLayer.getSource().clear(); @@ -421,7 +424,7 @@ export class Digitizing { set toolSelected(tool) { if (this._tools.includes(tool)) { // Disable all tools - mainLizmap.map.removeInteraction(this._drawInteraction); + this._map.removeInteraction(this._drawInteraction); // If tool === 'deactivate' or current selected tool is selected again => deactivate if (tool === this._toolSelected || tool === this._tools[0]) { @@ -521,7 +524,7 @@ export class Digitizing { unByKey(this._listener); }); - mainLizmap.map.addInteraction(this._drawInteraction); + this._map.addInteraction(this._drawInteraction); this._toolSelected = tool; @@ -582,11 +585,11 @@ export class Digitizing { this.drawColor = this.featureDrawn[0].get('color'); } - mainLizmap.map.removeInteraction(this._drawInteraction); + this._map.removeInteraction(this._drawInteraction); - mainLizmap.map.addInteraction(this._translateInteraction); - mainLizmap.map.addInteraction(this._selectInteraction); - mainLizmap.map.addInteraction(this._modifyInteraction); + this._map.addInteraction(this._translateInteraction); + this._map.addInteraction(this._selectInteraction); + this._map.addInteraction(this._modifyInteraction); this.toolSelected = 'deactivate'; this.isErasing = false; @@ -597,9 +600,9 @@ export class Digitizing { } else { // Clear selection this._selectInteraction.getFeatures().clear(); - mainLizmap.map.removeInteraction(this._translateInteraction); - mainLizmap.map.removeInteraction(this._selectInteraction); - mainLizmap.map.removeInteraction(this._modifyInteraction); + this._map.removeInteraction(this._translateInteraction); + this._map.removeInteraction(this._selectInteraction); + this._map.removeInteraction(this._modifyInteraction); this.saveFeatureDrawn(); @@ -622,9 +625,9 @@ export class Digitizing { this.isEdited = false; this.isSplitting = false; - mainLizmap.map.addInteraction(this._transformInteraction); + this._map.addInteraction(this._transformInteraction); } else { - mainLizmap.map.removeInteraction(this._transformInteraction); + this._map.removeInteraction(this._transformInteraction); } mainEventDispatcher.dispatch('digitizing.rotate'); @@ -703,7 +706,7 @@ export class Digitizing { geometry: new Polygon(parser.write(geom).getCoordinates()) }); - // Add splitted polygon to vector layer + // Add splitted polygon to vector layer this._drawSource.addFeature(splitted_polygon); this._selectInteraction.getFeatures().push(splitted_polygon); }); @@ -732,11 +735,11 @@ export class Digitizing { } }); }); - mainLizmap.map.addInteraction(this._splitInteraction); + this._map.addInteraction(this._splitInteraction); } else { - mainLizmap.map.removeInteraction(this._splitInteraction); + this._map.removeInteraction(this._splitInteraction); } - + mainEventDispatcher.dispatch('digitizing.split'); } } @@ -757,7 +760,7 @@ export class Digitizing { this.isSplitting = false; this._erasingCallBack = event => { - const features = mainLizmap.map.getFeaturesAtPixel(event.pixel, { + const features = this._map.getFeaturesAtPixel(event.pixel, { layerFilter: layer => { return layer === this._drawLayer; }, @@ -781,10 +784,10 @@ export class Digitizing { } }; - mainLizmap.map.on('singleclick', this._erasingCallBack ); + this._map.on('singleclick', this._erasingCallBack ); mainEventDispatcher.dispatch('digitizing.erasingBegins'); } else { - mainLizmap.map.un('singleclick', this._erasingCallBack ); + this._map.un('singleclick', this._erasingCallBack ); mainEventDispatcher.dispatch('digitizing.erasingEnds'); } } @@ -824,8 +827,8 @@ export class Digitizing { if (totalOverlay) { this._measureTooltips.forEach((measureTooltip) => { if(measureTooltip[1] === totalOverlay){ - mainLizmap.map.removeOverlay(measureTooltip[0]); - mainLizmap.map.removeOverlay(measureTooltip[1]); + this._map.removeOverlay(measureTooltip[0]); + this._map.removeOverlay(measureTooltip[1]); this._measureTooltips.delete(measureTooltip); return; } @@ -1033,7 +1036,7 @@ export class Digitizing { * @returns {string} The formatted length. */ formatLength(geom) { - const length = getLength(geom, {projection: mainLizmap.map.getView().getProjection()}); + const length = getLength(geom, {projection: this._map.getView().getProjection()}); let output; if (length > 100) { output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km'; @@ -1049,7 +1052,7 @@ export class Digitizing { * @returns {string} Formatted area. */ formatArea(polygon) { - const area = getArea(polygon, {projection: mainLizmap.map.getView().getProjection()}); + const area = getArea(polygon, {projection: this._map.getView().getProjection()}); let output; if (area > 10000) { output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km2'; @@ -1131,8 +1134,8 @@ export class Digitizing { }); this._measureTooltips.add([segmentOverlay, totalOverlay]); - mainLizmap.map.addOverlay(segmentOverlay); - mainLizmap.map.addOverlay(totalOverlay); + this._map.addOverlay(segmentOverlay); + this._map.addOverlay(totalOverlay); } // Get SLD for featureDrawn[index] @@ -1242,8 +1245,8 @@ export class Digitizing { this.isSplitting = false; this._measureTooltips.forEach((measureTooltip) => { - mainLizmap.map.removeOverlay(measureTooltip[0]); - mainLizmap.map.removeOverlay(measureTooltip[1]); + this._map.removeOverlay(measureTooltip[0]); + this._map.removeOverlay(measureTooltip[1]); this._measureTooltips.delete(measureTooltip); }); this._drawSource.clear(); @@ -1365,7 +1368,7 @@ export class Digitizing { download(format) { if (this.featureDrawn) { const options = { - featureProjection: mainLizmap.projection, + featureProjection: this._lizmap3.map.getProjection(), dataProjection: 'EPSG:4326' }; if (format === 'geojson') { @@ -1428,7 +1431,7 @@ export class Digitizing { // return (e) => { // const buffershp = e.target.result; // shp(buffershp).then(response => { - // let OL6features = (new GeoJSON()).readFeatures(response, {featureProjection: mainLizmap.projection}); + // let OL6features = (new GeoJSON()).readFeatures(response, {featureProjection: this._lizmap3.map.getProjection()}); // if (OL6features) { // // Add imported features to map and zoom to their extent @@ -1448,7 +1451,7 @@ export class Digitizing { // Handle GeoJSON, GPX or KML strings try { const options = { - featureProjection: mainLizmap.projection + featureProjection: this._lizmap3.map.getProjection() }; // Check extension for format type if (['json', 'geojson'].includes(fileExtension)) { @@ -1491,10 +1494,10 @@ export class Digitizing { register(proj4); } - features = reprojAll(features, projFGB, mainLizmap.projection); + features = reprojAll(features, projFGB, this._lizmap3.map.getProjection()); } else { - lizMap.addMessage(lizDict["digitizing.import.metadata.error"] + " : " + - mainLizmap.projection + this._lizmap3.addMessage(lizDict["digitizing.import.metadata.error"] + " : " + + this._lizmap3.map.getProjection() , 'info' , true) } @@ -1502,7 +1505,7 @@ export class Digitizing { OL6features = features; } } catch (error) { - lizMap.addMessage(error, 'danger', true) + this._lizmap3.addMessage(error, 'danger', true) } if (OL6features) { @@ -1513,7 +1516,7 @@ export class Digitizing { const featuresGeometryCollection = new GeometryCollection(featuresGeometry); const extent = featuresGeometryCollection.getExtent(); - mainLizmap.map.getView().fit(extent); + this._map.getView().fit(extent); } }; })(this); diff --git a/assets/src/modules/Lizmap.js b/assets/src/modules/Lizmap.js index e18c81387f..3254cd80a0 100644 --- a/assets/src/modules/Lizmap.js +++ b/assets/src/modules/Lizmap.js @@ -155,7 +155,7 @@ export default class Lizmap { this.featuresTable = new FeaturesTable(this.initialConfig, this.lizmap3); this.geolocation = new Geolocation(this.map, this.lizmap3); this.geolocationSurvey = new GeolocationSurvey(this.geolocation, this.edition); - this.digitizing = new Digitizing(); + this.digitizing = new Digitizing(this.map, this.lizmap3); this.selectionTool = new SelectionTool(this.map, this.digitizing, this.initialConfig, this.lizmap3); this.snapping = new Snapping(); this.layers = new Layers(); From 56c0046f9f9ed276a2c44ca60b5334095bf00e92 Mon Sep 17 00:00:00 2001 From: rldhont Date: Wed, 31 Jul 2024 18:34:06 +0200 Subject: [PATCH 4/5] [JavaScript] Remove mainLizmap from Snapping module --- assets/src/modules/Lizmap.js | 2 +- assets/src/modules/Snapping.js | 69 +++++++++++++++++++++------------- 2 files changed, 43 insertions(+), 28 deletions(-) diff --git a/assets/src/modules/Lizmap.js b/assets/src/modules/Lizmap.js index 3254cd80a0..3709484a29 100644 --- a/assets/src/modules/Lizmap.js +++ b/assets/src/modules/Lizmap.js @@ -157,7 +157,7 @@ export default class Lizmap { this.geolocationSurvey = new GeolocationSurvey(this.geolocation, this.edition); this.digitizing = new Digitizing(this.map, this.lizmap3); this.selectionTool = new SelectionTool(this.map, this.digitizing, this.initialConfig, this.lizmap3); - this.snapping = new Snapping(); + this.snapping = new Snapping(this.edition, this.state.rootMapGroup, this.state.layerTree, this.lizmap3); this.layers = new Layers(); this.proxyEvents = new ProxyEvents(); this.wfs = new WFS(); diff --git a/assets/src/modules/Snapping.js b/assets/src/modules/Snapping.js index 64f5044650..b9d217491b 100644 --- a/assets/src/modules/Snapping.js +++ b/assets/src/modules/Snapping.js @@ -5,7 +5,10 @@ * @license MPL-2.0 */ -import { mainLizmap, mainEventDispatcher } from '../modules/Globals.js'; +import { mainEventDispatcher } from '../modules/Globals.js'; +import Edition from './Edition.js'; +import { MapRootState } from './state/MapLayer.js'; +import { TreeRootState } from './state/LayerTree.js'; /** * @class @@ -13,7 +16,19 @@ import { mainLizmap, mainEventDispatcher } from '../modules/Globals.js'; */ export default class Snapping { - constructor() { + /** + * Create a snapping instance + * @param {Edition} edition - The edition module + * @param {MapRootState} rootMapGroup - Root map group + * @param {TreeRootState} layerTree - Root tree layer group + * @param {object} lizmap3 - The old lizmap object + */ + constructor(edition, rootMapGroup, layerTree, lizmap3) { + + this._edition = edition; + this._rootMapGroup = rootMapGroup; + this._layerTree = layerTree; + this._lizmap3 = lizmap3; this._active = false; this._snapLayersRefreshable = false; @@ -38,16 +53,16 @@ export default class Snapping { }) }); - mainLizmap.lizmap3.map.addLayer(snapLayer); + this._lizmap3.map.addLayer(snapLayer); const snapControl = new OpenLayers.Control.Snapping({ - layer: mainLizmap.edition.editLayer, + layer: this._edition.editLayer, targets: [{ layer: snapLayer }] }); - mainLizmap.lizmap3.map.addControls([snapControl]); - mainLizmap.lizmap3.controls['snapControl'] = snapControl; + this._lizmap3.map.addControls([snapControl]); + this._lizmap3.controls['snapControl'] = snapControl; this._setSnapLayersRefreshable = () => { if(this._active){ @@ -92,10 +107,10 @@ export default class Snapping { mainEventDispatcher.addListener( () => { // Get snapping configuration for edited layer - for (const editionLayer in mainLizmap.config.editionLayers) { - if (mainLizmap.config.editionLayers.hasOwnProperty(editionLayer)) { - if (mainLizmap.config.editionLayers[editionLayer].layerId === mainLizmap.edition.layerId){ - const editionLayerConfig = mainLizmap.config.editionLayers[editionLayer]; + for (const editionLayer in this._lizmap3.config.editionLayers) { + if (this._lizmap3.config.editionLayers.hasOwnProperty(editionLayer)) { + if (this._lizmap3.config.editionLayers[editionLayer].layerId === this._edition.layerId){ + const editionLayerConfig = this._lizmap3.config.editionLayers[editionLayer]; if (editionLayerConfig.hasOwnProperty('snap_layers') && editionLayerConfig.snap_layers.length > 0){ this._snapLayers = [...editionLayerConfig.snap_layers]; @@ -128,10 +143,10 @@ export default class Snapping { if (this._config !== undefined){ // Configure snapping - const snapControl = mainLizmap.lizmap3.controls.snapControl; + const snapControl = this._lizmap3.controls.snapControl; // Set edition layer as main layer - snapControl.setLayer(mainLizmap.edition.editLayer); + snapControl.setLayer(this._edition.editLayer); snapControl.targets[0].node = this._config.snap_vertices; snapControl.targets[0].vertex = this._config.snap_intersections; @@ -141,8 +156,8 @@ export default class Snapping { snapControl.targets[0].edgeTolerance = this._config.snap_segments_tolerance; // Listen to moveend event and to layers visibility changes to able data refreshing - mainLizmap.lizmap3.map.events.register('moveend', this, this._setSnapLayersRefreshable); - mainLizmap.state.rootMapGroup.addListener( + this._lizmap3.map.events.register('moveend', this, this._setSnapLayersRefreshable); + this._rootMapGroup.addListener( this._setSnapLayersVisibility, ['layer.visibility.changed','group.visibility.changed'] ); @@ -155,12 +170,12 @@ export default class Snapping { mainEventDispatcher.addListener( () => { this.active = false; - mainLizmap.lizmap3.map.getLayersByName('snaplayer')[0].destroyFeatures(); + this._lizmap3.map.getLayersByName('snaplayer')[0].destroyFeatures(); this.config = undefined; // Remove listener to moveend event to layers visibility event - mainLizmap.lizmap3.map.events.unregister('moveend', this, this._setSnapLayersRefreshable); - mainLizmap.state.rootMapGroup.removeListener( + this._lizmap3.map.events.unregister('moveend', this, this._setSnapLayersRefreshable); + this._rootMapGroup.removeListener( this._setSnapLayersVisibility, ['layer.visibility.changed','group.visibility.changed'] ) @@ -171,7 +186,7 @@ export default class Snapping { getSnappingData () { // Empty snapping layer first - mainLizmap.lizmap3.map.getLayersByName('snaplayer')[0].destroyFeatures(); + this._lizmap3.map.getLayersByName('snaplayer')[0].destroyFeatures(); // filter only visible layers and toggled layers on the the snap list const currentSnapLayers = this._snapLayers.filter( @@ -181,7 +196,7 @@ export default class Snapping { // TODO : group aync calls with Promises for (const snapLayer of currentSnapLayers) { - lizMap.getFeatureData(mainLizmap.lizmap3.getLayerConfigById(snapLayer)[0], null, null, 'geom', this._restrictToMapExtent, null, this._maxFeatures, + lizMap.getFeatureData(this._lizmap3.getLayerConfigById(snapLayer)[0], null, null, 'geom', this._restrictToMapExtent, null, this._maxFeatures, (fName, fFilter, fFeatures) => { // Transform features @@ -195,7 +210,7 @@ export default class Snapping { const gFormat = new OpenLayers.Format.GeoJSON({ ignoreExtraDims: true, externalProjection: snapLayerCrs, - internalProjection: mainLizmap.projection + internalProjection: this._lizmap3.map.getProjection() }); const tfeatures = gFormat.read({ @@ -204,7 +219,7 @@ export default class Snapping { }); // Add features - mainLizmap.lizmap3.map.getLayersByName('snaplayer')[0].addFeatures(tfeatures); + this._lizmap3.map.getLayersByName('snaplayer')[0].addFeatures(tfeatures); }); } @@ -221,11 +236,11 @@ export default class Snapping { */ getLayerTreeVisibility(layerId){ let visible = false; - let layerConfig = mainLizmap.lizmap3.getLayerConfigById(layerId); + let layerConfig = this._lizmap3.getLayerConfigById(layerId); if(layerConfig && layerConfig[0]) { try { - visible = lizMap.mainLizmap.state.layerTree.getTreeLayerByName(layerConfig[0]).visibility + visible = this._layerTree.getTreeLayerByName(layerConfig[0]).visibility } catch( error){ visible = false } @@ -238,7 +253,7 @@ export default class Snapping { * @returns {string} the layer title or layer name */ getLayerTitle(layerId){ - let layerConfig = mainLizmap.lizmap3.getLayerConfigById(layerId); + let layerConfig = this._lizmap3.getLayerConfigById(layerId); if (layerConfig) { return layerConfig[1].title || layerConfig[1].name; } @@ -278,15 +293,15 @@ export default class Snapping { // (de)activate snap control if (this._active) { this.getSnappingData(); - mainLizmap.lizmap3.controls.snapControl.activate(); + this._lizmap3.controls.snapControl.activate(); } else { // Disable refresh button when snapping is inactive this.snapLayersRefreshable = false; - mainLizmap.lizmap3.controls.snapControl.deactivate(); + this._lizmap3.controls.snapControl.deactivate(); } // Set snap layer visibility - mainLizmap.lizmap3.map.getLayersByName('snaplayer')[0].setVisibility(this._active); + this._lizmap3.map.getLayersByName('snaplayer')[0].setVisibility(this._active); mainEventDispatcher.dispatch('snapping.active'); } From 8dc5a03f1ce3b26edb62ab8f778b78e9a48af341 Mon Sep 17 00:00:00 2001 From: rldhont Date: Wed, 31 Jul 2024 20:15:15 +0200 Subject: [PATCH 5/5] [JavaScript] Remove mainLizmap from Tooltip module --- assets/src/modules/Lizmap.js | 2 +- assets/src/modules/Tooltip.js | 38 ++++++++++++++++++++++------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/assets/src/modules/Lizmap.js b/assets/src/modules/Lizmap.js index 3709484a29..8b1e2b6ff4 100644 --- a/assets/src/modules/Lizmap.js +++ b/assets/src/modules/Lizmap.js @@ -167,7 +167,7 @@ export default class Lizmap { this.popup = new Popup(this.initialConfig, this.state, this.map, this.digitizing); this.legend = new Legend(this.state.layerTree); this.search = new Search(this.map, this.lizmap3); - this.tooltip = new Tooltip(); + this.tooltip = new Tooltip(this.map, this.initialConfig.tooltipLayers, this.lizmap3); this.locateByLayer = new LocateByLayer( this.initialConfig.locateByLayer, this.initialConfig.vectorLayerFeatureTypeList, diff --git a/assets/src/modules/Tooltip.js b/assets/src/modules/Tooltip.js index d3e17514be..27c4e1628e 100644 --- a/assets/src/modules/Tooltip.js +++ b/assets/src/modules/Tooltip.js @@ -4,7 +4,8 @@ * @copyright 2024 3Liz * @license MPL-2.0 */ -import { mainLizmap, mainEventDispatcher } from '../modules/Globals.js'; +import { mainEventDispatcher } from '../modules/Globals.js'; +import { TooltipLayersConfig } from './config/Tooltip.js'; import GeoJSON from 'ol/format/GeoJSON.js'; import VectorLayer from 'ol/layer/Vector.js'; import VectorSource from 'ol/source/Vector.js'; @@ -16,14 +17,23 @@ import { Circle, Fill, Stroke, Style } from 'ol/style.js'; */ export default class Tooltip { - constructor() { + /** + * Create the tooltip Map + * @param {Map} map - OpenLayers map + * @param {TooltipLayersConfig} tooltipLayersConfig - The config tooltipLayers + * @param {object} lizmap3 - The old lizmap object + */ + constructor(map, tooltipLayersConfig, lizmap3) { + this._map = map; + this._tooltipLayersConfig = tooltipLayersConfig; + this._lizmap3 = lizmap3; this._activeTooltipLayer; this._tooltipLayers = new Map(); } /** * Activate tooltip for a layer order - * @param {number} layerOrder + * @param {number} layerOrder a layer order */ activate(layerOrder) { if (layerOrder === "") { @@ -32,9 +42,9 @@ export default class Tooltip { } // Remove previous layer if any - mainLizmap.map.removeLayer(this._activeTooltipLayer); + this._map.removeLayer(this._activeTooltipLayer); - const layerTooltipCfg = mainLizmap.initialConfig.tooltipLayers.layerConfigs[layerOrder]; + const layerTooltipCfg = this._tooltipLayersConfig.layerConfigs[layerOrder]; const layerName = layerTooltipCfg.name; const tooltipLayer = this._tooltipLayers.get(layerName); this._displayGeom = layerTooltipCfg.displayGeom; @@ -115,7 +125,7 @@ export default class Tooltip { }); this._activeTooltipLayer.getSource().on('featuresloaderror', () => { - lizMap.addMessage(lizDict['tooltip.loading.error'], 'danger', true); + this._lizmap3.addMessage(lizDict['tooltip.loading.error'], 'danger', true); console.warn(`Tooltip layer '${layerName}' could not be loaded.`); }); @@ -124,14 +134,14 @@ export default class Tooltip { this._tooltipLayers.set(layerName, this._activeTooltipLayer); } - mainLizmap.map.addToolLayer(this._activeTooltipLayer); + this._map.addToolLayer(this._activeTooltipLayer); const tooltip = document.getElementById('tooltip'); let currentFeature; this._onPointerMove = event => { - const pixel = mainLizmap.map.getEventPixel(event.originalEvent); + const pixel = this._map.getEventPixel(event.originalEvent); const target = event.originalEvent.target; if (currentFeature) { @@ -146,7 +156,7 @@ export default class Tooltip { const feature = target.closest('.ol-control') ? undefined - : mainLizmap.map.forEachFeatureAtPixel(pixel, feature => { + : this._map.forEachFeatureAtPixel(pixel, feature => { return feature; // returning a truthy value stop detection }, { hitTolerance: 5, @@ -173,26 +183,26 @@ export default class Tooltip { currentFeature = feature; }; - mainLizmap.map.on('pointermove', this._onPointerMove); + this._map.on('pointermove', this._onPointerMove); this._onPointerLeave = () => { currentFeature = undefined; tooltip.style.visibility = 'hidden'; }; - mainLizmap.map.getTargetElement().addEventListener('pointerleave', this._onPointerLeave); + this._map.getTargetElement().addEventListener('pointerleave', this._onPointerLeave); } /** * Deactivate tooltip */ deactivate() { - mainLizmap.map.removeLayer(this._activeTooltipLayer); + this._map.removeLayer(this._activeTooltipLayer); if (this._onPointerMove) { - mainLizmap.map.un('pointermove', this._onPointerMove); + this._map.un('pointermove', this._onPointerMove); } if (this._onPointerLeave) { - mainLizmap.map.getTargetElement().removeEventListener('pointerleave', this._onPointerLeave); + this._map.getTargetElement().removeEventListener('pointerleave', this._onPointerLeave); } } }