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é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é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