[{"data":1,"prerenderedAt":200},["ShallowReactive",2],{"$f3PG5vTfZ46bQDb8qhkyyxGFDGppAcmvXeWCcq0GDBpc":3},[4],{"id":5,"date":6,"date_gmt":7,"guid":8,"modified":10,"modified_gmt":11,"slug":12,"status":13,"type":14,"link":15,"title":16,"content":18,"excerpt":21,"author":23,"featured_media":24,"comment_status":25,"ping_status":25,"sticky":20,"template":26,"format":27,"meta":28,"categories":29,"tags":31,"class_list":32,"_links":40,"_embedded":84},59,"2022-02-01T19:00:00","2022-02-01T18:00:00",{"rendered":9},"https:\u002F\u002Fcms.lcdev.fr\u002F?p=59","2026-07-08T16:49:50","2026-07-08T14:49:50","utiliser-les-donnees-osm-pour-connaitre-les-cols-et-sommets-franchis-a-partir-d-un-fichier-gpx","publish","post","https:\u002F\u002Fcms.lcdev.fr\u002Futiliser-les-donnees-osm-pour-connaitre-les-cols-et-sommets-franchis-a-partir-d-un-fichier-gpx\u002F",{"rendered":17},"Utiliser les données OSM pour connaître les cols et sommets franchis à partir d&rsquo;un fichier GPX",{"rendered":19,"protected":20},"\n\u003Cp class=\"wp-block-paragraph\">Chaque année, je passe des cols et gravit des sommets à pied (trail \u002F randonnée) ou à vélo de route. J&rsquo;enregistre chacune de mes sorties avec une montre Suunto ou mon téléphone et synchronise le tout sur Strava. Toutes mes activités sportives sont donc sur le web et en fin d&rsquo;année, j&rsquo;aimerai bien me faire un petit récap pour me remémorer où je suis passé sans me palucher toutes mes sorties. Après un peu de recherche et quelques lignes de codes, je peux désormais faire ça facilement. C&rsquo;est parti pour les explications !\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">Récupérer les POIs où j’ai pu passer\u003C\u002Fh2>\n\n\n\n\u003Ch3 class=\"wp-block-heading\">\u003Cstrong>Données OpenStreetMap\u003C\u002Fstrong>\u003C\u002Fh3>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">La première chose à faire, c’est de récupérer tous les POIs (Point Of Intereset ; dans mon cas les cols et sommet) où j’aurai pu passer, avec leurs coordonnées géographiques (latitude \u002F longitude).\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Pour avoir ce genre de données, il existe un super projet opensource qui est la base d’une bonne partie des projets cartographiques sur le Web : OpenStreetMap.\u003C\u002Fp>\n\n\n\n\u003Cfigure class=\"wp-block-image size-full\">\u003Cimg loading=\"lazy\" decoding=\"async\" width=\"285\" height=\"42\" src=\"http:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fpropulse-par-osm.png\" alt=\"\" class=\"wp-image-24\"\u002F>\u003C\u002Ffigure>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">\u003Cem>Le service Mapbox utilise les données OSM pour générer ses cartes\u003C\u002Fem>\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">\u003Ca href=\"https:\u002F\u002Fwww.openstreetmap.org\u002F\">OpenStreetMap.org\u003C\u002Fa>, propose d’exporter toutes les informations d’une zone affichée à l’écran. Malheureusement, cette zone est limitée en taille et impossible pour moi d’exporter tous les massifs où je me suis rendu, à moins de le faire en plusieurs fois. Je me suis donc tourné vers Geofabrik qui propose de télécharger toutes les données d’un pays ou d’une région.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">A noter que les exports OpenStreetMap se font au format .OSM, qui sont des fichiers XML, qu’on peut lire facilement avec n’importe quel langage de programmation.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Geofabrik lui, propose les données au format .pbf, qui est un format compilé. Enfaite, ils ont été obligés de compiler les données car rien que l&rsquo;Europe c&rsquo;est presque 25Go donc imaginez en bon vieux XML&#8230;\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">J’ai donc récupéré le fichier Rhône-Alpes étant donné que 99.5% de mes sorties étaient dans cette zone.\u003C\u002Fp>\n\n\n\n\u003Ch3 class=\"wp-block-heading\">Serveur MongoDB avec Docker\u003C\u002Fh3>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Pour stocker tous les POIs qui m’intéressent, j’ai fait le choix d’une base de données NoSQL MongoDB. À la base, j’avais fait ce choix car MongoDB propose des fonctionnalités géographiques sans installer quoi que ce soit en plus, mais finalement je n’en aurai pas eu besoin. Autre avantage, c&rsquo;est que je ne perdrai pas de temps à imaginer une structure de données au préalable (MongoDB est « schemaless »).\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Pour avoir un serveur MongoDB avec Docker :\u003C\u002Fp>\n\n\n\n\u003Cpre class=\"wp-block-code\">\u003Ccode>docker run -p 27017:27017 -v \u002Fopt\u002Fmongodb\u002Fdb:\u002Fdata\u002Fdb --name my-mongo -d mongo\u003Cbr>​\u003Cbr>Explication :\u003Cbr>-p 27017:27017 pour mapper le port 27017 (port par défaut de mongoDB) du container avec le 27017 du host\u003Cbr>-v \u002Fopt\u002Fmongodb\u002Fdb:\u002Fdata\u002Fdb pour indiquer où stocker les données et ne pas les perdre au redémarrage de la machine \u002F du container\u003Cbr>--name my-mongo un jolie nom à notre container\u003Cbr>-d pour détacher le container du terminal\u003Cbr>mongo le nom de l'image utilisé\u003C\u002Fcode>\u003C\u002Fpre>\n\n\n\n\u003Ch3 class=\"wp-block-heading\">Comment se présente un fichier OSM ?\u003C\u002Fh3>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Avant de lire le fichier de données, il me semble intéressant d&rsquo;expliquer rapidement ce qu&rsquo;il contient pour mieux comprendre la suite des explications.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Comme je le disais plus haut, les fichiers OSM sont des fichiers au format XML. Ils contiennent :\u003C\u002Fp>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>des nœuds (un point avec une latitude et une longitude)\u003C\u002Fli>\n\n\n\n\u003Cli>des chemins (ensemble de nœuds)\u003C\u002Fli>\n\n\n\n\u003Cli>des relations (ensemble de nœuds et chemin pour décrire une ligne de bus par exemple)\u003C\u002Fli>\n\u003C\u002Ful>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Ces éléments peuvent avoir des tags qui donnent des informations supplémentaires. Voilà comment se présente le nœud du Mont Ventoux :\u003C\u002Fp>\n\n\n\n\u003Cpre class=\"wp-block-code\">\u003Ccode> &lt;node id=\"411436529\" visible=\"true\" version=\"7\" changeset=\"75561193\" timestamp=\"2019-10-11T11:51:34Z\" user=\"mirelon\" uid=\"1270972\" lat=\"44.1739649\" lon=\"5.2783976\"&gt;\u003Cbr> &nbsp;&lt;tag k=\"alt_name\" v=\"Le Sommet\"\u002F&gt;\u003Cbr> &nbsp;&lt;tag k=\"ele\" v=\"1909\"\u002F&gt;\u003Cbr> &nbsp;&lt;tag k=\"name\" v=\"Mont Ventoux\"\u002F&gt;\u003Cbr> &nbsp;&lt;tag k=\"natural\" v=\"peak\"\u002F&gt;\u003Cbr> &nbsp;&lt;tag k=\"prominence\" v=\"1150\"\u002F&gt;\u003Cbr> &nbsp;&lt;tag k=\"source\" v=\"cadastre-dgi-fr source : Direction Générale des Impôts - Cadastre\"\u002F&gt;\u003Cbr> &nbsp;&lt;tag k=\"tourism\" v=\"attraction\"\u002F&gt;\u003Cbr> &nbsp;&lt;tag k=\"website\" v=\"http:\u002F\u002Fwww.veloventoux.com\u002F?c=montVentoux\"\u002F&gt;\u003Cbr> &nbsp;&lt;tag k=\"wikidata\" v=\"Q209064\"\u002F&gt;\u003Cbr> &nbsp;&lt;tag k=\"wikipedia\" v=\"fr:Mont Ventoux\"\u002F&gt;\u003Cbr> &lt;\u002Fnode&gt;\u003C\u002Fcode>\u003C\u002Fpre>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Les fichiers .PBF retrouvent les mêmes informations, ils ont juste été compilé et demande à être décompilé pour être lu.\u003C\u002Fp>\n\n\n\n\u003Ch3 class=\"wp-block-heading\">Extraire les cols et sommets de la région Rhône-Alpes\u003C\u002Fh3>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">J’ai choisi le langage Python et le package \u003Ccode>osmiter\u003C\u002Fcode> pour lire le fichier binaire .pbf et en extraire tous les cols et sommets pour les stocker dans la base de données. L’occasion pour moi de changer un peu de langage (et de galérer aussi !). Pardonnez-moi d’avance si ce code n’est pas des plus beaux 😄\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">J&rsquo;ai donc écrit un programme qui lit chaque nœud du fichier rhone-alpes-latest.osm.pbf. Pour chaque nœud qui possède le tag \u003Ccode>natural\u003C\u002Fcode> avec pour valeur \u003Ccode>saddle\u003C\u002Fcode> (= col) ou \u003Ccode>peak\u003C\u002Fcode> (=sommet) et qui ont un nom (il y a des sommets ou cols sans nom parfois mais ça ne m&rsquo;intéresse guère), je l’insère dans un tableau. Tous les 100 POIs, j’envoie le tableau en base de données. Sur environ 4500 points d&rsquo;intérêts ça permet d’éviter 4500 appels à la base de données et de réduire ça à 450. Bon, c’était plus pour le fun car on fera ce processus une seul fois donc l’intérêt reste limité.\u003C\u002Fp>\n\n\n\n\u003Cpre class=\"wp-block-code\">\u003Ccode>#!\u002Fusr\u002Fbin\u002Fpython3\u003Cbr># coding: utf-8\u003Cbr>​\u003Cbr>from pymongo import MongoClient\u003Cbr>import osmiter\u003Cbr>​\u003Cbr>client = MongoClient(host=\"localhost\", port=27017)\u003Cbr>​\u003Cbr>db = client.osm\u003Cbr>poi = db.poi\u003Cbr>​\u003Cbr>results = &#91;]\u003Cbr>for feature in osmiter.iter_from_osm(\"rhone-alpes-latest.osm.pbf\"):\u003Cbr> &nbsp; &nbsp;if feature&#91;\"type\"] == \"node\" and \"natural\" in feature&#91;\"tag\"]:\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp;if feature&#91;\"tag\"]&#91;\"natural\"] in &#91;\"saddle\", \"peak\"] and \"name\" in feature&#91;\"tag\"]:\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;results.append({\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'name': feature&#91;\"tag\"]&#91;\"name\"],\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'type': feature&#91;\"tag\"]&#91;'natural'],\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\"coord\": &#91;feature&#91;\"lat\"], feature&#91;\"lon\"]],\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  })\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp;if len(results) == 100:\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;db.poi.insert_many(results)\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;results = &#91;]\u003Cbr>​\u003Cbr>db.poi.insert_many(results)\u003Cbr>print(str(db.poi.count()) + \" POIs extracted !\")\u003C\u002Fcode>\u003C\u002Fpre>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Après quelques minutes de traitement, notre base de données se retrouve avec 4593 POIs. C’est beau l’Auvergne Rhône Alpes et bien rempli de cols &amp; sommets !\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">Comparer les POIs avec mes traces GPS\u003C\u002Fh2>\n\n\n\n\u003Ch3 class=\"wp-block-heading\">Demander ses données Strava\u003C\u002Fh3>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Comme je le disais en introduction, toutes mes traces d&rsquo;activités sportives sont sur Strava. Une aubaine car Strava propose de télécharger une archive contenant toutes ses informations.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Dans : Paramètres -&gt; Mon compte -&gt; Télécharger ou supprimer le compte -&gt; Commencer -&gt; Demander une archive.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Au bout de quelques minutes, je reçois par mail une archive avec toutes mes données. L&rsquo;archive contient un dossier \u003Cem>activities\u003C\u002Fem> qui lui-même contient les fichiers de toutes mes activités. Etant donné que cela fait plusieurs années que j&rsquo;utilise Strava, j&rsquo;ai plusieurs années d&rsquo;activités. Je me suis servi du fichier \u003Cem>activities.csv\u003C\u002Fem> pour faire le trie et garder uniquement les fichiers de l&rsquo;année 2021.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">J&rsquo;avais des fichiers (pas tous, c&rsquo;est assez curieux) compressé en gzip. Pour dézipper tous les fichiers gzippé :\u003C\u002Fp>\n\n\n\n\u003Cpre class=\"wp-block-code\">\u003Ccode>gunzip *.gz\u003C\u002Fcode>\u003C\u002Fpre>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">J&rsquo;avais également des fichiers au format .fit. C&rsquo;est (encore!) un fichier compilé. J&rsquo;ai converti ça en .gpx (pour obtenir un fichier XML lisible sans passer par un package) à l&rsquo;aide du soft \u003Cem>gpsbabel\u003C\u002Fem>.\u003C\u002Fp>\n\n\n\n\u003Cpre class=\"wp-block-code\">\u003Ccode>sudo apt-get install gpsbabel\u003C\u002Fcode>\u003C\u002Fpre>\n\n\n\n\u003Cpre class=\"wp-block-code\">\u003Ccode>for file in *.fit; do \u003Cbr> &nbsp; &nbsp;if &#91; -f \"$file\" ]; then \u003Cbr> &nbsp; &nbsp; &nbsp;  gpsbabel -i garmin_fit -f $file -o gpx -F $file.gpx \u003Cbr> &nbsp; &nbsp;fi \u003Cbr>done\u003C\u002Fcode>\u003C\u002Fpre>\n\n\n\n\u003Ch3 class=\"wp-block-heading\">Comparer ses traces avec les POIs\u003C\u002Fh3>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Il ne me restait plus qu&rsquo;à écrire un script qui lise mes fichiers GPX et regarde près de quel point je suis passé. J&rsquo;ai choisi de continuer en Python, et voici le code final :\u003C\u002Fp>\n\n\n\n\u003Cpre class=\"wp-block-code\">\u003Ccode>#!\u002Fusr\u002Fbin\u002Fpython3\u003Cbr># coding: utf-8\u003Cbr>​\u003Cbr>from xml.dom import minidom\u003Cbr>from pymongo import MongoClient\u003Cbr>from haversine import haversine\u003Cbr>import csv\u003Cbr>import os\u003Cbr>​\u003Cbr>def extract(path, distanceAccepted):\u003Cbr> &nbsp; &nbsp;# 1. Extract all point of .gpx file &amp; date of first point\u003Cbr> &nbsp; &nbsp;gpxPoints = &#91;]\u003Cbr> &nbsp; &nbsp;xmldoc = minidom.parse(path)\u003Cbr>​\u003Cbr> &nbsp; &nbsp;date = xmldoc.getElementsByTagName('time')&#91;1].firstChild.nodeValue\u003Cbr>​\u003Cbr> &nbsp; &nbsp;for point in xmldoc.getElementsByTagName('trkpt'):\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp;gpxPoints.append({\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'lat': float(point.attributes&#91;'lat'].value),\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'lon': float(point.attributes&#91;'lon'].value),\u003Cbr> &nbsp; &nbsp; &nbsp;  })\u003Cbr>​\u003Cbr> &nbsp; &nbsp;# 2. Search max point\u003Cbr> &nbsp; &nbsp;seq = &#91;x&#91;'lat'] for x in gpxPoints]\u003Cbr> &nbsp; &nbsp;maxlat = max(seq)\u003Cbr> &nbsp; &nbsp;minlat = min(seq)\u003Cbr>​\u003Cbr> &nbsp; &nbsp;seq = &#91;x&#91;'lon'] for x in gpxPoints]\u003Cbr> &nbsp; &nbsp;minlon = min(seq)\u003Cbr> &nbsp; &nbsp;maxlon = max(seq)\u003Cbr>​\u003Cbr> &nbsp; &nbsp;# 3. Get all POIs in this perimeters\u003Cbr> &nbsp; &nbsp;client = MongoClient(host=\"localhost\", port=27017)\u003Cbr> &nbsp; &nbsp;db = client.osm\u003Cbr>​\u003Cbr> &nbsp; &nbsp;pois = db.poi.find(\u003Cbr> &nbsp; &nbsp; &nbsp;  {\"coord.0\": {\"$gt\": float(minlat), \"$lt\": float(maxlat)},\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; \"coord.1\": {\"$gt\": float(minlon), \"$lt\": float(maxlon)}}\u003Cbr> &nbsp;  )\u003Cbr>​\u003Cbr> &nbsp; &nbsp;# 4. Compare points with OSM point\u003Cbr> &nbsp; &nbsp;for osmPoint in pois:\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp;mostNear = &#91;]\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp;osmObject = (osmPoint&#91;'coord']&#91;0], osmPoint&#91;'coord']&#91;1])\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp;for point in gpxPoints:\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mostNear.append(haversine(osmObject, (point&#91;\"lat\"], point&#91;\"lon\"]), unit='m'))\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp;if mostNear and min(mostNear) &lt; distanceAccepted:\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;with open('results_'+str(distanceAccepted)+'m.csv', 'a') as file:\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;writer = csv.writer(file)\u003Cbr> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;writer.writerow(&#91;date, osmPoint&#91;\"name\"], str(round(min(mostNear), 0))])\u003Cbr>​\u003Cbr>for filename in os.listdir(\"activities\"):\u003Cbr> &nbsp; &nbsp;print(\"Treat \" + filename)\u003Cbr> &nbsp; &nbsp;extract(\".\u002Factivities\u002F\" + filename, 20)\u003C\u002Fcode>\u003C\u002Fpre>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Quelques explications du script :\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Pour chaque fichier présent dans le dossier \u003Cem>activities\u003C\u002Fem>, j&rsquo;appelle la fonction extract avec en paramètre le path du fichier ainsi que la distance en mètre maximum entre un POIs et la trace pour qu&rsquo;on considère que je suis passé par ce point.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">La fonction extract() est assez simple mais voici quelques explications. Je récupère chaque point (une latitude et une longitude) du fichier dans un tableau gpxPoints. Je récupère ensuite la latitude et la longitude maximal et minimal. Je requête ensuite la base de données qui contient tous les POIs de la région Rhône Alpes pour récupèrer tous les POIs situé entre ces latitudes et longitudes maximales\u002Fminimales. Je finis par comparer chaque POIs aux coordonnées de ma trace. La fonction haversine() permet de calculer la distance entre 2 points à partir de coordonnées géographique. Si un des points de ma trace c&rsquo;est trouvé à moins de X mètres du POIs, alors on ajoute la date, le nom du POIs et la plus petite distance entre lui et la trace dans un fichier CSV.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Note : j&rsquo;ai utilisé minidom plutôt que xml.etree.ElementTree car j&rsquo;ai longtemps galéré pour récupérer tous les élements trkpt du fichier .gpx jusqu&rsquo;à renoncer et opter pour minidom.\u003C\u002Fp>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">Resultat\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Il ne reste plus qu&rsquo;à ouvrir le fichier .csv, trié par date et voilà le résultat :\u003C\u002Fp>\n\n\n\n\u003Cfigure class=\"wp-block-image size-full\">\u003Cimg loading=\"lazy\" decoding=\"async\" width=\"377\" height=\"226\" src=\"http:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fresultats-osm.png\" alt=\"\" class=\"wp-image-25\" srcset=\"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fresultats-osm.png 377w, https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fresultats-osm-300x180.png 300w\" sizes=\"auto, (max-width: 377px) 100vw, 377px\" \u002F>\u003C\u002Ffigure>\n\n\n\n\u003Ch2 class=\"wp-block-heading\">Limitations\u003C\u002Fh2>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Après avoir fait plusieurs essais, la distance maximum optimale pour déterminer qu&rsquo;on est passé par un POIs me semble être de 20m. Cela peut paraître énorme mais c&rsquo;est dû à deux facteurs :\u003C\u002Fp>\n\n\n\n\u003Col class=\"wp-block-list\">\n\u003Cli>la précision de nos GPS\u003C\u002Fli>\n\n\n\n\u003Cli>la précision des POIs\u003C\u002Fli>\n\u003C\u002Fol>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">L&rsquo;addition de ces deux facteurs donne lieu à pas mal d&rsquo;imprécision. Si l&rsquo;on prend le « col de la Cochette » où je suis passé plusieurs fois par exemple, on se demande où peut bien être ce col.\u003C\u002Fp>\n\n\n\n\u003Cfigure class=\"wp-block-image size-full\">\u003Cimg loading=\"lazy\" decoding=\"async\" width=\"788\" height=\"451\" src=\"http:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-osm-1.png\" alt=\"Passage n°1 au col de la Cochette\" class=\"wp-image-13\" srcset=\"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-osm-1.png 788w, https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-osm-1-300x172.png 300w, https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-osm-1-768x440.png 768w\" sizes=\"auto, (max-width: 788px) 100vw, 788px\" \u002F>\u003C\u002Ffigure>\n\n\n\n\u003Cfigure class=\"wp-block-image size-full\">\u003Cimg loading=\"lazy\" decoding=\"async\" width=\"789\" height=\"451\" src=\"http:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-osm-2.png\" alt=\"Passage n°2 au col de la Cochette\" class=\"wp-image-14\" srcset=\"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-osm-2.png 789w, https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-osm-2-300x171.png 300w, https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-osm-2-768x439.png 768w\" sizes=\"auto, (max-width: 789px) 100vw, 789px\" \u002F>\u003C\u002Ffigure>\n\n\n\n\u003Cfigure class=\"wp-block-image size-full\">\u003Cimg loading=\"lazy\" decoding=\"async\" width=\"782\" height=\"453\" src=\"http:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-osm-3.png\" alt=\"Passage n°3 au col de la Cochette\" class=\"wp-image-15\" srcset=\"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-osm-3.png 782w, https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-osm-3-300x174.png 300w, https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-osm-3-768x445.png 768w\" sizes=\"auto, (max-width: 782px) 100vw, 782px\" \u002F>\u003C\u002Ffigure>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Lorsque l&rsquo;on contribue au projet OSM pour placer des points ou tracer des chemins, on peut s&rsquo;aider de photographies satellites. Malheureusement, ce col est en pleine forêt.. Dur dur de placer le point avec précision.\u003C\u002Fp>\n\n\n\n\u003Cfigure class=\"wp-block-image size-full\">\u003Cimg loading=\"lazy\" decoding=\"async\" width=\"789\" height=\"509\" src=\"http:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-satellite.png\" alt=\"Col de la Cochette sur image satellite\" class=\"wp-image-16\" srcset=\"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-satellite.png 789w, https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-satellite-300x194.png 300w, https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fcol-cochette-satellite-768x495.png 768w\" sizes=\"auto, (max-width: 789px) 100vw, 789px\" \u002F>\u003C\u002Ffigure>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Il pourrait également être intéressant de rajouter lors de l&rsquo;extraction des POIs les entrées de grottes (tag natural avec pour valeur cave_entrance), les glaciers (tag natural ; valeur glacier) les lacs (tag natural ; valeur water) ou encore les croix (tag man_made ; valeur cross).\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Attention pour les lacs : j&rsquo;habite près du Lac du Bourget et il m&rsquo;arrive plusieurs fois dans la saison d&rsquo;aller courir au bord de celui-ci. Autant dire qu&rsquo;il risque de ressortir plusieurs fois dans le fichier. Mais c&rsquo;est le seul moyen pour détecter quand on est passé aux abords d&rsquo;un lac de montagne.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Pour finir, il y a certaines randonnées où l&rsquo;intérêt réside dans le chemin (chemin de l&rsquo;ancienne crémaillère du Revard par exemple) et aucun POIs n&rsquo;est rencontré. Les balades sur ces chemins ne pourront malheureusement pas ressortir dans le fichier final.\u003C\u002Fp>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Hormis ces petits aléas, je suis vraiment content de ce projet qui m&rsquo;a permis de découvrir un peu OpenStreetMap et c&rsquo;est vraiment le feu tant il y a de projets possibles autour des données cartographiques. J&rsquo;ai également pu contribuer en ajoutant quelques chemins et c&rsquo;est plutôt plaisant de les voir appaître dans les applications de tracé de parcours et de pouvoir s&rsquo;en servir.\u003C\u002Fp>\n",false,{"rendered":22,"protected":20},"\u003Cp>Développement en Python d&rsquo;un petit script capable de détecter les cols et sommets franchis à partir de trace GPS.\u003C\u002Fp>\n",1,17,"open","","standard",{"footnotes":26},[30],7,[],[33,14,34,35,36,37,38,39],"post-59","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-python",{"self":41,"collection":47,"about":50,"author":53,"replies":57,"version-history":60,"predecessor-version":63,"wp:featuredmedia":67,"wp:attachment":70,"wp:term":73,"curies":80},[42],{"href":43,"targetHints":44},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts\u002F59",{"allow":45},[46],"GET",[48],{"href":49},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts",[51],{"href":52},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Ftypes\u002Fpost",[54],{"embeddable":55,"href":56},true,"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fusers\u002F1",[58],{"embeddable":55,"href":59},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fcomments?post=59",[61],{"count":23,"href":62},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts\u002F59\u002Frevisions",[64],{"id":65,"href":66},60,"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts\u002F59\u002Frevisions\u002F60",[68],{"embeddable":55,"href":69},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fmedia\u002F17",[71],{"href":72},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fmedia?parent=59",[74,77],{"taxonomy":75,"embeddable":55,"href":76},"category","https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fcategories?post=59",{"taxonomy":78,"embeddable":55,"href":79},"post_tag","https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Ftags?post=59",[81],{"name":82,"href":83,"templated":55},"wp","https:\u002F\u002Fapi.w.org\u002F{rel}",{"author":85,"wp:featuredmedia":102,"wp:term":176},[86],{"id":23,"name":87,"url":88,"description":26,"link":89,"slug":87,"avatar_urls":90,"_links":94},"lcdev","http:\u002F\u002Fcms.lcdev.fr","https:\u002F\u002Fcms.lcdev.fr\u002Fauthor\u002Flcdev\u002F",{"24":91,"48":92,"96":93},"https:\u002F\u002Fsecure.gravatar.com\u002Favatar\u002F8578aee4d4c25728b0f2cb389c2c80a414b27a57d2a499ce695a879ec3e1fd97?s=24&d=mm&r=g","https:\u002F\u002Fsecure.gravatar.com\u002Favatar\u002F8578aee4d4c25728b0f2cb389c2c80a414b27a57d2a499ce695a879ec3e1fd97?s=48&d=mm&r=g","https:\u002F\u002Fsecure.gravatar.com\u002Favatar\u002F8578aee4d4c25728b0f2cb389c2c80a414b27a57d2a499ce695a879ec3e1fd97?s=96&d=mm&r=g",{"self":95,"collection":99},[96],{"href":56,"targetHints":97},{"allow":98},[46],[100],{"href":101},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fusers",[103],{"id":24,"date":104,"slug":105,"type":106,"link":107,"title":108,"author":23,"featured_media":109,"caption":110,"alt_text":26,"media_type":111,"mime_type":112,"media_details":113,"source_url":150,"_links":154},"2026-07-06T15:26:42","connaitre-cols-sommets-franchis-python-openstreetmap","attachment","https:\u002F\u002Fcms.lcdev.fr\u002Fformulaire-elementor-wordpress-0-spam-avec-cette-methode\u002Fconnaitre-cols-sommets-franchis-python-openstreetmap\u002F",{"rendered":105},0,{"rendered":26},"image","image\u002Fpng",{"width":114,"height":115,"file":116,"filesize":117,"sizes":118,"image_meta":151},1920,1080,"2026\u002F07\u002Fconnaitre-cols-sommets-franchis-python-openstreetmap.png",108924,{"medium":119,"large":125,"thumbnail":131,"medium_large":136,"1536x1536":142,"full":148},{"file":120,"width":121,"height":122,"filesize":123,"mime_type":112,"source_url":124},"connaitre-cols-sommets-franchis-python-openstreetmap-300x169.png",300,169,16858,"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fconnaitre-cols-sommets-franchis-python-openstreetmap-300x169.png",{"file":126,"width":127,"height":128,"filesize":129,"mime_type":112,"source_url":130},"connaitre-cols-sommets-franchis-python-openstreetmap-1024x576.png",1024,576,69926,"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fconnaitre-cols-sommets-franchis-python-openstreetmap-1024x576.png",{"file":132,"width":133,"height":133,"filesize":134,"mime_type":112,"source_url":135},"connaitre-cols-sommets-franchis-python-openstreetmap-150x150.png",150,11781,"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fconnaitre-cols-sommets-franchis-python-openstreetmap-150x150.png",{"file":137,"width":138,"height":139,"filesize":140,"mime_type":112,"source_url":141},"connaitre-cols-sommets-franchis-python-openstreetmap-768x432.png",768,432,48403,"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fconnaitre-cols-sommets-franchis-python-openstreetmap-768x432.png",{"file":143,"width":144,"height":145,"filesize":146,"mime_type":112,"source_url":147},"connaitre-cols-sommets-franchis-python-openstreetmap-1536x864.png",1536,864,106885,"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fconnaitre-cols-sommets-franchis-python-openstreetmap-1536x864.png",{"file":149,"width":114,"height":115,"mime_type":112,"source_url":150},"connaitre-cols-sommets-franchis-python-openstreetmap.png","https:\u002F\u002Fcms.lcdev.fr\u002Fwp-content\u002Fuploads\u002F2026\u002F07\u002Fconnaitre-cols-sommets-franchis-python-openstreetmap.png",{"aperture":152,"credit":26,"camera":26,"caption":26,"created_timestamp":152,"copyright":26,"focal_length":152,"iso":152,"shutter_speed":152,"title":26,"orientation":152,"keywords":153,"alt":26},"0",[],{"self":155,"collection":159,"about":162,"author":165,"replies":167,"wp:attached-to":170,"curies":174},[156],{"href":69,"targetHints":157},{"allow":158},[46],[160],{"href":161},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fmedia",[163],{"href":164},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Ftypes\u002Fattachment",[166],{"embeddable":55,"href":56},[168],{"embeddable":55,"href":169},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fcomments?post=17",[171],{"embeddable":55,"post_type":14,"id":172,"href":173},8,"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts\u002F8",[175],{"name":82,"href":83,"templated":55},[177,199],[178],{"id":30,"link":179,"name":180,"slug":181,"taxonomy":75,"_links":182},"https:\u002F\u002Fcms.lcdev.fr\u002Fcategory\u002Fpython\u002F","Python","python",{"self":183,"collection":188,"about":191,"wp:post_type":194,"curies":197},[184],{"href":185,"targetHints":186},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fcategories\u002F7",{"allow":187},[46],[189],{"href":190},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fcategories",[192],{"href":193},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Ftaxonomies\u002Fcategory",[195],{"href":196},"https:\u002F\u002Fcms.lcdev.fr\u002Fwp-json\u002Fwp\u002Fv2\u002Fposts?categories=7",[198],{"name":82,"href":83,"templated":55},[],1785314930927]