Créer une carte géographique colorée dynamiquement en PHP et
Mysql
Pour vous éviter de faire des copier-coller à répétition, et
d'avoir des problèmes avec les caractères spéciaux, vous trouverez toutes
les sources décrites dans ce tutorial, ainsi que les frontières de la carte,
ici ;-)
Pour comprendre les fonctions PHP (syntaxe et utilité), rendez-vous
ici
I. Installation de Apache, PHP et Mysql
La première chose à faire est effectivement d'avoir à disposition un
serveur web, PHP et Mysql...
Un hébergeur gratuit qui propose des hébergements 100 Mo avec PHP et Mysql :
free
Sinon, vous pouvez installer vous méme sur votre machine le tout :
- Sur Mac OS-X, 3 freewares :
Complete Apache 2
Complete PHP 4
Complete MySQL
Permet d'installer PHP (avec tous les modules qu'il faut), Mysql et Apache
- Sur OS-9, il y a sûrement une manière d'installer ces serveurs, mais je ne la
connais pas :(
- Sur Linux, quasiment déjà tout intégré au système,
je ne m'étend pas dessus...
- Sur Window$, il paraît que EasyPHP est pas mal...
Jamais testé...
II. Initialisation de Apache, PHP et Mysql (Mac OS-X uniquement avec les freewares de
www.serverlogistics.com)
- Apache 2
Ouvrez le fichier /Library/Apache2/conf/httpd.conf dans un éditeur de texte simple
(c'est à dire pas un truc avec plein
de formatages spéciaux comme word)...
Je conseille BBEdit par exemple ; ou au niveau shell : emacs, pico ou vim... Un éditeur
qui vous donne le numéro de la ligne est conseillé ;)
Lignes à changer :
- 347 : DocumentRoot "chemin_de_la_racine_du_serveur"
- 372 : <Directory "chemin_de_la_racine_du_serveur">
- 393 : AllowOverride All
- 407 : UserDir Sites
Ensuite, relancer Apache à partir des préférences système "Apache2"
(que vous avez normalement rajoutées lors de l'installation...
- PHP : rien à reconfigurer
- Mysql : allez dans les préférences système (rajoutées aussi à
l'installation) "MySQL", "Start", "Initialize", "Set Root Password"
Attention, le password root de MySQL n'a rien avoir avec celui du système... Ne choississez
pas un pass trop important, vous allez devoir le mettre en clair dans un fichier pour PHPMyAdmin...
III. Installation de PHPMyAdmin
Téléchargez PHPMyAdmin, décompressez-le
et mettez le à la racine de votre serveur...
Editez dans le dossier de PHPMyAdmin le fichier config.inc.php :
- Ligne 39 : $cfg['PmaAbsoluteUri'] = 'http://localhost/nom_du_fichier_phpMyadmin';
- Ligne 74 : $cfg['Servers'][$i]['user'] = 'root';
- Ligne 75 : $cfg['Servers'][$i]['password'] = 'password';
Où password est le pass que vous avez choisi pour le root de mysql dans la partie
précédente.
Voilà, nous sommes prêts à commencer le vrai travail : la carte dynamique :)
IV. Creation de la base MySQL
- Dans phpmyadmin, page de présentation, créez une nouvelle base de données
appelé carte
- Dans l'onglet "SQL", créez la table de cette manière :
DROP TABLE IF EXISTS zones;
CREATE TABLE zones
(
nom
VARCHAR(50) PRIMARY KEY,
nombre INT
NOT NULL,
x
SMALLINT NOT NULL,
y
SMALLINT NOT NULL
);
On crée tout simplement une table mysql avec des tuples de composition :
- Un nom qui sert de référence (longueur maximale : 50 caractères)
Ce nom est le nom d'une zone.
- Un numéro entier défini
Ce numéro représente l'indice de la zone (exemple : nombre de personnes qui y vivent).
- Deux coordonnées x et y qui sont celles d'un point de la zone sur le dessin
de la carte.
En vérifiant auparavant si elle n'existe pas déjà
On doit obtenir :
V. Préparation de la carte et remplissage de la base de données
La carte est au départ un plan blanc (attention, du vrai blanc), avec des zones
définies par des frontières fermées noires (ici, le noir n'a pas
d'importance, les frontières peuvent être de toutes les couleurs, sauf blanc bien
entendu... Vous pouvez même avoir des frontières multicolores :o) ).
Pour les scripts qui suivent, la carte doit être en format ".png", mais il faut savoir,
qu'on peut travailler avec d'autres formats d'image...
Exemple de carte valide avec cinq zones fermées :
Vous devez ensuite repérer sur le dessin des coordonnées d'un point dans chaque
zone que vous voulez traîter, et donner un petit nom à ces zones...
Il faut faire attention à ce que ces points soient des points blancs (surtout pas des points
de la frontière
Exemple pour la carte précédente :
On peut maintenant remplir la base de données ...
Par exemple, pour la carte précédente :
INSERT INTO zones VALUES ('ROSE',0,43,76);
INSERT INTO zones VALUES ('CARRE',0,115,107);
INSERT INTO zones VALUES ('CERCLE',0,122,205);
INSERT INTO zones VALUES ('BIZARRE1',0,67,149);
INSERT INTO zones VALUES ('BIZARRE2',0,178,170);
Les "0" représentent les valeurs des zones... Il est évident que l'on peut mettre
n'importe quelle valeur...
VI. Script PHP de l'affichage de la carte et de l'échelle
- Script de connection à la base : connect.php
<?
/* Connection a mysql : host = localhost, user = root, pass = le password du root mysql */
$connect = mysql_connect('localhost','root','pass_root_mysql');
$db = mysql_select_db('carte',$connect);
?>
- Script de gestion des couleurs : couleurs.php
Une couleur est donnée par 3 entiers entre 0 et 255 : la valeur en rouge, la valeur en vert, et
la valeur en bleu.
De nombreuses applications gèrent les couleurs de cette façon, et peuvent vous aider
à choisir vos couleurs (Photoshop par exemple sur Mac/PC, ou GraphicConverter sur Mac).
Par exemple, pour une échelle dans les bleus :
<?
/* Pour i de 0 a 10, remplit le tableau de couleurs avec des couleurs bleues de plus en plus
foncees */
for($i=0;$i<=10;$i++)
$coulniv[$i] = imagecolorallocate($image,20*$i,255-20*$i,255);
?>
- Le script de la fonction d'échelle : fnechelle.php
Il faut une fonction d'échelle qui établit une correspondance chiffre -> couleur
Ici, on a pris une échelle de 0 à 10, il faut donc une bijection de l'ensemble des
entiers dans [0;10]
On prend ici une fonction simple : 0-4 -> 0 ; 5-9 -> 1 ... 45-49 -> 9 ; 50 ou plus -> 10
Soit E(indice/5) + majoration
On crée aussi des fonctions qui pour une couleur donnée, donnent l'intervalle de cette
couleur (limite inférieure et limite supérieure)
Cela servira pour créer l'échelle graphique...
Par exemple, la couleur 9 correspond à l'intervalle 45 et 49 -> limite inférieure = 45
; limite supérieure = 49
<?
function etalonne($indice)
{
$niv = (int)($indice/5);
if($niv>10) $niv = 10;
return $niv;
}
function limiteinf($i)
{
return $i*5;
}
function limitesup($i)
{
return $i*5+4;
}
?>
- Le script de la carte dynamique : carte.php
Le script qui fait tout :)
<?
/* fonctions d'echelle et connection a la base */
include("fnechelle.php");
include("connect.php");
/* La requete MySQL qui selectionne les parametres des zones */
$req = "SELECT nom,nombre,x,y FROM zones";
$rep = mysql_query($req);
/* on recupere le nombre de zones */
$nb_zones = mysql_num_rows($rep);
/* On inclut le header qui gere les images png */
header("Content-type: image/png");
/* On cree une image a partir de carte.png */
$image = imagecreatefrompng("carte.png");
/* Definition de la couleur bleue */
$bleu = imagecolorallocate($image,0,114,188);
/* Definition des autres couleurs avec couleurs.php */
include("couleurs.php");
/* Colorisation de certaines zones avant le coloriage dynamique : mers ou autres */
/* Ici, on colorise le contour en bleu-mer */
imagefill($image,5,5,$bleu);
/* Boucle pour coloriser chaque zone */
for ($i=0; $i<$nb_zones; $i++)
{
/* On recupere pour chaque zone le nom, le nombre et les coordonnees du
"point-a-coloriser" */
$zone = mysql_fetch_array($rep);
$xx = $zone['x'];
$yy = $zone['y'];
$nmreg = $zone['nom'];
$ind = $zone['nombre'];
/* On passe a la fonction d'etalonnage */
$niv = etalonne($ind);
/* On remplit la zone */
imagefill($image,$xx,$yy,$coulniv[$niv]);
}
/* Affichage et destruction de l'image */
imagepng($image);
imagedestroy($image);
?>
- Le script de l'échelle dynamique : echelle.php
Pour dessinner l'échelle graphique de manière dynamique :-)
<?
/* On inclut les fonctions d'echelle */
include("fnechelle.php");
/* On inclut le header qui gere les images png */
header("Content-type: image/png");
/* On cree une image vide de bonne dimension pour tout contenir */
$image = imagecreate(95,330);
/* Definition des couleurs blanc, quasi-blanc et noir */
$blanc = imagecolorallocate($image,255,255,255);
$qblanc = imagecolorallocate($image,255,254,255);
$noir = imagecolorallocate($image,0,0,0);
/* Definition du blanc comme couleur transparente */
imagecolortransparent($image,$blanc);
/* Definition des autres couleurs avec couleurs.php */
include("couleurs.php");
/* Boucle pour chaque couleur */
for($i=0;$i<=10;$i++)
{
/* On cree un rectangle de bords noirs pour chaque couleur */
imagerectangle($image,49,4+30*$i,91,26+30*$i,$noir);
/* On remplit ce rectangle de la couleur voulue */
imagefill($image,50,5+30*$i,$coulniv[$i]);
/* On recupere les limites inferieures, superieures ... */
$liminf = limiteinf($i);
$derlim = $liminf-1;
$limsup = limitesup($i);
/* On prepare le texte de l'echelle */
if($i==10) $text = ">$derlim";
else $text = "$liminf-$limsup";
/* On complete le texte de l'echelle */
while(strlen($text)<5)
$text = " ".$text;
/* On affiche le texte de l'echelle */
imagestring($image,5,1,$i*30+7,$text,$qblanc);
}
/* Affichage et destruction de l'image */
ImagePNG($image);
ImageDestroy($image);
?>
- La page de présentation de la carte et de l'échelle : carte.html
<HTML>
<HEAD>
<TITLE>Carte</TITLE>
</HEAD>
<BODY BGCOLOR="#000000" ALINK="#FF0000" LINK="#FF0000">
<CENTER>
<IMG SRC="echelle.php">
<IMG SRC="carte.php">
</CENTER>
</BODY>
</HTML>
Et voici le résultat :-)
VII. Frontal Web
On peut, bien-entendu modifier les valeurs pour les zones directement dans PhpMyAdmin...
Mais il faut avouer que ce n'est pas vraiment pratique ;-)
Nous allons donc faire un frontal web qui permet de rajouter facilement 5 à une
zone
- La page de présentation : ajout.php
<HTML>
<HEAD>
<TITLE>Ajout de 5 é une zone</TITLE>
</HEAD>
<BODY>
<?
/* Connection a la base */
include("connect.php");
?>
<FORM name='f' action="traitement.php" method='POST'>
<SELECT name='vote'>
<?
/* Requete MySQL pour recuperer les zones */
$req = "SELECT nom FROM zones";
$liste_nm = mysql_query($req);
$nb_nm = mysql_num_rows($liste_nm);
/* Boucle pour creer le menu deroulant */
for ($i=0; $i<$nb_nm; $i++)
{
/* Recuperation des donnees pour chaque zone */
$zone = mysql_fetch_array($liste_nm);
$nom = $zone['nom'];
?>
<OPTION VALUE='<?=$nom?>'><?=$nom?>
<?
}
?>
</SELECT>
<INPUT type='submit' value='Ajouter'>
</FORM>
</BODY>
</HTML>
- Le script de traitement : traitement.php
<HTML>
<HEAD>
<TITLE>Traitement ajout</TITLE>
</HEAD>
<BODY>
<P>Vous ajoutez 5 à : <?=$vote?></P>
<?
/* Connection a la base */
include("connect.php");
/* Requete MySQL qui selectionne le nombre pour la zone */
$req = "SELECT nombre FROM zones WHERE nom='$vote'";
$rep = mysql_query($req);
/* Recuperation du nombre pour la zone */
$res = mysql_fetch_array($rep);
$nb = $res['nombre'];
/* ajout de 5 au nombre */
$nb += 5;
/* Requete MySQL qui update le nombre */
$req = "UPDATE zones SET nombre='$nb' WHERE nom='$vote'";
mysql_query($req);
?>
<P>L'ajout a bien été fait...</P>
</BODY>
</HTML>
Vous pouvez bien sûr faire le même script pour n'ajouter que 1
à une zone, ou soustraire un certain nombre a une zone très
facilement ;-)
ajout.php
soustr.php
Voilà, ce tutoriel est fini... Vous trouverez le code source d'une
application complète (celle
là ;-) )
ici