mirror of
https://expo.survex.com/repositories/troggle/.git
synced 2024-11-30 22:01:53 +00:00
120 lines
4.3 KiB
Python
120 lines
4.3 KiB
Python
import os
|
|
import folium
|
|
from pathlib import Path
|
|
from PIL import Image, ExifTags
|
|
from itertools import chain
|
|
|
|
"""To do
|
|
- create gpx file for adding in to existing GPSprune maps
|
|
- omit all the thumbs
|
|
- include *.jpeg
|
|
- can we also do other formats than JPG ?
|
|
- we want popup that hotlinks to URL of the photo of course
|
|
"""
|
|
|
|
def get_coordinates(photo_path):
|
|
"""Extracting EXIF data from jpg files requires an external package because the EXIF standard
|
|
is interpreted differently by the many different implementations of the JPG file format
|
|
"""
|
|
try:
|
|
# Read EXIF data from photo
|
|
img = Image.open(photo_path)
|
|
exif_data = img._getexif()
|
|
|
|
# Extract latitude and longitude from EXIF data
|
|
gps_info = exif_data.get(34853) #'GPSInfo is a dict
|
|
# This does not mean that all the GPS fields are populated.
|
|
|
|
lat = gps_info.get(2, None)
|
|
lon = gps_info.get(4, None)
|
|
isn = gps_info.get(1, None)
|
|
ise = gps_info.get(3, None)
|
|
if isn and isn != "N":
|
|
print(f"{photo_path} WRONG hemisphere N/S {isn}")
|
|
if ise and ise != "E":
|
|
print(f"{photo_path} WRONG hemisphere E/W")
|
|
point = gps_info.get(17, None) # direction the camera is point towards
|
|
pointref = gps_info.get(16, None) # "M" for magnetic
|
|
taken = gps_info.get(29, None) # GPS datestamp
|
|
except:
|
|
#print(f"{photo_path} - lat/lon exception")
|
|
# for key, value in gps_info.items():
|
|
# print(key, value, value.type())
|
|
return None, None
|
|
|
|
# Convert coordinates to decimal format
|
|
if lat and lon:
|
|
# lat and lon are tuples e.g. (47.0, 35.0, 5.77)
|
|
latitude = float(lat[0] + lat[1] / 60 + lat[2] / 3600)
|
|
longitude = float(lon[0] + lon[1] / 60 + lon[2] / 3600)
|
|
|
|
# Reverse geocode coordinates to get address
|
|
#address = geolocator.reverse((latitude, longitude))
|
|
return latitude, longitude
|
|
else:
|
|
# print(f"{photo_path} - lat/lon conversion exception {lat=} {lon=}")
|
|
# for key, value in gps_info.items():
|
|
# print(key, value, type(value))
|
|
return None, None
|
|
|
|
|
|
# Specify the folder containing the photos
|
|
#photo_folder = Path("../../expoweb")
|
|
photo_folder = Path("/mnt/d/EXPO/PHOTOS")
|
|
#photo_folder = Path("/mnt/d/EXPO/PHOTOS/2019")
|
|
#photo_folder = Path("/mnt/d/EXPO/PHOTOS/2022/JonoL") # jpeg
|
|
save_gpx = "photos_jpg.gpx"
|
|
|
|
# these are generators, not lists
|
|
photosjpg = photo_folder.rglob("*.jpg")
|
|
photosjpeg = photo_folder.rglob("*.jpeg")
|
|
photos = chain(photosjpg, photosjpeg)
|
|
|
|
|
|
# Initialize a Folium map centered at an initial location
|
|
map = folium.Map(location=[47.691036, 13.821314], zoom_start=13)
|
|
|
|
photoset = []
|
|
# Iterate through photos in the folder
|
|
for photo_path in photos:
|
|
if photo_path.stem.startswith("slide_"):
|
|
#print(f" - abort slide")
|
|
continue
|
|
if photo_path.stem.startswith("thumb_"):
|
|
#print(f" - abort thumb")
|
|
continue
|
|
|
|
# Extract latitude, longitude, and address from photo
|
|
latitude, longitude = get_coordinates(photo_path)
|
|
|
|
if latitude and longitude:
|
|
print(f"{photo_path} {latitude:.6f} {longitude:.6f}")
|
|
# Create a marker for each photo with its location and address
|
|
folium.Marker(
|
|
location=[latitude, longitude],
|
|
popup=f"{photo_path}",
|
|
icon=folium.Icon(color="red", icon="camera"),
|
|
).add_to(map)
|
|
photoset.append((photo_path, latitude, longitude))
|
|
|
|
# Save the folium map as an HTML file
|
|
map.save("photo_map.html")
|
|
print(f"Found {len(photoset)} GPS located photos in '{photo_folder}' and subdirectories.")
|
|
|
|
header = """<?xml version="1.0" encoding="windows-1252"?>
|
|
<gpx version="1.0" creator="troggle pmap"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xmlns="http://www.topografix.com/GPX/1/0"
|
|
xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
|
|
<name>pmap photo GPS</name>
|
|
<desc>Troggle photos archive</desc>
|
|
"""
|
|
with open(save_gpx, "w") as f:
|
|
f.write(header)
|
|
for p in photoset:
|
|
photo_path, latitude, longitude = p
|
|
# add ele=
|
|
f.write(f'<wpt lat="{latitude:.6f}" lon="{longitude:.6f}"> <name>[{photo_path.stem}]</name><type>photo</type><desc>{str(photo_path).replace(str(photo_folder),"")}</desc></wpt>\n')
|
|
f.write(f'</gpx>\n')
|
|
|