Subversion Repositories eFlore/Applications.coel

Rev

Rev 1721 | Details | Compare with Previous | 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() {
1696 raphael 56
		$this->bdd->requeter("USE ".Config::get("tables.bdd_nom_coel"));
1721 raphael 57
		$requete = sprintf(
58
            "SELECT cs_id_structure, cs_nom, cs_code_postal, cs_ville FROM %s"
59
            . " JOIN coel_meta_liste_valeur ON cs_ce_truk_pays = cmlv_id_valeur"
60
            . " WHERE cmlv_abreviation IN ('FR', 'RE', 'YT', 'GP', 'MQ', 'GF', 'NC')"
61
            . " AND (cs_latitude IS NULL OR cs_latitude='0' OR Length(Trim(cs_latitude)) = 0)"
62
            . " AND (cs_longitude IS NULL OR cs_longitude='0' OR Length(Trim(cs_longitude)) = 0)"
63
            . " ORDER BY cs_ville",
64
            Config::get("tables.table_structures_coel"));
65
 
1646 alex 66
		$this->structures = $this->bdd->recupererTous($requete);
67
	}
68
 
69
	private function determinerDepartementsStructures() {
70
		$departements = array();
71
		foreach ($this->structures as $index => $structure) {
72
			$codeDepartement = '';
73
			if (strlen($structure['cs_code_postal']) == 5) {
74
				if (substr($structure['cs_code_postal'], 0, 2) > "95") {
75
					$codeDepartement = substr($structure['cs_code_postal'], 0, 3);
76
				} else {
77
					$codeDepartement = substr($structure['cs_code_postal'], 0, 2);
78
				}
79
			}
80
			$this->structures[$index]['departement'] = $codeDepartement;
81
			if (strlen($codeDepartement) > 0 && !in_array($codeDepartement, $departements)) {
82
				$departements[] = $codeDepartement;
83
			}
84
		}
85
		return $departements;
86
	}
87
 
88
	private function recupererCommunes($departements) {
89
		foreach ($departements as $index => $codeDepartement) {
90
			$departements[$index] = "'$codeDepartement'";
91
		}
92
		$listeDepartements = implode(',', $departements);
1696 raphael 93
		$this->bdd->requeter("USE ".Config::get("tables.bdd_nom_floradata"));
94
		$requete = "SELECT code, nom, wgs84_latitude, wgs84_longitude FROM ".Config::get("tables.table_communes")." ".
1646 alex 95
		"ORDER BY code;";
96
		$communes = $this->bdd->recupererTous($requete);
97
		// reorganiser le tableau en series des tableaux contenant les communes par departement
98
		$communes[0]['recherche'] = self::transformerChainePourRecherche($communes[0]['nom']);
99
		$communesDepartement = array($communes[0]);
100
		$numeroDepartement = substr($communes[0]['code'], 0, 2) > '95' ? substr($communes[0]['code'], 0, 3)
101
			: substr($communes[0]['code'], 0, 2);
102
		for ($index = 1; $index < count($communes); $index ++) {
103
			$numeroDept = substr($communes[$index]['code'],0,2) > '95' ? substr($communes[$index]['code'],0,3)
104
				: substr($communes[$index]['code'],0,2);
105
			if ($numeroDept != $numeroDepartement) {
106
				$this->communes[$numeroDepartement] = $communesDepartement;
107
				$communesDepartement = array();
108
				$numeroDepartement = $numeroDept;
109
			}
110
			$communes[$index]['recherche'] = self::transformerChainePourRecherche($communes[$index]['nom']);
111
			$communesDepartement[] = $communes[$index];
112
		}
113
		$this->communes[$numeroDepartement] = $communesDepartement;
114
	}
115
 
116
	private static function transformerChainePourRecherche($chaine, $charset='utf-8') {
117
		$str = htmlentities($chaine, ENT_NOQUOTES, $charset);
118
		$str = preg_replace('#&([A-za-z])(?:acute|cedil|circ|grave|orn|ring|slash|th|tilde|uml);#', '\1', $str);
119
		$str = preg_replace('#&([A-za-z]{2})(?:lig);#', '\1', $str);
120
		$str = preg_replace('#&[^;]+;#', '', $str);
121
		for ($position = 0; $position < strlen($str); $position ++) {
122
			if ($str[$position] == "," || $str[$position] == "-" || $str[$position] == "'") {
123
				$str[$position] = " ";
124
			}
125
		}
126
		return strtolower($str);
127
	}
128
 
129
	private function chercherCoordonneesVillesStructures() {
130
		foreach ($this->structures as $index => $structure) {
131
			if (strlen(trim($structure['cs_ville'])) > 0) {
132
				if (strlen(trim($structure['departement'])) > 0) {
133
					$this->structures[$index] = $this->retrouverCoordonneesDansDepartement($structure);
134
				} else {
135
					$this->structures[$index] = $this->retrouverCoordonneesDansListeCommunes($structure);
136
				}
137
			} else {
138
				$this->nonTrouvees[] = $structure;
139
			}
140
		}
141
	}
142
 
143
	private function retrouverCoordonneesDansDepartement($structure) {
144
		$villeRecherche = self::transformerChainePourRecherche(($structure['cs_ville']));
145
		$communeTrouvee = null;
146
		// comparaison dans un premier temps si les deux chaines de caracteres sont identiques
147
		// dans un second temps on applique la recherche de sous chaines identiques
148
		foreach ($this->communes[$structure['departement']] as $commune) {
149
			if ($commune['recherche'] == $villeRecherche) {
150
				$communeTrouvee = $commune;
151
				break;
152
			}
153
		}
154
		if (is_null($communeTrouvee)) {
155
			foreach ($this->communes[$structure['departement']] as $commune) {
156
				if (strstr($commune['recherche'], $villeRecherche) !== false) {
157
					$communeTrouvee = $commune;
158
					break;
159
				} else if (strstr($villeRecherche, $commune['recherche']) !== false) {
160
					$communeTrouvee = $commune;
161
					break;
162
				}
163
			}
164
		}
165
		if (!is_null($communeTrouvee)) {
166
			$structure['cs_ville']  = $communeTrouvee['nom'];
167
			$structure['latitude']  = $communeTrouvee['wgs84_latitude'];
168
			$structure['longitude'] = $communeTrouvee['wgs84_longitude'];
169
		} else {
170
			$this->nonTrouvees[] = $structure;
171
		}
172
		return $structure;
173
	}
174
 
175
	private function retrouverCoordonneesDansListeCommunes($structure) {
176
		$villeRecherche = self::transformerChainePourRecherche(($structure['cs_ville']));
177
		$communeTrouvee = null;
178
		$codeDepartement = "";
179
		// meme comportement que la methode precedente, mais la recherche est etendue a toutes les communes
180
		// si une commune est trouvee, on lui attribuera le code departement au code postal par defaut
181
		foreach ($this->communes as $departement => $communes) {
182
			foreach ($communes as $commune) {
183
				if ($commune['recherche'] == $villeRecherche) {
184
					$communeTrouvee = $commune;
185
					$codeDepartement = $departement;
186
					break;
187
				}
188
			}
189
			if (is_null($communeTrouvee)) {
190
				foreach ($communes as $commune) {
191
					if (strstr($commune['recherche'], $villeRecherche) !== false) {
192
						$communeTrouvee = $commune;
193
						$codeDepartement = $departement;
194
						break;
195
					} else if (strstr($villeRecherche, $commune['recherche']) !== false) {
196
						$communeTrouvee = $commune;
197
						$codeDepartement = $departement;
198
						break;
199
					}
200
				}
201
			}
202
		}
203
		if (!is_null($communeTrouvee)) {
204
			$structure['cs_ville']  = $communeTrouvee['nom'];
205
			$structure['latitude']  = $communeTrouvee['wgs84_latitude'];
206
			$structure['longitude'] = $communeTrouvee['wgs84_longitude'];
207
			$structure['cs_code_postal'] = $codeDepartement;
208
		} else {
209
			$this->nonTrouvees[] = $structure;
210
		}
211
		return $structure;
212
	}
213
 
214
	private function mettreAJourDonneesStructures() {
1696 raphael 215
		$this->bdd->requeter("USE ".Config::get("tables.bdd_nom_coel"));
1646 alex 216
		$updates = array();
217
		// pour faire une seule requete de mise a jour, on va pas utiliser l'ordre UPDATE qui n'accepte
218
		// qu'une seule condition, mais l'ordre INSERT en rajoutant a la fin ON DUPLICATE KEY UPDATE
219
		// avec les correspondances au niveau des codes postaux et villes
220
		foreach ($this->structures as $structure) {
221
			if (isset($structure['latitude']) && isset($structure['longitude'])) {
222
				$updates[] = "({$structure['cs_id_structure']},'{$structure['cs_code_postal']}',".
223
					$this->bdd->proteger($structure['cs_ville']).",'{$structure['latitude']}',".
224
					"'{$structure['longitude']}')";
225
			}
226
		}
1721 raphael 227
 
228
        if(!$updates) return;
229
 
1696 raphael 230
		$sql = "INSERT INTO ".Config::get("tables.table_structures_coel")." (cs_id_structure, cs_code_postal, ".
1646 alex 231
		"cs_ville, cs_latitude, cs_longitude) VALUES ".implode(",", $updates)." ".
232
		"ON DUPLICATE KEY UPDATE cs_code_postal=VALUES(cs_code_postal), cs_ville=VALUES(cs_ville), ".
233
		"cs_latitude=VALUES(cs_latitude), cs_longitude=VALUES(cs_longitude);";
234
		$this->bdd->requeter($sql);
235
	}
236
 
237
	private function afficherResultatScript() {
238
		$nombreUpdates = count($this->structures) - count($this->nonTrouvees);
239
		$message = "Mise à jour des coordonnées des communes terminée. Les structures qui n'avaient pas de ".
240
		"coordonnées se sont vues attribuer les coordonnées de la commune dans laquelle elles sont situées.\n\n".
241
		"Mises à jour effectuées pour $nombreUpdates structures.\n";
242
		if (count($this->nonTrouvees) > 0) {
243
			$message .= "Des problèmes ont été rencontrées pour les structures suivantes : \n";
244
			foreach ($this->nonTrouvees as $structure) {
245
				$message .= "  - {$structure['cs_nom']} ({$structure['cs_ville']}, {$structure['cs_code_postal']})\n";
246
			}
247
			$message .= "Veuillez vérifier le nom de la commune saisi ou aller dans la fiche structure ".
248
			"pour y rajouter les coordonnées longitude/latitude\n";
249
		} else {
250
			$message .= "Vous pourrez toujours par la suite aller dans la fiche structure ".
251
			"pour affiner la précision les coordonnées longitude/latitude au niveau des locaux.\n";
252
		}
253
		print($message);
254
	}
255
 
256
}
257
 
258
?>