Created
September 9, 2016 14:59
-
-
Save vigevenoj/42a1eba4c9c1c3aabc8ca4eb1a71d80f to your computer and use it in GitHub Desktop.
Generate a json file with image location information and then display that on a mapbox map
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title>tripmapper</title> | |
<meta charset="utf-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.css" /> | |
<script src="http://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.js"></script> | |
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> | |
<style media="screen" type="text/css"> | |
body { | |
padding: 0; | |
margin: 0; | |
} | |
html, body, #map { | |
height: 100%; | |
} | |
.thumbnail { | |
maxWidth: 200px; } | |
.prev { | |
text-align: left; | |
width: 45%; | |
display: inline-block; | |
vertical-align: top; | |
/*float: left;*/ | |
} | |
.next { | |
text-align: right; | |
width: 45%; | |
display: inline-block; | |
vertical-align: top; | |
/*float: right;*/ | |
} | |
</style> | |
<script> | |
// set some global state | |
$photostops = new Object(); | |
// location data is in trip.json | |
// photo location data is in images.json | |
// it's an array so for each element in the array: | |
// latitude & longitude coordinates and a filename | |
var customOptions = { 'maxWidth': '500', 'maxHeight':'500', 'keepInView': true } | |
$.getJSON('images.json').done(function( data ) { | |
$photostops = data | |
loadMap(); | |
$.each(data, function(i, val) { | |
// TODO: iterate over the array of photos and add markers to the information stored. | |
// then use the marker data to generate links to next/previous marker instead of image | |
if (isNaN(data[i]['latitude'] )|| isNaN(data[i]['longitude']) ) { | |
console.error(data[i]['latitude'] + ", " + data[i]['longitude'] + " is not valid"); | |
} else { | |
marker = L.marker([data[i]['latitude'], data[i]['longitude']]).addTo($map); | |
$photostops[i]['marker'] = marker | |
var popupContent = '<div class="popup">'; | |
if (!(typeof data[i-1] === 'undefined')) { | |
popupContent += '<div class="prev"><a href="' + data[i-1]['filename'] + '">Prev</a></div>' | |
} else { | |
console.log( data[i-1] ); | |
} | |
if ( !(typeof data[i+1] === 'undefined')) { | |
popupContent += '<div class="next"><a href="' + data[i+1]['filename'] + '">Next</a></div>' | |
} else { | |
console.log( data[i+1] ); | |
} | |
popupContent += '<div class="thumbnail">' | |
+ '<a href="' + data[i]['filename'] + '">' + data[i]['filename'] | |
+ '<img src="' + data[i]['filename'] + '" height="306" width="408"/>' | |
+ '</a>' | |
+ '</div>' | |
+ '</div>'; | |
marker.bindPopup(popupContent, customOptions); | |
} | |
}); | |
}); | |
function loadMap() { | |
defaultLat = $photostops[1]['latitude']; | |
defaultLong = $photostops[1]['longitude']; | |
console.log("Starting map at " + defaultLat + ", " + defaultLong); | |
$map = new L.map('map').setView([defaultLat, defaultLong], 13); | |
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', { | |
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>', | |
maxZoom: 18, | |
id: 'vigevenoj.53e008d2', | |
accessToken: 'pk.eyJ1IjoidmlnZXZlbm9qIiwiYSI6IjMwYzk0YzZmMjFlNzU2MjFkOGU4OWIxNWU5YzBjZjg5In0.LbhD_uBPGZaDpagI0jNlSA' | |
}).addTo($map); | |
} | |
</script> | |
</head> | |
<body> | |
<div id="map"></div> | |
<script> | |
// | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Script to parse GPS location and time out of photos and return the data as json""" | |
import argparse | |
import sys | |
import os | |
import exifread | |
import imghdr | |
from fractions import Fraction | |
from collections import defaultdict | |
import json | |
def main(): | |
"""Main entry point for script""" | |
parser = argparse.ArgumentParser(description="Script to parse gps location and time from a directory of photos") | |
parser.add_argument("source") | |
args = parser.parse_args() | |
gps_info_for_files = [] | |
#file_list = get_file_list(args.source) | |
files = [] | |
if os.path.isdir(args.source): | |
for(dirpath, dirnames, filenames) in os.walk(args.source): | |
for filename in filenames: | |
if os.path.splitext(filename)[1].lower() in ('.jpg', '.jpeg', '.png'): | |
latitude, longitude = read_gps_data(os.path.join(dirpath,filename)) | |
if latitude and longitude: | |
this_image = { 'filename': filename, 'latitude': latitude, 'longitude': longitude } | |
gps_info_for_files.append(this_image) | |
break | |
else: | |
sys.exit(path + " is not a directory") | |
info = json.dumps(gps_info_for_files) | |
print info | |
def read_gps_data(photofile): | |
"""Read exif gps data from a single image file""" | |
# Reminder: the values in the exif tags dict are not strings | |
latitude = None | |
longitude = None | |
f = open(photofile, 'rb') | |
tags = exifread.process_file(f) | |
for key in tags.keys(): | |
if str(key) == "GPS GPSLongitude": | |
longitude = _convert_to_degrees(_get_if_exist(tags, key)) | |
if str(key) == "GPS GPSLatitude": | |
latitude = _convert_to_degrees(_get_if_exist(tags, key)) | |
gps_latitude_ref = str(_get_if_exist(tags, "GPS GPSLatitudeRef")) | |
gps_longitude_ref = str(_get_if_exist(tags, "GPS GPSLongitudeRef")) | |
if latitude and gps_latitude_ref and longitude and gps_longitude_ref: | |
if gps_latitude_ref != "N": # if not north, negative latitude (south of equator) | |
latitude = 0 - latitude | |
if gps_longitude_ref != "E": # if not east, negative longitude (west of prime meridian) | |
longitude = 0 - longitude | |
return latitude, longitude | |
def get_timestamp(exif_data): | |
"""Extract gps timestamp from exif data""" | |
dt = None | |
utc = pytz.utc | |
if "GPSInfo" in exif_data: | |
gps_time_stamp = exif_data["GPS GPSTimeStamp"] | |
if 'GPSDateStamp' in exif_data: | |
gps_date = [int(i) for i in exif_data["GPS GPSTimeStamp"].split(':')] | |
def _convert_to_degrees(value): | |
degrees = float(Fraction(str(value.values[0]))) | |
minutes = float(Fraction(str(value.values[1]))) | |
seconds = float(Fraction(str(value.values[2]))) | |
return degrees + (minutes / 60.0) + (seconds / 3600.0) | |
def _get_if_exist(data, key): | |
if key in data: | |
return data[key] | |
return None | |
if __name__ == '__main__': | |
sys.exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment