Subversion Repositories eFlore/Applications.cel

Rev

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

Rev Author Line No. Line
416 aurelien 1
<?php
766 aurelien 2
/**
3
 * Service recherche de commune par coordonnées et vice versa
4
 * Encodage en entrée : utf8
5
 * Encodage en sortie : utf8
6
 *
7
 * @author Aurélien PERONNET <aurelien@tela-botanica.org>
8
 * @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
9
 * @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
10
 * @version $Id$
11
 */
772 aurelien 12
class CoordSearch extends Cel {
2143 jpm 13
 
766 aurelien 14
	private $adresse_service_geonames = null;
15
	private $adresse_service_local = null;
2143 jpm 16
 
766 aurelien 17
	private $nom_service_geocoding = null;
18
	private $nom_service_reverse_geocoding = null;
2143 jpm 19
 
766 aurelien 20
	function CoordSearch($config) {
2143 jpm 21
 
766 aurelien 22
		parent::__construct($config);
2143 jpm 23
 
970 aurelien 24
		$this->adresse_service_geonames = $this->config['cel']['url_service_geo_geonames'];
25
		$this->adresse_service_local = $this->config['cel']['url_service_geo_local'];
2143 jpm 26
 
970 aurelien 27
		$this->nom_service_geocoding = $this->config['cel']['nom_service_geocoding_geonames'];
28
		$this->nom_service_reverse_geocoding = $this->config['cel']['nom_service_reverse_geocoding_geonames'];
416 aurelien 29
	}
30
 
766 aurelien 31
	/**
32
	 * Recherche de coordonnées suivant ce qui est fourni
2143 jpm 33
	 *
766 aurelien 34
	 * $uid[0] = latitude (ou * si recherche coordonnées d'une commune)
35
	 * $uid[1] = longitude (ou * si recherche coordonnées d'une commune)
36
	 * $uid[2] = commune (ou * si recherche d'une commune correspondant à des coordonnées)
37
	 * $uid[3] = code_postal (ou * si recherche d'une commune correspondant à des coordonnées)
38
	 * $uid[4] = code_pays (ou * si recherche d'une commune correspondant à des coordonnées, par défaut vaut FR)
39
	 */
416 aurelien 40
	function getElement($uid){
41
 
766 aurelien 42
		$header = '';
43
		$retour = array();
416 aurelien 44
 
766 aurelien 45
		$params = $this->traiterParametres($uid);
2143 jpm 46
 
766 aurelien 47
		if ($this->estUneRequeteReverseGeocoding($params)) {
416 aurelien 48
 
766 aurelien 49
			$informations_communes = $this->effectuerRequeteReverseGeocodingCartoOsm($params['lat'], $params['lon']);
2143 jpm 50
 
766 aurelien 51
			if (!$informations_communes) {
52
				$informations_communes = $this->effectuerRequeteReverseGeocodingGeonames($params['lat'], $params['lon']);
53
			}
2143 jpm 54
 
766 aurelien 55
			$header = 'Content-Type: application/json; charset=UTF-8';
56
			$retour = json_encode($informations_communes) ;
416 aurelien 57
 
766 aurelien 58
	    } elseif ($this->estUneRequeteGeocoding($params)) {
2143 jpm 59
 
1296 aurelien 60
			$informations_coord = $this->chercherCentroideCommuneBdd($params['commune'],$params['code_postal']);
61
			if(!$informations_coord) {
62
				$informations_coord = $this->effectuerRequeteGeocodingGeonames($params['commune'],$params['code_postal'],$params['code_pays']);
63
			}
416 aurelien 64
 
766 aurelien 65
			$header = 'Content-Type: application/json; charset=UTF-8';
66
			$retour = json_encode($informations_coord);
416 aurelien 67
 
766 aurelien 68
	    } else {
416 aurelien 69
 
766 aurelien 70
	      $header = 'HTTP/1.0 400 Bad Request';
71
	      $retour = 'Commune ou Coordonnées non spécifiées' ;
72
	    }
416 aurelien 73
 
766 aurelien 74
		header($header);
75
		echo $retour;
76
	}
2143 jpm 77
 
766 aurelien 78
	protected function traiterParametres($params) {
2143 jpm 79
 
766 aurelien 80
		$lat = $this->affecterValeurParametreOuDefaut($params, 0, '*');
2143 jpm 81
		$lng = $this->affecterValeurParametreOuDefaut($params, 1, '*');
416 aurelien 82
 
2143 jpm 83
		$commune = $this->affecterValeurParametreOuDefaut($params, 2, '*');
766 aurelien 84
		$code_postal = $this->affecterValeurParametreOuDefaut($params, 3, '*');
416 aurelien 85
 
766 aurelien 86
		$code_pays = $this->affecterValeurParametreOuDefaut($params, 4, 'FR');
2143 jpm 87
 
766 aurelien 88
		return array('lat' => $lat, 'lon' => $lng, 'commune' => $commune,
89
					'code_postal' => $code_postal, 'code_pays' => $code_pays);
90
	}
2143 jpm 91
 
766 aurelien 92
	private function affecterValeurParametreOuDefaut($params, $indice, $valeur_si_non_present) {
2143 jpm 93
		return isset($params[$indice]) ? str_replace('"','',urldecode($params[$indice])) : $valeur_si_non_present;
766 aurelien 94
	}
2143 jpm 95
 
766 aurelien 96
	private function estUneRequeteReverseGeocoding($params) {
2143 jpm 97
 
766 aurelien 98
		return ($params['lat'] != '*' && $params['lon'] != '*');
99
	}
2143 jpm 100
 
766 aurelien 101
	private function estUneRequeteGeocoding($params) {
102
		return ($params['commune'] != '*');
103
	}
2143 jpm 104
 
766 aurelien 105
	private function effectuerRequeteReverseGeocodingCartoOsm($lat, $lon) {
2143 jpm 106
 
1296 aurelien 107
		$infos_commune_json = @file_get_contents($this->adresse_service_local."?lat=".$lat."&lon=".$lon);
766 aurelien 108
		$infos_commune = json_decode($infos_commune_json);
2143 jpm 109
 
766 aurelien 110
		$retour = false;
2143 jpm 111
 
766 aurelien 112
		if ($this->estUnRetourOsmValide($infos_commune)) {
113
			$retour = array('nom' => $infos_commune->nom, 'code_insee' => $infos_commune->codeINSEE);
114
		}
2143 jpm 115
 
766 aurelien 116
		return $retour;
117
	}
2143 jpm 118
 
766 aurelien 119
	private function estUnretourOsmValide($retour) {
120
		return (is_a($retour,'stdClass') && property_exists($retour,'nom') && property_exists($retour,'codeINSEE'));
121
	}
2143 jpm 122
 
766 aurelien 123
	private function effectuerRequeteReverseGeocodingGeonames($lat, $lon) {
2143 jpm 124
 
766 aurelien 125
		$infos_commune_json = @file_get_contents($this->adresse_service_geonames.
1296 aurelien 126
			$this->nom_service_reverse_geocoding.
1970 aurelien 127
			"?lat=".urlencode($lat)."&lng=".urlencode($lon).
128
			"&style=full");
766 aurelien 129
		$objet_retour = json_decode($infos_commune_json);
2143 jpm 130
 
766 aurelien 131
		$retour = false;
2143 jpm 132
		if($this->estUnRetourReverseGeocodingGeonamesValide($objet_retour)) {
1970 aurelien 133
			$retour = array('nom' => $objet_retour->geonames[0]->adminName4, 'code_insee' => $objet_retour->geonames[0]->adminCode4);
766 aurelien 134
		}
2143 jpm 135
 
766 aurelien 136
		return $retour;
137
	}
2143 jpm 138
 
772 aurelien 139
	private function estUnRetourReverseGeocodingGeonamesValide($retour) {
2143 jpm 140
 
766 aurelien 141
		$valide = false;
2143 jpm 142
 
143
		if (is_a($retour,'stdClass') && property_exists($retour,'geonames')
794 aurelien 144
			&& is_array($retour->geonames) && count($retour->geonames) > 0) {
772 aurelien 145
			$objet_resultats = $retour->geonames[0];
146
			if (property_exists($objet_resultats,'adminName4') && property_exists($objet_resultats,'adminCode2')) {
766 aurelien 147
				$valide = true;
148
			}
2143 jpm 149
		}
150
 
766 aurelien 151
		return $valide;
152
	}
1296 aurelien 153
 
154
	private function chercherCentroideCommuneBdd($commune, $departement) {
155
 
1311 aurelien 156
		$commune_formatee = str_replace(' ','_',$commune);
157
		$commune_formatee = str_replace('-','_',$commune_formatee);
1296 aurelien 158
 
159
		if(strlen($departement) > 2) {
160
			$departement = substr($departement,0,2);
161
		}
162
		$requete_selection_commune = 'SELECT utm_x, utm_y, utm_secteur, code FROM cel_zones_geo '.
1765 raphael 163
					      'WHERE nom LIKE '.Cel::db()->proteger($commune_formatee).' AND code LIKE '.Cel::db()->proteger($departement.'%');
1296 aurelien 164
 
2143 jpm 165
		$commune_coordonnees = Cel::db()->requeter($requete_selection_commune);
1296 aurelien 166
 
167
		$retour = false;
168
 
169
		if($commune_coordonnees && is_array($commune_coordonnees) && count($commune_coordonnees) > 0) {
170
 
171
			  $lat_lon = $this->convertirUtmVersLatLong($commune_coordonnees[0]['utm_x'],$commune_coordonnees[0]['utm_y'],$commune_coordonnees[0]['utm_secteur']);
2143 jpm 172
 
1296 aurelien 173
			  $retour = array('lat' => (float)$lat_lon['lat'],
174
			  'lng' => (float)$lat_lon['lng'],
175
			  'nom' => $commune,
176
			  'code_insee' => $commune_coordonnees[0]['code']
177
			  );
178
 
179
		}
180
 
181
		return $retour;
182
	}
183
 
184
	private function convertirUtmVersLatLong($x, $y, $sector) {
2143 jpm 185
 
1296 aurelien 186
		$lat_long = array();
2143 jpm 187
 
1296 aurelien 188
		$convertisseur = new gPoint();
189
		$convertisseur->setUTM($x, $y, $sector);
190
		$convertisseur->convertTMtoLL();
191
		$lat_long['lat'] = str_replace(',','.',$convertisseur->Lat());
192
		$lat_long['lng'] = str_replace(',','.',$convertisseur->Long());
2143 jpm 193
 
1296 aurelien 194
		return $lat_long;
195
	}
2143 jpm 196
 
766 aurelien 197
	private function effectuerRequeteGeocodingGeonames($commune, $code_postal, $code_pays) {
2143 jpm 198
 
766 aurelien 199
		$requete = $this->adresse_service_geonames.
200
				$this->nom_service_geocoding.
201
				"?placename_startsWith=".urlencode($commune);
416 aurelien 202
 
766 aurelien 203
		if($code_postal != '*') {
204
			$requete .= "&postalcode_startsWith=".urlencode($code_postal);
1296 aurelien 205
		}
766 aurelien 206
		$requete .= "&country=".urlencode($code_pays)."&maxRows=10" ;
416 aurelien 207
 
766 aurelien 208
		$coord_json = @file_get_contents($requete);
772 aurelien 209
		$objet_retour = json_decode($coord_json);
2143 jpm 210
 
772 aurelien 211
		$retour = false;
2143 jpm 212
 
213
		if($this->estUnRetourGeocodingGeonamesValide($objet_retour)) {
214
			$retour = array('lat' => $objet_retour->postalCodes[0]->lat,
772 aurelien 215
							'lng' => $objet_retour->postalCodes[0]->lng,
216
							'nom' => $objet_retour->postalCodes[0]->placeName,
217
							'code_insee' => $objet_retour->postalCodes[0]->postalCode
218
							);
219
		}
766 aurelien 220
 
772 aurelien 221
		return $retour;
416 aurelien 222
	}
2143 jpm 223
 
772 aurelien 224
	private function estUnRetourGeocodingGeonamesValide($retour) {
225
		$valide = false;
2143 jpm 226
 
227
		if (is_a($retour,'stdClass') && property_exists($retour,'postalCodes')
794 aurelien 228
			&& is_array($retour->postalCodes) && count($retour->postalCodes) > 0) {
772 aurelien 229
			$objet_resultats = $retour->postalCodes[0];
230
			if (property_exists($objet_resultats,'lat') && property_exists($objet_resultats,'lng')) {
231
				$valide = true;
232
			}
2143 jpm 233
		}
234
 
772 aurelien 235
		return $valide;
236
	}
416 aurelien 237
}
809 aurelien 238
?>