src/pyams_gis/resources/js/pyams_gis.js
changeset 0 c73bb834ccbe
child 4 96f1ba4f8fc7
equal deleted inserted replaced
-1:000000000000 0:c73bb834ccbe
       
     1 /**
       
     2  * PyAMS_GIS package extension
       
     3  */
       
     4 (function($, globals) {
       
     5 
       
     6 	"use strict";
       
     7 
       
     8 	var MyAMS = globals.MyAMS;
       
     9 	var L;
       
    10 
       
    11 	var PyAMS_GIS = {
       
    12 
       
    13 		RPC_ENDPOINT: '/api/gis/json',
       
    14 		WGS_SRID: 4326,
       
    15 
       
    16 		_layersControlAddItem: function(obj) {
       
    17 			var group = $('<div></div>').addClass('inline-group'),
       
    18 				label = $('<label></label>').addClass(obj.overlay ? "checkbox" : "radio"),
       
    19 				input,
       
    20 				span = $('<i></i>'),
       
    21 				name,
       
    22 				checked = this._map.hasLayer(obj.layer);
       
    23 			if (obj.overlay) {
       
    24 				input = document.createElement('input');
       
    25 				input.type = 'checkbox';
       
    26 				input.className = 'leaflet-control-layers-selector';
       
    27 				input.defaultChecked = checked;
       
    28 			} else {
       
    29 				input = this._createRadioElement('leaflet-base-layers', checked);
       
    30 			}
       
    31 			input.layerId = L.stamp(obj.layer);
       
    32 			$(input).addClass(obj.overlay ? "checkbox" : "radio");
       
    33 			L.DomEvent.on(input, 'click', this._onInputClick, this);
       
    34 			name = $('<span></span>').text(' ' + obj.name);
       
    35 			label.append(input);
       
    36 			label.append(span);
       
    37 			label.append(name);
       
    38 			group.append(label);
       
    39 			var container = obj.overlay ? this._overlaysList : this._baseLayersList;
       
    40 			$(container).append(group);
       
    41 			// $($(container).parents('form').get(0)).data("async", true);
       
    42 			return group;
       
    43 		},
       
    44 
       
    45 		init: function(context, options, callback) {
       
    46 			var map = context;
       
    47 			MyAMS.ajax.check(globals.L,
       
    48 							 '/--static--/pyams_gis/js/leaflet-1.0.3' + MyAMS.devext + '.js',
       
    49 							 function(first_load) {
       
    50 								if (first_load) {
       
    51 									L = globals.L;
       
    52 									L.Control.Layers.prototype._addItem = PyAMS_GIS._layersControlAddItem;
       
    53 									MyAMS.getCSS('/--static--/pyams_gis/css/leaflet-1.0.3' + MyAMS.devext + '.css',
       
    54 												 'leaflet');
       
    55 								}
       
    56 								MyAMS.ajax.post('get-map-configuration.json', {}, function(config) {
       
    57 									var data = map.data();
       
    58 									var settings = {
       
    59 										preferCanvas: data.mapLeafletPreferCanvas || false,
       
    60 										attributionControl: data.mapLeafletAttributionControl === undefined ?
       
    61 											config.attributionControl :
       
    62 											data.mapLeafletAttributionControl,
       
    63 										zoomControl: data.mapLeafletZoomControl === undefined ?
       
    64 											config.zoomControl :
       
    65 											data.mapLeafletZoomControl,
       
    66 										crs: data.mapLeafletCrs || MyAMS.getObject(config.crs) || globals.L.CRS.EPSG3857,
       
    67 										center: data.mapLeafletCenter || config.center,
       
    68 										zoom: data.mapLeafletZoom || config.zoom
       
    69 									};
       
    70 									settings = $.extend({}, settings, options);
       
    71 									map.trigger('map.init', [map, settings, config]);
       
    72 									var leafmap = L.map(map.attr('id'), settings);
       
    73 									if (config.layers) {
       
    74 										for (var index = 0; index < config.layers.length; index++) {
       
    75 											var layerConfig = config.layers[index];
       
    76 											map.trigger('map.layer.init', [map, layerConfig]);
       
    77 											PyAMS_GIS.getLayer(layerConfig).addTo(leafmap);
       
    78 										}
       
    79 									} else {
       
    80 										L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
       
    81 											maxZoom: 19,
       
    82 											id: 'osm',
       
    83 											attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
       
    84 										}).addTo(leafmap);
       
    85 									}
       
    86 									if (config.zoomControl && (data.mapLeafletHideZoomControl !== true)) {
       
    87 										L.control.scale().addTo(leafmap);
       
    88 									}
       
    89 									if (config.bounds) {
       
    90 										leafmap.fitBounds(config.bounds);
       
    91 									}
       
    92 									map.data('leafmap', leafmap);
       
    93 									map.data('leafmap.config', config);
       
    94 									map.trigger('map.finishing', [map, leafmap]);
       
    95 									if (callback) {
       
    96 										callback(leafmap, config);
       
    97 									}
       
    98 									map.trigger('map.finished', [map, leafmap]);
       
    99 								});
       
   100 							 });
       
   101 		},
       
   102 
       
   103 		getLayer: function(layer) {
       
   104 			var factory = MyAMS.getObject(layer.factory);
       
   105 			if (factory !== undefined) {
       
   106 				delete layer.factory;
       
   107 				var deferred = [];
       
   108 				if (layer.dependsOn) {
       
   109 					for (var name in layer.dependsOn) {
       
   110 						if (!layer.dependsOn.hasOwnProperty(name)) {
       
   111 							continue;
       
   112 						}
       
   113 						if (MyAMS.getObject(name) === undefined) {
       
   114 							deferred.push(MyAMS.getScript(layer.dependsOn[name]));
       
   115 						}
       
   116 					}
       
   117 					delete layer.dependsOn;
       
   118 				}
       
   119 				if (deferred.length > 0) {
       
   120 					$.when.apply($, deferred);
       
   121 				}
       
   122 				return factory(layer);
       
   123 			}
       
   124 		},
       
   125 
       
   126 		factory: {
       
   127 			TileLayer: function(layer) {
       
   128 				var url = layer.url;
       
   129 				delete layer.url;
       
   130 				return L.tileLayer(url, layer);
       
   131 			},
       
   132 			WMS: function(layer) {
       
   133 				var url = layer.url;
       
   134 				delete layer.url;
       
   135 				return L.tileLayer.wms(url, layer);
       
   136 			},
       
   137 			Geoportal: {
       
   138 				WMS: function(layer) {
       
   139 					MyAMS.getCSS('/--static--/pyams_gis/css/leaflet-gp-3.0.2' + MyAMS.devext + '.css', 'geoportal');
       
   140 					return L.geoportalLayer.WMS(layer);
       
   141 				}
       
   142 			},
       
   143 			ESRI: {
       
   144 				Feature: function(layer) {
       
   145 					return L.esri.featureLayer(layer);
       
   146 				}
       
   147 			},
       
   148 			Google: function(layer) {
       
   149 				var apiKey = layer.apiKey;
       
   150 				delete layer.apiKey;
       
   151 				if (MyAMS.getObject('window.google.maps') === undefined) {
       
   152 					var script = MyAMS.getScript('https://maps.googleapis.com/maps/api/js?key=' + apiKey);
       
   153 					$.when.apply($, [script]);
       
   154 				}
       
   155 				return L.gridLayer.googleMutant(layer);
       
   156 			}
       
   157 		},
       
   158 
       
   159 		callJSON: function(method, params, callback) {
       
   160 			MyAMS.ajax.check($.jsonRPC,
       
   161 							 MyAMS.baseURL + 'ext/jquery-jsonrpc' + MyAMS.devext + '.js',
       
   162 							 function() {
       
   163 								$.jsonRPC.withOptions({
       
   164 									endPoint: PyAMS_GIS.RPC_ENDPOINT,
       
   165 									cache: false
       
   166 								}, function() {
       
   167 									$.jsonRPC.request(method, {
       
   168 										id: new Date().getTime(),
       
   169 										params: params,
       
   170 										success: callback,
       
   171 										error: MyAMS.error.show
       
   172 									});
       
   173 								});
       
   174 							 });
       
   175 		},
       
   176 
       
   177 		/**
       
   178 		 * Single position marker management
       
   179 		 */
       
   180 		position: {
       
   181 
       
   182 			init: function() {
       
   183 				/* Position marker initialization */
       
   184 				var map = $('.map', $(this));
       
   185 				if (map.data('leafmap') === undefined) {
       
   186 					map.css('height', $(window).height() - 200);
       
   187 					PyAMS_GIS.init(map, {}, function (leafmap, config) {
       
   188 						var data = map.data();
       
   189 						var icon = L.icon({
       
   190 							iconUrl: '/--static--/pyams_gis/img/marker-icon.png',
       
   191 							iconSize: [25, 41],
       
   192 							iconAnchor: [13, 40]
       
   193 						});
       
   194 						var marker = L.marker();
       
   195 						marker.setIcon(icon);
       
   196 						var fieldname = data.mapLeafletFieldname;
       
   197 						var longitude = $('input[name="' + fieldname + '.widgets.longitude"]');
       
   198 						var latitude = $('input[name="' + fieldname + '.widgets.latitude"]');
       
   199 						if (longitude.val() && latitude.val()) {
       
   200 							var projection = $('select[name="' + fieldname + '.widgets.projection:list"]');
       
   201 							var params = {
       
   202 								point: {
       
   203 									longitude: parseFloat(longitude.val()),
       
   204 									latitude: parseFloat(latitude.val())
       
   205 								},
       
   206 								from_projection: projection.val() || PyAMS_GIS.WGS_SRID,
       
   207 								to_projection: PyAMS_GIS.WGS_SRID
       
   208 							};
       
   209 							PyAMS_GIS.callJSON('transformPoint', params, function(result) {
       
   210 								if (!result.error) {
       
   211 									var point = result.result.point;
       
   212 									marker.setLatLng({
       
   213 										lon: point.longitude,
       
   214 										lat: point.latitude
       
   215 									});
       
   216 									marker.addTo(leafmap);
       
   217 									leafmap.setView(marker.getLatLng(), config.zoom || 13);
       
   218 								}
       
   219 							});
       
   220 						} else {
       
   221 							marker.setLatLng([-90, 0]);
       
   222 							marker.addTo(leafmap);
       
   223 						}
       
   224 						map.data('marker', marker);
       
   225 						leafmap.on('click', PyAMS_GIS.position.onClick);
       
   226 					});
       
   227 				}
       
   228 			},
       
   229 
       
   230 			onClick: function(event) {
       
   231 				var map = event.target.getContainer();
       
   232 				var data = $(map).data();
       
   233 				var marker = data.marker;
       
   234 				var latlng = event.latlng;
       
   235 				marker.setLatLng(latlng);
       
   236 				var fieldname = data.mapLeafletFieldname;
       
   237 				var projection = $('select[name="' + fieldname + '.widgets.projection:list"]');
       
   238 				var params = {
       
   239 					point: {
       
   240 						longitude: latlng.lng,
       
   241 						latitude: latlng.lat
       
   242 					},
       
   243 					from_projection: PyAMS_GIS.WGS_SRID,
       
   244 					to_projection: projection.val()
       
   245 				};
       
   246 				PyAMS_GIS.callJSON('transformPoint', params, function(result) {
       
   247 					if (!result.error) {
       
   248 						var point = result.result.point;
       
   249 						$('input[name="' + fieldname + '.widgets.longitude"]').val(point.longitude);
       
   250 						$('input[name="' + fieldname + '.widgets.latitude"]').val(point.latitude);
       
   251 					}
       
   252 				});
       
   253 			},
       
   254 
       
   255 			changedCoordinate: function() {
       
   256 				var input = $(this);
       
   257 				var map = $('.map', input.parents('fieldset:first'));
       
   258 				if (!map.data('marker')) {
       
   259 					return;
       
   260 				}
       
   261 				var fieldname = map.data('map-leaflet-fieldname');
       
   262 				var longitude = $('input[name="' + fieldname + '.widgets.longitude"]');
       
   263 				var latitude = $('input[name="' + fieldname + '.widgets.latitude"]');
       
   264 				if (longitude.val() && latitude.val()) {
       
   265 					var projection = $('select[name="' + fieldname + '.widgets.projection:list"]');
       
   266 					var params = {
       
   267 						point: {
       
   268 							longitude: parseFloat(longitude.val()),
       
   269 							latitude: parseFloat(latitude.val())
       
   270 						},
       
   271 						from_projection: projection.val(),
       
   272 						to_projection: 4326
       
   273 					};
       
   274 					PyAMS_GIS.callJSON('transformPoint', params, function (result) {
       
   275 						if (!result.error) {
       
   276 							var point = result.result.point;
       
   277 							var marker = map.data('marker');
       
   278 							marker.setLatLng({
       
   279 								lon: point.longitude,
       
   280 								lat: point.latitude
       
   281 							});
       
   282 						}
       
   283 					});
       
   284 				}
       
   285 			},
       
   286 
       
   287 			changedProjection: function(event) {
       
   288 				var select = $(this);
       
   289 				var map = $('.map', select.parents('fieldset:first'));
       
   290 				var fieldname = map.data('map-leaflet-fieldname');
       
   291 				var longitude = $('input[name="' + fieldname + '.widgets.longitude"]');
       
   292 				var latitude = $('input[name="' + fieldname + '.widgets.latitude"]');
       
   293 				if (event.removed) {
       
   294 					var previous = event.removed.id;
       
   295 					var current = event.added.id;
       
   296 					if (previous !== current) {
       
   297 						if (longitude.val() && latitude.val()) {
       
   298 							var params = {
       
   299 								point: {
       
   300 									longitude: parseFloat(longitude.val()),
       
   301 									latitude: parseFloat(latitude.val())
       
   302 								},
       
   303 								from_projection: previous,
       
   304 								to_projection: current
       
   305 							};
       
   306 							PyAMS_GIS.callJSON('transformPoint', params, function (result) {
       
   307 								if (!result.error) {
       
   308 									var point = result.result.point;
       
   309 									longitude.val(point.longitude);
       
   310 									latitude.val(point.latitude);
       
   311 								}
       
   312 							});
       
   313 						}
       
   314 					}
       
   315 				} else {
       
   316 					PyAMS_GIS.position.changedCoordinate.apply(longitude);
       
   317 				}
       
   318 			},
       
   319 
       
   320 			clear: function(event) {
       
   321 				var fieldset = $(this).parents('fieldset:first');
       
   322 				$('input', fieldset).val(null);
       
   323 			}
       
   324 		},
       
   325 
       
   326 
       
   327 		/**
       
   328 		 * Single rectangular area management
       
   329 		 */
       
   330 		area: {
       
   331 
       
   332 			init: function () {
       
   333 				var map = $('.map', $(this));
       
   334 				if (map.data('leafmap') === undefined) {
       
   335 					map.css('height', $(window).height() - 200);
       
   336 					PyAMS_GIS.init(map, {}, function(leafmap) {
       
   337 						L.Draw = L.Draw || {};
       
   338 						L.Edit = L.Edit || {};
       
   339 						MyAMS.ajax.check([L.Draw, L.Draw.Event, L.Map.TouchExtend, L.Edit.SimpleShape],
       
   340 										 ['/--static--/pyams_gis/js/leaflet.Draw' + MyAMS.devext + '.js',
       
   341 										  '/--static--/pyams_gis/js/leaflet.Draw.Event' + MyAMS.devext + '.js',
       
   342 										  '/--static--/pyams_gis/js/TouchEvents' + MyAMS.devext + '.js',
       
   343 										  '/--static--/pyams_gis/js/Edit.SimpleShape' + MyAMS.devext + '.js'],
       
   344 										 function() {
       
   345 											MyAMS.ajax.check(L.Edit.Rectangle,
       
   346 															 '/--static--/pyams_gis/js/Edit.Rectangle' + MyAMS.devext + '.js',
       
   347 															 function () {
       
   348 
       
   349 																function initRectangle(p1, p2) {
       
   350 																	var group = new L.FeatureGroup();
       
   351 																	rectangle = L.rectangle([p1, p2]);
       
   352 																	group.addLayer(rectangle);
       
   353 																	leafmap.addLayer(group);
       
   354 																	leafmap.fitBounds(rectangle.getBounds());
       
   355 																	rectangle.editing.enable();
       
   356 																	map.data('area', rectangle);
       
   357 																	leafmap.on(L.Draw.Event.EDITMOVE, PyAMS_GIS.area.changedArea);
       
   358 																	leafmap.on(L.Draw.Event.EDITRESIZE, PyAMS_GIS.area.changedArea);
       
   359 																	leafmap.on(L.Draw.Event.EDITVERTEX, PyAMS_GIS.area.changedArea);
       
   360 																}
       
   361 
       
   362 																var data = map.data();
       
   363 																var fieldname = data.mapLeafletFieldname;
       
   364 																var x1 = $('input[name="' + fieldname + '.widgets.x1"]');
       
   365 																var y1 = $('input[name="' + fieldname + '.widgets.y1"]');
       
   366 																var x2 = $('input[name="' + fieldname + '.widgets.x2"]');
       
   367 																var y2 = $('input[name="' + fieldname + '.widgets.y2"]');
       
   368 																var p1,
       
   369 																	p2,
       
   370 																	rectangle;
       
   371 																if (x1.val() && y1.val() && x2.val() && y2.val()) {
       
   372 																	var projection = $('select[name="' + fieldname + '.widgets.projection:list"]');
       
   373 																	var params = {
       
   374 																		area: {
       
   375 																			x1: parseFloat(x1.val()),
       
   376 																			y1: parseFloat(y1.val()),
       
   377 																			x2: parseFloat(x2.val()),
       
   378 																			y2: parseFloat(y2.val())
       
   379 																		},
       
   380 																		from_projection: projection.val(),
       
   381 																		to_projection: PyAMS_GIS.WGS_SRID
       
   382 																	};
       
   383 																	PyAMS_GIS.callJSON('transformArea', params, function(result) {
       
   384 																		if (!result.error) {
       
   385 																			var area = result.result.area;
       
   386 																			p1 = L.latLng({lon: area.x1, lat: area.y1});
       
   387 																			p2 = L.latLng({lon: area.x2, lat: area.y2});
       
   388 																			initRectangle(p1, p2);
       
   389 																		}
       
   390 																	});
       
   391 																} else {
       
   392 																	p1 = L.latLng({lon: -168, lat: -56.37});
       
   393 																	p2 = L.latLng({lon: 191.25, lat: 83.72});
       
   394 																	initRectangle(p1, p2);
       
   395 																}
       
   396 															 });
       
   397 										 });
       
   398 					});
       
   399 				}
       
   400 			},
       
   401 
       
   402 			last_event: null,
       
   403 
       
   404 			changedArea: function(event) {
       
   405 				PyAMS_GIS.area.last_event = event;
       
   406 				setTimeout(function() {
       
   407 					if (event === PyAMS_GIS.area.last_event) {
       
   408 						var map = event.target.getContainer();
       
   409 						var data = $(map).data();
       
   410 						var area = data.area.getBounds();
       
   411 						var fieldname = data.mapLeafletFieldname;
       
   412 						var projection = $('select[name="' + fieldname + '.widgets.projection:list"]').val();
       
   413 						var params = {
       
   414 							area: {
       
   415 								x1: area.getWest(),
       
   416 								y1: area.getSouth(),
       
   417 								x2: area.getEast(),
       
   418 								y2: area.getNorth()
       
   419 							},
       
   420 							from_projection: PyAMS_GIS.WGS_SRID,
       
   421 							to_projection: projection
       
   422 						};
       
   423 						PyAMS_GIS.callJSON('transformArea', params, function(result) {
       
   424 							if (!result.error) {
       
   425 								var area = result.result.area;
       
   426 								$('input[name="' + fieldname + '.widgets.x1"]').val(area.x1);
       
   427 								$('input[name="' + fieldname + '.widgets.y1"]').val(area.y1);
       
   428 								$('input[name="' + fieldname + '.widgets.x2"]').val(area.x2);
       
   429 								$('input[name="' + fieldname + '.widgets.y2"]').val(area.y2);
       
   430 							}
       
   431 						});
       
   432 					}
       
   433 				}, 100);
       
   434 			},
       
   435 
       
   436 			changedCoordinate: function() {
       
   437 				var input = $(this);
       
   438 				var map = $('.map', input.parents('fieldset:first'));
       
   439 				if (!map.data('area')) {
       
   440 					return;
       
   441 				}
       
   442 				var fieldname = map.data('map-leaflet-fieldname');
       
   443 				var x1 = $('input[name="' + fieldname + '.widgets.x1"]');
       
   444 				var y1 = $('input[name="' + fieldname + '.widgets.y1"]');
       
   445 				var x2 = $('input[name="' + fieldname + '.widgets.x2"]');
       
   446 				var y2 = $('input[name="' + fieldname + '.widgets.y2"]');
       
   447 				if (x1.val() && y1.val() && x2.val() && y2.val()) {
       
   448 					var projection = $('select[name="' + fieldname + '.widgets.projection:list"]');
       
   449 					var params = {
       
   450 						area: {
       
   451 							x1: parseFloat(x1.val()),
       
   452 							y1: parseFloat(y1.val()),
       
   453 							x2: parseFloat(x2.val()),
       
   454 							y2: parseFloat(y2.val())
       
   455 						},
       
   456 						from_projection: projection.val(),
       
   457 						to_projection: 4326
       
   458 					};
       
   459 					PyAMS_GIS.callJSON('transformArea', params, function (result) {
       
   460 						if (!result.error) {
       
   461 							var area = result.result.area;
       
   462 							var rect = map.data('area');
       
   463 							rect.editing.disable();
       
   464 							rect.setBounds([L.latLng({lon: area.x1, lat: area.y1}),
       
   465 											L.latLng({lon: area.x2, lat: area.y2})]);
       
   466 							rect.editing.enable();
       
   467 						}
       
   468 					});
       
   469 				}
       
   470 			},
       
   471 
       
   472 			changedProjection: function(event) {
       
   473 				var select = $(this);
       
   474 				var map = $('.map', select.parents('fieldset:first'));
       
   475 				var fieldname = map.data('map-leaflet-fieldname');
       
   476 				var x1 = $('input[name="' + fieldname + '.widgets.x1"]');
       
   477 				var y1 = $('input[name="' + fieldname + '.widgets.y1"]');
       
   478 				var x2 = $('input[name="' + fieldname + '.widgets.x2"]');
       
   479 				var y2 = $('input[name="' + fieldname + '.widgets.y2"]');
       
   480 				if (event.removed) {
       
   481 					var previous = event.removed.id;
       
   482 					var current = event.added.id;
       
   483 					if (previous !== current) {
       
   484 						if (x1.val() && y1.val() && x2.val() && y2.val()) {
       
   485 							var params = {
       
   486 								area: {
       
   487 									x1: parseFloat(x1.val()),
       
   488 									y1: parseFloat(y1.val()),
       
   489 									x2: parseFloat(x2.val()),
       
   490 									y2: parseFloat(y2.val())
       
   491 								},
       
   492 								from_projection: previous,
       
   493 								to_projection: current
       
   494 							};
       
   495 							PyAMS_GIS.callJSON('transformArea', params, function (result) {
       
   496 								if (!result.error) {
       
   497 									var area = result.result.area;
       
   498 									x1.val(area.x1);
       
   499 									y1.val(area.y1);
       
   500 									x2.val(area.x2);
       
   501 									y2.val(area.y2);
       
   502 								}
       
   503 							});
       
   504 						}
       
   505 					}
       
   506 				} else {
       
   507 					PyAMS_GIS.area.changedCoordinate.apply(x1);
       
   508 				}
       
   509 			},
       
   510 
       
   511 			clear: function(event) {
       
   512 				var fieldset = $(this).parents('fieldset:first');
       
   513 				$('input', fieldset).val(null);
       
   514 			}
       
   515 		}
       
   516 	};
       
   517 	globals.PyAMS_GIS = PyAMS_GIS;
       
   518 
       
   519 })(jQuery, this);