src/pyams_gis/resources/js/pyams_gis.js
changeset 0 c73bb834ccbe
child 4 96f1ba4f8fc7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_gis/resources/js/pyams_gis.js	Thu May 18 17:23:48 2017 +0200
@@ -0,0 +1,519 @@
+/**
+ * PyAMS_GIS package extension
+ */
+(function($, globals) {
+
+	"use strict";
+
+	var MyAMS = globals.MyAMS;
+	var L;
+
+	var PyAMS_GIS = {
+
+		RPC_ENDPOINT: '/api/gis/json',
+		WGS_SRID: 4326,
+
+		_layersControlAddItem: function(obj) {
+			var group = $('<div></div>').addClass('inline-group'),
+				label = $('<label></label>').addClass(obj.overlay ? "checkbox" : "radio"),
+				input,
+				span = $('<i></i>'),
+				name,
+				checked = this._map.hasLayer(obj.layer);
+			if (obj.overlay) {
+				input = document.createElement('input');
+				input.type = 'checkbox';
+				input.className = 'leaflet-control-layers-selector';
+				input.defaultChecked = checked;
+			} else {
+				input = this._createRadioElement('leaflet-base-layers', checked);
+			}
+			input.layerId = L.stamp(obj.layer);
+			$(input).addClass(obj.overlay ? "checkbox" : "radio");
+			L.DomEvent.on(input, 'click', this._onInputClick, this);
+			name = $('<span></span>').text(' ' + obj.name);
+			label.append(input);
+			label.append(span);
+			label.append(name);
+			group.append(label);
+			var container = obj.overlay ? this._overlaysList : this._baseLayersList;
+			$(container).append(group);
+			// $($(container).parents('form').get(0)).data("async", true);
+			return group;
+		},
+
+		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.getCSS('/--static--/pyams_gis/css/leaflet-1.0.3' + MyAMS.devext + '.css',
+												 'leaflet');
+								}
+								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]);
+								});
+							 });
+		},
+
+		getLayer: function(layer) {
+			var factory = MyAMS.getObject(layer.factory);
+			if (factory !== undefined) {
+				delete layer.factory;
+				var deferred = [];
+				if (layer.dependsOn) {
+					for (var name in layer.dependsOn) {
+						if (!layer.dependsOn.hasOwnProperty(name)) {
+							continue;
+						}
+						if (MyAMS.getObject(name) === undefined) {
+							deferred.push(MyAMS.getScript(layer.dependsOn[name]));
+						}
+					}
+					delete layer.dependsOn;
+				}
+				if (deferred.length > 0) {
+					$.when.apply($, deferred);
+				}
+				return factory(layer);
+			}
+		},
+
+		factory: {
+			TileLayer: function(layer) {
+				var url = layer.url;
+				delete layer.url;
+				return L.tileLayer(url, layer);
+			},
+			WMS: function(layer) {
+				var url = layer.url;
+				delete layer.url;
+				return L.tileLayer.wms(url, layer);
+			},
+			Geoportal: {
+				WMS: function(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) {
+					return L.esri.featureLayer(layer);
+				}
+			},
+			Google: function(layer) {
+				var apiKey = layer.apiKey;
+				delete layer.apiKey;
+				if (MyAMS.getObject('window.google.maps') === undefined) {
+					var script = MyAMS.getScript('https://maps.googleapis.com/maps/api/js?key=' + apiKey);
+					$.when.apply($, [script]);
+				}
+				return L.gridLayer.googleMutant(layer);
+			}
+		},
+
+		callJSON: function(method, params, callback) {
+			MyAMS.ajax.check($.jsonRPC,
+							 MyAMS.baseURL + 'ext/jquery-jsonrpc' + MyAMS.devext + '.js',
+							 function() {
+								$.jsonRPC.withOptions({
+									endPoint: PyAMS_GIS.RPC_ENDPOINT,
+									cache: false
+								}, function() {
+									$.jsonRPC.request(method, {
+										id: new Date().getTime(),
+										params: params,
+										success: callback,
+										error: MyAMS.error.show
+									});
+								});
+							 });
+		},
+
+		/**
+		 * Single position marker management
+		 */
+		position: {
+
+			init: function() {
+				/* Position marker initialization */
+				var map = $('.map', $(this));
+				if (map.data('leafmap') === undefined) {
+					map.css('height', $(window).height() - 200);
+					PyAMS_GIS.init(map, {}, function (leafmap, config) {
+						var data = map.data();
+						var icon = L.icon({
+							iconUrl: '/--static--/pyams_gis/img/marker-icon.png',
+							iconSize: [25, 41],
+							iconAnchor: [13, 40]
+						});
+						var marker = L.marker();
+						marker.setIcon(icon);
+						var fieldname = data.mapLeafletFieldname;
+						var longitude = $('input[name="' + fieldname + '.widgets.longitude"]');
+						var latitude = $('input[name="' + fieldname + '.widgets.latitude"]');
+						if (longitude.val() && latitude.val()) {
+							var projection = $('select[name="' + fieldname + '.widgets.projection:list"]');
+							var params = {
+								point: {
+									longitude: parseFloat(longitude.val()),
+									latitude: parseFloat(latitude.val())
+								},
+								from_projection: projection.val() || PyAMS_GIS.WGS_SRID,
+								to_projection: PyAMS_GIS.WGS_SRID
+							};
+							PyAMS_GIS.callJSON('transformPoint', params, function(result) {
+								if (!result.error) {
+									var point = result.result.point;
+									marker.setLatLng({
+										lon: point.longitude,
+										lat: point.latitude
+									});
+									marker.addTo(leafmap);
+									leafmap.setView(marker.getLatLng(), config.zoom || 13);
+								}
+							});
+						} else {
+							marker.setLatLng([-90, 0]);
+							marker.addTo(leafmap);
+						}
+						map.data('marker', marker);
+						leafmap.on('click', PyAMS_GIS.position.onClick);
+					});
+				}
+			},
+
+			onClick: function(event) {
+				var map = event.target.getContainer();
+				var data = $(map).data();
+				var marker = data.marker;
+				var latlng = event.latlng;
+				marker.setLatLng(latlng);
+				var fieldname = data.mapLeafletFieldname;
+				var projection = $('select[name="' + fieldname + '.widgets.projection:list"]');
+				var params = {
+					point: {
+						longitude: latlng.lng,
+						latitude: latlng.lat
+					},
+					from_projection: PyAMS_GIS.WGS_SRID,
+					to_projection: projection.val()
+				};
+				PyAMS_GIS.callJSON('transformPoint', params, function(result) {
+					if (!result.error) {
+						var point = result.result.point;
+						$('input[name="' + fieldname + '.widgets.longitude"]').val(point.longitude);
+						$('input[name="' + fieldname + '.widgets.latitude"]').val(point.latitude);
+					}
+				});
+			},
+
+			changedCoordinate: function() {
+				var input = $(this);
+				var map = $('.map', input.parents('fieldset:first'));
+				if (!map.data('marker')) {
+					return;
+				}
+				var fieldname = map.data('map-leaflet-fieldname');
+				var longitude = $('input[name="' + fieldname + '.widgets.longitude"]');
+				var latitude = $('input[name="' + fieldname + '.widgets.latitude"]');
+				if (longitude.val() && latitude.val()) {
+					var projection = $('select[name="' + fieldname + '.widgets.projection:list"]');
+					var params = {
+						point: {
+							longitude: parseFloat(longitude.val()),
+							latitude: parseFloat(latitude.val())
+						},
+						from_projection: projection.val(),
+						to_projection: 4326
+					};
+					PyAMS_GIS.callJSON('transformPoint', params, function (result) {
+						if (!result.error) {
+							var point = result.result.point;
+							var marker = map.data('marker');
+							marker.setLatLng({
+								lon: point.longitude,
+								lat: point.latitude
+							});
+						}
+					});
+				}
+			},
+
+			changedProjection: function(event) {
+				var select = $(this);
+				var map = $('.map', select.parents('fieldset:first'));
+				var fieldname = map.data('map-leaflet-fieldname');
+				var longitude = $('input[name="' + fieldname + '.widgets.longitude"]');
+				var latitude = $('input[name="' + fieldname + '.widgets.latitude"]');
+				if (event.removed) {
+					var previous = event.removed.id;
+					var current = event.added.id;
+					if (previous !== current) {
+						if (longitude.val() && latitude.val()) {
+							var params = {
+								point: {
+									longitude: parseFloat(longitude.val()),
+									latitude: parseFloat(latitude.val())
+								},
+								from_projection: previous,
+								to_projection: current
+							};
+							PyAMS_GIS.callJSON('transformPoint', params, function (result) {
+								if (!result.error) {
+									var point = result.result.point;
+									longitude.val(point.longitude);
+									latitude.val(point.latitude);
+								}
+							});
+						}
+					}
+				} else {
+					PyAMS_GIS.position.changedCoordinate.apply(longitude);
+				}
+			},
+
+			clear: function(event) {
+				var fieldset = $(this).parents('fieldset:first');
+				$('input', fieldset).val(null);
+			}
+		},
+
+
+		/**
+		 * Single rectangular area management
+		 */
+		area: {
+
+			init: function () {
+				var map = $('.map', $(this));
+				if (map.data('leafmap') === undefined) {
+					map.css('height', $(window).height() - 200);
+					PyAMS_GIS.init(map, {}, function(leafmap) {
+						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() {
+											MyAMS.ajax.check(L.Edit.Rectangle,
+															 '/--static--/pyams_gis/js/Edit.Rectangle' + MyAMS.devext + '.js',
+															 function () {
+
+																function initRectangle(p1, p2) {
+																	var group = new L.FeatureGroup();
+																	rectangle = L.rectangle([p1, p2]);
+																	group.addLayer(rectangle);
+																	leafmap.addLayer(group);
+																	leafmap.fitBounds(rectangle.getBounds());
+																	rectangle.editing.enable();
+																	map.data('area', rectangle);
+																	leafmap.on(L.Draw.Event.EDITMOVE, PyAMS_GIS.area.changedArea);
+																	leafmap.on(L.Draw.Event.EDITRESIZE, PyAMS_GIS.area.changedArea);
+																	leafmap.on(L.Draw.Event.EDITVERTEX, PyAMS_GIS.area.changedArea);
+																}
+
+																var data = map.data();
+																var fieldname = data.mapLeafletFieldname;
+																var x1 = $('input[name="' + fieldname + '.widgets.x1"]');
+																var y1 = $('input[name="' + fieldname + '.widgets.y1"]');
+																var x2 = $('input[name="' + fieldname + '.widgets.x2"]');
+																var y2 = $('input[name="' + fieldname + '.widgets.y2"]');
+																var p1,
+																	p2,
+																	rectangle;
+																if (x1.val() && y1.val() && x2.val() && y2.val()) {
+																	var projection = $('select[name="' + fieldname + '.widgets.projection:list"]');
+																	var params = {
+																		area: {
+																			x1: parseFloat(x1.val()),
+																			y1: parseFloat(y1.val()),
+																			x2: parseFloat(x2.val()),
+																			y2: parseFloat(y2.val())
+																		},
+																		from_projection: projection.val(),
+																		to_projection: PyAMS_GIS.WGS_SRID
+																	};
+																	PyAMS_GIS.callJSON('transformArea', params, function(result) {
+																		if (!result.error) {
+																			var area = result.result.area;
+																			p1 = L.latLng({lon: area.x1, lat: area.y1});
+																			p2 = L.latLng({lon: area.x2, lat: area.y2});
+																			initRectangle(p1, p2);
+																		}
+																	});
+																} else {
+																	p1 = L.latLng({lon: -168, lat: -56.37});
+																	p2 = L.latLng({lon: 191.25, lat: 83.72});
+																	initRectangle(p1, p2);
+																}
+															 });
+										 });
+					});
+				}
+			},
+
+			last_event: null,
+
+			changedArea: function(event) {
+				PyAMS_GIS.area.last_event = event;
+				setTimeout(function() {
+					if (event === PyAMS_GIS.area.last_event) {
+						var map = event.target.getContainer();
+						var data = $(map).data();
+						var area = data.area.getBounds();
+						var fieldname = data.mapLeafletFieldname;
+						var projection = $('select[name="' + fieldname + '.widgets.projection:list"]').val();
+						var params = {
+							area: {
+								x1: area.getWest(),
+								y1: area.getSouth(),
+								x2: area.getEast(),
+								y2: area.getNorth()
+							},
+							from_projection: PyAMS_GIS.WGS_SRID,
+							to_projection: projection
+						};
+						PyAMS_GIS.callJSON('transformArea', params, function(result) {
+							if (!result.error) {
+								var area = result.result.area;
+								$('input[name="' + fieldname + '.widgets.x1"]').val(area.x1);
+								$('input[name="' + fieldname + '.widgets.y1"]').val(area.y1);
+								$('input[name="' + fieldname + '.widgets.x2"]').val(area.x2);
+								$('input[name="' + fieldname + '.widgets.y2"]').val(area.y2);
+							}
+						});
+					}
+				}, 100);
+			},
+
+			changedCoordinate: function() {
+				var input = $(this);
+				var map = $('.map', input.parents('fieldset:first'));
+				if (!map.data('area')) {
+					return;
+				}
+				var fieldname = map.data('map-leaflet-fieldname');
+				var x1 = $('input[name="' + fieldname + '.widgets.x1"]');
+				var y1 = $('input[name="' + fieldname + '.widgets.y1"]');
+				var x2 = $('input[name="' + fieldname + '.widgets.x2"]');
+				var y2 = $('input[name="' + fieldname + '.widgets.y2"]');
+				if (x1.val() && y1.val() && x2.val() && y2.val()) {
+					var projection = $('select[name="' + fieldname + '.widgets.projection:list"]');
+					var params = {
+						area: {
+							x1: parseFloat(x1.val()),
+							y1: parseFloat(y1.val()),
+							x2: parseFloat(x2.val()),
+							y2: parseFloat(y2.val())
+						},
+						from_projection: projection.val(),
+						to_projection: 4326
+					};
+					PyAMS_GIS.callJSON('transformArea', params, function (result) {
+						if (!result.error) {
+							var area = result.result.area;
+							var rect = map.data('area');
+							rect.editing.disable();
+							rect.setBounds([L.latLng({lon: area.x1, lat: area.y1}),
+											L.latLng({lon: area.x2, lat: area.y2})]);
+							rect.editing.enable();
+						}
+					});
+				}
+			},
+
+			changedProjection: function(event) {
+				var select = $(this);
+				var map = $('.map', select.parents('fieldset:first'));
+				var fieldname = map.data('map-leaflet-fieldname');
+				var x1 = $('input[name="' + fieldname + '.widgets.x1"]');
+				var y1 = $('input[name="' + fieldname + '.widgets.y1"]');
+				var x2 = $('input[name="' + fieldname + '.widgets.x2"]');
+				var y2 = $('input[name="' + fieldname + '.widgets.y2"]');
+				if (event.removed) {
+					var previous = event.removed.id;
+					var current = event.added.id;
+					if (previous !== current) {
+						if (x1.val() && y1.val() && x2.val() && y2.val()) {
+							var params = {
+								area: {
+									x1: parseFloat(x1.val()),
+									y1: parseFloat(y1.val()),
+									x2: parseFloat(x2.val()),
+									y2: parseFloat(y2.val())
+								},
+								from_projection: previous,
+								to_projection: current
+							};
+							PyAMS_GIS.callJSON('transformArea', params, function (result) {
+								if (!result.error) {
+									var area = result.result.area;
+									x1.val(area.x1);
+									y1.val(area.y1);
+									x2.val(area.x2);
+									y2.val(area.y2);
+								}
+							});
+						}
+					}
+				} else {
+					PyAMS_GIS.area.changedCoordinate.apply(x1);
+				}
+			},
+
+			clear: function(event) {
+				var fieldset = $(this).parents('fieldset:first');
+				$('input', fieldset).val(null);
+			}
+		}
+	};
+	globals.PyAMS_GIS = PyAMS_GIS;
+
+})(jQuery, this);