TUTTO¶
SOMMAIRE¶
Objectif : Géoréférencer des photographies à partir d'une table de coordonnées CSV.
I. PRÉREQUIS & PRÉPARATION QGIS¶
Avant de lancer le script, assurez-vous d'avoir installé Visual Studio Code et Python.
1. Préparation des données sur QGIS¶
Pour faire le lien entre vos clichés et le terrain, suivez ces étapes :
- Création de la couche : Créez une couche de points (GPKG ou Shapefile) avec les champs :
fid,chemin,x,y. - Saisie des données : Pointez sur la carte l'emplacement exact de la prise de vue.
- Champ Chemin : Renseignez le chemin complet du fichier (ex:
C:\Photos\P1010.jpg). > Important : Ne pas mettre de guillemets dans les chemins. - Calculatrice de champ : Mettez à jour les champs
xety(en Lambert 93 - EPSG:2154).
2. Exportation¶
Exportez la table attributaire en CSV dans le même dossier que vos photos.
* Format : UTF-8.
* Séparateur : Point-virgule (;).
* Géométrie : Choisissez "Pas de géométrie" lors de l'export.
II. CONFIGURATION DU SCRIPT PYTHON¶
Ouvrez Visual Studio Code, créez un nouveau fichier .py et collez-y le code ci-dessous.
!!! warning "Attention : Variables à modifier"
Vous devez modifier les variables suivantes dans le script :
* base_dir : Le dossier racine (ex: 06_prospection).
* test_dir : Le sous-dossier contenant les images (ex: Fenioux).
* csv_file : Le nom de votre fichier CSV (ex: fenioux.csv).
```python import os import pandas as pd from pyproj import Transformer import piexif from PIL import Image
---- 1. CONFIGURATION DES CHEMINS ----¶
base_dir = r"C:\photos\06_Prospection" test_dir = os.path.join(base_dir, "Fenioux") csv_file = os.path.join(test_dir, "fenioux.csv")
---- 2. CHARGEMENT ET NETTOYAGE ----¶
df = pd.read_csv(csv_file, sep=";", encoding="utf-8-sig") df = df.rename(columns=lambda c: c.strip())
---- 3. CONVERSION COORDONNÉES (Lambert93 -> WGS84) ----¶
transformer = Transformer.from_crs("EPSG:2154", "EPSG:4326", always_xy=True) df["lon"], df["lat"] = transformer.transform(df["x"].values, df["y"].values)
def deg_to_dms_rational(deg): d = int(abs(deg)) m = int((abs(deg) - d) * 60) s = round((abs(deg) - d - m/60) * 3600 * 100) return ((d, 1), (m, 1), (s, 100))
---- 4. TRAITEMENT DES IMAGES ----¶
output_dir = os.path.join(base_dir, "EXF") os.makedirs(output_dir, exist_ok=True)
for _, row in df.iterrows(): chemin = row["chemin"].strip().replace("\u202a", "") lat, lon = row["lat"], row["lon"]
lat_ref = "N" if lat >= 0 else "S"
lon_ref = "E" if lon >= 0 else "W"
gps_ifd = {
piexif.GPSIFD.GPSLatitudeRef: lat_ref,
piexif.GPSIFD.GPSLatitude: deg_to_dms_rational(lat),
piexif.GPSIFD.GPSLongitudeRef: lon_ref,
piexif.GPSIFD.GPSLongitude: deg_to_dms_rational(lon),
}
exif_dict = {"GPS": gps_ifd}
exif_bytes = piexif.dump(exif_dict)
try:
im = Image.open(chemin)
nom_fichier = os.path.basename(chemin)
sortie = os.path.join(output_dir, nom_fichier)
im.save(sortie, exif=exif_bytes)
print(f"✅ Succès : {nom_fichier}")
except Exception as e:
print(f"❌ Erreur pour {chemin} : {e}")