|
| 1 | +--- |
| 2 | +title: "Accéder aux données de Mapillary et les intégrer dans son SIG" |
| 3 | +authors: |
| 4 | + - Florian Boret |
| 5 | +categories: |
| 6 | + - article |
| 7 | + - tutoriel |
| 8 | +date: 2022-05-31 14:20 |
| 9 | +description: "Accéder aux données de Mapillary et les intégrer dans son SIG" |
| 10 | +image: "https://cdn.geotribu.fr/img/articles-blog-rdp/articles/mapillary_data/mapillary_data.png" |
| 11 | +license: default |
| 12 | +tags: |
| 13 | + - Bash |
| 14 | + - cURL |
| 15 | + - data |
| 16 | + - OGR |
| 17 | + - Mapillary |
| 18 | + - MVT |
| 19 | + - PostGIS |
| 20 | + - PostgreSQL |
| 21 | + - tuiles vectorielles |
| 22 | +--- |
| 23 | + |
| 24 | +# Accéder aux données de Mapillary et les intégrer dans son SIG |
| 25 | + |
| 26 | +:calendar: Date de publication initiale : 31 Mai 2022 |
| 27 | + |
| 28 | +## Prérequis |
| 29 | + |
| 30 | +- un [jeton Mapillary](https://www.mapillary.com/dashboard/developers) |
| 31 | +- l'interpréteur [Bourne-Again shell](https://fr.wikipedia.org/wiki/Bourne-Again_shell) |
| 32 | +- l'outil de conversion [ogr2ogr](https://gdal.org/programs/ogr2ogr.html) |
| 33 | +- [cURL](https://curl.se) |
| 34 | + |
| 35 | +## Intro |
| 36 | + |
| 37 | +{: .img-rdp-news-thumb } |
| 38 | + |
| 39 | +Aujourd'hui, je vais vous présenter différentes manières d'accéder aux données identifiées à partir des prises de vue publiées sur Mapillary et qui pourront peut-être vous permettre d'enrichir votre SIG sur certaines thématiques. Pour ce faire nous allons nous appuyer sur les différents services proposés par la [4ème version de l'API](https://www.mapillary.com/developer/api-documentation/). |
| 40 | + |
| 41 | +[Commenter cet article :fontawesome-solid-comments:](#__comments){: .md-button } |
| 42 | +{: align=middle } |
| 43 | + |
| 44 | +---- |
| 45 | + |
| 46 | +## 1. Les tuiles vectorielles Mapillary dans QGIS |
| 47 | + |
| 48 | +{: .img-rdp-news-thumb } |
| 49 | + |
| 50 | +Lorsqu'on épluche la documentation, on peut voir que Mapillary propose un service d'accès à ses données basé sur des services de [tuiles vectorielles](https://docs.qgis.org/3.22/fr/docs/user_manual/working_with_vector_tiles/vector_tiles_properties.html). Ils ont l'avantage d'offrir une solution assez souple et légère permettant de visualiser de grandes quantités d'informations. Les tuiles vectorielles de Mapillary suivent les [spécifications des tuiles Mapbox (MVT)](https://docs.mapbox.com/data/tilesets/guides/vector-tiles-standards/) et offrent la possbilité : |
| 51 | + |
| 52 | +- de réaliser des filtrages et des rendus spécifiques |
| 53 | +- d'interroger la donnée |
| 54 | + |
| 55 | +Il existe trois URL permettant d'accéder aux tuiles vectorielles de Mapillary : |
| 56 | + |
| 57 | +1. [Tuiles de couverture](https://www.mapillary.com/developer/api-documentation/#coverage-tiles) : qui permettent de visualiser les séquences (traces) et la position des prises de vue : `https://tiles.mapillary.com/maps/vtp/mly1_computed_public/2/{z}/{x}/{y}?access_token=XXX` |
| 58 | +2. [Tuiles de points](https://www.mapillary.com/developer/api-documentation/#point-tiles) : qui permettent de visualiser la position des [objets détectés par les algorithmes de mapillary (autres que des panneaux de signalisation)](https://www.mapillary.com/developer/api-documentation/points) : `https://tiles.mapillary.com/maps/vtp/mly_map_feature_point/2/{z}/{x}/{y}?access_token=XXX` |
| 59 | +3. [Tuiles de panneaux de signalisation](https://www.mapillary.com/developer/api-documentation/#traffic-sign-tiles) : qui permettent de visualiser la position des [panneaux de signalisation détectés par les algorithmes de Mapillary](https://www.mapillary.com/developer/api-documentation/traffic-signs) : `https://tiles.mapillary.com/maps/vtp/mly_map_feature_traffic_sign/2/{z}/{x}/{y}?access_token=XXX` |
| 60 | + |
| 61 | +### Ajout des tuiles vectorielles |
| 62 | + |
| 63 | +Dans l'explorateur du Gestionnaire de données de QGIS, ajouter une couche de tuiles vectorielles. |
| 64 | + |
| 65 | +[{: .img-center loading=lazy }](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/mapillary_data/explorateur.png "Explorateur"){: data-mediabox="gallery-lightbox" data-title="Explorateur" } |
| 66 | + |
| 67 | +Nommer proprement la couche vectorielle à ajouter et renseigner l'URL de la couche vectorielle qui vous intéresse en n'oubliant pas de modifier le jeton Mapillary qui vous permet de vous identifier. |
| 68 | + |
| 69 | +[{: .img-center loading=lazy }](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/mapillary_data/connexion.png "Connexion"){: data-mediabox="gallery-lightbox" data-title="Connexion" } |
| 70 | + |
| 71 | +Ajouter la nouvelle couche de tuiles dans QGIS (pour visualiser l'information, vous devrez zoomer au niveau 14 ou +). |
| 72 | + |
| 73 | +### Interrogation des tuiles vectorielles |
| 74 | + |
| 75 | +Les tuiles vectorielles sont interrogeables et permettent une consultation des différents champs publiés. Si l'on prend l'exemple du flux lié à la signalisation, il est possible d'accéder au type de panneau detecté ainsi qu'aux dates auxquelles il a été vu pour la première et la dernière fois. |
| 76 | + |
| 77 | +[{: .img-center loading=lazy }](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/mapillary_data/information.png "Information"){: data-mediabox="gallery-lightbox" data-title="Information" } |
| 78 | + |
| 79 | +### Personnalisation des tuiles vectorielles |
| 80 | + |
| 81 | +Par défaut lors de l'ajout, les données présentent dans les tuiles vectorielles sont automatiquement réparties en : |
| 82 | + |
| 83 | +- Polygones |
| 84 | +- Lignes |
| 85 | +- Points |
| 86 | + |
| 87 | +[{: .img-center loading=lazy }](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/mapillary_data/symbologie.png "Symbologie"){: data-mediabox="gallery-lightbox" data-title="Symbologie" } |
| 88 | + |
| 89 | +Il est possible d'enrichir ce rendu par défaut en ajoutant de nouveaux styles, en définissant la couche sur laquelle vous souhaitez travailler, exemple : `traffic_signs` et en jouant avec les filtres, exemple : `(geometry_type($geometry)='Point') AND ("value" IS 'information--general-directions--g1')` |
| 90 | + |
| 91 | +!!! info |
| 92 | + Il y a aussi la possibilité d'importer un style déjà configuré au format QML ou MapBox GL Json. |
| 93 | + |
| 94 | +## 2. Extraire les données vectorielles des tuiles vectorielles |
| 95 | + |
| 96 | +Mainteant qu'on s'est bien amusé sur le tunning des tuiles vectorielles :race_car:, il pourrait être intéressant de récupérer l'information vectorielle pour la stocker. Dans cette partie, je vais vous présenter un script qui me permet : |
| 97 | + |
| 98 | +1. de récupérer de données vecteurs à partir des différents flux des tuiles vectorielles, |
| 99 | +2. d'intégrer les données dans une base de données PosgreSQL/PostGIS. |
| 100 | + |
| 101 | +### Fonctionnement global |
| 102 | + |
| 103 | +```mermaid |
| 104 | +flowchart TD; |
| 105 | + A[Tuiles vectorielles ] |
| 106 | + A <--> |curl| B{Script mapillary_vt2pg} |
| 107 | + B <--> C{config.env} |
| 108 | + B --> |ogr2ogr| E(PostgreSQL/PostGIS) |
| 109 | +``` |
| 110 | + |
| 111 | +### Un environnement de travail : config.env |
| 112 | + |
| 113 | +Avant de se lancer, il est bon de paramétrer le fichier de configuration que vous devrez adapter à votre organisation et qui sera utilisé pour intégrer les données Mapillary dans votre base de données. On y définit les différents répertoires de travail ainsi que les variables permettant d'accéder à la base de données (connexion par [pg_service.conf](http://archives.postgresql.fr/v2/index9215.html?q=node/1388)). |
| 114 | + |
| 115 | +Voici le fichier `config.env` à adapter : |
| 116 | + |
| 117 | +```ini |
| 118 | +# REPERTOIRE DE TRAVAIL |
| 119 | +REPER='/mapillary' |
| 120 | + |
| 121 | +#REPERTOIRE DE STOCKAGE DES LOGS |
| 122 | +REPER_LOGS='logs' |
| 123 | + |
| 124 | +#MAPILLARY |
| 125 | +TOKEN='MLY|XXXXXXXXXXXXXXXXXXXXXX|XXXXXXXXXXXXXXXXXXXXXX' |
| 126 | + |
| 127 | +V_LONG_MIN='3.96440' |
| 128 | +V_LONG_MAX='4.20430' |
| 129 | +V_LAT_MIN='43.57840' |
| 130 | +V_LAT_MAX='43.81890' |
| 131 | +V_ZOOM='14' |
| 132 | + |
| 133 | +# PERMET DE DEFINIR UNE DATE DE DEBUT |
| 134 | +DATE_DEBUT='2021-01-01T00:00:00-00:00' |
| 135 | + |
| 136 | +# PARAMETRES OGR |
| 137 | +ENCODAGE='UTF-8' |
| 138 | + |
| 139 | +# CONNEXION A LA BASE DE DONNEES : https://gdal.org/drivers/vector/pg.html#connecting-to-a-database |
| 140 | +C_SERVICE='XXXXXXXXXXXXXXXXXXXXXX' |
| 141 | +C_SCHEMA='ref_mapillary' |
| 142 | +``` |
| 143 | + |
| 144 | +[Consulter le fichier de configuration :fontawesome-regular-file-code:](https://github.com/igeofr/mapillary2pg/blob/main/config.env){: .md-button } |
| 145 | +{: align=middle } |
| 146 | + |
| 147 | +### Convertir l'emprise lat/long dans le système de numérotation des tuiles |
| 148 | + |
| 149 | +Les tuiles ne sont pas définies par une longitude/latitude mais par une numérotation spécifique, il nous faut donc identifier les numéros des tuiles qui croisent notre emprise de travail et pour cela, je me suis appuyé sur une [solution proposée sur le wiki d'OpenStreetMap](https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Bourne_shell_with_Awk). |
| 150 | + |
| 151 | +```bash |
| 152 | +# BBOX ET IDENTIFICATION DES TUILES |
| 153 | +long2xtile(){ |
| 154 | + long=$1 |
| 155 | + zoom=$2 |
| 156 | + echo -n "${long} ${zoom}" | awk '{ xtile = ($1 + 180.0) / 360 * 2.0^$2; |
| 157 | + xtile+=xtile<0?-0.5:0.5; |
| 158 | + printf("%d", xtile ) }' |
| 159 | +} |
| 160 | +lat2ytile() { |
| 161 | + lat=$1; |
| 162 | + zoom=$2; |
| 163 | + ytile=`echo "${lat} ${zoom}" | awk -v PI=3.14159265358979323846 '{ |
| 164 | + tan_x=sin($1 * PI / 180.0)/cos($1 * PI / 180.0); |
| 165 | + ytile = (1 - log(tan_x + 1/cos($1 * PI/ 180))/PI)/2 * 2.0^$2; |
| 166 | + ytile+=ytile<0?-0.5:0.5; |
| 167 | + printf("%d", ytile ) }'`; |
| 168 | + echo -n "${ytile}"; |
| 169 | +} |
| 170 | + |
| 171 | +XMIN=$(long2xtile $(echo $V_LONG_MIN | sed -e 's/\./,/g') $V_ZOOM) |
| 172 | +XMAX=$(long2xtile $(echo $V_LONG_MAX | sed -e 's/\./,/g') $V_ZOOM) |
| 173 | +YMIN=$(lat2ytile $(echo $V_LAT_MIN | sed -e 's/\./,/g') $V_ZOOM) |
| 174 | +YMAX=$(lat2ytile $(echo $V_LAT_MAX | sed -e 's/\./,/g') $V_ZOOM) |
| 175 | +echo $XMIN $YMIN $XMAX $YMAX |
| 176 | +``` |
| 177 | + |
| 178 | +### Téléchargement des tuiles et création de GPKG |
| 179 | + |
| 180 | +Ensuite, à l'aide de `curl` on va pouvoir télécharger chacune des tuiles en local et en extraire l'information pour l'intégrer dans un Géopackage (que l'on pourra archiver facilement). |
| 181 | + |
| 182 | +``` bash |
| 183 | +Z=$V_ZOOM |
| 184 | +for X in $(seq $XMIN $XMAX);do |
| 185 | + for Y in $(seq $YMAX $YMIN);do |
| 186 | + |
| 187 | + MVT_FILE=${Z}'_'${X}'_'${Y}'.mvt' |
| 188 | + |
| 189 | + #------------------------------------------------------------------------------- |
| 190 | + URL="https://tiles.mapillary.com/maps/vtp/$VAR_URL/2/$Z/$X/$Y?access_token=$TOKEN" |
| 191 | + #echo "https://tiles.mapillary.com/maps/vtp/$VAR_URL/2/$Z/$X/$Y?access_token=$TOKEN" |
| 192 | + |
| 193 | + mkdir $REPER'/tuiles/tuiles_'$L_TYPE'/'${DATE_YMD} |
| 194 | + mkdir $REPER'/tuiles/tuiles_'$L_TYPE'/'${DATE_YMD}'/'${Z} |
| 195 | + mkdir $REPER'/tuiles/tuiles_'$L_TYPE'/'${DATE_YMD}'/'${Z}'/'${X} |
| 196 | + mkdir $REPER'/tuiles/tuiles_'$L_TYPE'/'${DATE_YMD}'/'${Z}'/'${X}'/'${Y} |
| 197 | + |
| 198 | + # TELECHARGEMENT DES TUILES |
| 199 | + curl -w "%{http_code}" $URL --max-time 120 --connect-timeout 60 -o $REPER'/tuiles/tuiles_'$L_TYPE'/'${DATE_YMD}'/'${Z}'/'${X}'/'${Y}'/'$MVT_FILE |
| 200 | + |
| 201 | + # FUSION EN GPKG |
| 202 | + ogr2ogr \ |
| 203 | + -progress \ |
| 204 | + -f 'GPKG' \ |
| 205 | + -update -append \ |
| 206 | + --debug ON \ |
| 207 | + -lco SPATIAL_INDEX=YES \ |
| 208 | + $file \ |
| 209 | + $REPER'/tuiles/tuiles_'$L_TYPE'/'${DATE_YMD}'/'${Z}'/'${X}'/'${Y}'/'$MVT_FILE $LAYER \ |
| 210 | + -nlt PROMOTE_TO_MULTI \ |
| 211 | + -oo x=${X} -oo y=${Y} -oo z=${Z} |
| 212 | + |
| 213 | + done |
| 214 | +done |
| 215 | +``` |
| 216 | + |
| 217 | +### Import dans une base de données PostgreSQL/PostGIS |
| 218 | + |
| 219 | +Après avoir extrait les données vectorielles des tuiles vectorielles, il ne nous reste plus qu'à les intégrer dans notre base de données PostgreSQL/PostGIS à l'aide d'`ogr2ogr`. |
| 220 | + |
| 221 | +``` bash |
| 222 | +ogr2ogr \ |
| 223 | + -append \ |
| 224 | + -f "PostgreSQL" PG:"service='$C_SERVICE' schemas='$C_SCHEMA'" \ |
| 225 | + -nln 'mapillary_vt_signalisation' \ |
| 226 | + -s_srs 'EPSG:3857' \ |
| 227 | + -t_srs 'EPSG:2154' \ |
| 228 | + $file 'traffic_sign' \ |
| 229 | + -where "last_seen_at>$DATE_EPOCH" \ |
| 230 | + -dialect SQLITE \ |
| 231 | + --config OGR_TRUNCATE YES \ |
| 232 | + --debug ON \ |
| 233 | + --config CPL_LOG './'$REPER_LOGS'/'$DATE_YMD'_mapillary_vt_signalisation.log' |
| 234 | +``` |
| 235 | + |
| 236 | +[Accéder au script complet :fontawesome-regular-file-code:](https://github.com/igeofr/mapillary2pg/blob/main/mapillary_vt2pg.sh){: .md-button } |
| 237 | +{: align=middle } |
| 238 | + |
| 239 | +### Exécution |
| 240 | + |
| 241 | +Maintenant que le fichier de configuration est complété et que vous avez bien compris le principe du script `mapillary_vt2pg.sh`, vous allez pouvoir lancer le script de cette manière pour récupérer les données qui vous intéressent dans PostgreSQL/PostGIS. |
| 242 | + |
| 243 | +```bash |
| 244 | +sh mapillary_vt2pg.sh image |
| 245 | +sh mapillary_vt2pg.sh point |
| 246 | +sh mapillary_vt2pg.sh signalisation |
| 247 | +``` |
| 248 | + |
| 249 | +### Rendu |
| 250 | + |
| 251 | +Pour terminer, on peut charger la donnée dans QGIS et créer un style en s'appuyant sur les [symboles partagés par Mapillary](https://github.com/mapillary/mapillary_sprite_source). |
| 252 | + |
| 253 | +[{: .img-center loading=lazy }](https://cdn.geotribu.fr/img/articles-blog-rdp/articles/mapillary_data/signalisation.png "Signalisation"){: data-mediabox="gallery-lightbox" data-title="Signalisation" } |
| 254 | + |
| 255 | +---- |
| 256 | + |
| 257 | +## Conclusion |
| 258 | + |
| 259 | +Grâce aux capacités de rendu des tuiles vectorielles de QGIS, il est possible de filtrer et personnaliser les données de Mapillary en fonction des besoins, tout en ayant accès à l'information en quasi temps réel. |
| 260 | + |
| 261 | +En parallèle et pour d'autres usages, le script de téléchargement des données va vous permettre de stocker l'information dans votre base de données afin qu'elle puisse : |
| 262 | + |
| 263 | +1. bénéficier à vos services concernés (services techniques, voirie...), |
| 264 | +2. contribuer à améliorer la qualité de vos données. |
| 265 | + |
| 266 | +---- |
| 267 | + |
| 268 | +## Références |
| 269 | + |
| 270 | +- Un article de Morgan Hite sur son blog : [QGIS 3 and Vector map tiles](https://wanderingcartographer.wordpress.com/2021/01/09/qgis-3-and-vector-map-tiles/) |
| 271 | +- [De l'intérêt de mettre en place un "streetview" libre](https://prezi.com/p/ufcelyteyqzc/n-street-view-libre_retour_experience_grandmontauban_aitf/) par J. Sidgwick, CA du Grand Montauban |
| 272 | + |
| 273 | +---- |
| 274 | + |
| 275 | +## Auteur {: data-search-exclude } |
| 276 | + |
| 277 | +--8<-- "content/team/fbor.md" |
| 278 | + |
| 279 | +{% include "licenses/default.md" %} |
0 commit comments