Commit 12d93102 authored by Pedro Eduardo Trujillo's avatar Pedro Eduardo Trujillo
Browse files

Refactoriza gestión de widgets de Leaflet

Separa la definición y configuración de aquellos widgets de Leaflet que
necesitan más lógica, para evitar mezclar problemáticas propias de cada
uno en un lugar común.

Resuelve asuntos relativos a widgets en su lugar, sin interferir en la
implementación general de Leaflet.

Mejora proceso de instancia de leaflet-measure, evitando usar deferred y
manipulando nodos de botón en su lugar, permitiendo que los siguientes
widgets se instancien sin esperar por él.

Soluciona bug antiguo de miniMap, el parche que se aplicó ya no es
necesario.
parent 9bbfe2ad
Loading
Loading
Loading
Loading
+2 −6
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ define([

			this.map.on("layeradd", lang.hitch(this, this._onLayerAdd));
			this.map.on("layerremove", lang.hitch(this, this._onLayerRemove));
			this.map.on("baselayerchange", lang.hitch(this, this._onBaseLayerChangedFromControl));
			this.map.on("baselayerchange", lang.hitch(this, this._onBaseLayerChange));
			this.map.on("zoomend", lang.hitch(this, this._groupEventArgs, 'ZOOM_END'));
			this.map.on("moveend", lang.hitch(this, this._groupEventArgs, 'PAN'));
			this.map.on("click", lang.hitch(this, this._onMapClick));
@@ -122,7 +122,7 @@ define([

		_onMapClick: function(evt) {

			!this._clickDisabled && this._emitEvt('CLICK', {
			this._emitEvt('CLICK', {
				latLng: evt.latlng,
				zoom: this.getZoom(),
				bbox: this.getBounds(),
@@ -234,10 +234,6 @@ define([
			}

			this.map.invalidateSize();

			if (this.miniMap && this.miniMapInstance) {
				this.miniMapInstance.addTo(this.map);
			}
		},

		hasLayer: function(layer) {
+11 −161
Original line number Diff line number Diff line
define([
	'dojo/_base/declare'
	, 'dojo/_base/lang'
	, 'dojo/_base/kernel'
	, 'dojo/Deferred'
	, 'dojo/dom-class'
	, 'dojo/on'
	, 'leaflet'
	, 'L-miniMap'
	, 'src/component/map/widget/_LeafletLayersSelector'
	, 'src/component/map/widget/_LeafletMeasureTools'
	, 'src/component/map/widget/_LeafletMiniMap'
	, 'src/component/map/widget/_LeafletTimeDimension'

	, 'awesome-markers'
	, 'L-coordinates'
@@ -14,15 +13,14 @@ define([
], function(
	declare
	, lang
	, kernel
	, Deferred
	, domClass
	, on
	, L
	, MiniMap
	, _LeafletLayersSelector
	, _LeafletMeasureTools
	, _LeafletMiniMap
	, _LeafletTimeDimension
) {

	return declare(null, {
	return declare([_LeafletLayersSelector, _LeafletMeasureTools, _LeafletMiniMap, _LeafletTimeDimension], {
		//	summary:
		//		Incluye y configura widgets para Leaflet.
		//	description:
@@ -32,40 +30,20 @@ define([

			this.config = {
				zoomControl: true,
				layersSelector: true,
				coordinatesViewer: true,
				navBar: true,
				miniMap: true,
				scaleBar: true,
				measureTools: true
				scaleBar: true
			};

			lang.mixin(this, this.config, args);

			this._createNeededFromStartWidgets();
		},

		_createNeededFromStartWidgets: function() {

			if (this.layersSelector) {
				this._layersSelectorInstance = L.control.layers();
			}
		},

		_addMapWidgets: function() {

			this._addZoomControl();
			this._addLayersSelector();
			this._addCoordinatesViewer();
			this._addNavBar();

			var measureToolsDfd = new Deferred();
			measureToolsDfd.then(lang.hitch(this, function() {

				this._addMiniMap();
			this._addScaleBar();
			}));
			this._addMeasureTools(measureToolsDfd);
		},

		_addZoomControl: function() {
@@ -80,16 +58,6 @@ define([
			}).addTo(this.map);
		},

		_addLayersSelector: function() {

			if (!this._layersSelectorInstance) {
				return;
			}

			this._layersSelectorInstance.addTo(this.map);
			domClass.add(this._layersSelectorInstance._container.firstChild, 'fa-globe');
		},

		_addCoordinatesViewer: function() {

			if (!this.coordinatesViewer) {
@@ -127,86 +95,6 @@ define([
			}).addTo(this.map);
		},

		_addMiniMap: function() {

			if (!this.miniMap) {
				return;
			}

			var baseLayer = this._getStaticLayerInstance('eoc-map');

			var miniMapConfig = {
				position: 'topright',
				collapsedWidth: 28,
				collapsedHeight: 28,
				toggleDisplay: true,
				minimized: true,
				strings: {
					showText: this.i18n.miniMapShowText,
					hideText: this.i18n.miniMapHideText
				}
			};

			var miniMap = new MiniMap(baseLayer, miniMapConfig);
			miniMap.addTo(this.map);

			// TODO workaround for https://github.com/Norkart/Leaflet-MiniMap/issues/114
			on(miniMap._miniMap._container, 'click', function(evt) { evt.stopPropagation(); });

			this.miniMapInstance = miniMap;
		},

		_addMeasureTools: function(dfd) {

			if (!this.measureTools) {
				dfd.resolve();
				return;
			}

			var measureToolsPath = 'leaflet-measure/leaflet-measure.' + kernel.locale;

			require([measureToolsPath], lang.hitch(this, this._onMeasureToolsLoaded, dfd));

			this.map.on('measurestart', lang.hitch(this, function() {

				this._clickDisabled = true;
			}));

			this.map.on('measurefinish', lang.hitch(this, function() {

				this._clickDisabled = false;
			}));
		},

		_onMeasureToolsLoaded: function(dfd) {

			// TODO workaround >= v1.8 https://github.com/ljagis/leaflet-measure/issues/171#issuecomment-1137483548
			L.Control.Measure.include({
				// set icon on the capture marker
				_setCaptureMarkerIcon: function () {
					// disable autopan
					this._captureMarker.options.autoPanOnFocus = false;

					// default function
					this._captureMarker.setIcon(
						L.divIcon({
							iconSize: this._map.getSize().multiplyBy(2)
						})
					);
				},
			});

			new L.Control.Measure({
				position: 'topright',
				primaryLengthUnit: 'meters',
				secondaryLengthUnit: 'kilometers',
				primaryAreaUnit: 'sqmeters',
				secondaryAreaUnit: 'hectares'
			}).addTo(this.map);

			dfd.resolve();
		},

		_addScaleBar: function() {

			if (!this.scaleBar) {
@@ -217,44 +105,6 @@ define([
				position: 'bottomright',
				imperial: false
			}).addTo(this.map);
		},

		_addLayerToSelector: function(layer, label, optional) {

			if (!this._layersSelectorInstance) {
				return;
			}

			var addMethod = !optional ? 'addBaseLayer' : 'addOverlay',
				layerLabel = this.i18n[label] || label;

			this._layersSelectorInstance[addMethod](layer, layerLabel);
		},

		_removeLayerFromSelector: function(layer) {

			if (!this._layersSelectorInstance) {
				return;
			}

			this._layersSelectorInstance.removeLayer(layer);
		},

		_onBaseLayerChangedFromControl: function(evt) {

			var layerInstance = evt.layer,
				layerId = layerInstance._leaflet_id;

			this._setLayerZIndex(layerInstance, 0);

			this._emitEvt('TRACK', {
				type: TRACK.type.event,
				info: {
					category: TRACK.category.layer,
					action: TRACK.action.click,
					label: 'Basemap changed: ' + layerId
				}
			});
		}
	});
});
+88 −0
Original line number Diff line number Diff line
define([
	'dojo/_base/declare'
	, 'dojo/_base/lang'
	, 'dojo/dom-class'
	, 'dojo/aspect'
	, 'leaflet'
], function(
	declare
	, lang
	, domClass
	, aspect
	, L
) {

	return declare(null, {
		//	summary:
		//		Incluye y configura widget selector de capas para Leaflet y prepara callbacks relacionados con la
		//		gestión de capas.

		constructor: function(args) {

			this.config = {
				layersSelector: true
			};

			lang.mixin(this, this.config, args);

			if (this.layersSelector) {
				this._layersSelectorInstance = L.control.layers();
			}

			aspect.before(this, '_addMapWidgets', lang.hitch(this, this._addLayersSelectorMapWidgets));
		},

		_addLayersSelectorMapWidgets: function() {

			if (!this.layersSelector || !this._layersSelectorInstance) {
				return;
			}

			this._addLayersSelector();
		},

		_addLayersSelector: function() {

			this._layersSelectorInstance.addTo(this.map);
			domClass.add(this._layersSelectorInstance._container.firstChild, 'fa-globe');
		},

		_addLayerToSelector: function(layer, label, optional) {

			if (!this._layersSelectorInstance) {
				return;
			}

			var addMethod = !optional ? 'addBaseLayer' : 'addOverlay',
				layerLabel = this.i18n[label] || label;

			this._layersSelectorInstance[addMethod](layer, layerLabel);
		},

		_removeLayerFromSelector: function(layer) {

			if (!this._layersSelectorInstance) {
				return;
			}

			this._layersSelectorInstance.removeLayer(layer);
		},

		_onBaseLayerChange: function(evt) {

			var layerInstance = evt.layer,
				layerId = layerInstance._leaflet_id;

			this._setLayerZIndex(layerInstance, 0);

			this._emitEvt('TRACK', {
				type: TRACK.type.event,
				info: {
					category: TRACK.category.layer,
					action: TRACK.action.click,
					label: 'Basemap changed: ' + layerId
				}
			});
		}
	});
});
+107 −0
Original line number Diff line number Diff line
define([
	'dojo/_base/declare'
	, 'dojo/_base/kernel'
	, 'dojo/_base/lang'
	, 'dojo/aspect'
	, 'leaflet'
	, 'put-selector'
], function(
	declare
	, kernel
	, lang
	, aspect
	, L
	, put
) {

	return declare(null, {
		//	summary:
		//		Incluye y configura widget leaflet-measure para Leaflet.

		constructor: function(args) {

			this.config = {
				measureTools: true
			};

			lang.mixin(this, this.config, args);

			aspect.before(this, '_addMapWidgets', lang.hitch(this, this._addMeasureToolsMapWidgets));
		},

		_addMeasureToolsMapWidgets: function() {

			if (!this.measureTools) {
				return;
			}

			this._addMeasureTools();
		},

		_addMeasureTools: function() {

			var measureToolsPath = 'leaflet-measure/leaflet-measure.' + kernel.locale;

			require([measureToolsPath], lang.hitch(this, this._onMeasureToolsLoaded));

			this.map.on('measurestart', lang.hitch(this, this._onLeafletMeasureStart));
			this.map.on('measurefinish', lang.hitch(this, this._onLeafletMeasureFinish));
		},

		_onMeasureToolsLoaded: function() {

			this._applyAutoJumpIssuePatch();

			var measureTools = new L.Control.Measure({
				position: 'topright',
				primaryLengthUnit: 'meters',
				secondaryLengthUnit: 'kilometers',
				primaryAreaUnit: 'sqmeters',
				secondaryAreaUnit: 'hectares'
			}).addTo(this.map);

			this._reorderMeasureToolsMapButton(measureTools._container);
		},

		_applyAutoJumpIssuePatch: function() {

			// TODO workaround >= v1.8 https://github.com/ljagis/leaflet-measure/issues/171#issuecomment-1137483548
			L.Control.Measure.include({
				// set icon on the capture marker
				_setCaptureMarkerIcon: function () {
					// disable autopan
					this._captureMarker.options.autoPanOnFocus = false;

					// default function
					this._captureMarker.setIcon(
						L.divIcon({
							iconSize: this._map.getSize().multiplyBy(2)
						})
					);
				},
			});
		},

		_reorderMeasureToolsMapButton: function(buttonContainerNode) {

			var controlsNode = buttonContainerNode.parentNode,
				childControlNodes = Array.from(controlsNode.children),
				desiredPreviousControlNode = childControlNodes.find(function(childNode) {

					return childNode.firstChild.title === 'Layers';
				}) || controlsNode.children[0];

			if (desiredPreviousControlNode) {
				put(desiredPreviousControlNode, '+', buttonContainerNode);
			}
		},

		_onLeafletMeasureStart: function(evt) {

		},

		_onLeafletMeasureFinish: function(evt) {

		}
	});
});
+67 −0
Original line number Diff line number Diff line
define([
	'dojo/_base/declare'
	, 'dojo/_base/lang'
	, 'dojo/aspect'
	, 'L-miniMap'
], function(
	declare
	, lang
	, aspect
	, MiniMap
) {

	return declare(null, {
		//	summary:
		//		Incluye y configura widget Leaflet-MiniMap para Leaflet.

		constructor: function(args) {

			this.config = {
				miniMap: true
			};

			lang.mixin(this, this.config, args);

			aspect.after(this, '_addMapWidgets', lang.hitch(this, this._addMiniMapMapWidgets));
			aspect.after(this, 'invalidateSize', lang.hitch(this, this._miniMapInvalidateSize));
		},

		_addMiniMapMapWidgets: function() {

			if (!this.miniMap) {
				return;
			}

			this._addMiniMap();
		},

		_addMiniMap: function() {

			var baseLayer = this._getStaticLayerInstance('eoc-map');

			var miniMapConfig = {
				position: 'topright',
				collapsedWidth: 28,
				collapsedHeight: 28,
				toggleDisplay: true,
				minimized: true,
				strings: {
					showText: this.i18n.miniMapShowText,
					hideText: this.i18n.miniMapHideText
				}
			};

			this._miniMapInstance = new MiniMap(baseLayer, miniMapConfig);
			this._miniMapInstance.addTo(this.map);
		},

		_miniMapInvalidateSize: function() {

			if (!this.miniMap || !this._miniMapInstance) {
				return;
			}

			this._miniMapInstance.addTo(this.map);
		}
	});
});