Compare commits
No commits in common. "e1b8f087249eb897083450722b78db73ab935db6" and "d86208190f1de942b4a53d5c1cd25e2a8af8d66a" have entirely different histories.
e1b8f08724
...
d86208190f
12
README.md
12
README.md
@ -2,12 +2,6 @@
|
|||||||
|
|
||||||
Récupération de Données OSM via Overpass
|
Récupération de Données OSM via Overpass
|
||||||
|
|
||||||
## Prérequis
|
|
||||||
`pip3 install requests`
|
|
||||||
|
|
||||||
`pip3 install pyexcel-ods3`
|
|
||||||
|
|
||||||
|
|
||||||
## But
|
## But
|
||||||
Ce script sert à récupérer (en JSON et tableau ods) les infos de stationnement vélo, d'ateliers, d'associations, vendeurs, réparateurs et fabricants de vélo.
|
Ce script sert à récupérer (en JSON et tableau ods) les infos de stationnement vélo, d'ateliers, d'associations, vendeurs, réparateurs et fabricants de vélo.
|
||||||
|
|
||||||
@ -45,11 +39,6 @@ Ces chemins sont relatifs à `rdoo.py`, il est possible de passer des chemins ab
|
|||||||
|
|
||||||
Il est possible de ne pas archiver en passant l'argument `-na, --no-archive`.
|
Il est possible de ne pas archiver en passant l'argument `-na, --no-archive`.
|
||||||
|
|
||||||
## Umap
|
|
||||||
Les fichiers json générés peuvent être directements utilisés dans [umap](https://umap.openstreetmap.fr/fr/) en les [important](https://wiki.openstreetmap.org/wiki/FR:UMap/Guide/Importer_un_fichier_de_donn%C3%A9es) et choisissant le format de données `osm`.
|
|
||||||
|
|
||||||
Si vous disposez d'un serveur pour héberger le script ou ses résultats, le lien du fichier peut être utilisé directement dans umap comme `données distantes` d'un calque, en cochant `dynamique` et `avec proxy`.
|
|
||||||
|
|
||||||
## Inspirations / ressources :
|
## Inspirations / ressources :
|
||||||
### urls ressources
|
### urls ressources
|
||||||
- https://towardsdatascience.com/loading-data-from-openstreetmap-with-python-and-the-overpass-api-513882a27fd0
|
- https://towardsdatascience.com/loading-data-from-openstreetmap-with-python-and-the-overpass-api-513882a27fd0
|
||||||
@ -66,6 +55,7 @@ penser à cocher "proxy" dans la rubrique "données distantes" du calque
|
|||||||
|
|
||||||
### export ODS :
|
### export ODS :
|
||||||
- https://pythonhosted.org/pyexcel-ods/
|
- https://pythonhosted.org/pyexcel-ods/
|
||||||
|
`pip3 install pyexcel-ods3`
|
||||||
|
|
||||||
|
|
||||||
## Licence
|
## Licence
|
||||||
|
@ -25,7 +25,6 @@ import os
|
|||||||
import datetime
|
import datetime
|
||||||
import shutil
|
import shutil
|
||||||
import pathlib
|
import pathlib
|
||||||
import csv
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import requests
|
import requests
|
||||||
from pyexcel_ods3 import save_data
|
from pyexcel_ods3 import save_data
|
||||||
@ -149,74 +148,77 @@ class Utils:
|
|||||||
|
|
||||||
return response.json()
|
return response.json()
|
||||||
|
|
||||||
def geocodage_csv(self, data):
|
def run_reverse_geocoding(self, lat, lon):
|
||||||
"""
|
"""Retourne une adresse JSON à partir d'une position GPS."""
|
||||||
Renseigne une adresse pour chaque élément de data
|
|
||||||
en une fois via csv
|
|
||||||
"""
|
|
||||||
|
|
||||||
url = self.geo_api_url + "/reverse/csv/"
|
url = self.geo_api_url + "/reverse/"
|
||||||
|
|
||||||
# création du fichier à envoyer à l'API
|
response = requests.get(url, params={"lon": str(lon), "lat": str(lat)})
|
||||||
with open("tmp_geocodage.csv", "w", newline="") as tmp_csv_file:
|
|
||||||
csv_writer = csv.writer(tmp_csv_file)
|
|
||||||
csv_writer.writerow(["lat", "lon"])
|
|
||||||
|
|
||||||
for element in data["elements"]:
|
|
||||||
if element["type"] == "node":
|
|
||||||
csv_writer.writerow([element["lat"], element["lon"]])
|
|
||||||
else:
|
|
||||||
csv_writer.writerow(
|
|
||||||
[element["center"]["lat"], element["center"]["lon"]]
|
|
||||||
)
|
|
||||||
|
|
||||||
# préparation et envoi de la requête
|
|
||||||
payload = dict(
|
|
||||||
[("data", ("tmp_geocodage.csv", open("tmp_geocodage.csv", "rb").read()))]
|
|
||||||
)
|
|
||||||
response = requests.post(url, files=payload)
|
|
||||||
|
|
||||||
# nettoyage
|
|
||||||
os.remove("tmp_geocodage.csv")
|
|
||||||
|
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
raise errors.GeoApiError(response.status_code)
|
raise errors.GeoApiError(response.status_code)
|
||||||
|
|
||||||
# affectation des addresses
|
return response.json()
|
||||||
for element in data["elements"]:
|
|
||||||
for row in csv.DictReader(response.text.splitlines()):
|
|
||||||
if element["type"] == "node":
|
|
||||||
lat_ok = row["lat"] == str(element["lat"])
|
|
||||||
lon_ok = row["lon"] == str(element["lon"])
|
|
||||||
else:
|
|
||||||
lat_ok = row["lat"] == str(element["center"]["lat"])
|
|
||||||
lon_ok = row["lon"] == str(element["center"]["lon"])
|
|
||||||
|
|
||||||
if lat_ok and lon_ok:
|
def geocodage(self, data):
|
||||||
element["tags"]["api_adresse:geometry:coordinates:lon"] = row[
|
"""Renseigne une adresse pour chaque élément de data"""
|
||||||
"result_longitude"
|
|
||||||
]
|
for element in data["elements"]:
|
||||||
element["tags"]["api_adresse:geometry:coordinates:lat"] = row[
|
|
||||||
"result_latitude"
|
if element["type"] == "node":
|
||||||
]
|
rev_geocode = self.run_reverse_geocoding(element["lat"], element["lon"])
|
||||||
element["tags"]["api_adresse:properties:label"] = row[
|
else:
|
||||||
"result_label"
|
rev_geocode = self.run_reverse_geocoding(
|
||||||
]
|
element["center"]["lat"], element["center"]["lon"]
|
||||||
element["tags"]["api_adresse:properties:housenumber"] = row[
|
)
|
||||||
"result_housenumber"
|
|
||||||
]
|
api_adresse = rev_geocode["features"][0]
|
||||||
element["tags"]["api_adresse:properties:type"] = row["result_type"]
|
|
||||||
element["tags"]["api_adresse:properties:name"] = row["result_name"]
|
element["tags"]["api_adresse:geometry:coordinates:lon"] = api_adresse[
|
||||||
element["tags"]["api_adresse:properties:postcode"] = row[
|
"geometry"
|
||||||
"result_postcode"
|
]["coordinates"][0]
|
||||||
]
|
element["tags"]["api_adresse:geometry:coordinates:lat"] = api_adresse[
|
||||||
element["tags"]["api_adresse:properties:citycode"] = row[
|
"geometry"
|
||||||
"result_citycode"
|
]["coordinates"][1]
|
||||||
]
|
|
||||||
element["tags"]["api_adresse:properties:city"] = row["result_city"]
|
element["tags"]["api_adresse:properties:label"] = api_adresse["properties"][
|
||||||
element["tags"]["api_adresse:properties:street"] = row[
|
"label"
|
||||||
"result_street"
|
]
|
||||||
]
|
element["tags"]["api_adresse:properties:score"] = api_adresse["properties"][
|
||||||
|
"score"
|
||||||
|
]
|
||||||
|
|
||||||
|
if "housenumber" in api_adresse["properties"]:
|
||||||
|
element["tags"]["api_adresse:properties:housenumber"] = api_adresse[
|
||||||
|
"properties"
|
||||||
|
]["housenumber"]
|
||||||
|
|
||||||
|
element["tags"]["api_adresse:properties:type"] = api_adresse["properties"][
|
||||||
|
"type"
|
||||||
|
]
|
||||||
|
|
||||||
|
element["tags"]["api_adresse:properties:name"] = api_adresse["properties"][
|
||||||
|
"name"
|
||||||
|
]
|
||||||
|
element["tags"]["api_adresse:properties:postcode"] = api_adresse[
|
||||||
|
"properties"
|
||||||
|
]["postcode"]
|
||||||
|
element["tags"]["api_adresse:properties:citycode"] = api_adresse[
|
||||||
|
"properties"
|
||||||
|
]["citycode"]
|
||||||
|
element["tags"]["api_adresse:properties:city"] = api_adresse["properties"][
|
||||||
|
"city"
|
||||||
|
]
|
||||||
|
|
||||||
|
if "street" in api_adresse["properties"]:
|
||||||
|
element["tags"]["api_adresse:properties:street"] = api_adresse[
|
||||||
|
"properties"
|
||||||
|
]["street"]
|
||||||
|
|
||||||
|
element["tags"]["api_adresse:properties:attribution"] = rev_geocode[
|
||||||
|
"attribution"
|
||||||
|
]
|
||||||
|
element["tags"]["api_adresse:properties:licence"] = rev_geocode["licence"]
|
||||||
|
|
||||||
logging.info("Géocodage inversé terminé")
|
logging.info("Géocodage inversé terminé")
|
||||||
|
|
||||||
@ -240,11 +242,7 @@ class Utils:
|
|||||||
return
|
return
|
||||||
|
|
||||||
date_fichier = datetime.date.fromtimestamp(fichier.stat().st_ctime)
|
date_fichier = datetime.date.fromtimestamp(fichier.stat().st_ctime)
|
||||||
|
os.makedirs(dossier_archive + str(date_fichier), exist_ok=True)
|
||||||
# une seule archive par date
|
|
||||||
if os.path.isdir(dossier_archive + str(date_fichier)):
|
|
||||||
shutil.rmtree(dossier_archive + str(date_fichier))
|
|
||||||
os.makedirs(dossier_archive + str(date_fichier))
|
|
||||||
|
|
||||||
# pylint: disable=W0106
|
# pylint: disable=W0106
|
||||||
[
|
[
|
||||||
|
6
rdoo.py
6
rdoo.py
@ -169,7 +169,7 @@ def main():
|
|||||||
if nb_resultats > 0:
|
if nb_resultats > 0:
|
||||||
if args.geocoding_inverse:
|
if args.geocoding_inverse:
|
||||||
# géocodage inverse
|
# géocodage inverse
|
||||||
data = utils.geocodage_csv(data)
|
data = utils.geocodage(data)
|
||||||
|
|
||||||
# traduction
|
# traduction
|
||||||
data = utils.traduction(
|
data = utils.traduction(
|
||||||
@ -188,9 +188,9 @@ def main():
|
|||||||
break
|
break
|
||||||
except errors.ApiError:
|
except errors.ApiError:
|
||||||
|
|
||||||
if nb_essai >= MAX_RETRY - 1:
|
if nb_essai == MAX_RETRY:
|
||||||
logging.error("Trop d'erreurs d'API - abandon")
|
logging.error("Trop d'erreurs d'API - abandon")
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
logging.error(f"Erreur API - on retente dans {RETRY_DELAY}s")
|
logging.error(f"Erreur API - on retente dans {RETRY_DELAY}s")
|
||||||
except:
|
except:
|
||||||
|
Loading…
Reference in New Issue
Block a user