IdGeo

Des données OSM à la carte interactive sur Internet

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

  1. 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&parameters=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>

12 février 2017

0Réponses surDes données OSM à la carte interactive sur Internet"

Laisser Un Message

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

3 × 2 =

IdGeo.fr - 1, allée Maurice Magre, 31770 Colomiers - 05 34 55 60 65