
Cartographie des hotels autour du centre de formation
Objectif : Afficher sur une page internet la carte des hôtels autour du centre de formation
Je me propose de détailler les différentes étapes permettant, à partir de données brutes, de générer une carte interactive sur Internet.
Chercher les données
- Pour afficher les hôtels de Toulouse et des environs, OpenStreetMap est une des seules source de données gratuite et immédiatement disponible.Trois possibilités : Télécharger les donnéees (sans filtres) depuis le site de OSM, utiliser un plugin dans QGIS (logiciel SIG OpenSource) ou utiliser Overpass-turbo.Il faut pouvoir savoir à quel clé et valeur correspondent les hôtels :
- https://wiki.openstreetmap.org/wiki/FR:Page_principale
-> Parcourir la documentation des éléments cartographiques (https://wiki.openstreetmap.org/wiki/FR:%C3%89l%C3%A9ments_cartographiques) ;
Recherche du tag « hotel » avec le navigateur :
->Clé : building ou tourism; valeur: hotel
=>building=hotel et tourism=hotel
- Dans QGIS, plugin QuickOSM(75 hôtels) ou avec Overpass-turbo (http://overpass-turbo.eu/) (76 hôtels) : manque le Canard sur le toit (Colomiers)
Enregistrer le geojson en shape et en 3857 pour import dans PostGIS
Stoker les données
Afin de mettre à disposition les données sur le web, il faut d’abord les stocker dans une base de données spatiale (PostGIS) :
- Création base de données avec un schéma hotel et import des données avec shapefile and dbf loader
Création de la page HTML avec OpenLayers :
OpenLayers est une bibliothèque de fonctions écrites en Javascript et permettant de mettre en place une interface cartographique dynamique.
Les données vectorielles visualisables dans OpenLayers sont principalement le format GeoJSON, les flux WFS. J’ai choisi de générer les points des hôtels stockés dans la base PostGIS automatiquement en GeoJSON grâce à une page écrite en PHP et donc exécutée sur le serveur web : postgis_geojson.php.
<HTML>
<script src= »http://openlayers.org/en/v3.20.1/build/ol.js » type= »text/javascript »></script>
<link rel= »stylesheet » href= »http://openlayers.org/en/v3.20.1/css/ol.css » type= »text/css »>
<BODY>
<DIV id= »carte » style=’width:90%;height:400px;’></DIV>
<SCRIPT>
//MAP
var map = new ol.Map({
target: ‘carte’,
layers:[
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view:new ol.View({
center: [159071,5403488],
zoom: 10
})
});
var donnees_geojson = new ol.source.Vector({
url:’postgis_geojson.php?geotable=hotel.hotels&geomfield=geom’,
format :new ol.format.GeoJSON()
});
var couche_depts = new ol.layer.Vector({
source :donnees_geojson
});
map.addLayer(couche_depts);
</SCRIPT>
</BODY>
</HTML>
Ajout des infos au clic
…
//gestion de l’affichage des infos sur le clic
var contenu= »;
map.on(‘singleclick‘,
function(evt){
var objets =map.forEachFeatureAtPixel(
evt.pixel,
function(feature,layer){
if(layer.get(‘name’)==’hotels’){
return feature;
}
}
);
if (objets) {
//récupération des infos
var idhotel=objets.get(‘gid’);
var nomhotel=objets.get(‘name’);
var phonehotel=objets.get(‘phone’);
var starshotel=objets.get(‘stars’);
var websitehotel=objets.get(‘website’);
var addr_househotel=objets.get(‘addr_house’);
var addr_postchotel=objets.get(‘addr_postc’);
var addr_streehotel=objets.get(‘addr_stree’);
var emailhotel=objets.get(’email’);
//création de l’infobulle
contenu=nomhotel;
if(phonehotel!= »){contenu+='<BR /> num tél. : ‘+phonehotel;}
if(starshotel!= »){contenu+='<BR /> étoiles : ‘+starshotel;}
}
else {
//pas d’objet, on vide le contenu de l’infobulle
var contenu= »;
}
$(« .infobulle »).html(contenu);
}
);
Création du formulaire
<HTML>
<script src= »http://openlayers.org/en/v3.20.1/build/ol.js » type= »text/javascript »></script>
<link rel= »stylesheet » href= »http://openlayers.org/en/v3.20.1/css/ol.css » type= »text/css>
<BODY>
…
<DIV id= »info » class=’infobulle’><FORM id=f_hotel></FORM></div>
<SCRIPT>
…
//gestion de l’affichage des infos sur le clic
var contenu= »;
map.on(‘singleclick’,function(evt){
var objets =map.forEachFeatureAtPixel(evt.pixel,function(feature,layer){if(layer.get(‘name’)==’hotels’){return feature;}});
if (objets) {
…
…
//création de du formulaire
contenu='<INPUT type=hidden name=idhotel value=’+idhotel+’ />’;
contenu+='<STRONG>Nom de l\’hôtel : <INPUT type=text name= »nomhotel » value= »‘+nomhotel+' » size=50/></STRONG>’;
contenu+='<BR /> Numéro de tél. :
<INPUT type=text name= »tel » value= »‘+phonehotel+' » size=15/>’;
contenu+='<BR /> Nbre d\’étoiles :
<INPUT type=number name= »etoiles » value= »‘+starshotel+' » size=3/>’;
contenu+='<BR /> Email :
<INPUT type=email name= »mail » value= »‘+emailhotel+' » size=50/>’;
contenu+='<BR /> Site web :
<INPUT type=text name= »website » value= »‘+websitehotel+' » size=50/>’;
contenu+='<BR /> n° rue :
<INPUT type=text name= »numrue » value= »‘+addr_househotel+' » size=5/>’;
contenu+='<BR /> nom rue :
<INPUT type=text name= »nomrue » value= »‘+addr_streehotel+' » size=50/>’;
contenu+='<BR /><INPUT type=button value= »Modifier » />’;
}
contenu+='<BR /><INPUT type=submit value= »Modifier » />’;
}else {//pas d’objet, on vide le contenu de l’infobullevar contenu= »;}
$(« #f_hotel »).html(contenu);
});
Envoi des données du formulaire dans la base
…
contenu+='<BR /><INPUT type=submit value= »Modifier » />’;
}
else {
//pas d’objet, on vide le contenu de l’infobulle
var contenu= »;
}
$(« #f_hotel »).html(contenu);
}
);
$(« #f_hotel »).on(‘submit‘,function(e){
e.preventDefault(); // empêcher le comportement par défaut du navigateur, c-à -d de soumettre le formulaire
var donnees = $(‘#f_hotel’).serialize(); // On créer une variable content le formulaire sérialisé
$.ajax({
url : ‘maj_hotel.php’, // La ressource ciblée
type : ‘GET’, // Le type de la requête HTTP.
data : donnees
}).done(function(data){
console.log(data);
});
});
</SCRIPT>
maj_hotel.php :
<?php
$conn = pg_connect(« dbname=’idgeo_test’ user=’xxxxxx’ password=’xxxxxxx’ host=’postgresql.alwaysdata.com’ port=’5432′ »);
$idhotel=(int)htmlspecialchars($_GET[‘idhotel’]);
$nomhotel=htmlspecialchars($_GET[‘nomhotel’]);
$phonehotel=htmlspecialchars($_GET[‘phonehotel’]);
$emailhotel==htmlspecialchars($_GET[’emailhotel’]);
$starshotel=(int)htmlspecialchars($_GET[‘starshotel’]);
$websitehotel=htmlspecialchars($_GET[‘websitehotel’]);
$addr_househotel=htmlspecialchars($_GET[‘addr_househotel’]);
$addr_postchotel=htmlspecialchars($_GET[‘addr_postchotel’]);
$addr_streehotel=htmlspecialchars($_GET[‘addr_streehotel’]);
//création de la requête
$sql_maj= »UPDATE hotel.hotels
SET name=’$nomhotel’,
phone=’$phonehotel’,
stars=$starshotel,
website=’$websitehotel’,
addr_house=’$addr_househotel’,
addr_postc=’$addr_postchotel’,
addr_stree=’$addr_streehotel’,
email=’$emailhotel’
WHERE gid= ».$idhotel;
//exécution de la requête
$result_maj=pg_query($conn,$sql_maj) or die(‘mise à jour échouée’);
?>
Affichage des hôtels en fonction de la distance
…
<input id= »curseur » type= »range » value=100 title=’curseur'</input>
<DIV id= »val_curseur »>Distance des hôtels (à vol d’oiseau) : 10 000 m du centre de formation</DIV>
…
<SCRIPT>
…
//Affichage des hôtels en fonction de la distance au centre de formation
var curseur = document.getElementById(‘curseur’);
curseur.addEventListener(‘input’, function() {
var valeur=curseur.value;
var distance_max=10000 ;
var source=new ol.source.Vector({
url:’postgis_geojson.php?geotable=hotel.hotels&geomfield=geom¶meters=ST_DWithin(geom,(SELECT st_setsrid(st_point(154253,5398575),3857)),’+valeur*100+’)’,
format :new ol.format.GeoJSON()
});
couche_hotels.setSource(source);
$(‘#val_curseur’).html(‘Distance des hôtels (à vol d\’oiseau) : ‘+ Intl.NumberFormat().format(valeur*100)+’ m du centre de formation’);
map.render();
}, false);
</SCRIPT>
…
0Réponses surDes données OSM à la carte interactive sur Internet"