Data Grand Lyon Documentation

Transcription

Data Grand Lyon Documentation
Data Grand Lyon Documentation
Version 1.0
GrandLyon
13 October 2016
Table des matières
1
Guide du développeur
1.1 Les services offerts par GrandLyon Data
1.2 Authentification . . . . . . . . . . . . .
1.3 Bonnes Pratiques . . . . . . . . . . . . .
1.4 Exemples et extraits de code . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
10
12
18
i
ii
Data Grand Lyon Documentation, Version 1.0
Bienvenue dans la documentation de Data Grand Lyon. Cette documentation comporte plusieurs parties. La page
services vous donnera des informations générales sur les services disponibles et leur utilisation. Par la suite, plusieurs
exemples et extraits de code sont fournis dans la section exemples.
Table des matières
1
Data Grand Lyon Documentation, Version 1.0
2
Table des matières
CHAPITRE 1
Guide du développeur
Les différentes sections de la documentation sont accessibles directement.
1.1 Les services offerts par GrandLyon Data
La plateforme Data vous permet d’accéder à différents services de consultation des données OpenData. Les services
sont de deux types : des services de visualisation qui vous permettent d’afficher des images (cartes) et des services de
téléchargement qui vous permettent d’accéder directement à la donnée, selon des modalités et des formats variés.
Lors de la mise en oeuvre d’une application cartographique, on ne peut pas traiter toutes les données de la même
manière. Il y a en effet des données qui habillent (fond de carte par ex.), d’autres qui renseignent sur le contexte
(points d’intérêt divers : mairie, gare...) et d’autres enfin qui portent l’information importante, celle que l’on souhaite
vraiment mettre en avant et exploiter dans l’application (disponibilité des vélos, localisation des bus en temps réel...).
Le fond de plan sera toujours proposé au format image, non interactif, et très souvent issu d’un système de cache tuilé
permettant la récupération rapide sous forme de petites tuiles (256 x 256 pixels) de son contenu. Ce sera toujours la
couche la plus basse dans l’application, celle en dessous de toutes les autres, pour des raisons évidentes de visibilité.
Les informations cruciales, importantes, porteuses de la valeur ajoutée de l’application seront les plus interactives
possibles, pour que d’un survol une info-bulle donne accès à l’essentiel, qu’un clic ouvre une fiche complète, qu’un
changement de style (taille, couleur) dynamique permette de souligner la sélection, l’association, la relation avec un
autre élément. Pour ce faire il faut donc utiliser un service de téléchargement, seul à même de transmettre les données
brutes permettant la mise en oeuvre d’une couche vectorielle dans l’application cartographique ou de donner accès à
tous les attributs (informations associées à l’objet géographique) directement.
Pour les autres couches de données il faut faire des arbitrages. On ne peut tout charger en vectoriel pour des raisons de
lisibilité (trop de points/lignes qui clignotent, grossissent ou s’agitent en même temps rendent la carte inutilisable) et
de performance (chaque point est inscrit dans le DOM de la page. Plusieurs milliers de points deviennent très lourds
à gérer pour le navigateur). Donc on transige. On utilise les services de visualisation (WMS, format image) pour les
données dont l’emplacement l’information la plus importante (par ex : stationnement handicapé, il n’y a rien à mettre
dans une info-bulle, l’important est que la place soit là où elle est, et il suffit donc de l’afficher) ou dont l’emprise
spatiale a un intérêt particulier (contour d’un parc, d’une zone règlementée...). Et on choisit le format vectoriel pour
quelques informations certes secondaires par rapport à l’objet principal de l’application, mais dont les caractérisques
sont importantes à connaître (stations vélos, événement...)
1.1.1 Service WMS
Le service WMS est le service de visualisation par excellence. Il sert à “voir” la donnée géographique avec une mise
en forme prédéfinie (couleurs, styles, symboles...). C’est le service à privilégier pour intégrer des jeux de données au
format image.
3
Data Grand Lyon Documentation, Version 1.0
Il est accessible à partir de l’URL
https://download.data.grandlyon.com/wms/[nom_du_service]
Généralement on fait appel à son opération GetCapabilities pour connaître son contenu (liste des couches) :
https://download.data.grandlyon.com/wms/grandlyon?SERVICE=WMS&REQUEST=GetCapabilities&VERSION=1.3.0
renvoie ainsi un document XML listant (entre autres) les couches mises à disposition par le service, dont vous obtiendrez le contenu à l’aide d’une requête GetMap de ce type :
https://download.data.grandlyon.com/wms/grandlyon?LAYERS=adr_voie_lieu.adrcommune&FORMAT=image%2Fpng&EXCEPTION
Ca peut vous sembler un peu compliqué et fastidieux... Mais les librairies cartographiques sont là pour vous aider.
Leaflet et OpenLayers implémentent des classes WMS qui feront tout ça pour vous, en adaptant les requêtes selon les
manipulations faites sur la carte. Il vous suffit généralement de renseigner l’URL de base du service et d’indiquer le
nom de la couche que vous souhaitez utiliser comme l’illustrent nos Exemples et extraits de code.
1.1.2 Service WFS
Les services WFS permettent de récupérer la donnée brute telle qu’elle est enregistrée dans la base de données. Il
s’agit d’un service de téléchargement, même si ce téléchargement (récupération de la donnée) n’est pas forcément
complet, c’est-à-dire qu’on peut l’effectuer sur une partie seulement du territoire, notamment pour les données les
plus volumineuses.
Il est accessible à partir de l’URL
https://download.data.grandlyon.com/wfs/[nom_du_service]
Généralement on fait appel à son opération GetCapabilities pour connaître son contenu (liste des couches) :
https://download.data.grandlyon.com/wfs/grandlyon?SERVICE=WFS&REQUEST=GetCapabilities&VERSION=1.1.0
renvoie ainsi un document XML listant (entre autres) les couches mises à disposition par le service, dont vous obtiendrez le contenu à l’aide d’une requête GetFeatures de ce type :
https://download.data.grandlyon.com/wfs/grandlyon?SERVICE=WFS&REQUEST=GetFeature&typename=pvo_patrimoine_voirie.pvo
Mais là encore, rassurez-vous, les librairies cartographiques disposent des classes nécessaires à une utilisation simple
de ce type de service.
Le format généralement utilisé en WFS est le GML (Geographic Markup Language) qui est un dérivé du XML. Toutefois, ce format n’est pas forcément le plus simple à utiliser dans le cadre d’une application web. Aussi, tout en utilisant
le WFS, il est possible de recevoir un flux au format GeoJSON en ajoutant le paramètre OUTPUTFORMAT=geojson :
https://download.data.grandlyon.com/wfs/grandlyon?SERVICE=WFS&REQUEST=GetFeature&typename=pvo_patrimoine_voirie.pvo
1.1.3 Service WCS
Les services WCS (Web Coverage Service) permettent de récupérer directement les données brutes des couches raster
(comme les orthophotos et les MNT). Le terme Coverage (couverture) correspond au jeu de données raster. Il s’agit
donc d’un service de téléchargement dans lequel il est possible de filtrer le jeu de données à récupérer sur une partie
seulement du territoire.
Il est accessible à partir de l’URL :
https://download.data.grandlyon.com/wcs/[nom_du_service]
De même que pour les WMS ou le WFS, on fait appel à son opération GetCapabilities pour connaître son contenu
(liste des couches disponibles ) :
https://download.data.grandlyon.com/wcs/grandlyon?service=WCS&request=GetCapabilities&version=1.1.0
4
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
renvoie ainsi un document XML listant (entre autres) les couches mises à disposition par le service, dont vous obtiendrez la description détaillée à l’aide d’une requête DescribeCoverage de ce type :
https://download.data.grandlyon.com/wcs/grandlyon?service=WCS&request=DescribeCoverage&version=1.1.0&identifiers=Ortho2009
Les informations retournées ne concernent plus que les couches spécifiées dans le paramètre identifiers (ici Ortho2009_vue_ensemble_16cm_CC46 et 1830_5155_16_CC46) et sont un peu plus détaillées que dans le GetCapabilities.
Enfin, pour obtenir la couverture souhaitée, on utilise une requête GetCoverage de ce type :
https://download.data.grandlyon.com/wcs/grandlyon?service=WCS&BBOX=1830000,5155000,1830100,5155100&request=GetCovera
Encore une fois, c’est un service standardisé et les librairies cartographiques disposent des classes nécessaires à une
utilisation simple de ce type de service.
1.1.4 Service CSW
Les services CSW (Catalog Services for the Web) permettent d’interagir avec le catalogue de métadonnées de GrandLyon Data.
Ils recouvrent 2 grands types d’usage : la consultation et l’édition des métadonnées. Dans le cas présent, seules les
fonctionnalités de consultation sont concernées puisqu’il n’y a pas lieu de mettre à jour le catalogue de la plateforme
GrandLyon Data. Les requêtes CSW vont ainsi permettre de rechercher des données et d’accéder à la fiche descriptive
détaillée d’une donnée.
Comme pour les services précédemment décrit, la découverte du service se fait via le GetCapabilities :
https://download.data.grandlyon.com/catalogue/srv/fre/csw?SERVICE=CSW&request=GetCapabilities&service=CSW&version=2.0.2
Pour effectuer une recherche, on utilise l’opération GetRecords, dans laquelle on peut spécifier des critères de recherche. Par exemple :
https://download.data.grandlyon.com/catalogue/srv/fre/csw?SERVICE=CSW&request=GetRecords&service=CSW&version=2.0.2&res
Notez le paramètre ELEMENTSETNAME qui permet de choisir le type d’élements retournés (brief, summary ou
full). L’utilisation de startPosition et maxRecords permet de gérer la pagination pour ne pas charger d’un coup les plus
de 500 fiches. Les critères de recherche peuvent être renseignés soit avec CQL, soit avec OGC FE (Filter Encoding).
L’opération GetRecordById permet d’accéder à une métadonnée à partir de son identifiant, donc d’obtenir le contenu
détaillée pour une fiche précise :
https://download.data.grandlyon.com/catalogue/srv/fre/csw?SERVICE=CSW&request=GetRecordById&service=CSW&version=2.0.2&
5adb-4d9c-8638-f22db9b121fd
L’utilisation de ce service n’est pas simple au premier abord mais il est très performant et permet de retrouver toutes
les fonctionnalités de recherche et de consultation disponibles sur le catalogue de la plateforme afin de les intégrer
dans un client externe. Enfin, c’est un service standard et diverses documentations beaucoup plus détaillées sur le
CSW sont facilement accessibles sur le web.
1.1.5 Services REST (en JSON)
Pour accéder aux données sous forme alphanumérique (par opposition aux services cartographiques), notre infrastructure dispose de services JSON permettant une navigation facile et rapide entre les différents jeux de données mis à
disposition.
Le point d’entrée de chaque service est construit sur le pattern suivant :
https://download.data.grandlyon.com/ws/<service>/all.json
Les services actuellement disponibles sont “grandlyon” et “rdata” :
1.1. Les services offerts par GrandLyon Data
5
Data Grand Lyon Documentation, Version 1.0
https://download.data.grandlyon.com/ws/grandlyon/all.json
et
https://download.data.grandlyon.com/ws/rdata/all.json
Ces documents listent l’ensemble des tables disponibles en consultation/téléchargement. Certaines peuvent avoir un
accès restreint en fonction de vos droits.
Exemple de résultat :
{
results: [{
table_schema: "abr_arbres_alignement",
href: "https://download.data.grandlyon.com/ws/grandlyon/abr_arbres_alignement.abrarbre.json",
table_name: "abrarbre"
},{
table_schema: "adr_voie_lieu",
href: "https://download.data.grandlyon.com/ws/grandlyon/adr_voie_lieu.adradresse.json",
table_name: "adradresse"
},{
...
}]
}
A chaque table est associée une URL de la forme :
https://download.data.grandlyon.com/ws/<service>/<table_schema>.<table_name>.json
De lien en lien, vous pouvez alors naviguer vers la description des tables.
Exemple : https://download.data.grandlyon.com/ws/grandlyon/abr_arbres_alignement.abrarbre.json
{
requested_table: "abr_arbres_alignement.abrarbre",
nb_records: 92216,
database_href: "https://download.data.grandlyon.com/ws/grandlyon/all.json",
nb_results: 26,
results: [{
is_pk: false,
column_type: "varchar",
6
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
precision: 50,
is_nullable: "YES",
href: "https://download.data.grandlyon.com/ws/grandlyon/abr_arbres_alignement.abrarbre/essencef
column_name: "essencefrancais"
},{
is_pk: false,
column_type: "int4",
precision: 32,
is_nullable: "YES",
href: "https://download.data.grandlyon.com/ws/grandlyon/abr_arbres_alignement.abrarbre/circonfe
column_name: "circonference_cm"
},{
...
}]
}
Liste des champs affiches :
— is_pk : est-ce l’identifiant de la couche
— column_type : type de champ (numerique, texte, etc.)
— precision : longueur du champ
— is_nullable : peut il y avoir des valeurs nulles ?
— href : valeurs distinctes possible de l’attribut cible
— column_name : nom du champ
L’url contenue dans href permet de consulter les différentes valeurs présentes dans un champ particulier (par ex. les
essences des arbres de la métropole).
Exemple : https://download.data.grandlyon.com/ws/grandlyon/abr_arbres_alignement.abrarbre/essencefrancais.json
{
fields: [
"essencefrancais"
],
nb_results: 401,
values: [
"Magnolia à grandes fleurs",
"Erable rouge 'Schlesingeri'",
1.1. Les services offerts par GrandLyon Data
7
Data Grand Lyon Documentation, Version 1.0
"Arbre puant des Chinois",
"Chène rouge d'Espagne",
"Frêne d'Amérique",
"Orme champêtre",
"Chêne pédonculé fastigié, Chêne pyramidal",
...
]
}
Ce dernier mode dispose d’options particulières :
— compact : si false, décrit la valeur pour chacun des enregistrements, sinon liste les différentes valeurs trouvées
dans la table. True par défaut.
— maxfeatures : indique le nombre maximal d’enregistrement à faire remonter par le service. 1000 par défaut.
— start : indique l’index de départ, afin de pouvoir paginer les résultats. 1 par défaut.
On peut ainsi demander au service les essences de 50 arbres à partir du 100e dans la base :
https://download.data.grandlyon.com/ws/grandlyon/abr_arbres_alignement.abrarbre/essencefrancais.json?compact=false&maxfeatures=
On peut également accéder à la totalité du contenu de la table (ou paginer ce contenu) en utilisant une URL du type :
https://download.data.grandlyon.com/ws/rdata/jcd_jcdecaux.jcdvelov/all.json?compact=false
pour consulter l’intégralité des enregistrements.
Il faut noter que sur l’appel de all.json (affichage de tous les champs), seul le mode compact est disponible.
Le nombre d’objet renvoye par defaut est fixe a 1000 pour des raisons de performances. Il est possible d’outrepasser
ce retour grace au parametre « maxfeatures ».
Exemple : https://download.data.grandlyon.com/ws/grandlyon/gip_proprete.gipdecheterie/all.json?maxfeatures=10
Il est également possible de filtrer les objets renvoyés selon une valeur d’attribut avec une url de la forme :
https://download.data.grandlyon.com/ws/<service>/<table_schema>.<table_name>/all.json?field
Exemple : https://download.data.grandlyon.com/ws/grandlyon/abr_arbres_alignement.abrarbre/all.json?field=essencefrancais&value=M
all.json contient aussi des informations supplémentaires liées à la pagination, à savoir des liens vers les pages précédentes et suivantes sous la forme d’une URL reprenant la valeur de maxfeatures utilisée pour la page en cours et
modifiant la valeur du paramètre “start” en fonction de la page en cours.
Exemple : https://download.data.grandlyon.com/ws/grandlyon/gip_proprete.gipdecheterie/all.json?maxfeatures=5&start=10
Cette URL retourne les enregistrements 10 à 15 de la couche déchetterie.
Les services REST-JSON sont ainsi particulièrement adaptés à la constitution de listes de valeurs, de tableaux et de
grilles paginés, d’interface de navigation au sein des données.
1.1.6 Service WMTS
La plateforme Data propose un service de fonds de carte tuilés au standard WMTS. Deux couches y sont proposées,
d’une part l’orthophotographie 2015 de la Métropole et d’autre part une couverture construite à partir des données
OpenStreetMap des régions Auvergne-Rhône-Alpes et Bourgogne. Le service WMTS est utilisable à partir de l’URL :
https://openstreetmap.data.grandlyon.com/wmts/
8
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
Le nom des couches à utiliser est respectivement osm_grandlyon et ortho2015. Les couches sont disponibles en projection Mercator Sphérique (EPSG :3857 et EPSG :900913) et sont donc à ce titre compatibles avec d’autres services du même type, GoogleMaps ou API-IGN. Pour utiliser le service WMTS
dans QGIS veillez à utiliser l’URL du GetCapabilities comme URL du service : https ://openstreetmap.data.grandlyon.com/wmts/ ?REQUEST=GetCapabilities&SERVICE=WMTS
1.1.7 Services SOS (données de capteurs)
Le service SOS s’inscrit dans la collection de standards Sensor Web Enablement (SWE) de l’OGC. Il permet la
découverte des capteurs et de leurs mesures. Le standard SOS est décliné en deux versions : 1.0.0 et 2.0.0.
Le Grand Lyon diffuse deux services SOS. Le premier concerne les données de stations de mesure de bruit (1) dans
l’agglomération ; le deuxième la disponibilité de vélos libres sur les stations Vélo’V réparties entre Lyon et Villeurbanne.
(1) https://download.data.grandlyon.com/sos/bruit?service=SOS&request=GetCapabilities
(2) https://download.data.grandlyon.com/sos/velov?service=SOS&request=GetCapabilities
Pour le moment, les services SOS du Grand Lyon sont disponibles en version 1.0.0.
L’interrogation des services garde la logique des services de type OGC :
— La requête GetCapabilities retourne une description du service interrogé.
— Le DescribeSensor offre une description du capteur lui-même, autrement dit les métadonnées de capteur. Le
document de réponse est encodé dans le standard de l’OGC Sensor Model Language (SensorML).
— Enfin le GetObservation permet de récupérer les données en appliquant un filtre de sélection (par exemple une
période temporelle). Ces dernières sont encodées suivant le standard de l’OGC Observations & Measurements
(OGC :O&M).
Représentation graphique des données
L’exploitation des données de capteurs n’est pas évidente. Aussi le Grand Lyon propose un service de représentation
graphique simple de l’évolution temporelle des mesures pour chaque service SOS : l’évolution temporelle des niveaux
sonores de l’Observatoire Acoustique (1) ; l’évolution temporelle de la disponibilité des vélos et des stands (2).
URL du service : http://demo.data.grandlyon.com/graph/<bruit|velov>?
Le service prend deux paramètres (query string) :
— offering : Nom identifiant du réseau de capteur
— procedure : Nom identifiant du capteur
Les valeurs sont données dans les capacités (GetCapabilities) des services SOS.
(1) Pour les données de l’observatoire acoustique :
— http://demo.data.grandlyon.com/graph/bruit/?offering=observatoire_acoustique_grandlyon&procedure=AF01
— http://demo.data.grandlyon.com/graph/bruit/?offering=observatoire_acoustique_grandlyon&procedure=AF02
(2) Pour les données de disponibilité des stations Vélo’V :
— http://demo.data.grandlyon.com/graph/velov/?&procedure=velov-1001&offering=reseau_velov
— http://demo.data.grandlyon.com/graph/velov/?&procedure=velov-1002&offering=reseau_velov
Représentation cartographique (WMS-Time)
Les données sont aussi disponibles à travers un service WMS étendu (voir plus haut plus une description du WMS).
— http://mapserver.middle.data.grandlyon.com/wms/ldata ?
Ce service a la particularité de proposer des couches supportant les requêtes temporelles. Les couches concernées (ou
LAYER dans le vocabulaire OGC :WMS) prennent le suffixe _time. Ainsi vous trouverez les paires de couches WMS
suivantes :
1.1. Les services offerts par GrandLyon Data
9
Data Grand Lyon Documentation, Version 1.0
— bruit.stations_observatoire_acoustique / bruit.stations_observatoire_acoustique_time
pour les stations de mesure du bruit.
— velov.stations / velov.stations_time pour les stations Vélo’V.
Le Grand Lyon propose deux démonstrateurs cartographiques représentant respectivement les mesures du réseau de
capteurs de l’observatoire acoustique (1) et la disponibilité de vélos par station Vélo’V (2) :
— (1) http://demo.data.grandlyon.com/wmst/observatoire_acoustique_grandlyon.html
— (2) http://demo.data.grandlyon.com/wmst/reseau_velov.html
Chaque station (bruit comme Vélo’V) est interrogeable (par un simple clique sur la carte) et permet d’accéder par un
hyperlien à la représentation graphique des données. Un slider permet de naviguer sur l’axe temporel.
1.2 Authentification
1.2.1 Principes
Certaines des données publiées par les services Data nécessitent une autorisation. Afin d’en obtenir une, vous devez ouvrir un compte sur http://data.grandlyon.com/creation-de-compte/ et spécifier les différents jeux de données et
modalités d’accès que vous souhaitez.
Une fois ces opération réalisées, vous aurez un identifiant (généralement l’adresse email utilisée lors de la création
du compte) et un mot de passe. Ceux-ci vous sont personnels, et leur utilisation dans le contexte du développement
d’application pour les tiers doit donc être fait avec certaines précautions.
Mais voyons d’abord comment utiliser ces éléments d’identification pour accéder à des données protégées.
La méthode d’authentification utilisée est le Basic Auth HTTP Lors de l’accès à chacun des types de services, il est
donc nécessaire d’utiliser le header HTTP nommé ‘Authorization’ dans lequel seront insérés login et mot de passe,
séparés par deux points (” :”) et encodé en base64. Le header ressemble alors à ceci :
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
Mais ne vous y méprenez pas. L’encodage en base64 n’est pas un cryptage ! Le procédé est réversible et on peut donc
retrouver les valeurs encodés très facilement. Couplé à un flux HTTPS, qui crypte les informations transmises par et
vers le serveur, ils ne sont pas récupérables, mais écrits tels quels dans le code ils le sont.
1.2.2 Exemple avec cURL et WGET
L’utilisation du header authorization avec cURL est très simple. Imaginons un utilisateur doté des identifiants suivants :
— login : demo
— password : demo4dev
L’instruction cURL à utiliser pour accéder à la donnée “demo.demovelov” sur le service data serait alors :
cURL -u demo:demo4dev curl https://download.data.grandlyon.com/ws/rdata/demo.demovelov/all.json?compa
sauf erreur, vous devriez alors recevoir un flux json.
L’instruction WGET à utiliser est comparable :
wget --http-user=demo --http-password=demo4dev https://download.data.grandlyon.com/ws/rdata/demo.demo
10
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
1.2.3 Exemples avec PHP ou Python
Que ce soit en PHP ou en Python, les librairies utilisées pour émettre des requêtes HTTP intègrent toutes les possibilité
de déclarer le Header Authorization.
Pour Python et urllib2 nous aurons :
import urllib2, base64
# set basic information
username = 'demo'
password = 'demo4dev'
url = 'https://download.data.grandlyon.com/ws/rdata/demo.demovelov/all.json'
# prepare the request Object
request = urllib2.Request(url)
# encode the username / password couple into a single base64 string
base64string = base64.encodestring('%s:%s' % (username, password)))
# then add this string into the Authorization header
request.add_header("Authorization", "Basic %s" % base64string)
# and open the url
result = urllib2.urlopen(request)
# then handle the result the way you like
En PHP, nous utiliserons la librairie cURL intégrée :
<?php
// set basic information
$username='demo';
$password='demo4dev';
$URL='https://download.data.grandlyon.com/ws/rdata/demo.demovelov/all.json';
// instantiate a new cUrl object
$ch = curl_init();
// Everything is an option with PHPCurl !
curl_setopt($ch, CURLOPT_URL,$URL);
// set RETURNTRANSFER to true to be able to handle the result
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
// set this option for enabling Basic Auth HTTP rules
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
// the previous setting will help here to encode the username/password into the correct format
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
// and lift off...
$result=curl_exec ($ch);
// then handle the result the way you like
?>
1.2. Authentification
11
Data Grand Lyon Documentation, Version 1.0
1.3 Bonnes Pratiques
1.3.1 Principes
Que vous souhaitiez développer une application web ou embarquée dans un smartphone, vous avez sans doute le souci
de garantir son bon fonctionnement et sa disponibilité. Voici quelques conseils destinés à vous faire utiliser notre
plateforme de manière optimale.
1.3.2 Accès direct aux données protégées
Comme vous l’avez sans doute remarqué, certaines de nos données ne sont utilisables que si vous disposez d’un compte
vous y autorisant. Dès lors que vous implémentez ces informations dans votre code, il vous appartient de veiller à leur
sécurité, leur non-divulgation et leur facilité d’emploi tout au long de leur cycle de vie (mise à jour, suppression...)
En Javascript/Ajax
Une des particularité du Javascript est d’être chargé et de s’exécuter côté client. Si vous intégrez vos identifiants dans
votre code javascript, ils seront donc forcément accessibles à l’utilisateur de votre site. Employer ruses et contournements ne fera que rendre plus difficile leur récupération, mais à coup sûr ils apparaîtront tôt ou tard dans les requêtes
que vous allez émettre vers nos services. Pour tout développement en Javascript/Ajax, il faut donc utiliser les technique
de Proxyfication des requêtes décrites plus bas.
En PHP, Python, Java
Pas de problèmes avec ces languages qui s’exécutent côté serveur. Il suffit d’implémenter les exemples_ proposés.
Sur plateforme mobile
Les développements effectués sur plateforme mobile sont relativement sûrs dans la mesure où ils sont compilés et sont
donc distribués à vos utilisateurs sous une forme qui rend extrêmement difficile la récupération des informations qui
s’y trouvent. Par contre, il vous faut considérer un aspect pratique lié au cycle de vie de vos identifiant. Pour peu que
vous changiez de mot de passe, ou même de compte, comment va se passer la diffusion du nouveau couple login/mot
de passe sur les terminaux de vos utilisateurs ? Devront-ils faire une mise à jour ? Pourrez-vous provoquer cette mise
à jour obligatoire ? Cette réflexion devra avoir été menée avant de diffuser votre solution.
Performances
Une autre question importante est celle des performances de notre plateforme. Elle n’est pas dimensionnée pour tenir
la même charge que www.google.fr. Si votre application a du succès, si un tweet la propulse vers des sommets de
popularité très rapidement, êtes vous sûrs que nos infrastructures tiendront la charge et permettront à vos utilisateurs
d’avoir une bonne expérience avec votre application ?
Conclusion
Pour chacune des situations ci-dessus, il vous faut veiller à la mise en oeuvre des pratiques conseillées. Le plus simple
est parfois de récupérer directement la donnée.
12
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
1.3.3 Récupération des données
Vos droits d’accès vous permettent d’accéder à la donnée et de la stocker sur vos serveurs. Leur fréquence de récupération doit être adaptée à leur fréquence de mise à jour. Une fois intégrée à votre infrastructure, la résolution des
problèmes évoqués précédemment est beaucoup plus simple :
— Sur plateforme mobile, les utilisateurs accèdent directement à votre version des données. Si vos login/mot de
passe change, cela affecte votre script de récupération des données uniquement et non l’application déployée
chez les clients, qui de son côté peut utiliser un système d’authentification/autorisation qui vous est propre.
— Pour les performance : la récupération ponctuelle, même si elle est fréquente, affecte peu les performances
de notre plateforme. Pour peu que votre infrastructure soit dimensionnée pour absorber la charge générée par
votre application, vous n’aurez pas de problème à craindre de notre côté en vous y prenant ainsi.
1.3.4 Proxyfication
Que les données soient installées au sein de votre infrastructure ou que votre application accède directement aux
données sur la nôtre, il est des cas d’utilisation ou le recours à une proxyfication va néanmoins être indispensable.
C’est surtout le cas en environnement Javascript avec lequel vous avez deux obstacles :
— L’impossiblité de cacher les login/mot de passe à transmettre pour accéder aux données. Vous pouvez néanmoins avoir mis en oeuvre, après avoir récupéré les données, un mécanisme d’authentification qui est propre à
vos utilisateurs, auquel cas vous réglez une partie du problème
— L’accès à un domaine tiers en Ajax. Ceci est strictement interdit par “Same Origine Policy” qui impose au
contenu appelé par une requête Ajax d’être situé sur le même domaine et le même port que la page principale
dans laquelle se situe la requête. Cette règle ne vaut pas pour les images, ce qui explique que l’on puisse utiliser
les flux WMS externes directement, mais vaut pour tous nos autres types de services : WFS, JSON ou KML.
Pour contourner ces restrictions, vous pouvez employer l’astuce de la proxyfication. Le principe est de transmettre
les requêtes AJAX à un script situé sur votre propre serveur (donc mêmes domaine et port que la page principale),
qui transmettra les requêtes au service externe, sans être soumis aux mêmes contraintes d’un client web. Cela poeut
également vous servir pour distinguer les comptes d’accès à votre serveur de celui utilisé pour vous connecter à notre
infrastructure.
CLIENT WEB ——> SCRIPT PROXY ——> SERVICE EXTERNE
user :toto.........user :my_account......>
Implémenter un script de proxyfication n’est pas très compliqué, mais il faut respecter certaines règles. Ne pas le
laisser ouvert à tous vents par exemple, car sinon n’importe qui pourrait venir s’en servir pour naviguer sur internet
de manière anonyme. Ne pas le laisser faire n’importe quoi non plus, afin qu’un utilisateur ne puisse pas envoyer
n’importe quelle requête à votre serveur.
Implémentation en Python
Le script que nous allons utiliser ici est fourni avec OpenLayers sous le nom de proxy.cgi.
Il s’agit d’un script écrit en Python, parfaitement adapté au WFS. Pour l’utiliser, il faut le déposer dans un répertoire exécutable du serveur web (généralement le cgi-bin), en régler les droits pour le rendre exécutable (chmod a+x
proxy.cgi par exemple) et indiquer à OpenLayers sa présence pour qu’il l’utilise (car OpenLayers est malin mais pas
devin...) avec la directive :
OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url=";
Pour toute information complémentaire concernant OpenLayers et un Proxy, veuillez vous référer à la page de FAQ
http://trac.osgeo.org/openlayers/wiki/FrequentlyAskedQuestions#ProxyHost
1.3. Bonnes Pratiques
13
Data Grand Lyon Documentation, Version 1.0
#!/usr/local/bin/python
"""This is a blind proxy that we use to get around browser
restrictions that prevent the Javascript from loading pages not on the
same server as the Javascript. This has several problems: it's less
efficient, it might break some sites, and it's a security risk because
people can use this proxy to browse the web and possibly do bad stuff
with it. It only loads pages via http and https, but it can load any
content type. It supports GET and POST requests."""
import urllib2
import cgi
import sys, os
# Designed to prevent Open Proxy type stuff.
# replace 'my_target_server' by the external domain you are aiming to
allowedHosts = ['localhost','my_target_server']
method = os.environ["REQUEST_METHOD"]
if method == "POST":
qs = os.environ["QUERY_STRING"]
d = cgi.parse_qs(qs)
# checks if a url parameter exists in the POST request. If not, go to hell.
if d.has_key("url"):
url = d["url"][0]
else:
url = "http://www.openlayers.org"
else:
fs = cgi.FieldStorage()
# checks if a url parameter exists in the GET request. If not, go to hell.
url = fs.getvalue('url', "http://www.openlayers.org")
try:
host = url.split("/")[2]
# reply with HTTP 502 code if the host is not allowed
if allowedHosts and not host in allowedHosts:
print "Status: 502 Bad Gateway"
print "Content-Type: text/plain"
print
print "This proxy does not allow you to access that location (%s)." % (host,)
print
print os.environ
# checks if the request is a http or https request
elif url.startswith("http://") or url.startswith("https://"):
if method == "POST":
length = int(os.environ["CONTENT_LENGTH"])
headers = {"Content-Type": os.environ["CONTENT_TYPE"]}
body = sys.stdin.read(length)
r = urllib2.Request(url, body, headers)
y = urllib2.urlopen(r)
else:
y = urllib2.urlopen(url)
14
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
# print content type header
i = y.info()
if i.has_key("Content-Type"):
print "Content-Type: %s" % (i["Content-Type"])
else:
print "Content-Type: text/plain"
print
print y.read()
y.close()
else:
print "Content-Type: text/plain"
print
print "Illegal request."
except Exception, E:
print "Status: 500 Unexpected Error"
print "Content-Type: text/plain"
print
print "Some unexpected error occurred. Error text was:", E
Ce script PHP fait la même chose :
<?php
/*
License: LGPL as per: http://www.gnu.org/copyleft/lesser.html
$Id: proxy.php 3650 2007-11-28 00:26:06Z rdewit $
$Name$
*/
////////////////////////////////////////////////////////////////////////////////
// Description:
// Script to redirect the request http://host/proxy.php?url=http://someUrl
// to http://someUrl .
//
// This script can be used to circumvent javascript's security requirements
// which prevent a URL from an external web site being called.
//
// Author: Nedjo Rogers
////////////////////////////////////////////////////////////////////////////////
// define alowed hosts
$aAllowedDomains = array('localhost','my_target_server')
// read in the variables
if(array_key_exists('HTTP_SERVERURL', $_SERVER)){
$onlineresource=$_SERVER['HTTP_SERVERURL'];
}else{
$onlineresource=$_REQUEST['url'];
}
$parsed = parse_url($onlineresource);
$host = @$parsed["host"];
$path = @$parsed["path"] . "?" . @$parsed["query"];
if(empty($host)) {
$host = "localhost";
}
1.3. Bonnes Pratiques
15
Data Grand Lyon Documentation, Version 1.0
if(is_array($aAllowedDomains)) {
if(!in_array($host, $aAllowedDomains)) {
die("le domaine '$host' n'est pas autorisé. contactez l'administrateur.")
}
}
$port = @$parsed['port'];
if(empty($port)){
$port="80";
}
$contenttype = @$_REQUEST['contenttype'];
if(empty($contenttype)) {
$contenttype = "text/html; charset=ISO-8859-1";
}
$data = @$GLOBALS["HTTP_RAW_POST_DATA"];
// define content type
header("Content-type: " . $contenttype);
if(empty($data)) {
$result = send_request();
}
else {
// post XML
$posting = new HTTP_Client($host, $port, $data);
$posting->set_path($path);
echo $result = $posting->send_request();
}
// strip leading text from result and output result
$len=strlen($result);
$pos = strpos($result, "<");
if($pos > 1) {
$result = substr($result, $pos, $len);
}
//$result = str_replace("xlink:","",$result);
echo $result;
// define class with functions to open socket and post XML
// from http://www.phpbuilder.com/annotate/message.php3?id=1013274 by Richard Hundt
class HTTP_Client {
var $host;
var $path;
var $port;
var $data;
var $socket;
var $errno;
var $errstr;
var $timeout;
var $buf;
var $result;
var $agent_name = "MyAgent";
//Constructor, timeout 30s
function HTTP_Client($host, $port, $data, $timeout = 30) {
$this->host = $host;
$this->port = $port;
$this->data = $data;
$this->timeout = $timeout;
16
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
}
//Opens a connection
function connect() {
$this->socket = fsockopen($this->host,
$this->port,
$this->errno,
$this->errstr,
$this->timeout
);
if(!$this->socket)
return false;
else
return true;
}
//Set the path
function set_path($path) {
$this->path = $path;
}
//Send request and clean up
function send_request() {
if(!$this->connect()) {
return false;
}
else {
$this->result = $this->request($this->data);
return $this->result;
}
}
function request($data) {
$this->buf = "";
fwrite($this->socket,
"POST $this->path HTTP/1.0\r\n".
"Host:$this->host\r\n".
"Basic: ".base64_encode("guillaume:catch22")."\r\n".
"User-Agent: $this->agent_name\r\n".
"Content-Type: application/xml\r\n".
"Content-Length: ".strlen($data).
"\r\n".
"\r\n".$data.
"\r\n"
);
while(!feof($this->socket))
$this->buf .= fgets($this->socket, 2048);
$this->close();
return $this->buf;
}
function close() {
fclose($this->socket);
}
}
1.3. Bonnes Pratiques
17
Data Grand Lyon Documentation, Version 1.0
function send_request() {
global $onlineresource;
$ch = curl_init();
$timeout = 5; // set to zero for no timeout
// fix to allow HTTPS connections with incorrect certificates
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1);
//curl_setopt($ch, CURLOPT_USERPWD, 'guillaume:catch22');
//curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch,
curl_setopt($ch,
curl_setopt($ch,
curl_setopt($ch,
CURLOPT_URL,$onlineresource);
CURLOPT_RETURNTRANSFER, 1);
CURLOPT_CONNECTTIMEOUT, $timeout);
CURLOPT_ENCODING , "gzip, deflate");
if( ! $file_contents = curl_exec($ch)){
trigger_error(curl_error($ch));
}
curl_close($ch);
$lines = array();
$lines = explode("\n", $file_contents);
if(!($response = $lines)) {
echo "Unable to retrieve file '$service_request'";
}
$response = implode("",$response);
return utf8_decode($response);
}
?>
1.3.5 Synthèse
Comme nous l’avons vu, il y a différentes stratégies à utiliser selon les flux que vous utilisez et la plateforme pour
laquelle vous développez. Faire du WMS dans une application web sera plus simple que traiter du WFS volumineux
dans une application iPhone. On peut cependant distinguer les approches les plus intéressantes :
— Pour de l’image simple, sans authentification, utilisez un flux direct vers notre plateforme
— pour les gros volumes texte (WFS, JSON...) récupérez la donnée à intervalles réguliers et servez là depuis votre
serveur. Ca peut aussi vous éviter le recours à un script proxy.
— Pour les applications nomades sur Smartphone, privilégiez l’autonomie de l’application par rapport aux modalités d’accès aux données. Récupérez les données, et implémentez un service listant les données disponibles,
de sorte que vous pourrez intégrer de nouvelles couches de données à votre application sans la mettre à jour.
1.4 Exemples et extraits de code
1.4.1 WMS avec OpenLayers
Cet exemple montre l’utilisation du service WFS avec les bornes vélo’v en temps réel à travers la bibliothèque OpenLayers.
18
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
Code source correspondant :
<html>
<head>
<title>Utilisation des services GrandLyon Data : OpenLayers</title>
<script src="http://openlayers.org/api/OpenLayers.js"></script>
</head>
<body>
<div style="width:100%; height:100%" id="map"></div>
<script defer="defer" type="text/javascript">
var map = new OpenLayers.Map('map');
var osm = new OpenLayers.Layer.OSM('Simple OSM Map', null, {
//conversion en valeurs de gris à la volée
eventListeners: {
tileloaded: function(evt) {
var ctx = evt.tile.getCanvasContext();
if (ctx) {
var imgd = ctx.getImageData(0, 0, evt.tile.size.w, evt.tile.size.h);
var pix = imgd.data;
for (var i = 0, n = pix.length; i < n; i += 4) {
pix[i] = pix[i + 1] = pix[i + 2] = (3 * pix[i] + 4 * pix[i + 1] + pix[i + 2]) / 8;
}
ctx.putImageData(imgd, 0, 0);
evt.tile.imgDiv.removeAttribute("crossorigin");
evt.tile.imgDiv.src = ctx.canvas.toDataURL();
}
}
}
});
//URL du service data
var data_url = "https://download.data.grandlyon.com/wfs/rdata?";
//Définition du proxy pour gérer le cross-domain. Voir le paragraphe Bonne Pratiques -> Proxy
OpenLayers.ProxyHost = "/cgi-bin/proxy.cgi?url=";
//Styles pour le rendu
1.4. Exemples et extraits de code
19
Data Grand Lyon Documentation, Version 1.0
var colors = ["green", "blue", "orange", "grey"];
var context = {
getColor: function(feature) {
return colors[feature.data.availabilitycode - 1];
}
}
var template = {
pointRadius: 15,
fillColor: "${getColor}" // using context.getColor(feature)
};
var style = new OpenLayers.Style(template, {context: context});
//Définition du layer WFS
var wfs = new OpenLayers.Layer.Vector("WFS GL Data", {
strategies: [new OpenLayers.Strategy.BBOX()],
protocol: new OpenLayers.Protocol.WFS({
version: "1.1.0",
srsName: "EPSG:4326",
url: data_url,
featurePrefix : 'ms',
featureType: "jcd_jcdecaux.jcdvelov",
geometryName: "msGeometry",
formatOptions: {
xy: false
}
}),
styleMap: new OpenLayers.StyleMap(style),
renderers: OpenLayers.Layer.Vector.prototype.renderers
});
//gestion du click sur les markers
var selectControl = new OpenLayers.Control.SelectFeature(wfs);
map.addControl(selectControl);
selectControl.activate();
wfs.events.on({
featureselected: function(event) {
var feature = event.feature;
feature.popup = new OpenLayers.Popup.FramedCloud("box",
feature.geometry.getBounds().getCenterLonLat(),
null,
'<div><b>'+feature.data.name + '</b> (station '+feature.data.number+')<br/>'
+ 'Il reste <b>' + feature.data.available_bikes + '</b> v&eacute;los disponibles et '
+ '<b>' + feature.data.available_bike_stands + ' </b>bornes libres</div>',
null,
true
);
while( map.popups.length ) {
map.removePopup( map.popups[0] );
}
map.addPopup(feature.popup);
}
});
//Config de la map
map.addLayers([osm, wfs]);
var zoom = 15;
var lonLat = new OpenLayers.LonLat(4.85,45.76);
20
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
map.setCenter(
lonLat.transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
), zoom
);
</script>
</body>
</html>
1.4.2 WFS avec Leaflet
Cet exemple montre l’utilisation du service WFS avec les bornes vélo’v en temps réel à travers la bibliothèque LeafLet.
Code source correspondant :
<html>
<head>
<title>Utilisation des services GrandLyon Data : Leaflet</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<link rel="stylesheet" href="leaflet.css" />
<style>
body {
padding: 0;
margin: 0;
}
1.4. Exemples et extraits de code
21
Data Grand Lyon Documentation, Version 1.0
html, body, #map {
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
//Initialisation de la map
var map = L.map('map').setView([45.76, 4.85], 14);
//Layer WMS sur une orthophoto
L.tileLayer.wms("https://download.data.grandlyon.com/wms/grandlyon",{
layers: '1840_5175_16_CC46',
format: 'image/png',
transparent: true,
opacity: 0.6
}).addTo(map);
//Layer WMS openstreetmap
L.tileLayer.wms("https://openstreetmap.data.grandlyon.com/",{
layers: 'osm_grandlyon',
format: 'image/png',
transparent: true,
opacity: 0.7
}).addTo(map);
//Définition du proxy pour le WFS (cross domain). Voir le paragraphe Bonne Pratiques -> Proxy
var proxy = "proxy.php?url=";
var data_url = "https://download.data.grandlyon.com/wfs/rdata";
var params = '?SERVICE=WFS
&REQUEST=GetFeature
&VERSION=1.1.0
&TYPENAME=jcd_jcdecaux.jcdvelov
&outputformat=geojson';
var VertIcon = L.icon({
iconUrl: 'images/cycling_Vert.png',
iconSize:
[33, 21]
});
var OrangeIcon = L.icon({
iconUrl: 'images/cycling_Orange.png',
iconSize:
[33, 21]
});
var BleuIcon = L.icon({
iconUrl: 'images/cycling_Bleu.png',
iconSize:
[33, 21]
});
var GrisIcon = L.icon({
iconUrl: 'images/cycling_Gris.png',
iconSize:
[33, 21]
});
$.get(proxy + encodeURIComponent(data_url + params), function(json){
var obj = $.parseJSON(json);
// Add markers
for(i=0;i<obj.features.length;i++) {
//create feature from json
var ftr = obj.features[i];
// set marker options from properties
22
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
var options = {
gid: ftr.properties.gid,
number: ftr.properties.number,
name: ftr.properties.name,
available_bikes: ftr.properties.available_bikes,
available_bike_stands: ftr.properties.available_bike_stands
};
//set marker icon from availability
switch(ftr.properties.availability){
case 'Vert':
options.icon = VertIcon;
break;
case 'Orange':
options.icon = OrangeIcon;
break;
case 'Bleu' :
options.icon = BleuIcon;
break;
default :
options.icon = GrisIcon;
}
//ajout du marker à la map
var point = L.marker(
[ftr.geometry.coordinates[1],ftr.geometry.coordinates[0]],
options
).addTo(map);
//définition de la popup sur le click
point.bindPopup(
'<b>'+ point.options.name + '</b> (station '+point.options.number+')<br/>'
+ 'Il reste <b>' + point.options.available_bikes + '</b> v&eacute;los disponibles
+ ' et <b>' + point.options.available_bike_stands + ' </b>bornes libres',
{
closeButton: false
}
);
}
});
</script>
</body>
</html>
1.4.3 KML avec l’API Maps de Google
Cet exemple montre l’utilisation du service KML avec les bornes vélo’v à travers l’API Google Maps v3. Nécessite
une clé pour l’API.
1.4. Exemples et extraits de code
23
Data Grand Lyon Documentation, Version 1.0
Code source correspondant :
<html>
<head>
<title>Utilisation des services GrandLyon Data : Google API</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map-canvas { height: 100% }
</style>
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=API_KEY&sensor=false">
</script>
<script type="text/javascript">
function initialize() {
//Init map
var mapOptions = {
center: new google.maps.LatLng(45.76, 4.85),
zoom: 13
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
//Ajout WMS sur l'aménagement cyclable
var urlWMS = "https://download.data.grandlyon.com/wms/grandlyon?"
+ "&REQUEST=GetMap&SERVICE=WMS&VERSION=1.3.0&CRS=EPSG:4171"
+ "&LAYERS=pvo_patrimoine_voirie.pvoamenagementcyclable"
+ "&FORMAT=image/png&TRANSPARENT=TRUE&WIDTH=256&HEIGHT=256";
//L'API Google Map ne gère pas directement le WMS, il faut passer par un ImageMapType
var WMS_Layer = new google.maps.ImageMapType({
getTileUrl: function (coord, zoom) {
var projection = map.getProjection();
var zoomfactor = Math.pow(2, zoom);
24
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
var LL_upperleft = projection.fromPointToLatLng(
new google.maps.Point(
coord.x * 256 / zoomfactor,
coord.y * 256 / zoomfactor
)
);
var LL_lowerRight = projection.fromPointToLatLng(
new google.maps.Point(
(coord.x + 1) * 256 / zoomfactor,
(coord.y + 1) * 256 / zoomfactor
)
);
var bbox = "&bbox="
+ LL_lowerRight.lat() + "," + LL_upperleft.lng() + ","
+ LL_upperleft.lat() + "," + LL_lowerRight.lng();
var url = urlWMS + bbox;
return url;
},
tileSize: new google.maps.Size(256, 256),
isPng: true
});
map.overlayMapTypes.push(WMS_Layer);
//Ajout KML layer
var KML_Layer = new google.maps.KmlLayer({
url: 'https://download.data.grandlyon.com/kml/grandlyon/?'
+'request=layer&typename=pvo_patrimoine_voirie.pvostationvelov'
});
KML_Layer.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"/>
</body>
</html>
1.4.4 Utilisation du WCS
Cet exemple montre l’utilisation du service WCS pour obtenir les données brutes sur le NO2 en 2012. Nous utiliserons
dans ces exemples la version 2.0.1 qui est la plus récente. Il est encore possible d’utiliser aussi les versions 1.1.1 ou
1.0.0.
Etape 1 : lecture des capacités du service
https://download.data.grandlyon.com/wcs/rdata?SERVICE=WCS&REQUEST=GetCapabilities&VERSION=2.0.1
1.4. Exemples et extraits de code
25
Data Grand Lyon Documentation, Version 1.0
Parmi les informations retournées, on peut consulter les formats de sortie disponibles. Le WCS est un service destiné
à fournir de la donnée brute (raw data). Il est donc recommandé de l’utiliser avec un format comme image/x-aaigrid
pour un raster monobande ou image/tiff pour un raster multibandes, plutôt qu’avec un des formats de sortie prévus
pour la visualisation, comme image/jpeg ou image/gif.
Dans la dernière partie du XML renvoyé, on trouve la liste des couvertures disponibles pour ce service, dont la couverture Carte_agglo_lyon_NO2_2012, que nous utiliserons dans la suite de l’exemple.
Etape 2 : détail d’une couverture
https://download.data.grandlyon.com/wcs/rdata?SERVICE=WCS&REQUEST=DescribeCoverage&VERSION=2.0.1&COVERAGEID
26
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
Attention, en version 2.0.1, le paramètre pour indiquer la couverture demandée est COVERAGEID, mais en version
1.0 c’est IDENTIFIER et en version 1.1, c’est COVERAGE.
Attention également à la casse dans le nom de la couverture demandée si vous testez manuellement les requêtes : le
service WCS y est sensible. Ainsi la couverture Carte_agglo_lyon_NO2_2012 (avec un l minuscule pour Lyon) ne
sera pas trouvée.
Cette requête permet d’obtenir tous les détails de la couverture comme son étendue géographique ou des informations
sur les bandes. On voit ainsi dans notre cas qu’il s’agit d’images multi-canaux à 3 bandes.
Etape 3 : obtention de la couverture
La requête suivante permet d’obtenir un extrait du raster au format TIFF :
https://download.data.grandlyon.com/wcs/rdata?SERVICE=WCS&VERSION=2.0.1&REQUEST=GetCoverage&FORMAT=image/tiff
Un aperçu du raster obtenu avec une colorisation des 3 bandes :
Il est aussi possible de n’extraire qu’une seule bande en utilisant le paramètre RANGESUBSET. Ce paramètre permet
de choisir les bandes à utiliser, de les réorganiser, etc.. Le plus simple est d’indiquer la bande par son index (la première
bande commence à 1). Il est aussi possible de mixer des références aux bandes via des intervalles. Par exemple :
RANGESUBSET=1,3 :5,7
Avec une seule bande, on peut alors utiliser le format de sortie x-aaigrid (Arc/Info ASCII Grid).
https://download.data.grandlyon.com/wcs/rdata?SERVICE=WCS&VERSION=2.0.1&REQUEST=GetCoverage&FORMAT=image/xaaigrid&COVERAGEID=Carte_agglo_Lyon_NO2_2012&RANGESUBSET=1&SUBSET=x,http://www.opengis.net/def/crs/EPSG/0/2
Un aperçu du fichier obtenu :
1.4. Exemples et extraits de code
27
Data Grand Lyon Documentation, Version 1.0
Enfin, il est aussi possible d’utiliser SUBSET avec des coordonnées absolues pour les pixels en indiquant le paramètre
&SUBSETTINGCRS=imageCRS :
https://download.data.grandlyon.com/wcs/rdata?SERVICE=WCS&VERSION=2.0.1&REQUEST=GetCoverage&FORMAT=image/tiff
1.4.5 Utilisation du service CSW
Cet exemple montre l’utilisation du service CSW pour obtenir des informations sur les métadonnées.
Etape 1 : lecture des capacités du service
https://download.data.grandlyon.com/catalogue/srv/fre/csw?version=2.0.2&request=GetCapabilities&service=CSW
Exemple de présentation du XML reçu (plugin CSW dans QGIS) :
28
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
Etape 2 : recherche sur des mots clés (Réseaux de transport)
Requête POST : https://download.data.grandlyon.com/catalogue/srv/fre/csw avec dans le data du POST :
<?xml version="1.0" ?>
<csw:GetRecords maxRecords="10" outputFormat="application/xml" outputSchema="http://www.opengis.net/c
<csw:Query typeNames="csw:Record">
<csw:ElementSetName>full</csw:ElementSetName>
<csw:Constraint version="1.1.0">
<ogc:Filter>
<ogc:PropertyIsLike escapeChar="\" singleChar="_" wildCard="%">
<ogc:PropertyName>csw:AnyText</ogc:PropertyName>
<ogc:Literal>Réseaux de transport</ogc:Literal>
</ogc:PropertyIsLike>
</ogc:Filter>
</csw:Constraint>
</csw:Query>
</csw:GetRecords>
Extrait du XML obtenu en retour :
<?xml version="1.0" encoding="UTF-8"?>
<csw:GetRecordsResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2" xmlns:xsi="http://www.w3.org
<csw:SearchStatus timestamp="2015-11-06T16:36:24" />
<csw:SearchResults numberOfRecordsMatched="47" numberOfRecordsReturned="10" elementSet="full" nextR
1.4. Exemples et extraits de code
29
Data Grand Lyon Documentation, Version 1.0
<csw:Record xmlns:ows="http://www.opengis.net/ows" xmlns:geonet="http://www.fao.org/geonetwork" x
<dc:title xmlns:dct="http://purl.org/dc/terms/">Alertes accessibilité du réseau TCL</dc:title
<dc:creator xmlns:dct="http://purl.org/dc/terms/">256900994</dc:creator>
<dc:subject xmlns:dct="http://purl.org/dc/terms/">Réseaux de transport</dc:subject>
<dc:subject xmlns:dct="http://purl.org/dc/terms/">Services d'utilité publique et services publ
<dc:description xmlns:dct="http://purl.org/dc/terms/">Les alertes accessibilité recensent les
<dc:publisher xmlns:dct="http://purl.org/dc/terms/">SYTRAL</dc:publisher>
<dc:type xmlns:dct="http://purl.org/dc/terms/">nonGeographicDataset</dc:type>
<dc:format xmlns:dct="http://purl.org/dc/terms/">application/json</dc:format>
<dc:format xmlns:dct="http://purl.org/dc/terms/">text/csv</dc:format>
<dc:format xmlns:dct="http://purl.org/dc/terms/">csv (taille : 2 Ko)</dc:format>
<dc:source xmlns:dct="http://purl.org/dc/terms/">Données provenant de la base géographique et
<dc:language xmlns:dct="http://purl.org/dc/terms/">fre</dc:language>
<dc:relation xmlns:dct="http://purl.org/dc/terms/">https://download.data.grandlyon.com/ws/rdata
<dc:relation xmlns:dct="http://purl.org/dc/terms/">https://download.data.grandlyon.com/files/rd
<dc:relation xmlns:dct="http://purl.org/dc/terms/">https://download.data.grandlyon.com/files/gr
<dc:coverage xmlns:dct="http://purl.org/dc/terms/">North 45.917, South 45.55, East 5.067, West
<dc:rights xmlns:dct="http://purl.org/dc/terms/">Licence Engagée</dc:rights>
<dc:rights xmlns:dct="http://purl.org/dc/terms/">Pas de restriction d'accès public selon INSPI
<dct:created xmlns:dct="http://purl.org/dc/terms/">2014-12-04</dct:created>
<dct:dateSubmitted xmlns:dct="http://purl.org/dc/terms/">2015-02-02</dct:dateSubmitted>
<dct:isPartOf xmlns:dct="http://purl.org/dc/terms/">16a9a657-e938-484e-a067-5cdacd7a0419</dct:i
<dct:accessRights xmlns:dct="http://purl.org/dc/terms/">Free access with registration</dct:acce
<dct:accrualPeriodicity xmlns:dct="http://purl.org/dc/terms/">continuous</dct:accrualPeriodicit
<dct:modified xmlns:dct="http://purl.org/dc/terms/">2015-11-06T00:02:26</dct:modified>
<dc:identifier xmlns:dct="http://purl.org/dc/terms/">4721ec9e-86c8-4687-8713-f406290949ad</dc:i
<ows:BoundingBox crs="urn:x-ogc:def:crs:EPSG:6.11:4326">
<ows:LowerCorner>45.55 4.681</ows:LowerCorner>
<ows:UpperCorner>45.917 5.067</ows:UpperCorner>
</ows:BoundingBox>
</csw:Record>
<csw:Record xmlns:ows="http://www.opengis.net/ows" xmlns:geonet="http://www.fao.org/geonetwork" x
<dc:identifier>58f93af3-a651-4cbd-bd9d-b4562f8d404d</dc:identifier>
<dc:date>2015-11-06T00:04:55</dc:date>
<dc:title>Lignes de métro et funiculaire du réseau TCL</dc:title>
<dc:type>dataset</dc:type>
<dc:subject>Réseaux de transport</dc:subject>
<dc:subject>Services d'utilité publique et services publics</dc:subject>
<dc:subject>transportation</dc:subject>
<dc:format />
<dct:abstract>La représentation graphique des lignes de métro et de funiculaire du réseau TC
La représentation graphique des lignes est caractérisée par des informations de gestion (identifia
<dc:description>La représentation graphique des lignes de métro et de funiculaire du réseau
La représentation graphique des lignes est caractérisée par des informations de gestion (identifia
<dc:rights>license</dc:rights>
<dc:language>fre</dc:language>
<dc:source>Données provenant de la base géographique et topologique TCL SYTRAL.</dc:source>
<dc:relation>16a9a657-e938-484e-a067-5cdacd7a0419</dc:relation>
<dc:format />
<ows:BoundingBox crs="urn:ogc:def:crs:EPSG::RGF93 / CC46 (EPSG:3946)">
<ows:LowerCorner>5.1410943067093 45.486705557736</ows:LowerCorner>
<ows:UpperCorner>4.629545313738 45.945335689366</ows:UpperCorner>
</ows:BoundingBox>
<dc:URI protocol="DB:POSTGIS" name="tcl_sytral.tcllignemf" description="Lignes de métro et fun
<dc:URI protocol="OGC:WMS" name="tcl_sytral.tcllignemf" description="Lignes de métro et funicu
<dc:URI protocol="OGC:WFS" name="tcl_sytral.tcllignemf" description="Lignes de métro et funicu
<dc:URI protocol="WWW:LINK-1.0-http--link" name="tcl_sytral.tcllignemf/all.json" description="D
<dc:URI protocol="WWW:LINK-1.0-http--link" name="Licence Ouverte" description="Description des
30
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
<dc:URI protocol="image/png" name="thumbnail">https://download.data.grandlyon.com/catalogue/srv
<dc:URI protocol="image/png" name="large_thumbnail">https://download.data.grandlyon.com/catalog
</csw:Record>
<csw:Record xmlns:ows="http://www.opengis.net/ows" xmlns:geonet="http://www.fao.org/geonetwork" xm
...
</csw:Record>
</csw:SearchResults>
</csw:GetRecordsResponse>
Exemple de présentation du résultat (plugin CSW dans QGIS) :
Etape 3 : recherche sur des mots clés (Transport, Bus) et une zone géographique
Requête POST : https://download.data.grandlyon.com/catalogue/srv/fre/csw avec dans le data du POST :
<?xml version="1.0" ?>
<csw:GetRecords maxRecords="10" outputFormat="application/xml" outputSchema="http://www.opengis.net/c
<csw:Query typeNames="csw:Record">
<csw:ElementSetName>full</csw:ElementSetName>
<csw:Constraint version="1.1.0">
<ogc:Filter>
<ogc:And>
<ogc:BBOX>
<ogc:PropertyName>ows:BoundingBox</ogc:PropertyName>
<gml311:Envelope>
<gml311:lowerCorner>4.7027853 45.597999</gml3
<gml311:upperCorner>4.7191596 45.609031</gml3
</gml311:Envelope>
</ogc:BBOX>
<ogc:PropertyIsLike escapeChar="\" singleChar="_" wildCard="%
<ogc:PropertyName>csw:AnyText</ogc:PropertyName>
<ogc:Literal>Transport, Bus</ogc:Literal>
</ogc:PropertyIsLike>
</ogc:And>
</ogc:Filter>
</csw:Constraint>
</csw:Query>
</csw:GetRecords>
Exemple de présentation du résultat (plugin CSW dans QGIS) :
1.4. Exemples et extraits de code
31
Data Grand Lyon Documentation, Version 1.0
Etape 4 : chargement d’une metadata précise par son ID parmi les résultats obtenus
https://download.data.grandlyon.com/catalogue/srv/fre/csw?outputFormat=application%2Fxml&service=CSW&outputSchema=http%3
f9cf-4f3c-8684-6b55d6935f6f
XML obtenu en retour :
<csw:GetRecordByIdResponse xmlns:csw="http://www.opengis.net/cat/csw/2.0.2">
<csw:Record xmlns:ows="http://www.opengis.net/ows" xmlns:geonet="http://www.fao.org/geonetwor
<dc:identifier>f5b0fe8e-f9cf-4f3c-8684-6b55d6935f6f</dc:identifier>
<dc:date>2015-11-06T00:06:17</dc:date>
<dc:title>Aménagement cyclable</dc:title>
<dc:type>dataset</dc:type>
<dc:subject>Réseaux de transport</dc:subject>
<dc:subject>transportation</dc:subject>
<dc:subject>planningCadastre</dc:subject>
<dc:format/>
<dct:abstract>
L'aménagement cyclable est un objet linéaire décrivant une infrastructure dédiée à la
</dct:abstract>
<dc:description>
L'aménagement cyclable est un objet linéaire décrivant une infrastructure dédiée à la
</dc:description>
<dc:rights>license</dc:rights>
<dc:language>fre</dc:language>
<dc:source>
Mise à jour en continu : remontée d'informations travaux des services du Grand Lyon e
</dc:source>
<dc:format/>
<ows:BoundingBox crs="urn:ogc:def:crs:EPSG::RGF93 / CC46 (EPSG:3946)">
<ows:LowerCorner>5.067 45.55</ows:LowerCorner>
<ows:UpperCorner>4.681 45.917</ows:UpperCorner>
</ows:BoundingBox>
<dc:URI protocol="OGC:WMS" name="pvo_patrimoine_voirie.pvoamenagementcyclable" descri
<dc:URI protocol="OGC:WFS" name="pvo_patrimoine_voirie.pvoamenagementcyclable" descri
<dc:URI protocol="WWW:LINK-1.0-http--link" name="pvo_patrimoine_voirie.pvoamenagement
https://download.data.grandlyon.com/ws/grandlyon/pvo_patrimoine_voirie.pvoamenagement
</dc:URI>
<dc:URI protocol="WWW:LINK-1.0-http--link" name="Licence Ouverte" description="Descri
https://download.data.grandlyon.com/files/grandlyon/LicenceOuverte.pdf
</dc:URI>
<dc:URI protocol="image/png" name="thumbnail">
https://download.data.grandlyon.com/catalogue/srv/fre/resources.get?uuid=f5b0fe8e-f9c
32
Chapitre 1. Guide du développeur
Data Grand Lyon Documentation, Version 1.0
</dc:URI>
<dc:URI protocol="image/png" name="large_thumbnail">
https://download.data.grandlyon.com/catalogue/srv/fre/resources.get?uuid=f5b0fe8e-f9c
</dc:URI>
</csw:Record>
</csw:GetRecordByIdResponse>
Exemple de présentation du résultat (plugin CSW dans QGIS) :
1.4. Exemples et extraits de code
33

Documents pareils