| Images / GD
Cartographie frnacaise par Pascal Parois |
[0] | |  |
Créer une carte de france et place des lieux à l'aide de leur longitude-latitude.
La carte utilisé est dep_france_dom.mif (liste de polygones) distribué par l'IGN. La projection utilisée est Lambert-93.
Cette portion est une base pour la génération de cartes à partir de *.mif et un exemple de calcul pour la projection de Lambert-93. |
<?php
class carte
{
function carte($file)
{
$this->file=$file;
$this->limite_adm=0;
$this->marges=5;
$this->backgroundcolor_r=154;
$this->backgroundcolor_v=211;
$this->backgroundcolor_b=220;
$this->bordercolor_r=200;
$this->bordercolor_v=200;
$this->bordercolor_b=200;
$this->deptcolor_r=255;
$this->deptcolor_v=255;
$this->deptcolor_b=255;
$this->citycolor_r=34;
$this->citycolor_v=111;
$this->citycolor_b=50;
$this->citycdiam=7;
$this->fontsize=8;
$this->font='../font/VeraSe.ttf';
}
function g4p_set_limite_adm($i)
{
$this->limite_adm=$i;
}
function g4p_set_marges($i)
{
$this->marges=$i;
}
function g4p_set_backgroundcolor($r,$v,$b)
{
$this->backgroundcolor_r=$r;
$this->backgroundcolor_v=$v;
$this->backgroundcolor_b=$b;
}
function g4p_set_bordercolor($r,$v,$b)
{
$this->bordercolor_r=$r;
$this->bordercolor_v=$v;
$this->bordercolor_b=$b;
}
function g4p_set_deptcolor($r,$v,$b)
{
$this->deptcolor_r=$r;
$this->deptcolor_v=$v;
$this->deptcolor_b=$b;
}
function g4p_set_citycolor($r,$v,$b)
{
$this->citycolor_r=$r;
$this->citycolor_v=$v;
$this->citycolor_b=$b;
}
function g4p_set_citydiam($i)
{
$this->citycdiam=$i;
}
function g4p_set_fontsize($i)//en pixel
{
$this->fontsize=$i;
}
function g4p_set_font($i)//en pixel
{
$this->font=$i;
}
function g4p_read_map()
{
$g4p_ligne_cpt=0;
// recherches des infos de la carte:
if($f=fopen($this->file,'rb'))
{
// je recherche les limites de la carte
$this->bounds['x_max']=$this->bounds['y_max']=0;
$this->bounds['x_min']=$this->bounds['y_min']=1000000000;
while(!feof($f)){
$g4p_ligne_cpt++;
$buf=trim(fgets($f));
// Si on a deux numériques séparés par un espace
$num=explode(' ',$buf);
if((count($num)==2)&&is_numeric($num[0])&&is_numeric($num[1]))
{
if($this->bounds['x_max']<$num[0])
$this->bounds['x_max']=$num[0];
if($this->bounds['y_max']<$num[1])
$this->bounds['y_max']=$num[1];
if($this->bounds['x_min']>$num[0])
$this->bounds['x_min']=$num[0];
if($this->bounds['y_min']>$num[1])
$this->bounds['y_min']=$num[1];
if(isset($region_id))
{
if($this->liste_region[$region_id]['x_max']<$num[0])
$this->liste_region[$region_id]['x_max']=$num[0];
if($this->liste_region[$region_id]['y_max']<$num[1])
$this->liste_region[$region_id]['y_max']=$num[1];
if($this->liste_region[$region_id]['x_min']>$num[0])
$this->liste_region[$region_id]['x_min']=$num[0];
if($this->liste_region[$region_id]['y_min']>$num[1])
$this->liste_region[$region_id]['y_min']=$num[1];
}
}
elseif($num[0]=='Region')
{
$region_id=$g4p_ligne_cpt+1;
$this->liste_region[$region_id]['x_max']=$this->liste_region[$region_id]['y_max']=0;
$this->liste_region[$region_id]['x_min']=$this->liste_region[$region_id]['y_min']=10000000000;
$this->liste_region[$region_id]['ligne_deb']=$region_id;
}
elseif($num[0]=='Center')
{
$this->liste_region[$region_id]['center']=$num[1].'|'.$num[2];
}
}
fclose($f);
}
}
function g4p_build_map($select_region=0 , $dim=800)
{
if($select_region===0)
$select_region=array_keys($this->liste_region);
else
{
$this->bounds['x_min']=$this->bounds['y_min']=1000000000;
$this->bounds['x_max']=$this->bounds['y_max']=0;
foreach($select_region as $a_region)
{
if($this->bounds['x_min']>=$this->liste_region[$a_region]['x_min'])
$this->bounds['x_min']=$this->liste_region[$a_region]['x_min'];
if($this->bounds['y_min']>$this->liste_region[$a_region]['y_min'])
$this->bounds['y_min']=$this->liste_region[$a_region]['y_min'];
if($this->bounds['x_max']<$this->liste_region[$a_region]['x_max'])
$this->bounds['x_max']=$this->liste_region[$a_region]['x_max'];
if($this->bounds['y_max']<$this->liste_region[$a_region]['y_max'])
$this->bounds['y_max']=$this->liste_region[$a_region]['y_max'];
}
}
// Coefficient pour dessiner une carte de $dim en largeur ou longueur max
$dim=$dim-2*$this->marges; //j'enleve l'offset que j'ajoute après
if($this->bounds['x_max']-$this->bounds['x_min']>$this->bounds['y_max']-$this->bounds['y_min'])
{
$this->dim_x=$dim;
$this->x_echelle = $this->y_echelle = ($this->bounds['x_max']-$this->bounds['x_min'])/$this->dim_x;
$this->dim_y=round(($this->bounds['y_max']-$this->bounds['y_min'])/$this->y_echelle);
}
else
{
$this->dim_y=$dim;
$this->x_echelle = $this->y_echelle = ($this->bounds['y_max']-$this->bounds['y_min'])/$this->dim_y;
$this->dim_x=round(($this->bounds['x_max']-$this->bounds['x_min'])/$this->y_echelle);
}
$this->image=imagecreatetruecolor($this->dim_x+2*$this->marges,$this->dim_y+2*$this->marges);
$white=imagecolorallocate($this->image,$this->deptcolor_r,$this->deptcolor_v,$this->deptcolor_b);
$black=imagecolorallocate($this->image,$this->bordercolor_r,$this->bordercolor_v,$this->bordercolor_b);
$ceau=imagecolorallocate($this->image,$this->backgroundcolor_r,$this->backgroundcolor_v,$this->backgroundcolor_b);
imagefilledrectangle($this->image,1,1,$this->dim_x+(2*$this->marges-2),$this->dim_y+(2*$this->marges-2),$ceau);
// Pour chaque ligne du fichier dep_france_dom.mif
if($f=fopen($this->file,'rb'))
{
$g4p_ligne_cpt=0;
while(!feof($f))
{
$g4p_ligne_cpt++;
$buf=trim(fgets($f));
$num=explode(' ',$buf);
$eau=0;
if(in_array($g4p_ligne_cpt,$select_region))
{
while(!feof($f) and $num[0]!='Region')
{
// Si on a deux numériques séparés par un espace
if((count($num)==2)&&is_numeric($num[0])&&is_numeric($num[1]))
{
$x_lu = $num[0];
$y_lu = $num[1];
$polygone[] = ( $x_lu - $this->bounds['x_min'] ) / $this->x_echelle+$this->marges; //+5 decale la carte du bord
$polygone[] = $this->dim_y-( $y_lu - $this->bounds['y_min'] ) / $this->y_echelle+$this->marges; //la coord est ( $y_lu - $y_base ) / $y_echelle, on y applique une symétrie (-1) et une translation (dim_y) pour remettre la carte à l'endroit
}
elseif((count($num)==1)&&is_numeric($num[0]) and !empty($polygone))
{
imagefilledpolygon($this->image,$polygone,count($polygone)/2,$white);
if($this->limite_adm==1)
imagepolygon($this->image,$polygone,count($polygone)/2,$black);
$polygone=array();
$eau=1;
}
$g4p_ligne_cpt++;
$buf=trim(fgets($f));
$num=explode(' ',$buf);
}
if($eau==0)
{
imagefilledpolygon($this->image,$polygone,count($polygone)/2,$white);
if($this->limite_adm==1)
imagepolygon($this->image,$polygone,count($polygone)/2,$black);
}
else
{
imagefilledpolygon($this->image,$polygone,count($polygone)/2,$ceau);
if($this->limite_adm==1)
imagepolygon($this->image,$polygone,count($polygone)/2,$black);
}
$polygone=array();
$eau=0;
}
}
fclose($f);
}
}
function g4p_place_ville($latitude,$longitude,$texte='')
{
/**** Conversion latitude,longitude en coordonée lambert 93 ****/
// Projection conforme sécante, algo détailler dans NTG_71.pdf : http://www.ign.fr/affiche_rubrique.asp?rbr_id=1700&lng_id=FR
// > ACCUEIL > L'offre IGN Pro > Géodésie > RGF93 > Outils
//variables:
$a=6378137; //demi grand axe de l'ellipsoide (m)
$e=0.08181919106; //première excentricité de l'ellipsoide
$l0=$lc=deg2rad(3);
$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
$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
//exp(-1*$n*$l)*sin($n*($l-$l0));
$ys=$y0+$c*exp(-1*$n*$gl0);
//echo $n*($l-$lc);
$x93=$x0+$c*exp(-1*$n*$gl)*sin($n*($l-$lc));
$y93=$ys-$c*exp(-1*$n*$gl)*cos($n*($l-$lc));
$vert=imagecolorallocate($this->image,$this->citycolor_r,$this->citycolor_v,$this->citycolor_b);
$black=imagecolorallocate($this->image,0,0,0);
$x = ( $x93 - $this->bounds['x_min'] ) / $this->x_echelle + $this->marges; //+5 decale la carte du bord
$y = $this->dim_y-( $y93 - $this->bounds['y_min'] ) / $this->y_echelle + $this->marges; //la coord est ( $y_lu - $y_base ) / $y_echelle, on y applique une
imagefilledellipse($this->image,$x,$y,$this->citycdiam,$this->citycdiam,$vert);
if($texte!='')
{
$box=imagettfbbox ( $this->fontsize, 0,$this->font, $texte);
$box[0]+=$x;
$box[1]+=$y;
$box[2]+=$x;
$box[3]+=$y;
$box[4]+=$x;
$box[5]+=$y;
$box[6]+=$x;
$box[7]+=$y;
if(isset($this->box_coord))//anti-chevauchement primaire.
{
foreach($this->box_coord as $a_box)
{
if($box[7]<$a_box[1] and $box[7]>$a_box[7])
{
if(($box[7]-$a_box[7])<($a_box[1]-$box[7]))
$y+=($a_box[1]-$box[7]-2);
else
$y-=($box[7]-$a_box[7]+2);
}
if($box[1]<$a_box[1] and $box[1]>$a_box[7])
{
if(($box[1]-$a_box[7])<($a_box[1]-$box[1]))
$y+=($a_box[1]-$box[1]+2);
else
$y-=($box[1]-$a_box[7]-2);
}
}
}
imagettftext($this->image, $this->fontsize, 0, $x+$this->citycdiam/2+2, $y+$this->citycdiam/2+1, $black, '../font/VeraSe.ttf',$texte);
$this->box_coord[]=$box;
}
}
function g4p_send_carte()
{
header('Pragma: no-cache');
header('Expires: 0');
header("Content-type: image/png");
imagepng($this->image);
}
}
$carte=new carte('dep_france_dom_rgf93.mif');
$carte->g4p_read_map();//charge les infos de la carte
$carte->g4p_set_limite_adm(1);//1 trace les contours, 0 non (en fait ils sont invisibles...
$carte->g4p_set_marges(20);
$carte->g4p_build_map(0);//le premier paramètre ne permet de tracer que certains départements, le 2ème est la taille de l'image
//$carte->g4p_build_map(array(20,523,1209,1713,2188,2673,3006,3447,10589,11598,12148),1500);//le premier paramètre ne permet de tracer que certains départements, le 2ème est la taille de l'image
$carte->g4p_place_ville(45.75,4.85,'Lyon');
$carte->g4p_place_ville(47.217,-1.55,'Nantes');
$carte->g4p_send_carte();
?>
|
|
|


Voir toutes les portions de scripts de la même catégorie.
|