src/pyams_gis/resources/js/pyams_gis.js
changeset 75 a430cc4ae715
parent 54 4ce98983666a
child 79 c038be682567
--- a/src/pyams_gis/resources/js/pyams_gis.js	Wed Jan 27 15:38:26 2021 +0100
+++ b/src/pyams_gis/resources/js/pyams_gis.js	Wed Jan 27 15:39:14 2021 +0100
@@ -44,64 +44,91 @@
 
 		init: function(context, options, callback) {
 			var map = context;
-			MyAMS.ajax.check(globals.L,
-							 '/--static--/pyams_gis/js/leaflet-1.0.3' + MyAMS.devext + '.js',
-							 function(first_load) {
-								if (first_load) {
-									L = globals.L;
-									L.Control.Layers.prototype._addItem = PyAMS_GIS._layersControlAddItem;
+			MyAMS.ajax.check([
+					globals.L
+				], [
+					'/--static--/pyams_gis/js/leaflet-1.7.1' + MyAMS.devext + '.js'
+				], function(first_load) {
+					var required = [];
+					if (first_load) {
+						L = globals.L;
+						L.Control.Layers.prototype._addItem = PyAMS_GIS._layersControlAddItem;
+						required.push(MyAMS.getScript('/--static--/pyams_gis/js/leaflet-gesture-handling-1.2.1' + MyAMS.devext + '.js'));
+						MyAMS.getCSS('/--static--/pyams_gis/css/leaflet-1.7.1' + MyAMS.devext + '.css', 'leaflet');
+						MyAMS.getCSS('/--static--/pyams_gis/css/leaflet-gesture-handling-1.2.1' + MyAMS.devext + '.css',
+							'leaflet-gesture-handling');
+					}
+					$.when.apply($, required).then(function() {
+
+						function createMap(config) {
+							var settings = {
+								preferCanvas: data.mapLeafletPreferCanvas || false,
+								attributionControl: data.mapLeafletAttributionControl === undefined ?
+									config.attributionControl :
+									data.mapLeafletAttributionControl,
+								zoomControl: data.mapLeafletZoomControl === undefined ?
+									config.zoomControl :
+									data.mapLeafletZoomControl,
+								crs: data.mapLeafletCrs || MyAMS.getObject(config.crs) || globals.L.CRS.EPSG3857,
+								center: data.mapLeafletCenter || config.center,
+								zoom: data.mapLeafletZoom || config.zoom,
+								gestureHandling: true
+							};
+							settings = $.extend({}, settings, options);
+							map.trigger('map.init', [map, settings, config]);
+							var leafmap = L.map(map.attr('id'), settings);
+							var layersConfig = [];
+							if (config.layers) {
+								for (var idx = 0; idx < config.layers.length; idx++) {
+									var layerConfig = config.layers[idx];
+									map.trigger('map.layer.init', [map, layerConfig]);
+									layersConfig.push(PyAMS_GIS.getLayer(map, leafmap, layerConfig));
 								}
-								MyAMS.getCSS('/--static--/pyams_gis/css/leaflet-1.0.3' + MyAMS.devext + '.css',
-											 'leaflet', function() {
-									MyAMS.ajax.post('get-map-configuration.json', {}, function(config) {
-										var data = map.data();
-										var settings = {
-											preferCanvas: data.mapLeafletPreferCanvas || false,
-											attributionControl: data.mapLeafletAttributionControl === undefined ?
-												config.attributionControl :
-												data.mapLeafletAttributionControl,
-											zoomControl: data.mapLeafletZoomControl === undefined ?
-												config.zoomControl :
-												data.mapLeafletZoomControl,
-											crs: data.mapLeafletCrs || MyAMS.getObject(config.crs) || globals.L.CRS.EPSG3857,
-											center: data.mapLeafletCenter || config.center,
-											zoom: data.mapLeafletZoom || config.zoom
-										};
-										settings = $.extend({}, settings, options);
-										map.trigger('map.init', [map, settings, config]);
-										var leafmap = L.map(map.attr('id'), settings);
-										if (config.layers) {
-											for (var index = 0; index < config.layers.length; index++) {
-												var layerConfig = config.layers[index];
-												map.trigger('map.layer.init', [map, layerConfig]);
-												PyAMS_GIS.getLayer(layerConfig).addTo(leafmap);
-											}
-										} else {
-											L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
-												maxZoom: 19,
-												id: 'osm',
-												attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
-											}).addTo(leafmap);
-										}
-										if (config.zoomControl && (data.mapLeafletHideZoomControl !== true)) {
-											L.control.scale().addTo(leafmap);
-										}
-										if (config.bounds) {
-											leafmap.fitBounds(config.bounds);
-										}
-										map.data('leafmap', leafmap);
-										map.data('leafmap.config', config);
-										map.trigger('map.finishing', [map, leafmap]);
-										if (callback) {
-											callback(leafmap, config);
-										}
-										map.trigger('map.finished', [map, leafmap]);
-									});
-								});
-							 });
+							} else {
+								layersConfig.push(L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+									maxZoom: 19,
+									id: 'osm',
+									attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
+								}));
+							}
+							$.when.apply($, layersConfig).then(function(...layers) {
+								for (var idx=0; idx < layers.length; idx++) {
+									layers[idx].addTo(leafmap);
+								}
+								if (config.zoomControl && (data.mapLeafletHideZoomControl !== true)) {
+									L.control.scale().addTo(leafmap);
+								}
+								if (config.center) {
+									leafmap.setView(new L.LatLng(config.center.lat, config.center.lon),
+													config.zoom || 13);
+								} else if (config.bounds) {
+									leafmap.fitBounds(config.bounds);
+								}
+								map.data('leafmap', leafmap);
+								map.data('leafmap.config', config);
+								map.trigger('map.finishing', [map, leafmap, config]);
+								if (callback) {
+									callback(leafmap, config);
+								}
+								map.trigger('map.finished', [map, leafmap, config]);
+							});
+						}
+
+						var data = map.data(),
+							config = data.mapConfiguration;
+						if (config) {
+							createMap(config);
+						} else {
+							MyAMS.ajax.post(data.mapConfigurationUrl || 'get-map-configuration.json', {}, function(config) {
+								createMap(config);
+							});
+						}
+					});
+				}
+			);
 		},
 
-		getLayer: function(layer) {
+		getLayer: function(map, leafmap, layer) {
 			var factory = MyAMS.getObject(layer.factory);
 			if (factory !== undefined) {
 				delete layer.factory;
@@ -120,33 +147,49 @@
 				if (deferred.length > 0) {
 					$.when.apply($, deferred);
 				}
-				return factory(layer);
+				return factory(map, leafmap, layer);
 			}
 		},
 
 		factory: {
-			TileLayer: function(layer) {
+			GeoJSON: function(map, leafmap, layer) {
+				var url = layer.url;
+				delete layer.url;
+				var result = L.geoJSON(null, layer);
+				map.on('map.finished', function(evt, map, leafmap, config) {
+					$.get(url, function(data) {
+						result.addData(data.geometry, {
+							style: layer.style
+						});
+						if (config.fitLayer === layer.name) {
+							leafmap.fitBounds(result.getBounds());
+						}
+					});
+				});
+				return result;
+			},
+			TileLayer: function(map, leafmap, layer) {
 				var url = layer.url;
 				delete layer.url;
 				return L.tileLayer(url, layer);
 			},
-			WMS: function(layer) {
+			WMS: function(map, leafmap, layer) {
 				var url = layer.url;
 				delete layer.url;
 				return L.tileLayer.wms(url, layer);
 			},
 			Geoportal: {
-				WMS: function(layer) {
+				WMS: function(map, leafmap, layer) {
 					MyAMS.getCSS('/--static--/pyams_gis/css/leaflet-gp-3.0.2' + MyAMS.devext + '.css', 'geoportal');
 					return L.geoportalLayer.WMS(layer);
 				}
 			},
 			ESRI: {
-				Feature: function(layer) {
+				Feature: function(map, leafmap, layer) {
 					return L.esri.featureLayer(layer);
 				}
 			},
-			Google: function(layer) {
+			Google: function(map, leafmap, layer) {
 				var apiKey = layer.apiKey;
 				delete layer.apiKey;
 				if (MyAMS.getObject('window.google.maps') === undefined) {
@@ -176,6 +219,113 @@
 		},
 
 		/**
+		 * Init markers layer
+		 */
+		markers: {
+
+			init: function(leafmap, markers, config) {
+
+				MyAMS.ajax.check([
+					L.MarkerClusterGroup
+				], [
+					'/--static--/pyams_gis/js/leaflet-markercluster-1.4.1' + MyAMS.devext + '.js'
+				], function(firstLoad) {
+
+					if (firstLoad) {
+						MyAMS.getCSS('/--static--/pyams_gis/css/leaflet-markercluster-1.4.1' + MyAMS.devext + '.css',
+							'leaflet-markercluster');
+						MyAMS.getCSS('/--static--/pyams_gis/css/leaflet-markercluster-default-1.4.1' + MyAMS.devext + '.css',
+							'leaflet-markercluster-default');
+					}
+
+					// click marker
+					var clickMarker = function(e) {
+						window.location.href = this.options.clickURL;
+					}
+					// show tooltip
+					var hoverMarker = function(e) {
+						this.openTooltip();
+					}
+					// hide tooltip
+					var leaveMarker = function(e) {
+						this.closeTooltip();
+					}
+
+					// create custom icon
+					var markerIcon = L.icon({
+						iconUrl: markers.icon.url,
+						iconSize: markers.icon.size,
+						iconAnchor: markers.icon.anchor
+					});
+					// customize cluster icon
+					var markersClusterCustom = new L.MarkerClusterGroup({
+						iconCreateFunction: function(cluster) {
+							return L.divIcon({
+								html: cluster.getChildCount(),
+								className: markers.clusterClass || 'map-cluster',
+								iconSize: null
+							});
+						}
+					});
+
+					// object to save markers
+					var icons = {};
+
+					// create markers
+					for (var i = 0; i < markers.markers.length; i++) {
+						var markerConfig = markers.markers[i];
+						var latLng = new L.LatLng(markerConfig.point.y, markerConfig.point.x);
+						var marker = new L.Marker(latLng, {
+							icon: markerIcon,
+							clickURL: markerConfig.href,
+							markerId: markerConfig.id,
+							alt: markerConfig.id
+						});
+						if (markerConfig.href) {
+							marker.addEventListener('click', clickMarker);
+						}
+						icons[markerConfig.id] = marker;
+						// bind tooltip with title content
+						var label;
+						if (markerConfig.img) {
+							label = '<div>' +
+								'<div class="marker__label p-2"> ' + markerConfig.label + '</div>' +
+								'<div class="text-center">' +
+									'<img src="' + markerConfig.img.src + '" width="' + markerConfig.img.w + '" height="' + markerConfig.img.h + '" alt="" />' +
+								'</div>' +
+							'</div>';
+						} else {
+							label = markerConfig.label;
+						}
+						if (label) {
+							var className = markers.tooltipClass || 'map-tooltip';
+							if (markerConfig.img) {
+								className += ' p-0';
+							}
+							icons[markerConfig.id].bindTooltip(label, {
+								direction: 'top',
+								offset: [0, -markerIcon.options.iconSize[1]],
+								opacity: 1,
+								className: className
+							});
+							icons[markerConfig.id].addEventListener('mouseover', hoverMarker);
+							icons[markerConfig.id].addEventListener('mouseout', leaveMarker);
+						}
+						markersClusterCustom.addLayer(icons[markerConfig.id]);
+					}
+					leafmap.addLayer(markersClusterCustom);
+					if (config.adjust === 'auto') {
+						leafmap.fitBounds(markersClusterCustom.getBounds());
+						if (markers.markers.length === 1) {
+							debugger
+							leafmap.setZoom(config.zoom);
+						}
+					}
+				});
+			}
+		},
+
+		/**
 		 * Single position marker management
 		 */
 		position: {
@@ -190,7 +340,7 @@
 						var icon = L.icon({
 							iconUrl: '/--static--/pyams_gis/img/marker-icon.png',
 							iconSize: [25, 41],
-							iconAnchor: [13, 40]
+							iconAnchor: [12, 39]
 						});
 						var marker = L.marker();
 						marker.setIcon(icon);
@@ -383,13 +533,15 @@
 						L.Draw = L.Draw || {};
 						L.Edit = L.Edit || {};
 						MyAMS.ajax.check([L.Draw, L.Draw.Event, L.Map.TouchExtend, L.Edit.SimpleShape],
-										 ['/--static--/pyams_gis/js/leaflet.Draw' + MyAMS.devext + '.js',
-										  '/--static--/pyams_gis/js/leaflet.Draw.Event' + MyAMS.devext + '.js',
-										  '/--static--/pyams_gis/js/TouchEvents' + MyAMS.devext + '.js',
-										  '/--static--/pyams_gis/js/Edit.SimpleShape' + MyAMS.devext + '.js'],
-										 function() {
+										[
+											'/--static--/pyams_gis/js/Draw/Leaflet.draw' + MyAMS.devext + '.js',
+											'/--static--/pyams_gis/js/Draw/Leaflet.Draw.Event' + MyAMS.devext + '.js',
+											'/--static--/pyams_gis/js/Draw/ext/TouchEvents' + MyAMS.devext + '.js',
+											'/--static--/pyams_gis/js/Draw/edit/handler/Edit.SimpleShape' + MyAMS.devext + '.js'
+										],
+										function() {
 											MyAMS.ajax.check(L.Edit.Rectangle,
-															 '/--static--/pyams_gis/js/Edit.Rectangle' + MyAMS.devext + '.js',
+															 '/--static--/pyams_gis/js/Draw/edit/handler/Edit.Rectangle' + MyAMS.devext + '.js',
 															 function () {
 
 																function initRectangle(p1, p2) {