Subversion Repositories eFlore/Applications.moissonnage

Rev

Rev 31 | Rev 41 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
7 delphine 1
var map = null,
28 alex 2
optionsCoucheOSM = {
3
	attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors,'
4
	+ ' <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
5
	maxZoom: 18
6
},
7
optionsCoucheGoogle = {
31 alex 8
	attribution: 'Map data &copy;'+new Date().getFullYear()+' <a href="http://maps.google.com">Google</a>',
28 alex 9
	maxZoom: 18
10
},
37 alex 11
coucheOSM = new L.TileLayer("http://a.tile.openstreetmap.org/{z}/{x}/{y}.png",
28 alex 12
	optionsCoucheOSM),
37 alex 13
coucheRelief = new L.TileLayer("http://c.tile3.opencyclemap.org/landscape/{z}/{x}/{y}.png",
14
	optionsCoucheOSM),
15
coucheSatellite = new L.TileLayer("http://mt1.google.com/vt/lyrs=y@218131653&hl=fr&src=app&x={x}&y={y}&z={z}",
28 alex 16
	optionsCoucheGoogle),
7 delphine 17
optionsCarte = {
18
	center : new L.LatLng(46, 2),
19
	zoom : 6,
20
	minZoom : 3,
28 alex 21
	maxBounds : [[-85.051129, -180], [85.051129, 180]],
31 alex 22
	layers : [coucheOSM]
7 delphine 23
},
31 alex 24
zoom = 6,
28 alex 25
legende = null,
31 alex 26
coucheDepartement = null,
28 alex 27
infoBulle = null;
7 delphine 28
 
37 alex 29
var coucheSites = null,
31 alex 30
sources = new Object(),
37 alex 31
typeSite = 'maille',
7 delphine 32
overlays = [];
33
 
34
var requeteChargementPoints = null,
35
timer = null,
37 alex 36
ancienneRequete = null,
37
deplacement = true,
7 delphine 38
url = '';
39
 
40
 
41
 
42
 
43
$(document).ready(function() {
44
	initialiserWidget();
45
});
46
 
37 alex 47
$(window).resize(function() {
48
	dimensionnerCarte();
49
});
50
 
7 delphine 51
function initialiserWidget() {
52
	initialiserCarte();
37 alex 53
	chargerLimitesCommunales();
31 alex 54
	initialiserPanneauControle();
55
	initialiserSources();
7 delphine 56
	initialiserListeners();
37 alex 57
	chargerLocalisations();
7 delphine 58
}
59
 
60
function initialiserCarte() {
61
	dimensionnerCarte();
62
	map = L.map('map', optionsCarte);
37 alex 63
	coucheSatellite.addTo(map);
64
	coucheRelief.addTo(map);
7 delphine 65
	coucheOSM.addTo(map);
66
	var echelle = new L.Control.Scale({
37 alex 67
		maxWidth : 50,
7 delphine 68
		metric : true,
69
		imperial : false,
70
		updateWhenIdle : true
71
	});
72
	map.addControl(echelle);
31 alex 73
	zoom = map.getZoom();
7 delphine 74
}
31 alex 75
 
37 alex 76
function dimensionnerCarte() {
77
	$('#map').height($(window).height());
78
	$('#map').width($(window).width());
79
}
80
 
7 delphine 81
function initialiserListeners() {
37 alex 82
	map.on('moveend', surChangementVueCarte);
83
	map.on('zoomend', surChangementVueCarte);
7 delphine 84
	map.on('popupclose', function(e) {
85
		masquerInfoBulle();
28 alex 86
		programmerRafraichissementCarte();
7 delphine 87
	});
88
}
89
 
90
function initialiserPanneauControle() {
91
	var baseMaps = {
37 alex 92
		"Satellite" : coucheSatellite,
93
		"Relief" : coucheRelief,
94
		"Plan" : coucheOSM
7 delphine 95
	};
96
 
97
	var overlayMaps = {};
31 alex 98
	for (var index = 0; index < listeSources.length; index ++) {
99
		sources[listeSources[index]] = estValeurDansTableau(source, listeSources[index]);
100
		overlayMaps[listeSources[index]] = new L.LayerGroup();
7 delphine 101
	}
102
	L.control.layers(baseMaps, overlayMaps).addTo(map);
31 alex 103
	coucheOSM.bringToFront();
37 alex 104
	map.removeLayer(coucheRelief);
105
	map.removeLayer(coucheOSM);
7 delphine 106
 
107
	// garder par defaut la couche plan google comme selectionnee dans le panel
108
	var selecteursFonds = $('.leaflet-control-layers-base .leaflet-control-layers-selector');
31 alex 109
	selecteursFonds[0].checked = true;
110
	selecteursFonds[1].checked = false;
7 delphine 111
	selecteursFonds[2].checked = false;
112
}
113
 
28 alex 114
function chargerLimitesCommunales() {
31 alex 115
	coucheDepartement = new L.KML(null, {async : true}).addTo(map);
28 alex 116
	if (urlsLimitesCommunales != null) {
31 alex 117
		coucheDepartement.addKMLFiles(urlsLimitesCommunales);
28 alex 118
	}
119
}
120
 
7 delphine 121
function initialiserSources() {
122
	overlays = $('.leaflet-control-layers-overlays .leaflet-control-layers-selector');
123
	$.each(overlays, function (index, input) {
31 alex 124
		input.value = listeSources[index];
7 delphine 125
		input.id = 'overlay' + (index+1);
31 alex 126
		var lien = '<a href="' + liensVersSources[index] + '" target="_blank">' + nomListeSources[index] + '</a>';
7 delphine 127
		$('#overlay' + (index+1) + ' ~ span').html(lien);
31 alex 128
		input.checked = sources[listeSources[index]];
129
		input.onclick = function(event) {
7 delphine 130
			changerSource(event.target.value);
131
		}
132
	});
133
}
134
 
37 alex 135
function changerSource(projetClique) {
136
	var indexProjetClique;
137
	for (var index = 0; index < overlays.length; index ++) {
138
		if (overlays[index].value == projetClique) {
139
			indexProjetClique = index;
31 alex 140
		}
141
	}
37 alex 142
	masquerInfoBulle();
143
	sources[projetClique] = overlays[indexProjetClique].checked;
144
	if (sources[projetClique] == true) {
145
		programmerRafraichissementCarte(projetClique);
146
	} else {
147
		if (requeteEnCours()) {
148
			stopperRequeteAjax();
149
		}
150
		supprimerFeaturesSource(projetClique);
151
	}
31 alex 152
}
153
 
37 alex 154
function supprimerFeaturesSource(source) {
155
	if (coucheSites != null) {
156
		coucheSites.eachLayer(function(layer) {
157
			if (layer.typeSite == 'maille') {
158
				retirerStationsEtObservations(layer, source);
159
			} else {
160
				layer.supprimerSource(source, coucheSites);
161
				if (layer._map == 'null') {
162
					couheSites.removeLayer(layer);
163
				}
164
			}
165
		});
166
		if (typeSite == 'maille') {
167
			var nombreMailles = calculerNombreMaillesVisibles();
168
			if (nombreMailles == 0) {
169
				coucheSites.clearLayers();
170
				masquerLegende();
171
				typeSite = 'point';
172
			}
173
		}
174
	}
175
}
176
 
177
function retirerStationsEtObservations(maille, sourceRetrait) {
178
	var sources = maille.properties.source;
179
	var nombreStations = 0;
180
	for (var index = 0; index < sources.length; index ++) {
181
		var source = sources[index];
182
		if (source == sourceRetrait) {
183
			delete maille.properties.stations[source];
184
			delete maille.properties.observations[source];
185
		} else if (typeof(maille.properties.stations[source]) != 'undefined') {
186
			nombreStations += parseInt(maille.properties.stations[source]);
187
		}
188
	}
189
	if (nombreStations == 0) {
190
		coucheSites.removeLayer(maille);
28 alex 191
	} else {
37 alex 192
		colorerMaille(maille)
193
		genererInfobulle(maille);
28 alex 194
	}
195
}
7 delphine 196
 
37 alex 197
function calculerNombreMaillesVisibles() {
198
	var nombreMailles = 0;
199
	coucheSites.eachLayer(function(layer) {
200
		if($(layer._path).attr('fill-opacity') != '0') {
201
			nombreMailles ++;
202
		}
203
	});
204
	return nombreMailles;
205
}
206
 
207
function estValeurDansTableau(tableau, valeur) {
208
	var index;
209
	for (index = 0; index < tableau.length && tableau[index] != valeur; index ++);
210
	return (tableau.length > 0 && index != tableau.length);
211
}
212
 
213
//************************************
214
// requetes stations
215
 
216
function surChangementVueCarte() {
217
	programmerRafraichissementCarte();
218
}
219
 
220
function programmerRafraichissementCarte(source) {
221
	$('#tooltip').css('display', 'none');
222
	source = (source == null || source == 'null') ? null : source;
31 alex 223
	if (timer != null) {
37 alex 224
		window.clearTimeout(timer);
225
	}
31 alex 226
	if (requeteChargementPoints != null) {
227
		stopperRequeteAjax();
7 delphine 228
	}
37 alex 229
	var nombreSourcesVisibles = 0;
230
	for (var index = 0; index < overlays.length; index ++) {
231
		if (overlays[index].checked) {
232
			nombreSourcesVisibles ++;
31 alex 233
		}
37 alex 234
	}
235
	if (source == null) {
236
		timer = window.setTimeout("chargerLocalisations()", 100);
237
	} else {
238
		timer = window.setTimeout("chargerSource('"+source+"')", 100);
239
	}
31 alex 240
}
7 delphine 241
 
31 alex 242
function stopperRequeteAjax() {
243
	requeteChargementPoints.abort();
244
	requeteChargementPoints = null;
245
}
246
 
37 alex 247
function chargerLocalisations() {
248
	if (requeteEnCours()) {
249
		requeteChargementPoints.abort();
31 alex 250
	}
37 alex 251
	afficherMessageChargement('stations');
252
	if (!(ancienneRequete != null && ancienneRequete[1] == map.getZoom()
253
		&& map.getBounds().intersects(ancienneRequete[0]))) {
254
		supprimerFeatures();
255
		deplacement = false;
256
	}
257
	var bboxRequete = calculerBboxRequete();
258
	var parametres = {
259
		"bbox" : bboxRequete,
260
		"zoom" : map.getZoom(),
261
		"source" : recupererSourcesActivees(),
262
		"num_taxon" : numTaxon,
263
		"nn" : nn,
264
		"referentiel" : referentiel,
265
		"dept" : dept,
266
		"auteur" : auteur,
267
		"date_debut" : dateDebut,
268
		"date_fin" : dateFin,
269
		"nb_jours" : nbJours
270
	};
271
	if (deplacement == true) {
272
		parametres.format = typeSite;
273
	}
274
	ancienneRequete = [map.getBounds(), map.getZoom()];
275
	url = urlBase + "stations?" + convertirEnParametresUrl(parametres);
276
	fonctionCallback = traiterDonneesStations;
277
	executerAJAX();
31 alex 278
}
279
 
37 alex 280
function supprimerFeatures() {
281
	if (coucheSites != null) {
282
		coucheSites.clearLayers();
283
		coucheSites = null;
284
	}
7 delphine 285
}
286
 
37 alex 287
function recupererSourcesActivees(sourceAIgnorer) {
288
	sourceAIgnorer = typeof(sourceAIgnorer) == 'undefined' ? '' : sourceAIgnorer;
289
	var sourcesActivees = [];
290
	for (var index = 0; index < overlays.length; index ++) {
291
		if (overlays[index].checked == true && overlays[index].value != sourceAIgnorer) {
292
			sourcesActivees.push(overlays[index].value);
31 alex 293
		}
294
	}
37 alex 295
	return sourcesActivees.join(',');
31 alex 296
}
7 delphine 297
 
37 alex 298
function chargerSource(sourceAjout) {
299
	if (requeteEnCours()) {
300
		requeteChargementPoints.abort();
301
	}
302
	afficherMessageChargement('stations');
303
	var bboxRequete = determinerCoordonneesBordure();
304
	var parametres = {
305
		"bbox" : bboxRequete,
306
		"zoom" : map.getZoom(),
307
		"format" : typeSite,
308
		"source" : sourceAjout,
309
		"num_taxon" : numTaxon,
310
		"nn" : nn,
311
		"referentiel" : referentiel,
312
		"dept" : dept,
313
		"auteur" : auteur,
314
		"date_debut" : dateDebut,
315
		"date_fin" : dateFin,
316
		"nb_jours" : nbJours
317
	};
318
	ancienneRequete = [map.getBounds(), map.getZoom()];
319
	url = urlBase + "stations?" + convertirEnParametresUrl(parametres);
320
	fonctionCallback = traiterRetourChargementSource;
321
	executerAJAX();
31 alex 322
}
323
 
37 alex 324
function calculerBboxRequete() {
325
	var bordure = map.getBounds();
326
	var bboxRequete = "";
327
	if (ancienneRequete != null && ancienneRequete[1] == map.getZoom()
328
		&& bordure.intersects(ancienneRequete[0])) {
329
		bboxRequete = calculerIntersectionRectangle(ancienneRequete[0], bordure);
330
	} else {
331
		bboxRequete = determinerCoordonneesBordure();
332
	}
333
	return bboxRequete;
334
}
335
 
336
function calculerIntersectionRectangle(rectangle1, rectangle2) {
337
	var bbox1 = [rectangle2.getSouthWest().lng.toFixed(6), rectangle2.getSouthWest().lat.toFixed(6),
338
	    rectangle2.getNorthEast().lng.toFixed(6), rectangle2.getNorthEast().lat.toFixed(6)];
339
	var bbox2 = [rectangle2.getSouthWest().lng.toFixed(6), rectangle2.getSouthWest().lat.toFixed(6),
340
	    rectangle2.getNorthEast().lng.toFixed(6), rectangle2.getNorthEast().lat.toFixed(6)];
341
 
342
	if (rectangle2.getSouthWest().lng >= rectangle1.getSouthWest().lng
343
	 	&& rectangle2.getSouthWest().lng <= rectangle1.getNorthEast().lng) {
344
		bbox2[0] = bbox1[2] = rectangle1.getNorthEast().lng.toFixed(6);
345
		if (rectangle2.getSouthWest().lat >= rectangle1.getSouthWest().lat
346
			&& rectangle2.getSouthWest().lat <= rectangle1.getNorthEast().lat) {
347
			bbox1[1] = rectangle1.getNorthEast().lat.toFixed(6);
31 alex 348
		} else {
37 alex 349
			bbox1[3] = rectangle1.getSouthWest().lat.toFixed(6);
31 alex 350
		}
37 alex 351
	} else {
352
		bbox2[0] = bbox1[2] = rectangle1.getSouthWest().lng.toFixed(6);
353
		if (rectangle2.getSouthWest().lat >= rectangle1.getSouthWest().lat
354
			&& rectangle2.getSouthWest().lat <= rectangle1.getNorthEast().lat) {
355
			bbox2[1] = rectangle1.getNorthEast().lat.toFixed(6);
356
		} else {
357
			bbox2[3] = rectangle1.getSouthWest().lat.toFixed(6);
358
		}
31 alex 359
	}
37 alex 360
	return bbox1.join(',')+'|'+bbox2.join(',');
31 alex 361
}
362
 
37 alex 363
function determinerCoordonneesBordure() {
364
	var ouest = map.getBounds().getSouthWest().lng.toFixed(6),
365
		sud = Math.max(map.getBounds().getSouthWest().lat, -85.051129).toFixed(6),
366
		est = map.getBounds().getNorthEast().lng.toFixed(6),
367
		nord = Math.min(map.getBounds().getNorthEast().lat, 85.051129).toFixed(6);
368
	// appliquer les limites possibles de la projection actuellement utilisee aux coordonnees
369
	// longitudes ouest et est de la bbox (permettra d'eviter de renvoyer des messages d'erreur)
370
	if (ouest < -180) {
371
		ouest += 360;
372
	} else if (ouest > 180) {
373
		ouest -= 360;
7 delphine 374
	}
37 alex 375
	if (est < -180) {
376
		est += 360;
377
	} else if (est > 180) {
378
		est -= 360;
7 delphine 379
	}
37 alex 380
	return [ouest, sud, est, nord].join(',');
7 delphine 381
}
382
 
383
function afficherMessageChargement(element) {
31 alex 384
	if ($("#zone-chargement").css('display') == 'none') {
385
		var divTmplElement = 'tpl-chargement-' + element;
386
		$("#zone-chargement").append($("#" + divTmplElement).text());
387
		$("#zone-chargement").css('display', 'block');
388
	}
7 delphine 389
}
390
 
391
function masquerMessageChargement() {
392
	$("#zone-chargement").css('display', 'none');
393
	$("#zone-chargement").children().remove();
394
}
395
 
396
function executerAJAX() {
397
	if (requeteEnCours()) {
398
		requeteChargementPoints.abort();
399
	}
400
	requeteChargementPoints = $.getJSON(url).complete(function() {
28 alex 401
		fonctionCallback();
7 delphine 402
	});
403
}
404
 
405
function requeteEnCours() {
406
	return (requeteChargementPoints != null && requeteChargementPoints.readyState != 4);
407
}
408
 
31 alex 409
function estStatutRequeteOK() {
28 alex 410
	return ((requeteChargementPoints.status == 200 || requeteChargementPoints.status == 304)
411
		|| requeteChargementPoints.status == 0);
412
}
7 delphine 413
 
37 alex 414
function convertirEnParametresUrl(objet) {
415
	var parametresUrl = '';
416
	for (attribut in objet) {
417
		if (typeof(objet[attribut]) == 'function' || typeof(objet[attribut]) == 'undefined' ||
418
			objet[attribut] == null || objet[attribut] == '*' || objet[attribut] == 0)
419
			continue;
420
		parametresUrl += (parametresUrl == '' ? '' : '&') + attribut + "=" + objet[attribut];
31 alex 421
	}
37 alex 422
	return parametresUrl;
423
};
7 delphine 424
 
37 alex 425
function traiterDonneesStations() {
426
	masquerMessageChargement();
427
	masquerLegende();
428
	if (deplacement == true) {
429
		supprimerFeaturesHorsBbox();
7 delphine 430
	}
37 alex 431
	deplacement = true;
432
	var texte = requeteChargementPoints.responseText;
433
	if (!estStatutRequeteOK()) {
434
		alert(texte);
435
	} else {
436
		var donneesJSON = eval("(function(){return " + texte + ";})()");
437
		if (donneesJSON != null && donneesJSON.features.length > 0) {
438
			ajouterStationsSurCarte(donneesJSON);
439
		}
7 delphine 440
	}
441
}
442
 
37 alex 443
function traiterRetourChargementSource() {
28 alex 444
	masquerMessageChargement();
445
	var texte = requeteChargementPoints.responseText;
31 alex 446
	if (!estStatutRequeteOK()) {
28 alex 447
		alert(texte);
448
	} else {
449
		var donneesJSON = eval("(function(){return " + texte + ";})()");
37 alex 450
		if (donneesJSON != null && donneesJSON.features.length > 0) {
451
			var formatRetourDifferent = donneesJSON.stats.formeDonnees != typeSite;
31 alex 452
			ajouterStationsSurCarte(donneesJSON);
37 alex 453
			if (formatRetourDifferent) {
454
				var sourceAIgnorer = donneesJSON.stats.source[0];
455
				var sourcesARecharger = recupererSourcesActivees(sourceAIgnorer);
456
				rechargerSources(sourcesARecharger);
457
			}
28 alex 458
		}
459
	}
460
}
7 delphine 461
 
37 alex 462
function supprimerFeaturesHorsBbox() {
463
	var bordure = map.getBounds();
464
	var layersRestants = 0;
465
	if (coucheSites != null) {
466
		coucheSites.eachLayer(function(layer) {
467
			if (typeof(layer._latlng) != 'undefined') {
468
				if (bordure.contains(layer.getLatLng())) {
469
					layersRestants ++;
470
				} else {
471
					coucheSites.supprimerPoint(layer);
472
				}
473
			} else {
474
				if (bordure.intersects(layer.getBounds())) {
475
					layersRestants ++;
476
				} else {
477
					coucheSites.removeLayer(layer);
478
				}
479
			}
480
		});
7 delphine 481
	}
37 alex 482
	if (layersRestants == 0) {
483
		coucheSites = null;
31 alex 484
	}
37 alex 485
}
486
 
487
function rechargerSources(sourcesARecharger) {
488
	var listeSourcesASupprimer = sourcesARecharger.split(',');
489
	for (var index = 0; index < listeSourcesASupprimer.length; index ++) {
490
		supprimerFeaturesSource(listeSourcesASupprimer[index]);
7 delphine 491
	}
37 alex 492
	chargerSource(sourcesARecharger);
7 delphine 493
}
494
 
37 alex 495
function ajouterStationsSurCarte(donnees) {
496
	typeSite = donnees.stats.formeDonnees;
497
	if (coucheSites == null) {
498
		coucheSites = (typeSite == 'maille') ? new L.FeatureGroup() : new L.ClusterGroup();
499
		map.addLayer(coucheSites);
500
	}
501
	for (var index = 0; index < donnees.features.length; index ++) {
502
		var feature = donnees.features[index];
503
		if (typeSite == 'maille') {
504
			traiterMaille(feature);
505
		} else {
506
			ajouterPoint(feature);
507
		}
508
	}
509
	if (donnees.features.length > 0) {
510
		afficherLegende();
511
	}
512
	if (typeSite == 'maille') {
513
		genererInfobulleMailles();
31 alex 514
	} else {
37 alex 515
		coucheSites.afficherClusters();
31 alex 516
	}
517
}
518
 
37 alex 519
// =========================================
31 alex 520
// Gestion des mailles
521
 
522
function traiterMaille(feature) {
7 delphine 523
	var coordonnees = [];
524
	for (var i = 0; i < feature.geometry.coordinates.length; i++) {
525
		var sommet = new L.LatLng(feature.geometry.coordinates[i][0], feature.geometry.coordinates[i][1]);
526
		coordonnees.push(sommet);
527
	}
31 alex 528
	var maille = rechercherMailleExistante(coordonnees);
529
	if (maille) {
530
		mettreAJourMaille(maille, feature);
37 alex 531
	} else {
532
		maille = ajouterMaille(feature, coordonnees);
31 alex 533
	}
37 alex 534
	colorerMaille(maille);
7 delphine 535
}
536
 
31 alex 537
function rechercherMailleExistante(coordonnees) {
538
	var mailleTrouvee = null;
539
	coucheSites.eachLayer(function(layer) {
37 alex 540
		if ('typeSite' in layer && layer.typeSite == 'maille') {
31 alex 541
			if (sontMaillesIdentiques(coordonnees, layer._latlngs)) {
542
				mailleTrouvee = layer;
543
				return;
544
			}
545
		}
7 delphine 546
	});
31 alex 547
	return mailleTrouvee;
7 delphine 548
}
549
 
31 alex 550
function sontMaillesIdentiques(coordonnees1, coordonnees2) {
551
	return (
552
		coordonnees1[0].lat == coordonnees2[0].lat &&
553
		coordonnees1[0].lng == coordonnees2[0].lng &&
554
		coordonnees1[2].lat == coordonnees2[2].lat &&
555
		coordonnees1[2].lng == coordonnees2[2].lng
556
	);
557
}
558
 
37 alex 559
function ajouterMaille(feature, coordonnees) {
31 alex 560
	var maille = new L.Polygon(coordonnees);
37 alex 561
	var optionsMaille = {
562
		color: '#FFFFFF',
563
		opacity : 0.7,
564
		weight: 1,
565
		fillOpacity : 0.6
566
	};
31 alex 567
	maille.setStyle(optionsMaille);
37 alex 568
	maille.typeSite = 'maille';
569
	maille.properties = feature.properties;
31 alex 570
	coucheSites.addLayer(maille);
37 alex 571
	return maille;
28 alex 572
}
573
 
31 alex 574
function mettreAJourMaille(maille, feature) {
37 alex 575
	var sources = feature.properties.source;
576
	for (var index = 0; index < sources.length; index ++) {
577
		var source = sources[index];
578
		maille.properties.stations[source] = parseInt(feature.properties.stations[source]);
579
		maille.properties.observations[source] = parseInt(feature.properties.observations[source]);
580
		maille.properties.source.push(source);
581
	}
31 alex 582
}
583
 
37 alex 584
function colorerMaille(maille) {
585
	var nombreStations = 0;
586
	var sources = maille.properties.source;
587
	for (var index = 0; index < sources.length; index ++) {
588
		var source = sources[index];
589
		if (typeof(maille.properties.stations[source]) != 'undefined') {
590
			nombreStations += parseInt(maille.properties.stations[source]);
31 alex 591
		}
7 delphine 592
	}
37 alex 593
	if (nombreStations > 0) {
31 alex 594
		maille.on('click', surClicMaille);
37 alex 595
		maille.setStyle({fillColor : genererCouleur(nombreStations), fillOpacity: 0.45, opacity: 0.7});
31 alex 596
	} else {
597
		maille.setStyle({fillOpacity: 0, opacity: 0});
37 alex 598
		maille.off('click');
31 alex 599
	}
7 delphine 600
}
601
 
31 alex 602
function genererCouleur(nombrePoints) {
28 alex 603
	var couleur = {'bleu': 231, 'vert': 224, 'rouge': 64},
604
		seuils = [1, 10, 50 ,100, 500, 1000, 2500],
605
		pas = 26,
606
		position = 0;
607
	for (var index = 1; index < seuils.length-1 && nombrePoints >= seuils[index]; index ++) {
608
		position ++;
7 delphine 609
	}
28 alex 610
	couleur.vert -= position*pas;
611
	return 'rgb('+couleur.bleu+','+couleur.vert+','+couleur.rouge+')';
7 delphine 612
}
613
 
37 alex 614
function surClicMaille(event) {
615
	map.fitBounds(event.layer.getBounds());
616
}
617
 
7 delphine 618
function afficherLegende() {
31 alex 619
	if (legende == null) {
620
		legende = new L.Control({position : 'bottomright'});
621
		legende.onAdd = function(map) {
37 alex 622
			var contenuHtml = '';
623
			if (typeSite == 'maille') {
624
				contenuHtml = construireContenuHtmlLegendeMailles();
625
			} else {
626
				contenuHtml = construireContenuHtmlLegendePoints();
627
			}
628
			return contenuHtml;
31 alex 629
		};
630
		map.addControl(legende);
631
	}
7 delphine 632
}
633
 
37 alex 634
function construireContenuHtmlLegendeMailles() {
28 alex 635
	var div = L.DomUtil.create('div', 'info');
636
	div.innerHTML = '<h4>' + titreLegende + '</h4>';
637
	var seuils = [1, 10, 50 ,100, 500, 1000, 2500];
638
	var labels = [];
639
	for (var i = 0; i < seuils.length; i ++) {
640
		div.innerHTML +=
641
			'<div class="legend">'+
37 alex 642
				'<span class="couleur-maille" style="background:' + genererCouleur(seuils[i] + 1) + '">'+
643
				'</span>'+seuils[i]+ (i + 1 < seuils.length ? '&ndash;' + seuils[i + 1] : '+')+
28 alex 644
			'</div>';
7 delphine 645
	}
28 alex 646
	return div;
7 delphine 647
}
648
 
28 alex 649
function masquerLegende() {
31 alex 650
	if (legende != null) {
651
		map.removeControl(legende);
652
		legende = null;
653
	}
28 alex 654
}
7 delphine 655
 
37 alex 656
function genererInfobulleMailles() {
657
	coucheSites.eachLayer(function(layer) {
658
		if (layer.typeSite == 'maille') {
659
			genererInfobulle(layer);
660
		}
661
	});
31 alex 662
}
7 delphine 663
 
31 alex 664
function genererInfobulle(maille) {
37 alex 665
	var sources = maille.properties.source;
666
	var textes = new Array();
667
	for (var index = 0; index < sources.length; index ++) {
668
		var source = sources[index];
669
		if (typeof(maille.properties.stations[source]) != 'undefined') {
670
			textes.push(source+" : "+maille.properties.stations[source]+" stations, "
671
				+maille.properties.observations[source]+" observations");
31 alex 672
		}
673
	}
37 alex 674
	var contenu = textes.join('<br />');
675
	maille.on('mouseover', function() {
676
		afficherTooltip(contenu, map.latLngToContainerPoint(maille.getBounds().getSouthWest()));
677
	});
678
	maille.on('mouseout', function() {
679
		$("#tooltip").css('display', 'none');
680
	});
681
}
682
 
683
function afficherTooltip(texte, point) {
684
	$("#tooltip").html(texte);
685
	if ($("#tooltip").css('display') == 'none') {
686
		var x = point.x - 15;
687
		var y = point.y + (typeSite == 'maille' ? 1 : 10);
688
		$("#tooltip").css('display', 'block');
689
		$("#tooltip").css('left', x + 'px');
690
		$("#tooltip").css('top', y + 'px');
31 alex 691
	}
692
}
28 alex 693
 
31 alex 694
 
695
 
696
 
697
// ====================================================================
37 alex 698
// Gestion des points
31 alex 699
 
700
function ajouterPoint(feature) {
701
	var iconePoint = new L.Icon({ iconUrl : pointImageUrl,   iconSize : [16, 16] }),
702
		iconeCommune   = new L.Icon({ iconUrl : communeImageUrl, iconSize : [24, 32] }),
703
		icone = (feature.properties.typeSite == 'STATION') ? iconePoint : iconeCommune,
37 alex 704
		point = new L.LatLng(feature.geometry.coordinates[0], feature.geometry.coordinates[1]);
705
	var marker = new L.Cluster(point, {
706
		icon  : icone,
707
		titre : feature.properties.nom
708
	});
709
	marker.typeSite = feature.properties.typeSite.toLowerCase();
31 alex 710
	marker.source = feature.properties.source;
711
	marker.on('click', surClicMarqueur);
37 alex 712
	marker.on('mouseover', function() {
713
		afficherTooltip(marker.options.titre, map.latLngToContainerPoint(marker.getLatLng()));
31 alex 714
	});
37 alex 715
	marker.on('mouseout', function() {
716
		$("#tooltip").css('display', 'none');
31 alex 717
	});
37 alex 718
	coucheSites.ajouterPoint(marker);
31 alex 719
}
720
 
37 alex 721
function construireContenuHtmlLegendePoints() {
722
	var div = L.DomUtil.create('div', 'info');
723
	div.innerHTML =
724
	'<h4>Stations</h4>'+
725
	'<div class="legend"><table>'+
726
		'<tr>'+
727
			'<td class="image-station"><img src="'+communeImageUrl+'" width="24" height="32" /></td>'+
728
			'<td class="label-station">Commune</td>'+
729
		'</tr>'+
730
		'<tr>'+
731
			'<td class="image-station"><img src="'+pointImageUrl+'" /></td>'+
732
			'<td class="label-station">Lieu précis</td>'+
733
		'</tr>'+
734
		'<tr>'+
735
			'<td class="image-station"><img src="'+clusterImageUrl+'" width="20" height="20" /></td>'+
736
			'<td class="label-station">Groupe de stations proches</td>'+
737
		'</tr>'+
738
	'</table></div>';
739
	return div;
31 alex 740
}
741
 
742
 
37 alex 743
function surClicMarqueur(event) {
744
	var nombreMarkers = event.target.recupererMarkers().length;
745
	if (nombreMarkers == 1 || map.getZoom() == map.getMaxZoom()) {
746
		recupererObservations(event.target);
747
	} else {
748
		map.setView(event.target.getLatLng(), Math.min(map.getZoom()+2, map.getMaxZoom()));
31 alex 749
	}
750
}
751
 
37 alex 752
function recupererObservations(cluster) {
753
	pointClique = cluster;
754
	var latlng = cluster.getLatLng();
7 delphine 755
	afficherMessageChargement('observations');
28 alex 756
	var parametres = {
37 alex 757
		"source" : recupererSourcesCluster(cluster),
758
		"stations" : construireListeStationsCluster(cluster),
31 alex 759
		"num_taxon" : numTaxon,
37 alex 760
		"nn" : nn,
28 alex 761
		"referentiel" : referentiel,
762
		"auteur" : auteur,
31 alex 763
		"date_debut" : dateDebut,
764
		"date_fin" : dateFin,
765
		"nb_jours" : nbJours
28 alex 766
	};
767
	url = urlBase + "observations?" + convertirEnParametresUrl(parametres);
768
	fonctionCallback = traiterDonneesObservations;
769
	executerAJAX();
770
}
771
 
37 alex 772
function recupererSourcesCluster(cluster) {
773
	var markers = cluster.recupererMarkers();
774
	var sourcesCluster = [];
775
	for (var index = 0; index < markers.length; index ++) {
776
		if (sourcesCluster.indexOf(markers[index].source) == -1) {
777
			sourcesCluster.push(markers[index].source);
778
		}
779
	}
780
	return sourcesCluster.join(',');
781
}
782
 
783
function construireListeStationsCluster(cluster) {
784
	var markers = cluster.recupererMarkers();
785
	var listePoints = [];
786
	for (var index = 0; index < markers.length; index ++) {
787
		var latlng = markers[index].getLatLng();
788
		listePoints.push(markers[index].source+":"+markers[index].typeSite+":"+latlng.lng+","+latlng.lat);
789
	}
790
	return listePoints.join('|');
791
}
792
 
28 alex 793
function traiterDonneesObservations() {
794
	masquerMessageChargement();
795
	var texte = requeteChargementPoints.responseText;
31 alex 796
	if (!estStatutRequeteOK()) {
28 alex 797
		alert(texte);
798
	} else {
799
		obsJSON = eval("(function(){return " + texte + ";})()");
31 alex 800
		if (obsJSON != null) {
801
			viderListeObservations();
802
			if (obsJSON.total > 0) {
803
				doitRafraichirCarte = false;
804
				map.setView(new L.LatLng(pointClique.getLatLng().lat, pointClique.getLatLng().lng), map.getZoom());
805
				afficherInfoBulle();
806
			} else if (infoBulle != null)  {
807
				masquerInfoBulle();
808
			}
7 delphine 809
		}
810
	}
811
}
812
 
813
 
814
 
31 alex 815
 
28 alex 816
// ====================================================================
31 alex 817
// Gestion de l'infobulle
7 delphine 818
 
28 alex 819
var obsJSON = null,
7 delphine 820
	pointClique = null,
821
	obsStation = [],
37 alex 822
	pagineur = {'limite':100, 'start':0, 'total':0, 'stationId':null, 'format':'tableau'};
7 delphine 823
 
824
function afficherInfoBulle() {
825
	var latitude = pointClique.getLatLng().lat;
826
	var longitude = pointClique.getLatLng().lng;
37 alex 827
	infoBulle = new L.Popup({maxWidth : definirLargeurInfoBulle(), maxHeight : 380});
7 delphine 828
	infoBulle.setLatLng(new L.LatLng(latitude, longitude));
829
	infoBulle.setContent($("#tpl-obs").html());
37 alex 830
	infoBulle.openOn(map);
28 alex 831
	remplirContenuPopup();
37 alex 832
	$('#info-bulle').css('width', '99%');
833
	$('#observations').css('height', '250px');
834
	$('#observations').css('overflow', 'auto');
835
	$('.leaflet-popup-scrolled').css('overflow', 'visible');
28 alex 836
}
837
 
37 alex 838
function viderListeObservations() {
839
	obsStation = new Array();
840
}
841
 
28 alex 842
function definirLargeurInfoBulle() {
843
	var largeurViewPort = $(window).width();
844
	var lageurInfoBulle = null;
845
	if (largeurViewPort < 800) {
846
		largeurInfoBulle = 400;
847
	} else if (largeurViewPort >= 800 && largeurViewPort < 1200) {
848
		largeurInfoBulle = 500;
849
	} else if (largeurViewPort >= 1200) {
850
		largeurInfoBulle = 600;
851
	}
852
	return largeurInfoBulle;
853
}
854
 
855
function redimensionnerPopup() {
37 alex 856
	$('.leaflet-popup-content*').css('width', definirLargeurInfoBulle());
857
	$('#info-bulle').css('width', '99%');
28 alex 858
}
859
 
860
function remplirContenuPopup() {
7 delphine 861
	ajouterTableauTriable("#obs-tableau");
862
	ajouterTitre();
37 alex 863
	afficherTableau();
7 delphine 864
	afficherTexteStationId();
865
}
866
 
867
function masquerInfoBulle() {
31 alex 868
	if (infoBulle != null && map.hasLayer(infoBulle)) {
7 delphine 869
		map.removeLayer(infoBulle);
870
	}
871
	infoBulle = null;
872
}
873
 
874
function ajouterTitre() {
875
	var texteStationTitre = obsJSON.total + ' observation' + (obsJSON.total > 1 ? 's' : '')
37 alex 876
		+ ' sur ' + (pointClique.typeSite=='station' ? 'la station : ' : 'la commune : ')
7 delphine 877
		+ pointClique.options.title;
878
	$('#obs-station-titre').text(texteStationTitre);
879
}
880
 
37 alex 881
function afficherTableau() {
882
	construireListeObservations();
883
	afficherPagination();
884
	afficherObservationsDansHTML();
7 delphine 885
}
886
 
37 alex 887
function construireListeObservations() {
7 delphine 888
	if (obsStation.length==0) {
889
		// premiere execution de la fonction : faire une copie des objets JSON decrivant les observations
890
		for (var index = 0; index < obsJSON.observations.length; index ++) {
891
			obsStation.push(obsJSON.observations[index]);
892
		}
893
	}
37 alex 894
	pagineur.total = obsStation.length;
7 delphine 895
}
896
 
37 alex 897
function afficherPagination() {
898
	$(".navigation").pagination(pagineur.total, {
899
		items_per_page:pagineur.limite,
900
		callback:afficherObservationsDansHTML,
901
		next_text:'Suivant',
902
		prev_text:'Précédent',
903
		prev_show_always:false,
904
		num_edge_entries:1,
905
		num_display_entries:4,
906
		load_first_page:true
7 delphine 907
	});
908
}
909
 
37 alex 910
function afficherObservationsDansHTML(indexPage) {
911
	$("#obs-tableau-lignes").empty();
912
	if (typeof(indexPage) == 'undefined') {
913
		indexPage = 0;
914
	}
915
	var depart = indexPage * pagineur.limite;
916
	var obsPage = [];
917
	for (var index = depart; index < depart + pagineur.limite; index ++) {
918
		obsPage.push(obsStation[index]);
919
	}
920
	$("#tpl-obs-tableau").tmpl(obsPage).appendTo("#obs-tableau-lignes");
921
	mettreAJourTableauTriable();
7 delphine 922
}
923
 
37 alex 924
function ajouterTableauTriable() {
7 delphine 925
	$.tablesorter.addParser({
926
		id: 'date_cel',
927
		is: function(s) {
31 alex 928
			// doit retourner false si le parseur n'est pas autodétecté
7 delphine 929
			return /^\s*\d{2}[\/-]\d{2}[\/-]\d{4}\s*$/.test(s);
930
		},
931
		format: function(date) {
932
			// Transformation date jj/mm/aaaa en aaaa/mm/jj
37 alex 933
			date = date.replace(/^\s*(\d{2})[\/-](\d{2})[\/-](\d{4})\s*$/, "$3-$2-$1");
7 delphine 934
			// Remplace la date par un nombre de millisecondes pour trier numériquement
935
			return $.tablesorter.formatFloat(new Date(date).getTime());
936
		},
937
		type: 'numeric'
938
	});
37 alex 939
	$("#obs-tableau").tablesorter({
7 delphine 940
        headers: {
941
			1: {
37 alex 942
            	sorter:'date_cel'
7 delphine 943
        	}
31 alex 944
    	}
7 delphine 945
	});
946
}
947
 
37 alex 948
function mettreAJourTableauTriable() {
949
	$("#obs-tableau").trigger('update');
7 delphine 950
}
951
 
952
function afficherTexteStationId() {
37 alex 953
	var latitude = pointClique.getLatLng().lat.toFixed(5);
954
	var longitude = pointClique.getLatLng().lng.toFixed(5);
955
	var texteStationId = pointClique.typeSite.toUpperCase() + ':'
956
		+ latitude + '|' + longitude + ', SOURCE:' + pointClique.source;
7 delphine 957
	$('#obs-station-id').text(texteStationId);
958
}