Subversion Repositories eFlore/Applications.cel

Rev

Rev 2458 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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