Subversion Repositories eFlore/Applications.coel

Rev

Rev 1696 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1646 alex 1
<?php
2
 
3
/**
4
 * Exemple lancement:
5
 * /opt/lampp/bin/php -d memory_limit=3500M cli.php communes -a majCoordonnees
6
 */
7
 
8
class Communes extends Script {
9
 
10
	private $bdd = null;
11
	private $structures = array();
12
	private $communes = array();
13
	private $nonTrouvees = array();
14
 
15
	public function __construct($script_nom, $parametres) {
16
		parent::__construct($script_nom, $parametres);
17
		$this->bdd = new Bdd();
18
	}
19
 
20
	public function executer() {
21
		try {
22
			$this->initialiserScript();
23
			$cmd = $this->getParametre('a');
24
			switch ($cmd) {
25
				case "majCoordonnees" :
26
					$this->mettreAJourCoordonneesCommunes(); break;
27
				default :
28
					$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
29
			}
30
		} catch (Exception $erreur) {
31
			$this->traiterErreur($erreur->getMessage());
32
		}
33
	}
34
 
35
	private function initialiserScript() {
36
		$fichierIni = $this->getScriptChemin().'communes.ini';
37
		if (file_exists($fichierIni)) {
38
			Config::charger($fichierIni);
39
		} else {
40
			$erreur = "Veuillez configurer le projet en créant le fichier 'communes.ini' ".
41
				"dans le dossier du module de script du projet à partir du fichier 'config.defaut.ini'.";
42
			throw new Exception($erreur);
43
		}
44
	}
45
 
46
	private function mettreAJourCoordonneesCommunes() {
47
		$this->recupererStructures();
48
		$departements = $this->determinerDepartementsStructures();
49
		$this->recupererCommunes($departements);
50
		$this->chercherCoordonneesVillesStructures();
51
		$this->mettreAJourDonneesStructures();
52
		$this->afficherResultatScript();
53
	}
54
 
55
	private function recupererStructures() {
56
		$this->bdd->requeter("USE ".Config::get("bdd_nom_coel"));
57
		$requete =
58
		"SELECT cs_id_structure, cs_nom, cs_code_postal, cs_ville ".
59
		"FROM ".Config::get("table_structures_coel")." ".
60
		"WHERE (cs_latitude IS NULL OR cs_latitude='0' OR Length(Trim(cs_latitude)) = 0) ".
61
		"AND (cs_longitude IS NULL OR cs_longitude='0' OR Length(Trim(cs_longitude)) = 0) ".
62
		"AND cs_ce_truk_pays='2654' ORDER BY cs_ville;";
63
		$this->structures = $this->bdd->recupererTous($requete);
64
	}
65
 
66
	private function determinerDepartementsStructures() {
67
		$departements = array();
68
		foreach ($this->structures as $index => $structure) {
69
			$codeDepartement = '';
70
			if (strlen($structure['cs_code_postal']) == 5) {
71
				if (substr($structure['cs_code_postal'], 0, 2) > "95") {
72
					$codeDepartement = substr($structure['cs_code_postal'], 0, 3);
73
				} else {
74
					$codeDepartement = substr($structure['cs_code_postal'], 0, 2);
75
				}
76
			}
77
			$this->structures[$index]['departement'] = $codeDepartement;
78
			if (strlen($codeDepartement) > 0 && !in_array($codeDepartement, $departements)) {
79
				$departements[] = $codeDepartement;
80
			}
81
		}
82
		return $departements;
83
	}
84
 
85
	private function recupererCommunes($departements) {
86
		foreach ($departements as $index => $codeDepartement) {
87
			$departements[$index] = "'$codeDepartement'";
88
		}
89
		$listeDepartements = implode(',', $departements);
90
		$this->bdd->requeter("USE ".Config::get("bdd_nom_floradata"));
91
		$requete = "SELECT code, nom, wgs84_latitude, wgs84_longitude FROM ".Config::get("table_communes")." ".
92
		"ORDER BY code;";
93
		$communes = $this->bdd->recupererTous($requete);
94
		// reorganiser le tableau en series des tableaux contenant les communes par departement
95
		$communes[0]['recherche'] = self::transformerChainePourRecherche($communes[0]['nom']);
96
		$communesDepartement = array($communes[0]);
97
		$numeroDepartement = substr($communes[0]['code'], 0, 2) > '95' ? substr($communes[0]['code'], 0, 3)
98
			: substr($communes[0]['code'], 0, 2);
99
		for ($index = 1; $index < count($communes); $index ++) {
100
			$numeroDept = substr($communes[$index]['code'],0,2) > '95' ? substr($communes[$index]['code'],0,3)
101
				: substr($communes[$index]['code'],0,2);
102
			if ($numeroDept != $numeroDepartement) {
103
				$this->communes[$numeroDepartement] = $communesDepartement;
104
				$communesDepartement = array();
105
				$numeroDepartement = $numeroDept;
106
			}
107
			$communes[$index]['recherche'] = self::transformerChainePourRecherche($communes[$index]['nom']);
108
			$communesDepartement[] = $communes[$index];
109
		}
110
		$this->communes[$numeroDepartement] = $communesDepartement;
111
	}
112
 
113
	private static function transformerChainePourRecherche($chaine, $charset='utf-8') {
114
		$str = htmlentities($chaine, ENT_NOQUOTES, $charset);
115
		$str = preg_replace('#&([A-za-z])(?:acute|cedil|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str);
116
		$str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str);
117
		$str = preg_replace('#&[^;]+;#', '', $str);
118
		for ($position = 0; $position < strlen($str); $position ++) {
119
			if ($str[$position] == "," || $str[$position] == "-" || $str[$position] == "'") {
120
				$str[$position] = " ";
121
			}
122
		}
123
		return strtolower($str);
124
	}
125
 
126
	private function chercherCoordonneesVillesStructures() {
127
		foreach ($this->structures as $index => $structure) {
128
			if (strlen(trim($structure['cs_ville'])) > 0) {
129
				if (strlen(trim($structure['departement'])) > 0) {
130
					$this->structures[$index] = $this->retrouverCoordonneesDansDepartement($structure);
131
				} else {
132
					$this->structures[$index] = $this->retrouverCoordonneesDansListeCommunes($structure);
133
				}
134
			} else {
135
				$this->nonTrouvees[] = $structure;
136
			}
137
		}
138
	}
139
 
140
	private function retrouverCoordonneesDansDepartement($structure) {
141
		$villeRecherche = self::transformerChainePourRecherche(($structure['cs_ville']));
142
		$communeTrouvee = null;
143
		// comparaison dans un premier temps si les deux chaines de caracteres sont identiques
144
		// dans un second temps on applique la recherche de sous chaines identiques
145
		foreach ($this->communes[$structure['departement']] as $commune) {
146
			if ($commune['recherche'] == $villeRecherche) {
147
				$communeTrouvee = $commune;
148
				break;
149
			}
150
		}
151
		if (is_null($communeTrouvee)) {
152
			foreach ($this->communes[$structure['departement']] as $commune) {
153
				if (strstr($commune['recherche'], $villeRecherche) !== false) {
154
					$communeTrouvee = $commune;
155
					break;
156
				} else if (strstr($villeRecherche, $commune['recherche']) !== false) {
157
					$communeTrouvee = $commune;
158
					break;
159
				}
160
			}
161
		}
162
		if (!is_null($communeTrouvee)) {
163
			$structure['cs_ville']  = $communeTrouvee['nom'];
164
			$structure['latitude']  = $communeTrouvee['wgs84_latitude'];
165
			$structure['longitude'] = $communeTrouvee['wgs84_longitude'];
166
		} else {
167
			$this->nonTrouvees[] = $structure;
168
		}
169
		return $structure;
170
	}
171
 
172
	private function retrouverCoordonneesDansListeCommunes($structure) {
173
		$villeRecherche = self::transformerChainePourRecherche(($structure['cs_ville']));
174
		$communeTrouvee = null;
175
		$codeDepartement = "";
176
		// meme comportement que la methode precedente, mais la recherche est etendue a toutes les communes
177
		// si une commune est trouvee, on lui attribuera le code departement au code postal par defaut
178
		foreach ($this->communes as $departement => $communes) {
179
			foreach ($communes as $commune) {
180
				if ($commune['recherche'] == $villeRecherche) {
181
					$communeTrouvee = $commune;
182
					$codeDepartement = $departement;
183
					break;
184
				}
185
			}
186
			if (is_null($communeTrouvee)) {
187
				foreach ($communes as $commune) {
188
					if (strstr($commune['recherche'], $villeRecherche) !== false) {
189
						$communeTrouvee = $commune;
190
						$codeDepartement = $departement;
191
						break;
192
					} else if (strstr($villeRecherche, $commune['recherche']) !== false) {
193
						$communeTrouvee = $commune;
194
						$codeDepartement = $departement;
195
						break;
196
					}
197
				}
198
			}
199
		}
200
		if (!is_null($communeTrouvee)) {
201
			$structure['cs_ville']  = $communeTrouvee['nom'];
202
			$structure['latitude']  = $communeTrouvee['wgs84_latitude'];
203
			$structure['longitude'] = $communeTrouvee['wgs84_longitude'];
204
			$structure['cs_code_postal'] = $codeDepartement;
205
		} else {
206
			$this->nonTrouvees[] = $structure;
207
		}
208
		return $structure;
209
	}
210
 
211
	private function mettreAJourDonneesStructures() {
212
		$this->bdd->requeter("USE ".Config::get("bdd_nom_coel"));
213
		$updates = array();
214
		// pour faire une seule requete de mise a jour, on va pas utiliser l'ordre UPDATE qui n'accepte
215
		// qu'une seule condition, mais l'ordre INSERT en rajoutant a la fin ON DUPLICATE KEY UPDATE
216
		// avec les correspondances au niveau des codes postaux et villes
217
		foreach ($this->structures as $structure) {
218
			if (isset($structure['latitude']) && isset($structure['longitude'])) {
219
				$updates[] = "({$structure['cs_id_structure']},'{$structure['cs_code_postal']}',".
220
					$this->bdd->proteger($structure['cs_ville']).",'{$structure['latitude']}',".
221
					"'{$structure['longitude']}')";
222
			}
223
		}
224
		$sql = "INSERT INTO ".Config::get("table_structures_coel")." (cs_id_structure, cs_code_postal, ".
225
		"cs_ville, cs_latitude, cs_longitude) VALUES ".implode(",", $updates)." ".
226
		"ON DUPLICATE KEY UPDATE cs_code_postal=VALUES(cs_code_postal), cs_ville=VALUES(cs_ville), ".
227
		"cs_latitude=VALUES(cs_latitude), cs_longitude=VALUES(cs_longitude);";
228
		$this->bdd->requeter($sql);
229
	}
230
 
231
	private function afficherResultatScript() {
232
		$nombreUpdates = count($this->structures) - count($this->nonTrouvees);
233
		$message = "Mise à jour des coordonnées des communes terminée. Les structures qui n'avaient pas de ".
234
		"coordonnées se sont vues attribuer les coordonnées de la commune dans laquelle elles sont situées.\n\n".
235
		"Mises à jour effectuées pour $nombreUpdates structures.\n";
236
		if (count($this->nonTrouvees) > 0) {
237
			$message .= "Des problèmes ont été rencontrées pour les structures suivantes : \n";
238
			foreach ($this->nonTrouvees as $structure) {
239
				$message .= "  - {$structure['cs_nom']} ({$structure['cs_ville']}, {$structure['cs_code_postal']})\n";
240
			}
241
			$message .= "Veuillez vérifier le nom de la commune saisi ou aller dans la fiche structure ".
242
			"pour y rajouter les coordonnées longitude/latitude\n";
243
		} else {
244
			$message .= "Vous pourrez toujours par la suite aller dans la fiche structure ".
245
			"pour affiner la précision les coordonnées longitude/latitude au niveau des locaux.\n";
246
		}
247
		print($message);
248
	}
249
 
250
}
251
 
252
?>