Subversion Repositories Applications.annuaire

Rev

Rev 473 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
42 aurelien 1
<?php
2
// declare(encoding='UTF-8');
3
/**
4
 * Composant Cartographie gérant les images représentant le fond de carte à insérer dans un fichier html contenant une
5
 * image map.
6
 * Avantage :
7
 *  - pas de base de données liée au composant (simplicité d'utilisation dans les applications)
8
 *  - facilite l'utilisation du Javascript et CSS pour intéragir avec la carte (affichage du nom des zones au survol)
9
 *  - l'application qui utilise le composant définie elle-même l'intéraction avec le clic sur une zone
10
 * Inconvénient :
11
 *  - l'utilisation d'une balise map alourdie la page à renvoyer
12
 *
13
 * Il est possible de créer des fond de carte en vraies couleurs
14
 * (16 millions de zones maxi sur la carte) ou en couleurs indexées (255 zones maxi sur la carte).
15
 * Les couleurs réservées et a ne pas utiliser pour créer l'image png de fond sont :
16
 * - le blanc (rvb : 255-255-255)
17
 * - le noir (rvb : 0-0-0)
18
 * - le gris (rvb : 128-128-128)
19
 * - le rouge (rvb : 255-0-0)
20
 * Pour activer le cache indiquer la date de dernière mise à jour des données servant à créer la carte de cette façon :
21
 * $Carte->setCarteInfo(array('donnees_date_maj' => $date_maj_donnees));
22
 *
23
 * @category	PHP5
24
 * @package		Collection
25
 * @author		Jean-Pascal MILCENT <jpm@tela-botanica.org>
26
 * @copyright	2010 Tela-Botanica
27
 * @license		GPL-v3 et CECILL-v2
28
 * @version		SVN:$Id$
29
 */
30
 
31
class Cartographie {
32
	/*** Constantes : ***/
33
	const FORMULE_PROPORTIONNEL = 'proportionnel';
34
	const FORMULE_LEGENDE = 'legende';
35
 
36
	//+----------------------------------------------------------------------------------------------------------------+
37
	/*** Attributs : ***/
38
	/**
39
	* L'image de la carte.
40
	* @var string l'image de la carte.
41
	*/
42
	private $carte;
43
 
44
	/**
45
	* Le nom du fichier contenant la carte sans l'extension.
46
	* @var string le nom du fichier de la carte.
47
	*/
48
	private $carte_nom;
49
 
50
	/**
51
	* @var string le chemin et le nom du fichier de l'image de la carte générée.
52
	*/
53
	private $carte_fichier;
54
 
55
	/**
56
	* Tableaux associatif contenant les informations sur la carte.
57
	* donnees_date_maj = date de dernière mise à jour des données servant à créer la carte, si plus récente que la carte
58
	* déjà créée getCarteCache renvoie false.
59
	*
60
	* @var array le tableau des infos sur la carte.
61
	*/
62
	private $carte_info = array();
63
 
64
	/**
65
	* Indique si la carte existe déjà et à besoin ou pas d'être créée.
66
	* @var bool true si la carte existe..
67
	*/
68
	private $carte_cache = false;
69
 
70
	/**
71
	* Le nom du fichier de la carte de fond.
72
	* @var string nom du fichier de la carte de fond.
73
	*/
74
	private $carte_fond_fichier;
75
 
76
	/**
77
	* Le nom du dossier contenant les cartes de fond.
78
	* @var string nom du dossier contenant les cartes de fond.
79
	*/
80
	private $carte_fond_dossier;
81
 
82
	/**
83
	* Le nom du dossier où stocker les cartes créer via la classe Cartographie.
84
	* @var string nom du dossier contenant les cartes créées.
85
	*/
86
	private $carte_stockage_dossier;
87
 
88
	/**
89
	* L'url correspondant au dossier où sont stockées les cartes crées via la classe Cartographie.
90
	* L'url est passé à la fonction sprintf est doit donc contennir %s afin d'indiquer l'endroite où ajouter le nom du
91
	* fichier de la carte.
92
	* @var string url des cartes créées.
93
	*/
94
	private $carte_stockage_url;
95
 
96
	/**
97
	* Format du tableau :
98
	* carte_zone est un tableau de tableaux associatifs.
99
	* Chaque zone de la carte doit avoir son entrée dans ce tableau. Le code de la zone sert de clé.
100
	* Chaque zone est représentée par :
101
	* - nom : (string)
102
	* 	le nom de la zone qui sera affiché dans l'attribut title de la balise map html.
103
	* - rvb_fond : (string) Exemple : 255-255-255.
104
	* 	les valeurs entre 0 et 255 séparées par des tirets (-) de la couleur de la zone sur la carte de fond
105
	* 	Ne pas utiliser le blanc (255-255-255) et utiliser le noir pour les contours (0-0-0).
106
	* - poly : (string)
107
	* 	les coordonnées pour la balise map html. Si une même zone à plusieurs polygones, les séparer par le
108
	* 	caractère pipe "|".
109
	* - info_nombre : (int) Exemple : nombre de personnes présentent dans un département.
110
	* 	nombre d'occurence dans cette zone.
111
	* - url : (string) l'url qui doit être appelée sur un clic dans la zone.
112
	* - rvb_carte : (string) Exemple : 255-255-255.
113
	* 	les valeurs entre 0 et 255 séparées par des tirets (-) de la couleur de remplacement dans le cas de la formule
114
	* 	de coloriage de type "légende".
115
	* @var array les informations sur les zones de la carte.
116
	*/
117
	private $carte_zones = null;
118
 
119
	/**
120
	* Tableau contenant la valeur RVB de la zone du fond de carte en clé et la valeur RVB venant la remplacer en valeur.
121
	* @var array valeur RVB de la zone du fond de carte en clé et valeur RVB venant la remplacer en valeur.
122
	*/
123
	private $carte_correspondance_couleurs = array();
124
 
125
	/**
126
	* La valeur RVB, sous forme de chaine de nombres séparées par des tirets (-), de la zone géographique à mettre en
127
	* surbrillance.
128
	* @var string la valeur RVB de la zone à repérer.
129
	*/
130
	private $zone_marker;
131
 
132
	/**
133
	* La formule de coloriage de la carte. Les formules disponibles sont : légende, proportionnel.
134
	* @var string la formule de coloriage.
135
	*/
136
	private $formule_coloriage;
137
 
138
	/**
139
	* Les valeurs RVB séparés par des virgules pour la couleur la plus foncée utilisée, entre autre, par la formule de
140
	* coloriage "proportionnel".
141
	* @var string les valeurs RVB séparées par des virgules.
142
	*/
143
	private $coloriage_couleur_max;
144
 
145
	/**
146
	* Les valeurs RVB séparés par des virgules pour la couleur la plus claire utilisée, entre autre, par la formule de
147
	* coloriage "proportionnel".
148
	* @var string les valeurs RVB séparées par des virgules.
149
	*/
150
	private $coloriage_couleur_min;
151
 
152
	/**
153
	* Contient le nombre de couleurs différentes utilisées par le coloriage pour créer l'image finale.
154
	* @var int le nombre de couleurs.
155
	*/
156
	private $coloriage_couleurs;
157
 
158
	/**
159
	* Contient le tableau des fréquences et des couleurs correspondantes.
160
	* @var array les frequences et leurs couleurs.
161
	*/
162
	private $coloriage_tableau_frequence = array();
163
 
164
	/**
165
	* Permet de savoir si la cartographie est en mode déboguage ou pas.
166
	* @var bool true si on est en mode débug, sinon false.
167
	*/
168
	private $mode_debug;
169
 
170
	//+----------------------------------------------------------------------------------------------------------------+
171
	/*** Constructeur : ***/
172
	public function __construct($options = array()) {
173
		// Initialisation de l'objet Cartographie
174
		$this->setCarteNom(isset($options['carte_nom']) ? $options['carte_nom'] : '');
175
		$this->setFormuleColoriage(isset($options['formule']) ? $options['formule'] : '');
176
		$this->setColoriageCouleurClaire(isset($options['couleur_claire']) ? $options['couleur_claire'] : '');
177
		$this->setColoriageCouleurFoncee(isset($options['couleur_foncee']) ? $options['couleur_foncee'] : '');
178
		$this->setCarteFondFichier(isset($options['fond_fichier']) ? $options['fond_fichier'] : '');
179
		$this->setCarteFondDossier(isset($options['fond_dossier']) ? $options['fond_dossier'] : '');
180
		$this->setCarteStockageDossier(isset($options['stock_dossier']) ? $options['stock_dossier'] : '');
181
		$this->setCarteStockageUrl(isset($options['stock_url']) ? $options['stock_url'] : '');
182
		$this->setCarteZones(isset($options['zones']) ? $options['zones'] : null);
183
		$this->setZoneMarker(isset($options['zone_marker']) ? $options['zone_marker'] : '');
184
		$this->setModeDebug(isset($options['debug']) ? $options['debug'] : false);
185
	}
186
 
187
	//+----------------------------------------------------------------------------------------------------------------+
188
	/*** Accesseur : ***/
189
	public function getTableauFrequence() {
190
		ksort($this->coloriage_tableau_frequence);
191
		return $this->coloriage_tableau_frequence;
192
	}
193
 
194
	public function getCarteCache() {
195
		// Gestion du cache
196
		if ($this->getCarteNom() != '') {
197
			$fichier_carte = $this->carte_stockage_dossier.$this->getCarteNom().'.png';
198
			if (file_exists($fichier_carte)) {
199
				//echo filemtime($fichier_carte).'-'.strtotime($this->carte_info['donnees_date_maj']);
200
				if (filemtime($fichier_carte) < strtotime($this->carte_info['donnees_date_maj'])) {
201
					$this->carte_cache = false;
202
				} else {
203
					$this->carte_cache = true;
204
				}
205
			}
206
		}
207
		return $this->carte_cache;
208
	}
209
 
210
	public function getCarteInfo() {
211
		return $this->carte_info;
212
	}
213
	public function setCarteInfo($ci) {
214
		$this->carte_info = $ci;
215
	}
216
 
217
	public function getColoriageCouleurClaire() {
218
		return $this->coloriage_couleur_min;
219
	}
220
	public function setColoriageCouleurClaire($ccmi) {
221
		$this->coloriage_couleur_min = $ccmi;
222
	}
223
 
224
	public function getColoriageCouleurFoncee() {
225
		return $this->coloriage_couleur_max;
226
	}
227
	public function setColoriageCouleurFoncee($ccma) {
228
		$this->coloriage_couleur_max = $ccma;
229
	}
230
 
231
	public function getFormuleColoriage() {
232
		return $this->formule_coloriage;
233
	}
234
	public function setFormuleColoriage($fc) {
235
		$this->formule_coloriage = $fc;
236
	}
237
 
238
	public function getCarteNom() {
239
		return $this->carte_nom;
240
	}
241
	public function setCarteNom($cn) {
242
		$this->carte_nom = $cn;
243
	}
244
 
245
	public function getCarteFichier() {
246
		return $this->carte_fichier;
247
	}
248
	public function setCarteFichier($cf) {
249
		$this->carte_fichier = $cf;
250
	}
251
 
252
	public function getCarteFondFichier() {
253
		return $this->carte_fond_fichier;
254
	}
255
	public function setCarteFondFichier($cff) {
256
		$this->carte_fond_fichier = $cff;
257
	}
258
 
259
	public function getCarteFondDossier() {
260
		return $this->carte_fond_dossier;
261
	}
262
	public function setCarteFondDossier($cfd) {
263
		$this->carte_fond_dossier = $cfd;
264
	}
265
 
266
	public function getCarteStockageDossier() {
267
		return $this->carte_stockage_dossier;
268
	}
269
	public function setCarteStockageDossier($csd) {
270
		$this->carte_stockage_dossier = $csd;
271
	}
272
 
273
	public function getCarteStockageUrl() {
274
		return $this->carte_stockage_url;
275
	}
276
	public function setCarteStockageUrl($csu) {
277
		$this->carte_stockage_url = $csu;
278
	}
279
 
280
	public function getCarteZones() {
281
		if (is_null($this->carte_zones)) {
282
			$this->chargerZones();
283
		}
284
		return $this->carte_zones;
285
	}
286
	public function setCarteZones($cz) {
287
		$this->carte_zones = $cz;
288
	}
289
 
290
	public function getZoneMarker() {
291
		return $this->zone_marker;
292
	}
293
	public function setZoneMarker($zm) {
294
		$this->zone_marker = $zm;
295
	}
296
 
297
	public function getModeDebug() {
298
		return $this->mode_debug;
299
	}
300
	public function setModeDebug($md) {
301
		$this->mode_debug = $md;
302
	}
303
 
304
	//+----------------------------------------------------------------------------------------------------------------+
305
	/*** Méthodes PUBLIQUES : ***/
306
 
307
	public function creerCarte() {
308
 
309
		// Création de la carte car aucun cache ou cache à vider
310
		$carte_fond_fichier = $this->carte_fond_dossier.$this->getCarteFondFichier().'.png';
76 aurelien 311
 
42 aurelien 312
		$this->carte = imagecreatefrompng($carte_fond_fichier);
313
		// Vérification que la création à fonctionnée
314
		if (!$this->carte) {
315
			// Une erreur est survenue : création d'une image blanche
316
			$this->carte = imagecreatetruecolor(520, 60);
317
			$bgc = imagecolorallocate($this->carte, 255, 255, 255);
318
			$tc  = imagecolorallocate($this->carte, 0, 0, 0);
319
			imagefilledrectangle($this->carte, 0, 0, 520, 60, $bgc);
320
			// Affichage d'un message d'erreur
321
			imagestring($this->carte, 1, 5, 5, "Erreur de chargement de l'image :", $tc);
322
			imagestring($this->carte, 1, 5, 15, $carte_fond_fichier, $tc);
323
		} else {
324
			// Nous construisons le tableau de correspondance entre les couleurs présente sur l'image de fond
325
			// et les couleurs qui doivent les remplacer.
326
			$this->construireCorrespondanceCouleur();
327
 
328
			// Nous lançons la création de la carte
329
			$this->colorierCarte();
330
		}
331
 
332
		// Nous chercons à créer une image indéxées en sortie
473 jpm 333
		if (imageistruecolor($this->carte) && $this->formule_coloriage != 'legende') {
42 aurelien 334
			if ($this->coloriage_couleurs <= 253) {
335
				//imagetruecolortopalette(&$this->carte, false, ($this->coloriage_couleurs + 2));// + 2 car noir et blanc réservés.
336
			} else {
337
				// On force la création d'une palette... si cela pose problème ajouter un attribut permettant de désactiver
338
				// ce fonctionnement.
473 jpm 339
				imagetruecolortopalette($this->carte, false, 255);
42 aurelien 340
			}
341
		}
342
 
343
		// Nous écrivons le fichier de la carte.
344
		if ($this->getCarteNom() == '') {
345
			$this->setCarteNom(md5($this->carte));
346
		}
347
 
76 aurelien 348
		$fichier_image_carte = $this->carte_stockage_dossier.$this->getCarteNom().'.png';
349
		$this->setCarteFichier($fichier_image_carte);
350
 
351
		if(file_exists($fichier_image_carte)) {
352
			//echo 'suppression du fichier de carte : '.$fichier_html_carte;
353
			unlink($fichier_image_carte);
354
		}
355
 
473 jpm 356
		imagepng($this->carte, $this->getCarteFichier());
42 aurelien 357
		return true;
358
	}
359
 
360
	public function getImageMap() {
361
		// Initialisation de variables
362
		$carte_map = '';
363
 
364
		// Gestion de l'image map
365
		$chemin_carte_map_fond = $this->getCarteFondDossier().$this->getCarteFondFichier().'.tpl.html';
366
		$chemin_carte_map = $this->getCarteStockageDossier().$this->getCarteNom().'.html';
367
 
76 aurelien 368
		if(file_exists($chemin_carte_map)) {
369
			unlink($chemin_carte_map);
370
		}
371
 
42 aurelien 372
		if (file_exists($chemin_carte_map)) {
373
			$carte_map = file_get_contents($chemin_carte_map);
374
		} else {
375
			$nom_carte_png = $this->getCarteNom().'.png';
376
			$chemin_carte_png = $this->getCarteStockageDossier().$nom_carte_png;
377
			$donnees['carte_url'] = sprintf($this->getCarteStockageUrl(), $nom_carte_png);
378
			$donnees['carte_alt'] = 'info';
379
			$donnees['zones'] = $this->getCarteZones();
380
			//Debug::printr($donnees);
381
			$carte_map = SquelettePhp::analyser($chemin_carte_map_fond, $donnees);
382
			if (!file_put_contents($chemin_carte_map, $carte_map)) {
383
				$e = "Écriture du fichier contenant le html de la carte impossible : $chemin_carte_map";
384
				trigger_error($e, E_USER_WARNING);
385
			}
386
		}
387
 
388
		return $carte_map;
389
	}
390
 
391
	//+----------------------------------------------------------------------------------------------------------------+
392
	/*** Méthodes PRIVÉES : ***/
393
 
394
	/**
395
	 * Charge en mémoire les données du fichier csv des zones géographique de la carte
396
	 */
397
	private function chargerZones() {
398
		$fichier_csv = $this->getCarteFondDossier().$this->getCarteFondFichier().'.csv';
399
		$zones = array();
400
		if (($handle = fopen($fichier_csv, 'r')) !== false) {
401
			$ligne = 1;
402
			$cles = array();
403
			while (($donnees = fgetcsv($handle, 1000, ',')) !== false) {
404
				$cle = array_shift($donnees);
405
				if ($ligne == 1) {
406
					// Ligne 1 : les noms des champs
407
					$cles = $donnees;
408
 
409
				} else {
410
					// Ligne > 1 : traitements des données
411
					$zones[$cle] = array_combine($cles, $donnees);
412
				}
413
				$ligne++;
414
			}
415
			fclose($handle);
416
		}
417
		$this->setCarteZones($zones);
418
	}
419
 
420
	private function construireCorrespondanceCouleur() {
421
		switch ($this->formule_coloriage) {
422
			case self::FORMULE_LEGENDE :
423
				$this->construireCorrespondanceCouleurLegende();
424
				break;
425
			case self::FORMULE_PROPORTIONNEL :
426
				$this->construireCorrespondanceCouleurProportionnel();
427
				break;
428
			default :
429
				$e = 	"Aucune formule de coloriage n'a été définie parmis : ".
430
						self::FORMULE_LEGENDE.' et '.self::FORMULE_PROPORTIONNEL.'. '.
431
						"Veuillez la définir avec la méthode setFormuleColoriage().";
432
				trigger_error($e, E_USER_ERROR);
433
		}
434
	}
435
 
436
	private function construireCorrespondanceCouleurProportionnel() {
437
		// Création d'un tableau contenant seulement les nombres d'information pour chaque zone.
438
		$tab_valeurs = array();
439
		foreach ($this->getCarteZones() as $cle => $valeur) {
440
			//Nous recherchons le minimum, le maximum et le la valeur médium juste au dessous du maximum.
441
			if (isset($valeur['info_nombre'])) {
442
				$tab_valeurs[] = $valeur['info_nombre'];
443
				if ($valeur['info_nombre'] == 0){
444
					//trigger_error($valeur['nom'], E_USER_NOTICE);
445
				}
446
			}
447
		}
448
 
449
		//Nombre d'entrées dans le tableau de valeurs non nulles :
450
		$valeurs_nbre = count($tab_valeurs);
451
		$valeurs_somme = array_sum($tab_valeurs);
452
		// Tabeau des fréquences trié de la plus petite à la plus grande clé.
453
		$tab_frequences = array_count_values($tab_valeurs);
454
		krsort($tab_frequences);
455
		//trigger_error(print_r($tab_frequences, true), E_USER_NOTICE);
456
		$frequences_nbre = count($tab_frequences);
457
		if ($valeurs_nbre > 0){
458
			// Nous trions le tableau dans l'ordre croissant :
459
			sort($tab_valeurs);
460
			// Nous récupérons la valeur la plus petite :
461
			$mini = $tab_valeurs[0];
462
			$maxi = $tab_valeurs[$valeurs_nbre - 1];
463
			$medium = isset($tab_valeurs[$valeurs_nbre - 2]) ? $tab_valeurs[$valeurs_nbre - 2] : 0;
464
			$moyenne = $valeurs_somme / $valeurs_nbre;
465
			$ecart_au_carre_moyen = 0;
466
			for ($i = 0; $i < $valeurs_nbre; $i++) {
467
				$ecart_au_carre_moyen += pow(($tab_valeurs[$i] - $moyenne), 2);
468
			}
469
			$variance = $ecart_au_carre_moyen / $valeurs_nbre;
470
			$ecart_type = round(sqrt($variance), 0);
471
			$moyenne = round($moyenne, 0);
472
			$variance = round($variance, 0);
473
		}
474
 
475
		// Calcul de l'écart moyen pour chaque élément R, V et B.
476
		list($r_min, $v_min, $b_min) = explode(',', $this->coloriage_couleur_max);
477
		list($r_max, $v_max, $b_max) = explode(',', $this->coloriage_couleur_min);
478
		$r_diff = $r_min - $r_max;
479
		$r_ecart_moyen = abs($r_diff / $frequences_nbre);
480
 
481
		$v_diff = $v_min - $v_max;
482
		$v_ecart_moyen = abs($v_diff / $frequences_nbre);
483
 
484
		$b_diff = $b_min - $b_max;
485
		$b_ecart_moyen = abs($b_diff / $frequences_nbre);
486
 
487
		// Pour chaque fréquence nous attribuons une couleur.
488
		$i = 1;
489
		foreach ($tab_frequences as $cle => $valeur){
490
			if ($cle == 0) {
491
				$this->coloriage_tableau_frequence[$cle] = '255-255-255';
492
			} else {
493
				$r = $r_min + round(($i * $r_ecart_moyen), 0);
494
 
495
				$v = $v_min + round(($i * $v_ecart_moyen), 0);
496
				$b = $b_min + round(($i * $b_ecart_moyen), 0);
497
				$this->coloriage_tableau_frequence[$cle] = $r.'-'.$v.'-'.$b;
498
			}
499
			$i++;
500
		}
501
 
502
		// Attribution du nombre de couleurs utilisé pour réaliser la carte
503
		$this->coloriage_couleurs = count(array_count_values($this->coloriage_tableau_frequence));
504
		//trigger_error('<pre>'.print_r($this->coloriage_couleurs, true).'</pre>', E_USER_ERROR);
505
 
506
		// Nous attribuons les couleurs à chaque zone géographique
507
		foreach ($this->getCarteZones() as $cle => $zg) {
473 jpm 508
			if ($this->getModeDebug() && !isset($zg['rvb_fond'])) {
509
				$e = "La zone ".print_r($zg, true).") ne possède pas de clé 'rvb_fond'.";
510
				trigger_error($e, E_USER_WARNING);
511
				continue;
512
			}
42 aurelien 513
			if (isset($this->coloriage_tableau_frequence[$zg['info_nombre']])) {
514
				$this->carte_correspondance_couleurs[$zg['rvb_fond']] = $this->coloriage_tableau_frequence[$zg['info_nombre']];
515
			} else {
516
				$this->carte_correspondance_couleurs[$zg['rvb_fond']] = '128-128-128';
517
				if ($this->getModeDebug()) {
518
					$e = "La zone ".$zg['nom']." (".$zg['rvb_fond'].") ne possède pas de couleur RVB pour la remplir. ".
519
					 "La valeur 128-128-128 lui a été attribué.";
520
					trigger_error($e, E_USER_WARNING);
521
				}
522
			}
523
		}
524
	}
525
 
526
	private function construireCorrespondanceCouleurLegende() {
527
		$tab_couleurs = array();
528
		foreach ($this->getCarteZones() as $cle => $zg) {
529
			if ($zg['rvb_carte'] != '') {
530
				$this->carte_correspondance_couleurs[$zg['rvb_fond']] = $zg['rvb_carte'];
531
			} else {
532
				$this->carte_correspondance_couleurs[$zg['rvb_fond']] = '128-128-128';
533
				if ($this->getModeDebug()) {
534
					$e = "La zone ".$zg['nom']." (".$zg['rvb_fond'].") ne possède pas d'information pour la légende dans le champ".
535
					 " rvb_carte. La valeur 128-128-128 lui a été attribué.";
536
					trigger_error($e, E_USER_WARNING);
537
				}
538
			}
539
			if (!isset($tab_couleurs[$this->carte_correspondance_couleurs[$zg['rvb_fond']]])) {
540
				$tab_couleurs[$this->carte_correspondance_couleurs[$zg['rvb_fond']]] = 1;
541
			}
542
		}
543
		// Attribution du nombre de couleurs utilisé pour réaliser la carte
544
		$this->coloriage_couleurs = count($tab_couleurs);
545
	}
546
 
547
	private function colorierCarte() {
473 jpm 548
		if (imageistruecolor($this->carte)) {
42 aurelien 549
			//+--------------------------------------------------------------------------------------------------------+
550
			// Remplacement des couleurs sur la carte en mode vraies couleurs (RGB)
551
			$this->colorierCarteModeVraiCouleur();
552
		} else {
553
			//+--------------------------------------------------------------------------------------------------------+
554
			// Remplacement des couleurs sur la carte en mode couleurs indexées (palette de couleurs)
555
			$this->colorierCarteModeIndexe();
556
		}
557
	}
558
 
559
	private function colorierCarteModeVraiCouleur() {
560
		// Nous commençons le rempalcement des couleurs sur la carte de fond.
473 jpm 561
		$hauteur = imagesy($this->carte);
562
		$largeur = imagesx($this->carte);
42 aurelien 563
 
564
		// Tableau contenant les couleurs traitées, pour éviter de traiter plusieurs fois la même couleur
565
		$tab_rvb_ok = array();
566
		for ($x = 0; $x < $largeur; $x++) {
567
			for ($y = 0; $y < $hauteur; $y++) {
473 jpm 568
				$rvb = ImageColorAt($this->carte, $x, $y);
42 aurelien 569
				if (!isset($tab_rvb_ok[$rvb])) {
570
	   				// Récupération de la couleur rvb au format xxx-xxx-xxx
571
	   				$cle = (($rvb >> 16) & 0xFF).'-'.(($rvb >> 8) & 0xFF).'-'.($rvb & 0xFF);
572
	   				// Si nous n'avons pas à faire à la couleur noire (utilisé pour délimité les zones), nous continuons
573
	   				if ($cle != '255-255-255') {
574
		   				$rvb_final = null;
575
		   				if (isset($this->carte_correspondance_couleurs[$cle])) {
576
		   					if ($this->zone_marker != '' && $cle == $this->zone_marker) {
577
								$rvb_final = '255'<<16 | '0'<<8 | '0';
578
							} else {
579
		   						list($rouge, $vert, $bleu) = explode('-', $this->carte_correspondance_couleurs[$cle]);
580
		   						$rvb_final = $rouge<<16 | $vert<<8 | $bleu;
581
		   					}
582
		   					// Si le nombre de couleurs sur la carte finale est infèrieur à 255 nous créons une image indexée
473 jpm 583
		   					imagefill($this->carte, $x, $y, $rvb_final);
42 aurelien 584
		   				} else {
585
		   					$rvb_final = '128'<<16 | '128'<<8 | '128';
473 jpm 586
		   					imagefill($this->carte, $x, $y, $rvb_final);
42 aurelien 587
		   				}
588
	   					// Nous ajoutons la couleur ajoutée à la carte dans le tableau des couleurs traitées
589
	   					$tab_rvb_ok[$rvb_final] = true;
590
	   				}
591
	   				// Nous ajoutons la couleur trouvées sur la carte de fond dans le tableau des couleurs traitées
592
	   				$tab_rvb_ok[$rvb] = true;
593
				}
594
			}
595
		}
596
	}
597
 
598
	private function colorierCarteModeIndexe() {
599
		// Nous attribuons à chaque zone présente dans le tableau $this->getCarteZones() la valeur de l'index
600
		// de la couleur RVB représentant cette zone sur la carte de fond.
601
		$this->construireAssociationIndexZone();
602
 
603
		foreach ($this->getCarteZones() as $zg) {
604
			if (isset($this->carte_correspondance_couleurs[$zg['rvb_fond']])) {
605
 
606
				//Dans le cas où nous voulons repérer une zone sur la carte :
607
				if ($this->getZoneMarker() != '' && $zg['rvb_fond'] == $this->getZoneMarker()) {
608
					$rouge = 255;
609
					$vert = 0;
610
					$bleu = 0;
611
				} else {
612
					list($rouge, $vert, $bleu) = explode('-', $this->carte_correspondance_couleurs[$zg['rvb_fond']]);
613
				}
614
				if (isset($zg['index'])) {
473 jpm 615
					imagecolorset($this->carte, $zg['index'], $rouge, $vert, $bleu);
42 aurelien 616
				} else if ($this->getModeDebug()) {
617
					$e = "La zone '{$zg['nom']}' n'est pas présente sur la carte.";
618
					trigger_error($e, E_USER_WARNING);
619
				}
620
			}
621
		}
622
	}
623
 
624
	private function construireAssociationIndexZone() {
625
		// Nous récupérons le nombre de couleur différentes contenues dans l'image.
626
		$taille_palette = imagecolorstotal($this->carte);
627
		// Pour chaque couleur contenue dans l'image, nous cherchons l'objet correspondant
628
		// dans le tableau $this->getCarteZones(), qui contient des informations sur chaque zone de l'image,
629
		// et nous attribuons la valeur de l'index de sa couleur sur la carte de fond.
630
		for ($i = 0; $i < $taille_palette; $i++) {
631
			$rvb = array();
632
			$rvb = imagecolorsforindex($this->carte, $i);
633
			$rvb_cle = $rvb['red'].'-'.$rvb['green'].'-'.$rvb['blue'];
634
			// La couleur ne doit pas correspondre au noir ou au blanc car ces couleurs ne sont pas traitées
635
			if ($rvb_cle != '255-255-255' && $rvb_cle != '0-0-0') {
636
				$index_ok = false;
637
				foreach($this->getCarteZones() as $cle => $zg) {
638
					if (isset($zg['rvb_fond']) && $zg['rvb_fond'] == $rvb_cle) {
639
						$this->carte_zones[$cle]['index'] = $i;
640
						$index_ok = true;
641
						break;
642
					}
643
				}
644
				if (!$index_ok && $rvb_cle != '0-0-0' && $this->getModeDebug()) {
645
					$e = "Aucune information n'est fournie pour la zone sur la carte d'index $i : $rvb_cle";
646
					trigger_error($e, E_USER_WARNING);
647
					//$this->carte_zones[] = array('rvb_fond' => $rvb_cle, 'rvb_carte' => '128-128-128', 'index' => $i);
648
				}
649
			}
650
		}
651
	}
652
 
653
}
654
?>