1041 lines
43 KiB
PHP
1041 lines
43 KiB
PHP
<?
|
|
if ( !function_exists('htmlspecialchars_decode') )
|
|
{
|
|
function htmlspecialchars_decode($text)
|
|
{
|
|
return strtr($text, array_flip(get_html_translation_table(HTML_SPECIALCHARS)));
|
|
}
|
|
}
|
|
|
|
require_once 'framework/common/curl.php';
|
|
|
|
function supprDecimales($dec) {
|
|
if ($dec>0 )
|
|
return floor($dec);
|
|
else
|
|
return ceil($dec);
|
|
}
|
|
|
|
function dec2dms($dec) {
|
|
$d = supprDecimales($dec);
|
|
$m = supprDecimales(($dec - $d) * 60);
|
|
$s = abs(round(((($dec - $d) * 60) - $m) * 60));
|
|
$m = abs($m);
|
|
return $d.'°'.$m."'".$s.'"';
|
|
}
|
|
|
|
/**/
|
|
function ALG0001($phi,$e) {
|
|
$temp = ( 1 - ( $e * sin( $phi ) ) ) / ( 1 + ( $e * sin( $phi ) ) );
|
|
$L = log ( tan ( (pi()/4) + ($phi/2) ) * pow ($temp, ($e/2) ));
|
|
return $L;
|
|
}
|
|
|
|
/** Calcul de la latitude à partir de la latitude isométrique
|
|
**/
|
|
function ALG0002($L,$e,$epsilon) {
|
|
$phi[0] = 2 * atan(exp($L)) - (pi()/2);
|
|
|
|
$i=0;
|
|
do {
|
|
$i++;
|
|
$temp = ( 1 + ( $e * sin( $phi[$i-1] ) ) ) / ( 1 - ( $e * sin( $phi[$i-1] ) ) );
|
|
$phi[$i] = 2 * atan ( pow ($temp, ($e/2)) * exp ($L) ) - pi()/2;
|
|
}
|
|
while (abs($phi[$i] - $phi[$i - 1]) >= $epsilon);
|
|
|
|
return $phi[$i];
|
|
}
|
|
|
|
/** Transformation de coordonnées en projection conique conforme de Lambert, en coordonnées géographiques
|
|
** @param double $X Coordonnée X en projection conique conforme de Lambert du point
|
|
** @param double $Y Coordonnée Y en projection conique conforme de Lambert du point
|
|
** @param double $n Exposant de la projection
|
|
** @param double $c Constante de la projection
|
|
** @param double $Xs Coordonnée Xs en projection du pôle
|
|
** @param double $Ys Coordonnée Ys en projection du pôle
|
|
** @param double $lambdac Longitude de l'origine par rapport au méridien origine
|
|
** @param double $e Première excentricité de l'ellipsoïde
|
|
** @param double $epsilon Tolérance de convergence
|
|
** @return array lambda Longitude par rapport au méridien origine
|
|
** phi Latitude
|
|
**/
|
|
function ALG0004($X,$Y,$n,$c,$Xs,$Ys,$lambdac,$e,$epsilon) {
|
|
$R = sqrt( pow(($X - $Xs),2) + pow(($Y - $Ys),2) );
|
|
$gamma = atan(($X - $Xs)/($Ys - $Y));
|
|
|
|
$lambda = $lambdac + ($gamma / $n);
|
|
|
|
$L = (-1 / $n) * log(abs($R/$c));
|
|
|
|
$phi = ALG0002($L,$e,$epsilon);
|
|
|
|
$coords['lambda']=$lambda;
|
|
$coords['phi']=$phi;
|
|
|
|
return $coords;
|
|
}
|
|
|
|
/** Transformation des coordonnées géographiques ellipsoïdales en coordonnées cartésiennes
|
|
**
|
|
**/
|
|
function ALG0009($lambda,$phi,$he,$a,$e) {
|
|
$N = ALG0021($phi,$a,$e);
|
|
|
|
$X = ($N + $he) * cos($phi) * cos($lambda);
|
|
|
|
$Y = ($N + $he) * cos($phi) * sin($lambda);
|
|
|
|
$Z = ($N * (1 - $e*$e) + $he) * sin ($phi);
|
|
|
|
$coords['X']=$X;
|
|
$coords['Y']=$Y;
|
|
$coords['Z']=$Z;
|
|
|
|
return $coords;
|
|
}
|
|
|
|
/**/
|
|
function ALG0012($X,$Y,$Z,$a,$e,$epsilon) {
|
|
$lambda = atan ($Y/$X);
|
|
|
|
$P = sqrt($X*$X + $Y*$Y);
|
|
$phi[0] = atan ($Z/ ($P * (1 - ( ($a*$e*$e)/sqrt($X*$X + $Y*$Y + $Z*$Z) ) ) ) );
|
|
|
|
$i = 0;
|
|
do
|
|
{
|
|
$i++;
|
|
$temp = pow((1 - ( $a * $e*$e * cos($phi[$i - 1] )/( $P * sqrt(1 - $e*$e * sin($phi[$i - 1])*sin($phi[$i - 1]))))),-1);
|
|
$phi[$i] = atan( $temp * $Z / $P );
|
|
}
|
|
while (abs($phi[$i] - $phi[$i - 1]) >= $epsilon);
|
|
|
|
$phix = $phi[$i];
|
|
|
|
$he = ($P/cos($phix)) - ($a/sqrt(1 - $e*$e * sin($phix)*sin($phix)));
|
|
|
|
$coords['lambda']=$lambda;
|
|
$coords['phi']=$phix;
|
|
$coords['he']=$he;
|
|
|
|
return $coords;
|
|
}
|
|
|
|
/** Transformation d'un jeu de 7 paramètres entre 2 systèmes géodésiques
|
|
** @param double $Tx Translation suivant l'axe des X (de 1 vers 2)
|
|
** @param double $Ty Translation suivant l'axe des Y (de 1 vers 2)
|
|
** @param double $Tz Translation suivant l'axe des Z (de 1 vers 2)
|
|
** @param double $D Facteur d'échelle de 1 vers 2
|
|
** @param double $Rx Angle de rotation autour de l'axe des X en radian (de 1 vers 2)
|
|
** @param double $Ry Angle de rotation autour de l'axe des Y en radian (de 1 vers 2)
|
|
** @param double $Rz Angle de rotation autour de l'axe des Z en radian (de 1 vers 2)
|
|
** @param double $U Vecteur de coordonnées cartésiennes tridimensionnelles dans le système 1 : U=(Ux,Uy,Uz)
|
|
** @return array Vecteur de coordonnées cartésiennes tridimensionnelles dans le système 2, V=(Vx,Vy,Vz)
|
|
*/
|
|
function ALG0013($Tx,$Ty,$Tz,$D,$Rx,$Ry,$Rz,$U) {
|
|
$V=array();
|
|
$V['X'] = $Tx + $U['X'] * (1 + $D) + $U['Z'] * $Ry - $U['Y'] * $Rz;
|
|
$V['Y'] = $Ty + $U['Y'] * (1 + $D) + $U['X'] * $Rz - $U['Z'] * $Rx;
|
|
$V['Z'] = $Tz + $U['Z'] * (1 + $D) + $U['Y'] * $Rx - $U['X'] * $Ry;
|
|
|
|
return $V;
|
|
}
|
|
|
|
/** Détermination des paramètres de calcul d'une projection Lambert conique
|
|
** dans le cas tangent, avec ou sans facteur d'échelle en fonction des paramètres de définition usuels
|
|
** @return array n, C, lambdac, Xs, Ys
|
|
**/
|
|
function ALG0019($lambda0,$phi0,$k0,$X0,$Y0,$a,$e) {
|
|
$lambdac = $lambda0;
|
|
$n = sin($phi0);
|
|
$C = $k0 * ALG0021($phi0,$a,$e) * tan (pi()/2 - $phi0) * exp ( $n * ALG0001($phi0,$e) );
|
|
$Xs = $X0;
|
|
$Ys = $Y0 + $k0 * ALG0021($phi0,$a,$e) * tan (pi()/2 - $phi0) ;
|
|
|
|
$tab ['e'] = $e;
|
|
$tab ['n'] = $n;
|
|
$tab ['C'] = $C;
|
|
$tab ['lambdac'] = $lambdac;
|
|
$tab ['Xs'] = $Xs;
|
|
$tab ['Ys'] = $Ys;
|
|
|
|
return $tab;
|
|
|
|
}
|
|
|
|
/** Calcul de la grande normale de l'ellipsoïde
|
|
** @param double $phi Latitude
|
|
** @param double $a Demi-grand axe de l'ellipsoïde
|
|
** @param double $e Première excentricité de l'ellipsoïde
|
|
** @return double
|
|
**/
|
|
function ALG0021($phi,$a,$e) {
|
|
$N = $a/sqrt( 1 - $e * $e * sin($phi) * sin($phi) );
|
|
return $N;
|
|
|
|
}
|
|
|
|
/** Calcul des constantes d'une projection Lambert conique conforme dans le cas sécant
|
|
** @param double $lambda0 Longitude origine en radian par rapport au méridien origine
|
|
** @param double $phi0 Latitude origine
|
|
** @param double $X0 Coordonnée X en projection du point origine
|
|
** @param double $Y0 Coordonnée Y en projection du point origine
|
|
** @param double $phi1 Latitude en radian du 1er parallèle automécoïque
|
|
** @param double $phi2 Latitude en radian du 2ème parallèle automécoïque
|
|
** @param double $a Demi-grand axe de l'ellipsoïde
|
|
** @param double $e Première excentricité de l'ellipsoïde
|
|
** @return array n, C, lambdac, Xs, Ys
|
|
**/
|
|
function ALG0054($lambda0,$phi0,$X0,$Y0,$phi1,$phi2,$a,$e) {
|
|
$lambdac = $lambda0;
|
|
$n = ( (log( (ALG0021($phi2,$a,$e)*cos($phi2))/(ALG0021($phi1,$a,$e)*cos($phi1)) ))/(ALG0001($phi1,$e) - ALG0001($phi2,$e) ));
|
|
$C = ((ALG0021($phi1,$a,$e)* cos($phi1))/$n) * exp($n * ALG0001($phi1,$e));
|
|
|
|
if ($phi0 == (pi()/2)) {
|
|
$Xs = $X0;
|
|
$Ys = $Y0;
|
|
} else {
|
|
$Xs = $X0;
|
|
$Ys = $Y0 + $C * exp(-1 * $n * ALG0001($phi0,$e));
|
|
}
|
|
$tab=array( 'e' => $e,
|
|
'n' => $n,
|
|
'C' => $C,
|
|
'lambdac' => $lambdac,
|
|
'Xs'=> $Xs,
|
|
'Ys'=> $Ys);
|
|
return $tab;
|
|
|
|
}
|
|
|
|
function Lambert2WGS84($X,$Y,$orig='L93') {
|
|
$epsilon = 0.00000000001;
|
|
|
|
$lambdac = 0.04079234433; // pour greenwich
|
|
$e = 0.08248325676; // première excentricité de l ellipsoïde Clarke 1880 français
|
|
$he = 100;
|
|
$a = 6378249.2; // demi-grand axe de l'ellipsoide
|
|
|
|
$Tx = -168;
|
|
$Ty = -60;
|
|
$Tz = +320;
|
|
$D = 0;
|
|
$Rx = $Ry = $Rz = 0;
|
|
|
|
$orig=strtoupper($orig);
|
|
switch ($orig) {
|
|
case 'LI':
|
|
case 'L1': $n = 0.7604059656;
|
|
$c = 11603796.98;
|
|
$Xs = 600000;
|
|
$Ys = 5657616.674;
|
|
break;
|
|
case 'LII':
|
|
case 'LIIE':
|
|
case 'L2E':
|
|
case 'L2': $n = 0.7289686274;
|
|
$c = 11745793.39;
|
|
$Xs = 600000;
|
|
if ($orig=='L2E' || $orig=='LIIE')
|
|
$Ys = 8199695.768;
|
|
else $Ys = 6199695.768;
|
|
break;
|
|
case 'LIII':
|
|
case 'L3': $n = 0.6959127966;
|
|
$c = 11947992.52;
|
|
$Xs = 600000;
|
|
$Ys = 6791905.085;
|
|
break;
|
|
case 'LIV':
|
|
case 'L4': $n = 0.6712679322;
|
|
$c = 12136281.99;
|
|
$Xs = 234.358;
|
|
$Ys = 7239161.542;
|
|
break;
|
|
case 'L93':
|
|
default: $n = 0.7256077650;
|
|
$c = 11745255.426;
|
|
$Xs = 700000;
|
|
$Ys = 12655612.050;
|
|
break;
|
|
}
|
|
|
|
$coords = ALG0004($X,$Y,$n,$c,$Xs,$Ys,$lambdac,$e,$epsilon);
|
|
|
|
$coords = ALG0009($coords['lambda'],$coords['phi'],$he,$a,$e);
|
|
|
|
$coords = ALG0013($Tx,$Ty,$Tz,$D,$Rx,$Ry,$Rz,$coords);
|
|
|
|
$a = 6378137.0; // ellipsoïdes WGS84
|
|
$f = 1/298.257223563;
|
|
$b = $a*(1-$f);
|
|
$e = sqrt(($a*$a - $b*$b)/($a*$a));
|
|
|
|
$X = $coords['X'];
|
|
$Y = $coords['Y'];
|
|
$Z = $coords['Z'];
|
|
$coords = ALG0012($X,$Y,$Z,$a,$e,$epsilon);
|
|
|
|
$xy['long'] = rad2deg($coords['lambda']);
|
|
$xy['lat'] = rad2deg($coords['phi']);
|
|
return $xy;
|
|
}
|
|
|
|
/**
|
|
* Function to convert geographic coordinates to "lambert 2 etendue" coordinates
|
|
* from: http://www.forumsig.org/showthread.php?p=64050#post64050
|
|
**/
|
|
function geos2lambert($latitude,$longitude) {
|
|
//0)degres-minutes-secondes + orientation (d,m,s,o) en radian
|
|
$lambda_w = $longitude * pi()/180 ;
|
|
$phi_w = $latitude * pi()/180 ;
|
|
|
|
//1) coordonnées géographiques WGS84 (phi_w,lambda_w) en coordonnées cartésiennes WGS84 (X_w,Y_w,Z_w)
|
|
$a_w = 6378137.0;
|
|
$b_w = 6356752.314;
|
|
|
|
$e2_w = ($a_w*$a_w-$b_w*$b_w)/($a_w*$a_w);
|
|
|
|
//et on a la grande normale de l'ellipsoide WGS84
|
|
$N = $a_w/sqrt(1-$e2_w*pow(sin($phi_w),2));
|
|
|
|
//ainsi on obtient
|
|
$X_w = $N * cos($phi_w) * cos($lambda_w);
|
|
$Y_w = $N * cos($phi_w) * sin($lambda_w);
|
|
$Z_w = $N * (1-$e2_w) * sin($phi_w);
|
|
//Ref.: http://www.ign.fr/telechargement/MPr...RCE/NTG_80.pdf and http://de.wikipedia.org/wiki/WGS84
|
|
|
|
//2) coordonnées cartésiennes WGS84 (X_w,Y_w,Z_w) en coordonnées cartésiennes NTF (X_n,Y_n,Z_n)
|
|
|
|
$dX = 168.0;
|
|
$dY = 60.0;
|
|
$dZ = -320.0;
|
|
|
|
$X_n = $X_w + $dX;
|
|
$Y_n = $Y_w + $dY;
|
|
$Z_n = $Z_w + $dZ;
|
|
//ref.: http://support.esrifrance.fr/Documents/Generalites/Projections/Generalites/Generalites.htm#2
|
|
|
|
//3) coordonnées cartésiennes NTF (X_n,Y_n,Z_n) en coordonnées géographiques NTF (phi_n,lambda_n)
|
|
$a_n = 6378249.2;
|
|
$b_n = 6356515.0;
|
|
|
|
$e2_n = ($a_n*$a_n-$b_n*$b_n)/($a_n*$a_n);
|
|
//on définit une tolérance de convergence
|
|
$epsilon = pow(10,-10);
|
|
|
|
//puis on amorce une boucle de calcul
|
|
$p0=atan($Z_n/sqrt($X_n*$X_n+$Y_n*$Y_n)*(1-($a_n*$e2_n)/(sqrt($X_n*$X_n+$Y_n*$Y_n+$Z_n*$Z_n))));
|
|
$p1=atan(($Z_n/sqrt($X_n*$X_n+$Y_n*$Y_n))/(1-($a_n*$e2_n*cos($p0))/(sqrt(($X_n*$X_n+$Y_n*$Y_n)*(1-$e2_n*pow(sin($p0),2))))));
|
|
while(!(abs($p1-$p0)<$epsilon)){
|
|
$p0 = $p1;
|
|
$p1 = atan(($Z_n/sqrt($X_n*$X_n+$Y_n*$Y_n))/(1-($a_n*$e2_n*cos($p0))/(sqrt(($X_n*$X_n+$Y_n*$Y_n)*(1-$e2_n*pow(sin($p0),2))))));
|
|
}
|
|
$phi_n = $p1;
|
|
$lambda_n = atan($Y_n/$X_n);
|
|
|
|
//4) coordonnées géographiques NTF (phi_n,lambda_n) en coordonnées projetées en Lambert II étendu (X_l2e, Y_l2e)
|
|
$n = 0.7289686274;
|
|
$c = 11745793.39;
|
|
$Xs = 600000.0;
|
|
$Ys = 8199695.768;
|
|
|
|
$e_n = sqrt($e2_n);
|
|
$lambda0 = 0.04079234433198; //correspond à la longitude en radian de Paris (2°20'14.025" E) par rapport à Greenwich
|
|
//puis on calcule la latitude isométrique
|
|
$L = log(tan(pi()/4 + $phi_n/2) * pow(((1-$e_n*sin($phi_n))/(1+$e_n*sin($phi_n))),($e_n/2)));
|
|
|
|
//enfin on projette
|
|
$X_l2e = $Xs + $c*exp((-$n*$L))*sin($n*($lambda_n-$lambda0));
|
|
$Y_l2e = $Ys - $c*exp((-$n*$L))*cos($n*($lambda_n-$lambda0));
|
|
|
|
return array("x_l2e"=>$X_l2e,"y_l2e"=>$Y_l2e);
|
|
}
|
|
|
|
|
|
/** Conversion WGS84 en Lambert93
|
|
** NTG_71.pdf
|
|
** http://www.ign.fr/affiche_rubrique.asp?rbr_id=1700&lng_id=FR
|
|
**/
|
|
function geos2lambert93($latitude,$longitude) {
|
|
|
|
// Système WGS84
|
|
$a=6378137; // demi grand axe de l'ellipsoide (m)
|
|
$e=0.08181919106; // première excentricitè de l'ellipsoide
|
|
|
|
// Paramètres de projections
|
|
$l0=$lc=deg2rad(3); // longitude de référence
|
|
$phi0=deg2rad(46.5); // latitude d'origine en radian
|
|
$phi1=deg2rad(44); // 1er parallele automécoïque
|
|
$phi2=deg2rad(49); // 2eme parallele automécoïque
|
|
|
|
$x0=700000; //coordonnées à l'origine
|
|
$y0=6600000; //coordonnées à l'origine
|
|
|
|
// coordonnées du point à traduire
|
|
$phi=deg2rad($latitude);
|
|
$l=deg2rad($longitude);
|
|
|
|
// calcul des grandes normales
|
|
$gN1=$a/sqrt(1-$e*$e*sin($phi1)*sin($phi1));
|
|
$gN2=$a/sqrt(1-$e*$e*sin($phi2)*sin($phi2));
|
|
|
|
//calculs de slatitudes isométriques
|
|
$gl1=log(tan(pi()/4+$phi1/2)*pow((1-$e*sin($phi1))/(1+$e*sin($phi1)),$e/2));
|
|
$gl2=log(tan(pi()/4+$phi2/2)*pow((1-$e*sin($phi2))/(1+$e*sin($phi2)),$e/2));
|
|
$gl0=log(tan(pi()/4+$phi0/2)*pow((1-$e*sin($phi0))/(1+$e*sin($phi0)),$e/2));
|
|
$gl=log(tan(pi()/4+$phi/2)*pow((1-$e*sin($phi))/(1+$e*sin($phi)),$e/2));
|
|
|
|
//calcul de l'exposant de la projection
|
|
$n=(log(($gN2*cos($phi2))/($gN1*cos($phi1))))/($gl1-$gl2);//ok
|
|
|
|
//calcul de la constante de projection
|
|
$c=(($gN1*cos($phi1))/$n)*exp($n*$gl1);//ok
|
|
|
|
//calcul des coordonnées
|
|
$ys=$y0+$c*exp(-1*$n*$gl0);
|
|
|
|
//calcul des coordonnées lambert
|
|
$x93=$x0+$c*exp(-1*$n*$gl)*sin($n*($l-$lc));
|
|
$y93=$ys-$c*exp(-1*$n*$gl)*cos($n*($l-$lc));
|
|
|
|
return array("x_93"=>$x93,"y_93"=>$y93);
|
|
}
|
|
|
|
|
|
//http://www.ign.fr/telechargement/MPro/geodesie/CIRCE/transfo.pdf
|
|
//http://www.ign.fr/telechargement/MPro/geodesie/CIRCE/NTG_80.pdf
|
|
//http://www.ign.fr/telechargement/MPro/geodesie/CIRCE/NTG_71.pdf
|
|
/**
|
|
print_r(Lambert2WGS84(591647.56,2426659.65));
|
|
print_r(geos2lambert(48.838245134184 ,2.2227849815878));
|
|
**/
|
|
|
|
/** The point-in-polygon algorythm allows you to programmatically check if a particular point is inside a polygon or outside of it. A common way to tackle the problem is to count how many times a line drawn from the point (in any direction) intersects with the polygon boundary. If they intersect an even number of times, then the point is outside.
|
|
I used that approach in this PHP code, which doesn't contain detailed comments yet. A few people asked if I could post it anyway, so there it is... I'll try to add some more comment as soon as I have some spare time.
|
|
|
|
The returned values are:
|
|
"vertex" if the point sits exactly on a vertex AND you left true as the value for $pointOnVertex.
|
|
"boundary" if the point sits on the boundary. If $pointOnVertex is false, then "boundary" is also returned if the point is on a vertex.
|
|
"inside" if the point is inside the polygon.
|
|
"outside" if, you guessed it, the point is outside of the polygon.
|
|
*/
|
|
class pointLocation {
|
|
|
|
var $pointOnVertex = true; // Check if the point sits exactly on one of the vertices
|
|
|
|
function pointLocation() {
|
|
}
|
|
|
|
function pointInPolygon($point, $polygon, $pointOnVertex = true) {
|
|
$this->pointOnVertex = $pointOnVertex;
|
|
|
|
// Transform string coordinates into arrays with x and y values
|
|
$point = $this->pointStringToCoordinates($point);
|
|
$vertices = array();
|
|
foreach ($polygon as $vertex) {
|
|
$vertices[] = $this->pointStringToCoordinates($vertex);
|
|
}
|
|
//print_r($vertices);
|
|
//die();
|
|
// Check if the point sits exactly on a vertex
|
|
if ($this->pointOnVertex == true && $this->pointOnVertex($point, $vertices) == true) {
|
|
return "vertex";
|
|
}
|
|
|
|
// Check if the point is inside the polygon or on the boundary
|
|
$intersections = 0;
|
|
$vertices_count = count($vertices);
|
|
echo "vertices_count=$vertices_count".EOL;
|
|
|
|
for ($i=1; $i < $vertices_count; $i++) {
|
|
$vertex1 = $vertices[$i-1];
|
|
$vertex2 = $vertices[$i];
|
|
if ($vertex1['y'] == $vertex2['y'] && $vertex1['y'] == $point['y'] && $point['x'] > min($vertex1['x'], $vertex2['x']) && $point['x'] < max($vertex1['x'], $vertex2['x'])) {
|
|
// Check if point is on an horizontal polygon boundary
|
|
return "boundary";
|
|
}
|
|
if ($point['y'] > min($vertex1['y'], $vertex2['y']) && $point['y'] <= max($vertex1['y'], $vertex2['y']) && $point['x'] <= max($vertex1['x'], $vertex2['x']) && $vertex1['y'] != $vertex2['y']) {
|
|
$xinters = ($point['y'] - $vertex1['y']) * ($vertex2['x'] - $vertex1['x']) / ($vertex2['y'] - $vertex1['y']) + $vertex1['x'];
|
|
if ($xinters == $point['x']) {
|
|
// Check if point is on the polygon boundary (other than horizontal)
|
|
return "boundary";
|
|
}
|
|
if ($vertex1['x'] == $vertex2['x'] || $point['x'] <= $xinters) {
|
|
$intersections++;
|
|
}
|
|
}
|
|
}
|
|
// If the number of edges we passed through is even, then it's in the polygon.
|
|
echo "intersections=$intersections".EOL;
|
|
if ($intersections % 2 != 0) {
|
|
return "inside";
|
|
} else {
|
|
return "outside";
|
|
}
|
|
}
|
|
|
|
function pointOnVertex($point, $vertices) {
|
|
foreach($vertices as $vertex) {
|
|
if ($point == $vertex) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
function pointStringToCoordinates($pointString) {
|
|
$coordinates = explode(' ', $pointString);
|
|
return array('x'=>$coordinates[0], 'y'=>$coordinates[1]);
|
|
}
|
|
|
|
}
|
|
|
|
class MMap {
|
|
|
|
private $accesDist = true;
|
|
private $referer ='';
|
|
private $body = '';
|
|
private $header = '';
|
|
private $cookie = '';
|
|
private $codeRetour = 0;
|
|
private $codeRetourG = 0; // Code retour de l'api Google
|
|
private $codeRetourY = 0; // Code retour de l'api Yahoo
|
|
private $codeRetourM = 0; // Code retour de l'api Mappy
|
|
|
|
public $geocodeur='';
|
|
|
|
public $latitudeDec= 0; // Latitude en Décimal
|
|
public $latitudeDeg= 0; // Latitude en Dégrés
|
|
public $longitudeDec= 0; // Longitude en Décimal
|
|
public $longitudeDeg= 0; // Longitude en Dégrés
|
|
public $altitude = NULL; // Altitude en mètres
|
|
public $l93x = NULL; // Lambert 93, coordonnée X
|
|
public $l93y = NULL; // Lambert 93, coordonnée Y
|
|
|
|
public $precision = 0;
|
|
public $adresseValidee='';
|
|
public $enCache=false;
|
|
|
|
private $apiKeyG='ABQIAAAAuKBtUyFonYJBl1fqfc78tRQvADPcxwXf3Q2QIE-M32vuSkrxiBRLUHDB_YSLeTscTDeWRKM_wILaaw';
|
|
// private $apiKey='ABQIAAAAuKBtUyFonYJBl1fqfc78tRT4Qe_2x2fax4Crd4sBzQI-tDkl3BRm2l2feTV5Lnx0Ah-aTIlwHtglpA';
|
|
private $apiKeyY='klII0gzV34Ho2TCsN3XiXeh4No033AifxMeDXfFXj8TDCXO3WAtOLj9c74VsV45HcII-';
|
|
|
|
function __construct($accesDist=true) {// $adresse, $cp, $ville, $pays='France') {
|
|
$this->accesDist=$accesDist;
|
|
}
|
|
|
|
/*
|
|
http://platform.beta.mapquest.com/geocoding/v1/address?key=YOUR_KEY_HERE&location=Lancaster,PA&callback=renderGeocode
|
|
http://platform.beta.mapquest.com/geocoding/v1/address?key=YOUR_KEY_HERE&callback=renderOptions&inFormat=kvp&outFormat=json&location=77 rue lost al lann, 29000 quimper,france
|
|
|
|
Client ID: 83955
|
|
Email Address: buzuk77@aim.com
|
|
Registry Password: tU2cA4qV
|
|
Forums User Name:
|
|
JS/AS3 Key: Fmjtd%7Clu61nuuzlu%2Cr0%3Do5-5a1sd
|
|
*/
|
|
|
|
/*
|
|
GeoCodingHandler.ashx?addr=
|
|
<wsdl:import namespace="http://dev.virtualearth.net/webservices/v1/imagery/contracts" location="http://dev.virtualearth.net/webservices/v1/metadata/imageryservice/imageryservice1.wsdl" />
|
|
API keybing = 56D6CBA671C986D3EA11B1B48F97507BE9B46999
|
|
*/
|
|
public function geoCodeAdrCpVilleM($adresse,$cp,$ville,$pays='') {
|
|
|
|
if ($pays=='') $pays='France';
|
|
if (preg_match('/^([0-9]{1,4} )(.*)$/', $adresse, $matches)) {
|
|
$adresseVoie=trim($matches[2]);
|
|
$adresseNum=trim($matches[1]);
|
|
} else {
|
|
$adresseVoie=trim($adresse);
|
|
$adresseNum='';
|
|
}
|
|
$url='http://axe.mappy.com/services/loc/get.aspx?countryName='.urlencode($pays).'&townName='.urlencode($ville).'&wayName='.urlencode($adresseVoie).'&number='.urlencode($adresseNum).'&namedPlaceSearch=0&interactive=1&auth=maiaTest&format=json';
|
|
|
|
$page=getUrl($url, '', '', '', false, '', '', 3);
|
|
|
|
$res=json_decode($page['body']);
|
|
$result=$res->geocode->answer;
|
|
//print_r($result);die();
|
|
//$this->codeRetourM=
|
|
|
|
switch ($result->geocode_level->code) {
|
|
case 0: $this->precision=0; break; // No geocoding
|
|
case 1: $this->precision=1; break; // Country level geocoding
|
|
case 2: $this->precision=4; break; // Town level geocoding
|
|
case 3: $this->precision=6; break; // Way level geocoding
|
|
case 4: $this->precision=8; break; // Road element level geocoding
|
|
default: die('Precisions Inconnue : "'.$result->geocode_level->code.'"='.$result->geocode_level->label.EOL.$page['body']); break;
|
|
}
|
|
|
|
$this->adresseValidee=@preg_replace('/ +/', ' ', strtoupper(str_replace(''', "'", trim(htmlspecialchars_decode($result->road_element->number.' '.$result->way->name,ENT_QUOTES)))));
|
|
|
|
$this->codeRetourM=@$result->global_score;
|
|
/*
|
|
$result->postal_code->postal_code
|
|
$result->subcountry->iso_code // 11
|
|
$result->subcountry->language
|
|
$result->subcountry->Ile-de-France
|
|
|
|
$result->town->language] => FRE
|
|
$result->town->name] => Nanterre
|
|
$result->town->official_code] => 92050
|
|
$result->town->postal_codes->postal_code] => 92000
|
|
*/
|
|
|
|
|
|
/*
|
|
0 Unknown location. (Since 2.59)
|
|
1 Country level accuracy. (Since 2.59)
|
|
2 Region (state, province, prefecture, etc.) level accuracy. (Since 2.59)
|
|
3 Sub-region (county, municipality, etc.) level accuracy. (Since 2.59)
|
|
4 Town (city, village) level accuracy. (Since 2.59)
|
|
5 Post code (zip code) level accuracy. (Since 2.59)
|
|
6 Street level accuracy. (Since 2.59)
|
|
7 Intersection level accuracy. (Since 2.59)
|
|
8 Address level accuracy. (Since 2.59)
|
|
*/
|
|
$this->latitudeDec=@$result->location->coordinates->y;
|
|
$this->longitudeDec=@$result->location->coordinates->x;
|
|
$this->latitudeDeg=dec2dms($this->latitudeDec);
|
|
$this->longitudeDeg=dec2dms($this->longitudeDec);
|
|
|
|
$this->geocodeur='Mappy';
|
|
|
|
//if ($this->codeRetourM>0)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
private function geoCodeAdrCpVilleY($address) {
|
|
$_url = 'http://api.local.yahoo.com/MapsService/V1/geocode';
|
|
$_url .= sprintf('?appid=%s&location=%s',$this->apiKeyY,rawurlencode($address));
|
|
$_result = false;
|
|
$page=getUrl($_url, '', '', '', false, '', '', 3);
|
|
$_result=$page['body'];
|
|
// die("URL='$_url'".EOL.print_r($page));
|
|
$try=1;
|
|
while ($page['code']!=200 && $page['code']!=403) {
|
|
$page=getUrl($_url, '', '', '', false, '', '', 3);
|
|
$_result=$page['body'];
|
|
echo 'Yahoo '.$page['code']." : $address... Attente...".EOL;
|
|
$try++;
|
|
if ($try>=4) break;
|
|
sleep(1);
|
|
}
|
|
if ($page['code']==400 && preg_match('/<Message>unable to parse location<\/Message>/', $_result)) {
|
|
$this->latitudeDec=$this->longitudeDec=0;
|
|
$this->latitudeDeg=$this->longitudeDeg=0;
|
|
$this->geocodeur='Yahoo';
|
|
$this->precision=0;
|
|
return false;
|
|
} elseif ($page['code']==403 && preg_match('/<Message>limit exceeded<\/Message>/', $_result)) {
|
|
$this->latitudeDec=$this->longitudeDec=0;
|
|
$this->latitudeDeg=$this->longitudeDeg=0;
|
|
$this->geocodeur='Yahoo';
|
|
$this->precision=0;
|
|
$this->codeRetourY=620; // On adopte les codes Google
|
|
} elseif ($page['code']==408) { // Connexion impossible au site du partenaire
|
|
$this->latitudeDec=$this->longitudeDec=0;
|
|
$this->latitudeDeg=$this->longitudeDeg=0;
|
|
$this->geocodeur='Yahoo';
|
|
$this->precision=0;
|
|
$this->codeRetourY=500; // On adopte les codes Google
|
|
} elseif ($page['code']==200) {
|
|
preg_match('!<Latitude>(.*)</Latitude><Longitude>(.*)</Longitude>!U', $_result, $_match);
|
|
$lng = $_match[2];
|
|
$lat = $_match[1];
|
|
preg_match('/warning="(.*)"/Ui', $_result, $_match);
|
|
/*
|
|
1 Country level accuracy. (Since 2.59)
|
|
2 Region (state, province, prefecture, etc.) level accuracy. (Since 2.59)
|
|
7 Intersection level accuracy. (Since 2.59)
|
|
*/
|
|
$this->precision=0; // Unknown location
|
|
switch(@$_match[1]) {
|
|
case "The exact location could not be found. Here is a nearby county.": $this->precision=3; break; // Sub-region
|
|
case "The city could not be found. Here is the state/province.": $this->precision=3; break; // Sub-region
|
|
case "The exact location could not be found. Here is a nearby neighorhood.": $this->precision=4; break; // Town level
|
|
case "The exact location could not be found. Here is the center of the ZIP code.":
|
|
case "The street could not be found. Here is the center of the city.": $this->precision=5; break; // Post code (zip code)
|
|
case "The street number could not be found. Here is a nearby location.":
|
|
case "The Street name might have been changed": $this->precision=6; break; // Street level accuracy
|
|
case '': $this->precision=8; break; // Address level
|
|
default:
|
|
if (preg_match('/The exact location could not be found, here is the closest match/', @$_match[1]))
|
|
$this->precision=6;
|
|
else
|
|
die('Precisions Inconnue : "'.$_match[1].'"'.EOL.$_result);
|
|
break;
|
|
}
|
|
|
|
preg_match('!<Address>(.*)</Address>(?:|.*)<City>(.*)</City>(?:|.*)<State>(.*)</State>!Ui', $_result, $_match);
|
|
$adrValide=utf8_decode($_match[1].', '.$_match[2].', '.$_match[3]);
|
|
$this->adresseValidee=strtoupper(str_replace(''', "'", htmlspecialchars_decode($adrValide,ENT_QUOTES)));
|
|
$this->latitudeDec=$lat;
|
|
$this->longitudeDec=$lng;
|
|
$this->latitudeDeg=dec2dms($this->latitudeDec);
|
|
$this->longitudeDeg=dec2dms($this->longitudeDec);
|
|
$this->geocodeur='Yahoo';
|
|
if ($lat==0 && $lng==0 || $this->precision==0) die('Réponse Yahoo = '.$_result.EOL);
|
|
return true;//array("lat"=>$lat,"lng"=>$lng,"address"=>$address);
|
|
}
|
|
else {die("URL='$_url'".EOL.print_r($page));
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private function geoCodeAdrCpVilleG($adresse,$cp,$ville,$pays, $proxy='') {
|
|
|
|
$url='http://maps.google.com/maps/geo?q='.urlencode($adresse.', '.$cp.' '. $ville.', '.$pays).'&output=xml&key='.$this->apiKeyG;
|
|
|
|
$page=getUrl($url, '', '', $this->referer, false, 'maps.google.com', $proxy,3);
|
|
//getUrl($url, $strCookies='', $postData='', $referer='', $debug=false, $host='', $proxy='', $timeout=0) {
|
|
$this->body=$page['body'];
|
|
$this->codeRetour=$page['code'];
|
|
$this->header=$page['header'];
|
|
|
|
// REVERSE GEOCODING
|
|
// http://maps.google.com/maps/geo?oe=utf-8&ll=48.808955,2.34227&output=xml&key=ABQIAAAAuKBtUyFonYJBl1fqfc78tRQvADPcxwXf3Q2QIE-M32vuSkrxiBRLUHDB_YSLeTscTDeWRKM_wILaaw
|
|
|
|
//die($this->body=$page['body']);
|
|
//{"name":"3 rue viète, 75017 paris, france","Status":{"code":200,"request":"geocode"},"Placemark":[{"id":"p1","address":"3, Rue Viète, 75017 17ème Arrondissement, Paris, France","AddressDetails":{"Country":{"CountryNameCode":"FR","AdministrativeArea":{"AdministrativeAreaName":"Ile-de-France","SubAdministrativeArea":{"SubAdministrativeAreaName":"Paris","Locality":{"LocalityName":"Paris","DependentLocality":{"DependentLocalityName":"17ème Arrondissement","Thoroughfare":{"ThoroughfareName":"3, Rue Viète"},"PostalCode":{"PostalCodeNumber":"75017"}}}}}},"Accuracy": 8},"Point":{"coordinates":[2.306174,48.883705,0]}}]}
|
|
/*<?xml version="1.0" encoding="UTF-8"?><kml xmlns="http://earth.google.com/kml/2.0"><Response><name>3 rue viète, 75017 paris, france</name><Status><code>200</code><request>geocode</request></Status><Placemark id="p1"><address>3, Rue Viète, 75017 17ème Arrondissement, Paris, France</address><AddressDetails Accuracy="8" xmlns="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"><Country><CountryNameCode>FR</CountryNameCode><AdministrativeArea><AdministrativeAreaName>Ile-de-France</AdministrativeAreaName><SubAdministrativeArea><SubAdministrativeAreaName>Paris</SubAdministrativeAreaName><Locality><LocalityName>Paris</LocalityName><DependentLocality><DependentLocalityName>17ème Arrondissement</DependentLocalityName><Thoroughfare><ThoroughfareName>3, Rue Viète</ThoroughfareName></Thoroughfare><PostalCode><PostalCodeNumber>75017</PostalCodeNumber></PostalCode></DependentLocality></Locality></SubAdministrativeArea></AdministrativeArea></Country></AddressDetails><Point><coordinates>2.306174,48.883705,0</coordinates></Point></Placemark></Response></kml>*/
|
|
|
|
/*
|
|
0 Unknown location. (Since 2.59)
|
|
1 Country level accuracy. (Since 2.59)
|
|
2 Region (state, province, prefecture, etc.) level accuracy. (Since 2.59)
|
|
3 Sub-region (county, municipality, etc.) level accuracy. (Since 2.59)
|
|
4 Town (city, village) level accuracy. (Since 2.59)
|
|
5 Post code (zip code) level accuracy. (Since 2.59)
|
|
6 Street level accuracy. (Since 2.59)
|
|
7 Intersection level accuracy. (Since 2.59)
|
|
8 Address level accuracy. (Since 2.59)
|
|
*/
|
|
$this->codeRetourG=@getTextInHtml($this->body, '<Status>', '<code>', '/code>');
|
|
$this->precision=@getTextInHtml($this->body, '<AddressDetails Accuracy', '="', '" ');
|
|
|
|
$this->adresseValidee=strtoupper(str_replace(''', "'", htmlspecialchars_decode(utf8_decode(@getTextInHtml($this->body, '<Placemark', '<address>', '</address>')),ENT_QUOTES)));
|
|
$strTmp=@getTextInHtml($this->body, '<Point><coordinates>', '<coordinates>', '</coordinates>');
|
|
$tabTmp=explode(',', $strTmp);
|
|
$this->latitudeDec=@$tabTmp[1];
|
|
$this->longitudeDec=$tabTmp[0];
|
|
$this->latitudeDeg=dec2dms($this->latitudeDec);
|
|
$this->longitudeDeg=dec2dms($this->longitudeDec);
|
|
|
|
$this->geocodeur='Google';
|
|
|
|
/*
|
|
200 G_GEO_SUCCESS No errors occurred; the address was successfully parsed and its geocode has been returneds->geocodeur='Google';
|
|
|
|
.
|
|
400 G_GEO_BAD_REQUEST A directions request could not be successfully parsed.
|
|
500 G_GEO_SERVER_ERROR A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.
|
|
601 G_GEO_MISSING_QUERY The HTTP q parameter was either missing or had no value. For geocoding requests, this means that an empty address was
|
|
specified as input. For directions requests, this means that no query was specified in the input.
|
|
602 G_GEO_UNKNOWN_ADDRESS No corresponding geographic location could be found for the specified address. This may be due to the fact that the address
|
|
is relatively new, or it may be incorrect.
|
|
603 G_GEO_UNAVAILABLE_ADDRESS The geocode for the given address or the route for the given directions query cannot be returned due to legal or contractual
|
|
reasons.
|
|
604 G_GEO_UNKNOWN_DIRECTIONS The GDirections object could not compute directions between the points mentioned in the query. This is usually because
|
|
there is no route available between the two points, or because we do not have data for routing in that region.
|
|
610 G_GEO_BAD_KEY The given key is either invalid or does not match the domain for which it was given.
|
|
620 G_GEO_TOO_MANY_QUERIES The given key has gone over the requests limit in the 24 hour period.
|
|
*/
|
|
if ($this->codeRetourG==200)
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
/** Géocodage d'une adresse
|
|
** 0 Unknown location. (Since 2.59)
|
|
1 Country level accuracy. (Since 2.59)
|
|
2 Region (state, province, prefecture, etc.) level accuracy. (Since 2.59)
|
|
3 Sub-region (county, municipality, etc.) level accuracy. (Since 2.59)
|
|
4 Town (city, village) level accuracy. (Since 2.59)
|
|
5 Post code (zip code) level accuracy. (Since 2.59)
|
|
6 Street level accuracy. (Since 2.59)
|
|
7 Intersection level accuracy. (Since 2.59)
|
|
8 Address level accuracy. (Since 2.59)
|
|
**/
|
|
function geoCodeAdresse($adrNum, $adrIndRep, $adrTypeVoieCourt, $adrTypeVoieLong, $adrLibVoie, $cp, $ville='', $pays='France', $codeRivoli='') {
|
|
$iDb=new WDB();
|
|
$tabRep=array();
|
|
$adresse=addslashes(trim(preg_replace('/ +/',' ', "$adrNum $adrIndRep $adrTypeVoieLong $adrLibVoie")));
|
|
$ville=addslashes($ville);
|
|
$ret=$iDb->select( 'zonageXY', 'lat, lon, l93_x, l93_y, alt, precis, adresseValidee, dateInsert', "address='$adresse' AND adr_cp='$cp' AND adr_ville='$ville'",false, MYSQL_ASSOC);
|
|
if (count($ret)>0) {
|
|
$zonage=$ret[0];
|
|
$this->precision=$zonage['precis']*1;
|
|
$this->adresseValidee=strtoupper($zonage['adresseValidee']);
|
|
$this->latitudeDec=$zonage['lat']*1;
|
|
$this->longitudeDec=$zonage['lon']*1;
|
|
$this->l93x=$zonage['l93_x'];
|
|
$this->l93y=$zonage['l93_y'];
|
|
$this->altitude=$zonage['alt'];
|
|
if ($this->altitude==NULL && $this->precision>5) {
|
|
if ($this->accesDist) {
|
|
$alt=$this->getAltitude($this->latitudeDec,$this->longitudeDec);
|
|
$this->altitude=$alt['alt'];
|
|
}
|
|
}
|
|
if ($this->l93x==NULL && $this->precision>5) {
|
|
$tmp=geos2lambert93($this->latitudeDec,$this->longitudeDec);
|
|
$this->l93x=$tmp['x_93'];
|
|
$this->l93y=$tmp['y_93'];
|
|
}
|
|
if ($this->altitude<>NULL || $this->l93x<>NULL) {
|
|
$tabUpdate=array( 'alt'=>$this->altitude,
|
|
'l93_x'=>$this->l93x,
|
|
'l93_y'=>$this->l93y);
|
|
//'dateUpdate'=>DATETIME,
|
|
$iDb->update('zonageXY', $tabUpdate, "address='$adresse' AND adr_cp='$cp' AND adr_ville='$ville'");
|
|
}
|
|
|
|
$this->latitudeDeg=dec2dms($this->latitudeDec);
|
|
$this->longitudeDeg=dec2dms($this->longitudeDec);
|
|
$this->enCache=true;
|
|
$ligne='En base : '.print_r($zonage, true);
|
|
} elseif ($this->accesDist) {
|
|
$this->enCache=false;
|
|
$retM=$retY=false;
|
|
if (substr($codeRivoli,0,3)*1==971) $pays='Guadeloupe';
|
|
elseif (substr($codeRivoli,0,3)*1==972) $pays='Martinique';
|
|
elseif (substr($codeRivoli,0,3)*1==973) $pays='Guyane';
|
|
elseif (substr($codeRivoli,0,3)*1==974) $pays='La Réunion';
|
|
elseif (substr($codeRivoli,0,3)*1==975) $pays='Saint-Pierre-et-Miquelon';
|
|
elseif (substr($codeRivoli,0,3)*1==976) $pays='Mayotte';
|
|
elseif (substr($codeRivoli,0,3)*1==977) $pays='Saint-Martin';
|
|
elseif (substr($codeRivoli,0,3)*1==978) $pays='Saint-Barthélémy';
|
|
elseif (substr($codeRivoli,0,3)*1==985) $pays='Saint-Pierre-et-Miquelon';//98501 à 98502 St Pierre et Miquelon (anciens codes non compatibles 97501 à 97502)
|
|
elseif (substr($codeRivoli,0,3)*1==986) $pays='Wallis-et-Futuna'; // 98601 à 98617 Mayotte (anciens codes non compatibles : 98501 à 98517)
|
|
elseif (substr($codeRivoli,0,3)*1==987) $pays='Polynésie française'; // 98711 à 98758,98799 Polynésie française (sans changement)
|
|
elseif (substr($codeRivoli,0,3)*1==988) $pays='Nouvelle Calédonie'; // 98801 à 98832 Nouvelle Calédonie (sans changement)
|
|
elseif (substr($codeRivoli,0,3)*1==989) $pays='Wallis-et-Futuna'; // 98911 à 98913 Wallis et Futuna (anciens codes non compatibles : 98611 à 98613)
|
|
elseif (substr($codeRivoli,0,2)*1>96 && substr($codeRivoli,0,2)*1<99)
|
|
die("Code Rivoli non géré : '$codeRivoli'".EOL);
|
|
|
|
$retG=$this->geoCodeAdrCpVilleG($adresse, $cp, $ville, $pays);
|
|
if ($this->codeRetourG==620 || $this->precision==0)
|
|
/*if ($this->codeRetourG==620)
|
|
$retY=$this->geoCodeAdrCpVilleY("$adresse, $cp $ville");
|
|
|
|
if ($this->codeRetourY==620 || $this->codeRetourY==503 || $this->precision==0)*/
|
|
$retM=$this->geoCodeAdrCpVilleM($adresse, $cp, $ville, $pays);
|
|
|
|
// On récupère l'altitude
|
|
if ($this->precision>5) {
|
|
$alt=$this->getAltitude($this->latitudeDec,$this->longitudeDec);
|
|
$this->altitude=$alt['alt'];
|
|
}
|
|
$tmp=geos2lambert93($this->latitudeDec,$this->longitudeDec);
|
|
$this->l93x=$tmp['x_93'];
|
|
$this->l93y=$tmp['y_93'];
|
|
|
|
if ($retG || $retY || $retM) {
|
|
$adresse=stripslashes(strtoupper(trim(preg_replace('/ +/',' ', "$adrNum $adrIndRep $adrTypeVoieLong $adrLibVoie"))));
|
|
$ville=stripslashes($ville);
|
|
$tabInsert=array( 'address'=>$adresse,
|
|
'adr_cp'=>$cp,
|
|
'adr_ville'=>$ville,
|
|
'adrNum'=>$adrNum,
|
|
'adrIndRep'=>$adrIndRep,
|
|
'adrTypeVoie'=>$adrTypeVoieCourt,
|
|
'adrLibVoie'=>$adrLibVoie,
|
|
'rivoli'=>$codeRivoli,
|
|
'adresseValidee'=>$this->adresseValidee,
|
|
'lat'=>$this->latitudeDec,
|
|
'lon'=>$this->longitudeDec,
|
|
'l93_x'=>$this->l93x,
|
|
'l93_y'=>$this->l93y,
|
|
'alt'=>$this->altitude,
|
|
'precis'=>$this->precision,
|
|
'source'=>$this->geocodeur,
|
|
'dateInsert'=>DATETIME,
|
|
);
|
|
/** Insertion de l'adresse que si elle est possible
|
|
**/
|
|
if ($this->latitudeDec<>0 && $this->longitudeDec<>0)
|
|
$iDb->insert('zonageXY', $tabInsert);
|
|
|
|
$ligne='Accès Google : '.print_r($tabInsert, true);
|
|
}
|
|
else {
|
|
$this->precision=$this->latitudeDec=$this->longitudeDec=0;
|
|
$this->adresseValidee='';
|
|
$this->latitudeDeg=$this->longitudeDeg='';
|
|
$ligne="Erreur : $adrNum, $adrIndRep, $adrTypeVoieCourt, $adrTypeVoieLong, $adrLibVoie, $cp, $ville, $pays, $codeRivoli, ".$this->body;
|
|
}
|
|
}
|
|
|
|
}
|
|
/* if (latnorth == 'S') latdir='-'
|
|
if (lonwest == 'W') longdir='-'
|
|
latdec=Math.round(lat1)+lat2/60
|
|
londec=Math.round(long1)+long2/60
|
|
gmdatalat=latdir+latdec.toFixed(6)
|
|
gmdatalon=longdir+londec.toFixed(6)
|
|
//GM_log( 'Latdec:'+gmdatalat+' LongDec:'+gmdatalon)
|
|
gmx=gmdatalat*Math.pow(10,6)
|
|
gmy=gmdatalon*Math.pow(10,6)
|
|
if (gmx < 0) gmx=gmx+Math.pow(2,32)*/
|
|
|
|
|
|
/** Retourne la distance en kilomètres entre 2 coordonnées GPS à la surface de la terre
|
|
**
|
|
** @param double $latA Latitude du point A en décimal
|
|
** @param double $lonA Longitude du point A en décimal
|
|
** @param double $latB Latitude du point B en décimal
|
|
** @param double $lonB Longitude du point B en décimal
|
|
** @param string $sphere Type de sphère
|
|
** @return unknown
|
|
**/
|
|
function distance($latA=0, $lonA=0, $latB=0, $lonB=0, $sphere='GRS80') {
|
|
switch ($sphere) {
|
|
case 'HAYFORD': $R=6378.388; // Demi grand axe ou Rayon de la sphère International Hayford 1909 en Kms
|
|
$f=1/297; // Aplatissement
|
|
break;
|
|
case 'PICARD': $R=6371.598; // Demi grand axe ou Rayon de la sphère Picard en Kms
|
|
break;
|
|
case 'GRS80':
|
|
default: $R=6378.137; // Demi grand axe ou Rayon de la sphère GRS80 en Kms
|
|
$f=1/298.257222101;
|
|
break;
|
|
}
|
|
$a=pi()/180;
|
|
$e=$latA*$a;
|
|
$f=$lonA*$a;
|
|
$g=$latB*$a;
|
|
$h=$lonB*$a;
|
|
|
|
$j=acos(cos($e)*cos($g)*cos($f)*cos($h) + cos($e)*sin($f)*cos($g)*sin($h) + sin($e)*sin($g));
|
|
|
|
return round($R*$j,3); // div par 1.852 ==> résultat en miles nautiques
|
|
}
|
|
|
|
/** Retourne la distance en mètres entre 2 points sur une surface plane
|
|
** @param double $x1 Coordonnée X du point 1 en décimal
|
|
** @param double $y1 Coordonnée Y du point 1 en décimal
|
|
** @param double $x2 Coordonnée X du point 2 en décimal
|
|
** @param double $y2 Coordonnée Y du point 2 en décimal
|
|
** @return double
|
|
**/
|
|
function distanceLambert($x1,$y1,$x2,$y2) {
|
|
return sqrt ( pow($x1-$x2,2) + (pow($y1-$y2,2) ) );
|
|
}
|
|
|
|
/** Retourne l'altitude en mètres d'un point GPS. Shuttle Radar Topography Mission (SRTM) elevation data (resolution 90mx90m)
|
|
** @url http://ws.geonames.org/export/web-services.html
|
|
** @param double $tabLatLon Latitude du point ou Tableau de Points avec latitudes longitudes array('lat'=>x,'lon'=>y)
|
|
** @param double $lon Longitude ou false si tableau
|
|
** @return double
|
|
**/
|
|
function getAltitude($tabLatLon,$lon=false) {
|
|
if ($lon) {
|
|
/*Elevation - SRTM3
|
|
Shuttle Radar Topography Mission (SRTM) elevation data. SRTM consisted of a specially modified radar system that flew onboard the Space Shuttle Endeavour during an 11-day mission in February of 2000. The dataset covers land areas between 60 degrees north and 56 degrees south.
|
|
This web service is using SRTM3 data with data points located every 3-arc-second (approximately 90 meters) on a latitude/longitude grid. Documentation : Nasa
|
|
|
|
Webservice Type : REST
|
|
Url : api.geonames.org/srtm3?
|
|
Parameters : lat,lng;
|
|
sample area: ca 90m x 90m Result : a single number giving the elevation in meters according to srtm3, ocean areas have been masked as "no data" and have been assigned a value of -32768
|
|
Example http://api.geonames.org/srtm3?lat=50.01&lng=10.2&username=demo
|
|
|
|
This service is also available in XML and JSON format :api.geonames.org/srtm3XML?lat=50.01&lng=10.2&username=demo api.geonames.org/srtm3JSON?lat=50.01&lng=10.2&username=demo
|
|
|
|
The text version of the service also accepts a list of lat/lng for the parameters 'lats' and 'lngs'. On the free server the number of points per call is limited to 20, for the premium service the limit is 2000:
|
|
|
|
[0] => the daily limit of 30000 credits 78.31.45.206 has been exceeded. Please throttle your requests or use the commercial service
|
|
[1] => daily
|
|
[2] => 30000
|
|
[3] => 78.31.45.206
|
|
|
|
*/
|
|
$url="http://ws.geonames.org/srtm3?lat=$tabLatLon&lng=$lon";
|
|
$page=getUrl($url, '', '', '', false, '', '', 3);
|
|
$alt=trim($page['body']);
|
|
if (preg_match('/the (.*) limit of (.*) credits(.*) has been exceeded\. Please throttle your requests or use the commercial service/Uis', $alt, $matches)) {
|
|
print_r($matches);
|
|
$alt=NULL;
|
|
} elseif ($page['code']<>200 || $alt==-32768) {
|
|
if ($page['code']<>200) echo '==========================>'. $page['code']. '<=================================='.EOL;
|
|
$alt=NULL;
|
|
}
|
|
return array('lat'=>$tabLatLon,'lon'=>$lon,'alt'=>$alt);
|
|
} else {
|
|
$LatLon='';
|
|
$Lats='';
|
|
$Lons='';
|
|
foreach ($tabLatLon as $i=>$latlon) {
|
|
$lat=$latlon['lat'];
|
|
$lon2=$latlon['lon'];
|
|
if ($i>0) {
|
|
$LatLon.="%0D%0A";
|
|
$Lats.=',';
|
|
$Lons.=',';
|
|
}
|
|
$LatLon.="$lat%2C$lon2";
|
|
$Lats.=$lat;
|
|
$Lons.=$lon;
|
|
}
|
|
// http://api.geonames.org/srtm3?lats=50.01,51.01&lngs=10.2,11.2&username=demo
|
|
/* $url="http://api.geonames.org/srtm3?lats=$Lats&lng=$Lons&username=demo";
|
|
$page=getUrl($url, '', '', '', false, '', '', 3);
|
|
$alt=trim($page['body']);
|
|
die($alt);
|
|
if ($page['code']<>200 || $alt==-32768) {
|
|
if ($page['code']<>200) echo '==========================>'. $page['code']. '<=================================='.EOL;
|
|
$alt=NULL;
|
|
}
|
|
return array('lat'=>$tabLatLon,'lon'=>$lon,'alt'=>$alt);
|
|
*/
|
|
}
|
|
|
|
$url='http://www.fredorando.fr/Pages/altitude.php';
|
|
$post=array('LatLon'=>$LatLon,'qui'=>'');
|
|
$page=getUrl($url, '', $post, '', false, '', '', 3);
|
|
$body=$page['body'];
|
|
$tabRet=false;
|
|
if (preg_match('/<BODY>\s+IP\:(?:.*)<br\/>\s+url\:(?:.*)<br\/>(?:.*)<br\/>(?:.*)<br\/>(.*)<br\/>(?:.*)<a href="http/Uis', $body, $matches)) {
|
|
$tabRet=array();
|
|
$tabTmp=explode('<br />', $matches[1]);
|
|
foreach($tabTmp as $i=>$ret) {
|
|
$ret2=explode(',',trim($ret));
|
|
$alt=$ret2[2];
|
|
if ($alt==-32768) $alt=NULL;
|
|
$tabRet[$i]=@array('lat'=>$ret2[0],'lon'=>$ret2[1],'alt'=>$alt);
|
|
}
|
|
unset($tabRet[$i]);
|
|
}
|
|
if ($lon) return $tabRet[0];
|
|
return $tabRet;
|
|
}
|
|
|
|
}
|
|
if ( !function_exists('json_decode') ){
|
|
function json_decode($content, $assoc=false){
|
|
require_once 'Services/JSON.php';
|
|
if ( $assoc ){
|
|
$json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
|
|
} else {
|
|
$json = new Services_JSON;
|
|
}
|
|
return $json->decode($content);
|
|
}
|
|
}
|
|
|
|
if ( !function_exists('json_encode') ){
|
|
function json_encode($content){
|
|
require_once 'Services/JSON.php';
|
|
$json = new Services_JSON;
|
|
|
|
return $json->encode($content);
|
|
}
|
|
}
|
|
?>
|