|
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: '© <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); |