diff --git a/contribs/gmf/src/editing/Snapping.js b/contribs/gmf/src/editing/Snapping.js
index edfc1473028..d234b43a861 100644
--- a/contribs/gmf/src/editing/Snapping.js
+++ b/contribs/gmf/src/editing/Snapping.js
@@ -264,7 +264,7 @@ EditingSnappingService.prototype.registerTreeCtrl_ = function(treeCtrl) {
const uid = olUtilGetUid(treeCtrl);
const stateWatcherUnregister = this.rootScope_.$watch(
- () => treeCtrl.getState(),
+ () => this.isSnappingActiveForTreeCtrl_(treeCtrl),
this.handleTreeCtrlStateChange_.bind(this, treeCtrl)
);
@@ -287,7 +287,7 @@ EditingSnappingService.prototype.registerTreeCtrl_ = function(treeCtrl) {
};
// This extra call is to initialize the treeCtrl with its current state
- this.handleTreeCtrlStateChange_(treeCtrl, treeCtrl.getState());
+ this.handleTreeCtrlStateChange_(treeCtrl, this.isSnappingActiveForTreeCtrl_(treeCtrl));
}
}
};
@@ -410,7 +410,30 @@ EditingSnappingService.prototype.getWFSConfig_ = function(treeCtrl) {
/**
* @param {import("ngeo/layertree/Controller.js").LayertreeController} treeCtrl The layer tree controller
- * @param {string|undefined} newVal New state value
+ * @return {boolean} True if state is on and snapping is activated for that layer.
+ * @private
+ */
+EditingSnappingService.prototype.isSnappingActiveForTreeCtrl_ = function(treeCtrl) {
+ // Note: a snappable treeCtrl can only be a leaf, therefore the only possible
+ // states are: 'on' and 'off'.
+ if (treeCtrl.getState() !== 'on') {
+ return false;
+ }
+ if (treeCtrl.properties.snapping !== undefined) {
+ if (typeof treeCtrl.properties.snapping !== 'boolean') {
+ throw new Error('Wrong snappingActive type');
+ }
+ return treeCtrl.properties.snapping;
+ }
+ const node = /** @type {import('gmf/themes.js').GmfLayer} */ (treeCtrl.node);
+ const config = getSnappingConfig(node);
+ return config !== null && config.activated;
+};
+
+
+/**
+ * @param {import("ngeo/layertree/Controller.js").LayertreeController} treeCtrl The layer tree controller
+ * @param {boolean} newVal New value for the layer
* @private
*/
EditingSnappingService.prototype.handleTreeCtrlStateChange_ = function(treeCtrl, newVal) {
@@ -418,13 +441,7 @@ EditingSnappingService.prototype.handleTreeCtrlStateChange_ = function(treeCtrl,
const uid = olUtilGetUid(treeCtrl);
const item = this.cache_[uid];
- // Note: a snappable treeCtrl can only be a leaf, therefore the only possible
- // states are: 'on' and 'off'.
- if (newVal === 'on') {
- this.activateItem_(item);
- } else {
- this.deactivateItem_(item);
- }
+ newVal ? this.activateItem_(item) : this.deactivateItem_(item);
};
diff --git a/contribs/gmf/src/layertree/component.html b/contribs/gmf/src/layertree/component.html
index d41d8545919..99a267af1e0 100644
--- a/contribs/gmf/src/layertree/component.html
+++ b/contribs/gmf/src/layertree/component.html
@@ -118,6 +118,14 @@
title="{{'Currently editing this layer'|translate}}"
ng-if="layertreeCtrl.properties.editing">
+
+
+
diff --git a/contribs/gmf/src/layertree/component.js b/contribs/gmf/src/layertree/component.js
index 6a66ff80f40..4bcdaa195ea 100644
--- a/contribs/gmf/src/layertree/component.js
+++ b/contribs/gmf/src/layertree/component.js
@@ -8,7 +8,8 @@ import gmfLayertreeDatasourceGroupTreeComponent from 'gmf/layertree/datasourceGr
import gmfLayertreeSyncLayertreeMap from 'gmf/layertree/SyncLayertreeMap.js';
import gmfLayertreeTreeManager from 'gmf/layertree/TreeManager.js';
-import gmfThemeThemes, {getNodeMinResolution, getNodeMaxResolution} from 'gmf/theme/Themes.js';
+import gmfThemeThemes,
+{getNodeMinResolution, getNodeMaxResolution, getSnappingConfig} from 'gmf/theme/Themes.js';
import ngeoDatasourceOGC, {ServerType} from 'ngeo/datasource/OGC.js';
import ngeoLayertreeComponent from 'ngeo/layertree/component.js';
@@ -156,6 +157,7 @@ function gmfLayertreeTemplate($element, $attrs, gmfLayertreeTemplate) {
* * `printLayers`: A WMS layer that will be used instead of the WMTS layers in the print.
* * `queryLayers`: The WMS layers used as references to query the WMTS layers. For WMTS layers.
* * `isExpanded`: Whether the layer group is expanded by default. For layer groups (only).
+ * * `snappingConfig`: Whether the layer is used for snapping.
*
* @htmlAttribute {import("ol/Map.js").default} gmf-layertree-map The map.
* @htmlAttribute {Object|undefined} gmf-layertree-dimensions Global dimensions object.
@@ -463,6 +465,7 @@ Controller.prototype.listeners = function(scope, treeCtrl) {
});
};
+
/**
* Toggle the state of treeCtrl's node.
* @param {import("ngeo/layertree/Controller.js").LayertreeController} treeCtrl ngeo layertree controller,
@@ -655,6 +658,34 @@ Controller.prototype.getScale_ = function() {
};
+/**
+ * Is snapping activated for this LayertreeController
+ * @param {import("ngeo/layertree/Controller.js").LayertreeController} treeCtrl ngeo layertree controller.
+ * @return {boolean} True if snapping is activated for that layer.
+ */
+Controller.prototype.isSnappingActivated = function(treeCtrl) {
+ if (treeCtrl.properties.snapping !== undefined) {
+ if (typeof treeCtrl.properties.snapping !== 'boolean') {
+ throw new Error('Wrong snappingActive type');
+ }
+ return treeCtrl.properties.snapping;
+ }
+ // Default to node.metadata.activated
+ const node = /** @type {import('gmf/themes.js').GmfLayer} */ (treeCtrl.node);
+ const config = getSnappingConfig(node);
+ return config != null && config.activated;
+};
+
+
+/**
+ * Toggle snapping for this LayertreeController.
+ * @param {import("ngeo/layertree/Controller.js").LayertreeController} treeCtrl ngeo layertree controller.
+ */
+Controller.prototype.toggleSnapping = function(treeCtrl) {
+ treeCtrl.properties.snapping = !this.isSnappingActivated(treeCtrl);
+};
+
+
/**
* Opens a openIframePopup with the content of the metadata url of a node.
* @param {import("ngeo/layertree/Controller.js").LayertreeController} treeCtrl ngeo layertree controller,
diff --git a/contribs/gmf/src/theme/Themes.js b/contribs/gmf/src/theme/Themes.js
index c5a059d4369..77fc20408fd 100644
--- a/contribs/gmf/src/theme/Themes.js
+++ b/contribs/gmf/src/theme/Themes.js
@@ -570,6 +570,10 @@ export function getFlatNodes(node, nodes) {
export function getSnappingConfig(node) {
const config = (node.metadata && node.metadata.snappingConfig !== undefined) ?
node.metadata.snappingConfig : null;
+ // config.activated default to true
+ if (config && config.activated === undefined) {
+ config.activated = true;
+ }
return config;
}
diff --git a/contribs/gmf/src/themes.js b/contribs/gmf/src/themes.js
index 530dbc3d422..b8f9a242325 100644
--- a/contribs/gmf/src/themes.js
+++ b/contribs/gmf/src/themes.js
@@ -233,6 +233,7 @@
/**
* @typedef {Object} GmfSnappingConfig
+ * @property {boolean} [activated=true] Determines whether the snapping on this layer is activated by default.
* @property {boolean} [edge=true] Determines whethers the edges of features from the node layer can be
* snapped or not.
* @property {number} [tolerance=10] The tolerance in pixels the snapping should occur for the node layer.