Page 5 sur 10
IGN
Petite parenthèse, un exemple d'utilisation de l'API isochrones de l'IGN !
Merci aux étudiants du master de géomatique CYU (Cergy) !
import requests import time from qgis.core import (QgsProject, QgsVectorLayer, QgsFeature, QgsGeometry, QgsField, QgsPointXY, QgsWkbTypes, QgsCoordinateTransform, QgsCoordinateReferenceSystem) from PyQt5.QtCore import QVariant base_url = "https://data.geopf.fr/navigation/isochrone" # Temps de déplacement en minutes tempsDeplacement = 15 # Direction de déplacement directionDeplacement = "arrival" # Sélectionne la couche active dans QGIS input_layer = iface.activeLayer() if not input_layer: raise Exception("Aucune couche active sélectionnée") if input_layer.geometryType() != QgsWkbTypes.PointGeometry: raise Exception("La couche doit contenir des POINTS") source_crs = input_layer.crs() target_crs = QgsCoordinateReferenceSystem("EPSG:4326") transform = None if source_crs != target_crs: transform = QgsCoordinateTransform(source_crs, target_crs, QgsProject.instance()) print("Reprojection activée :", source_crs.authid(), "EPSG:4326") nomCouche = "Isochrones" + " " + str(tempsDeplacement) + " " + directionDeplacement output_layer = QgsVectorLayer("Polygon?crs=EPSG:4326", nomCouche, "memory") provider = output_layer.dataProvider() provider.addAttributes([ QgsField("id_point", QVariant.Int), QgsField("minutes", QVariant.Int), QgsField("direction", QVariant.String) ]) output_layer.updateFields() total = input_layer.featureCount() batch = [] # ajout toutes les 50 features batch_size = 50 for i, feat in enumerate(input_layer.getFeatures()): geom = feat.geometry() if not geom or geom.isEmpty(): continue if geom.isMultipart(): point = geom.asMultiPoint()[0] else: point = geom.asPoint() if transform: point = transform.transform(point) lon = point.x() lat = point.y() params = { "resource": "bdtopo-valhalla", "profile": "car", "costing": "auto", "costType": "time", "costValue": tempsDeplacement, "direction": directionDeplacement, "point": f"{lon},{lat}", "geometryFormat": "geojson", "timeUnit": "minute" } try: response = requests.get(base_url, params=params, timeout=30) response.raise_for_status() data = response.json() coords = data["geometry"]["coordinates"][0] polygon = QgsGeometry.fromPolygonXY( [[QgsPointXY(x, y) for x, y in coords]] ) new_feat = QgsFeature() new_feat.setGeometry(polygon) new_feat.setAttributes([i, tempsDeplacement, directionDeplacement]) batch.append(new_feat) # Ajout par paquet pour éviter surcharge mémoire if len(batch) >= batch_size: provider.addFeatures(batch) batch = [] print(f"{i+1}/{total} traité") # anti rate-limit (2 req/sec max) time.sleep(0.5) except Exception as e: print(f"Erreur point {i+1} :", e) # Ajouter le reste if batch: provider.addFeatures(batch) output_layer.updateExtents() QgsProject.instance().addMapLayer(output_layer) print("Traitement terminé")