[PLUGINS] ~maj globale
[lhc/web/www.git] / www / plugins / gis / javascript / leaflet.gis.js
1 (function () {
2 // Plugin Leaflet L.Map.Gis
3 L.Map.Gis = L.Map.extend({
4
5 includes: L.Mixin.Events,
6
7 options:{
8 mapId: 'map_gis',
9 utiliser_bb: false,
10 sw_lat: 0,
11 ne_lat: 0,
12 sw_lon: 0,
13 ne_lon: 0,
14 gis_layers: L.gisConfig.gis_layers,
15 default_layer: L.gisConfig.default_layer,
16 affiche_layers: L.gisConfig.affiche_layers,
17 scaleControl: false,
18 overviewControl: false,
19 layersControl: false,
20 layersControlOptions: {},
21 noControl: false,
22 cluster: false,
23 clusterOptions: {
24 disableClusteringAtZoom: 0,
25 showCoverageOnHover: false,
26 maxClusterRadius: 80,
27 spiderfyOnMaxZoom: false
28 },
29 pathStyles: null,
30 autocenterandzoom: false,
31 openId: false,
32 affiche_points: true,
33 json_points: {
34 url: '',
35 objets: '',
36 limit: 500,
37 env: [],
38 titre: '',
39 description: '',
40 icone: ''
41 },
42 localize_visitor: false,
43 localize_visitor_zoom: 0,
44 centrer_fichier: true,
45 kml: false,
46 gpx: false,
47 geojson: false,
48 topojson: false,
49 langue: false
50 },
51
52 initialize: function (id,options) {
53 L.Util.setOptions(this, options);
54
55 this.on('load', function () {
56 // Affecter sur l'objet du DOM
57 jQuery('#'+this._container.id).get(0).map = this;
58 // Appeler l'éventuelle fonction de callback
59 if (this.options.callback && typeof(this.options.callback) === 'function')
60 this.options.callback(this);
61 // trigger load sur l'objet du DOM
62 jQuery('#'+this._container.id).trigger('load',this);
63 });
64
65 L.Map.prototype.initialize.call(this, id, options);
66
67 if (this.options.utiliser_bb) {
68 this.fitBounds(
69 L.latLngBounds(
70 [this.options.sw_lat, this.options.sw_lon],
71 [this.options.ne_lat, this.options.ne_lon]
72 )
73 );
74 }
75
76 this.populateTileLayers(this.options.affiche_layers);
77
78 this.initControls();
79
80 this.loadData();
81
82 this.addOverlays();
83
84 if (this.options.localize_visitor) {
85 var maxZoom = this.options.localize_visitor_zoom;
86 this.on('locationerror',function (e) {
87 maxZoom = this.options.zoom;
88 alert(e.message);
89 });
90 this.locate({setView: true, maxZoom: maxZoom});
91 }
92
93 // Si pas de points affichés trigger ready ici
94 if (!this.options.affiche_points || !Object.keys(this.options.json_points).length) {
95 jQuery('#'+this._container.id).trigger('ready', this);
96 }
97 },
98
99 populateTileLayers: function () {
100 // Fond de carte par défaut
101 if (this.options.default_layer != 'none') {
102 var default_layer = this.createTileLayer(this.options.default_layer);
103 this.addLayer(default_layer);
104 }
105 // Fonds de carte supplémentaires
106 if (this.options.layersControl && !this.options.noControl && this.options.affiche_layers.length>1) {
107 var layers_control = L.control.layers('','',this.options.layersControlOptions);
108 if (this.options.default_layer != 'none') {
109 layers_control.addBaseLayer(default_layer,this.options.gis_layers[this.options.default_layer].nom);
110 }
111 for (var l in this.options.affiche_layers) {
112 if (this.options.affiche_layers[l]!==this.options.default_layer) {
113 var layer = this.createTileLayer(this.options.affiche_layers[l]);
114 if (typeof layer!=='undefined')
115 layers_control.addBaseLayer(layer,this.options.gis_layers[this.options.affiche_layers[l]].nom);
116 }
117 }
118 this.addControl(layers_control);
119 // Ajouter l'objet du controle de layers à la carte pour permettre d'y accéder depuis le callback
120 this.layersControl = layers_control;
121 // Classe noajax sur le layer_control pour éviter l'ajout de hidden par SPIP
122 L.DomUtil.addClass(layers_control._form,'noajax');
123 }
124 },
125
126 initControls: function () {
127 this.attributionControl.setPrefix('');
128 if (this.options.scaleControl)
129 L.control.scale().addTo(this);
130 if (this.options.overviewControl && this.options.default_layer != 'none') {
131 // todo ajouter une option pour permettre de choisir la couche à afficher dans la minimap
132 var minimap_layer = this.createTileLayer(this.options.default_layer);
133 L.control.minimap(minimap_layer,{width: 100,height: 100, toggleDisplay: true}).addTo(this);
134 }
135 },
136
137 createTileLayer: function (name) {
138 var layer;
139 if (typeof this.options.gis_layers[name]!=='undefined')
140 eval('layer=new '+ this.options.gis_layers[name].layer +';');
141 return layer;
142 },
143
144 // API setGeoJsonFeatureIcon : Pour Ajouter l'icone d'un point (feature = item d'un GeoJson)
145 setGeoJsonFeatureIcon: function (feature, layer) {
146 // Déclarer l'icone du points, si défini
147 if (feature.properties && feature.properties.icon) {
148 icon_options = {
149 'iconUrl': feature.properties.icon,
150 'iconSize': [feature.properties.icon_size[0], feature.properties.icon_size[1]],
151 'iconAnchor': [feature.properties.icon_anchor[0], feature.properties.icon_anchor[1]]
152 };
153 if (feature.properties.popup_anchor)
154 icon_options.popupAnchor = [feature.properties.popup_anchor[0], feature.properties.popup_anchor[1]];
155 if (feature.properties.shadow)
156 icon_options.shadowUrl = feature.properties.shadow;
157 if (feature.properties.shadow_size)
158 icon_options.shadowSize = [feature.properties.shadow_size[0], feature.properties.shadow_size[1]];
159 layer.setIcon(L.icon(icon_options));
160 }
161 },
162
163 // API setGeoJsonFeaturePopup : Pour Ajouter le texte de popup d'un point (feature = item d'un GeoJson)
164 setGeoJsonFeaturePopup: function (feature, layer) {
165 // Déclarer le contenu de la popup s'il y en a
166 if (feature.properties
167 && !feature.properties.noclick
168 && (feature.properties.title || feature.properties.description ||
169 (this.options.langue && (feature.properties['title_'+this.options.langue] || feature.properties['description_'+this.options.langue])))) {
170 var popupContent = '',
171 popupOptions = '',
172 description_ok = false;
173 if (this.options.langue) {
174 langue = this.options.langue;
175 if (feature.properties['title_'+langue]) {
176 popupContent = '<strong class="title">' + feature.properties['title_'+langue] + '</strong>';
177 } else if (feature.properties.title)
178 popupContent = '<strong class="title">' + feature.properties.title + '</strong>';
179 if (feature.properties['description_'+langue]) {
180 popupContent = popupContent + feature.properties['description_'+langue];
181 description_ok = true;
182 }
183 } else if(feature.properties.title)
184 popupContent = '<strong class="title">' + feature.properties.title + '</strong>';
185 if (!description_ok && feature.properties.description)
186 popupContent = popupContent + feature.properties.description;
187 if (feature.properties.popup_options)
188 popupOptions = feature.properties.popup_options;
189 layer.bindPopup(popupContent,popupOptions);
190 }
191 },
192
193 // API parseGeoJson
194 parseGeoJson: function (data) {
195 var map = this;
196 // Analyse des points et déclaration (sans regroupement des points en cluster)
197 if (!map.options.cluster) {
198 if (data.features && data.features.length > 0) {
199 var geojson = L.geoJson('', {
200 style: this.options.pathStyles ? this.options.pathStyles : function (feature) {
201 if (feature.properties && feature.properties.styles)
202 return feature.properties.styles;
203 else
204 return '';
205 },
206 onEachFeature: function (feature, layer) {
207 // Déclarer l'icone du point
208 if (feature.geometry.type == 'Point') {
209 map.setGeoJsonFeatureIcon(feature, layer);
210 }
211 // Déclarer le contenu de la popup s'il y en a
212 map.setGeoJsonFeaturePopup(feature, layer);
213 }
214 }).addData(data).addTo(map);
215
216 if (map.options.autocenterandzoom) {
217 if (data.features.length == 1 && data.features[0].geometry.type == 'Point')
218 map.setView(geojson.getBounds().getCenter(), map.options.zoom);
219 else
220 map.fitBounds(geojson.getBounds());
221 }
222 if (map.options.openId)
223 gis_focus_marker(map.options.openId,map.options.mapId);
224
225 if (typeof map.geojsons=='undefined') map.geojsons = [];
226 map.geojsons.push(geojson);
227 }
228 } else {
229 map.markerCluster = L.markerClusterGroup(map.options.clusterOptions).addTo(map);
230 var markers = [];
231 /* Pour chaque points présents, on crée un marqueur */
232 jQuery.each(data.features, function (i, feature) {
233 if (feature.geometry.coordinates[0]) {
234 var marker = L.marker([feature.geometry.coordinates[1], feature.geometry.coordinates[0]]);
235
236 // Déclarer l'icone du point
237 map.setGeoJsonFeatureIcon(feature, marker);
238 // Déclarer le contenu de la popup s'il y en a
239 map.setGeoJsonFeaturePopup(feature, marker);
240
241 marker.id = feature.id;
242 markers.push(marker);
243 }
244 });
245
246 map.markerCluster.addLayers(markers);
247
248 if (map.options.autocenterandzoom) {
249 if (data.features.length > 1)
250 map.fitBounds(map.markerCluster.getBounds());
251 else
252 map.setView(map.markerCluster.getBounds().getCenter(), map.options.zoom);
253 }
254 }
255 },
256
257 // API Compat GIS3
258 addJSON: function (data) {
259 return this.parseGeoJson(data);
260 },
261
262 // API Compat GIS3
263 removeAllMarkers: function () {
264 // virer les éléments du cluster s'il est utilisé
265 if (this.options.cluster) {
266 this.markerCluster.clearLayers();
267 }
268 // virer les points de la carte
269 if (typeof this.geojsons=='undefined') this.geojsons = [];
270 for (var i in this.geojsons) {
271 this.geojsons[i].clearLayers();
272 this.removeLayer(this.geojsons[i]);
273 }
274 this.geojsons = [];
275 },
276
277 loadData: function () {
278 var map = this;
279 if (map.options.affiche_points
280 && typeof(map.options.json_points) !== 'undefined'
281 && map.options.json_points.url.length) {
282 // Récupération des points à mettre sur la carte, via json externe
283 var args = {};
284 jQuery.extend(true, args, map.options.json_points.env);
285 if (typeof map.options.json_points.objets !== 'undefined') {
286 args.objets = map.options.json_points.objets;
287 if (args.objets == 'point_libre') {
288 args.lat = map.options.center[0];
289 args.lon = map.options.center[1];
290 if (typeof map.options.json_points.titre !== 'undefined')
291 args.titre = map.options.json_points.titre;
292 if (typeof map.options.json_points.description !== 'undefined')
293 args.description = map.options.json_points.description;
294 if (typeof map.options.json_points.icone !== 'undefined')
295 args.icone = map.options.json_points.icone;
296 }
297 }
298 if (typeof map.options.json_points.limit !== 'undefined')
299 args.limit = map.options.json_points.limit;
300 jQuery.getJSON(map.options.json_points.url,args,
301 function (data) {
302 if (data) {
303 // Charger le json (data) et déclarer les points
304 map.parseGeoJson(data);
305 jQuery('#'+map._container.id).trigger('ready',map);
306 }
307 }
308 );
309 }
310 },
311
312 addOverlays: function () {
313 var map = this;
314 if (map.options.kml && map.options.kml.length) {
315 map.kml = {};
316 for (var i in map.options.kml) {
317 map.kml[i] = new L.KML(map.options.kml[i], {async: true});
318 if (map.options.centrer_fichier)
319 map.kml[i].on('loaded', function (e) { map.fitBounds(e.target.getBounds()); });
320 map.addLayer(map.kml[i]);
321 }
322 }
323 if (map.options.gpx && map.options.gpx.length) {
324 map.gpx = {};
325 for (var i in map.options.gpx) {
326 map.gpx[i] = new L.GPX(map.options.gpx[i], {async: true});
327 if (map.options.centrer_fichier)
328 map.gpx[i].on('loaded', function (e) { map.fitBounds(e.target.getBounds()); });
329 map.addLayer(map.gpx[i]);
330 }
331 }
332 if (map.options.geojson && map.options.geojson.length) {
333 for (var i in map.options.geojson) {
334 jQuery.getJSON(map.options.geojson[i], function (data) {
335 if (data)
336 map.parseGeoJson(data);
337 });
338 }
339 }
340 if (map.options.topojson && map.options.topojson.length) {
341 for (var i in map.options.topojson) {
342 map.topojson[i] = new L.TOPOJSON(map.options.topojson[i], {async: true});
343 if (map.options.centrer_fichier) {
344 map.topojson[i].on('loaded', function (e) { map.fitBounds(e.target.getBounds()); });
345 }
346 map.addLayer(map.topojson[i]);
347 }
348 }
349 }
350 });
351
352 L.map.gis = function (id, options) {
353 return new L.Map.Gis(id, options);
354 };
355
356 })();