Skip to content

Commit bd5c2fb

Browse files
0.7
Updated to Python 3
1 parent 04c86cc commit bd5c2fb

File tree

2 files changed

+75
-74
lines changed

2 files changed

+75
-74
lines changed

README.md

+17-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# geotag2kml
22

33
### Description
4-
Blog post: http://forensenellanebbia.blogspot.it/2015/08/geotag2kml-python-script-to-create-kml.html
4+
Blog post: https://forensenellanebbia.blogspot.com/2015/08/geotag2kml-python-script-to-create-kml.html
55

66
The is a cross-platform script that uses ExifTool to find geotagged files and parse their metadata. It then creates two different Google Earth .KML files to display the photos/videos found.
77

@@ -19,36 +19,36 @@ The .KML file will be structured this way:
1919

2020
---
2121
### Prerequisites
22-
- Python v2.7
22+
- Python v3.8+
2323
- [geopy](https://pypi.org/project/geopy/)
2424
- [Pillow](https://python-pillow.org/)
2525
- [randomcolor](https://pypi.org/project/randomcolor/)
26-
- [Exiftool](https://www.sno.phy.queensu.ca/~phil/exiftool/) *(recommended version: 10.80 or above. If you're using Windows, please rename the executable to "exiftool.exe")*
26+
- [Exiftool](https://exiftool.org/) *(If you're using Windows, please rename the executable to "exiftool.exe")*
2727
- [ImageMagick](https://imagemagick.org/) *(Win/Mac)* or [libheif-examples](https://launchpad.net/~strukturag/+archive/ubuntu/libheif) *(Ubuntu)*
2828

2929
### How to install each component
30-
**#Python dependencies**<br>
31-
- geopy: pip install geopy
32-
- Pillow: pip install Pillow
33-
- randomcolor: pip install randomcolor
30+
**#Python3 dependencies**<br>
31+
- pip3 install geopy Pillow randomcolor
3432

35-
**#Windows**<br>
36-
- ExifTool: https://www.sno.phy.queensu.ca/~phil/exiftool/ (Windows Executable - rename to *exiftool.exe*)
33+
**#Windows 10 x64**<br>
34+
- ExifTool: https://exiftool.org/ (Windows Executable - rename to *exiftool.exe*)
3735
- ImageMagick: https://imagemagick.org/script/download.php#windows (Win64 dynamic at 16 bits-per-pixel component)
3836

39-
**#Ubuntu**<br>
40-
- ExifTool: https://www.sno.phy.queensu.ca/~phil/exiftool/ (Compile from source code: perl Makefile.PL && make && sudo make install)
41-
- libheif-examples: sudo add-apt-repository ppa:strukturag/libheif && sudo apt-get update && sudo apt-get install libheif-examples
37+
**#Ubuntu (tested with Ubuntu 20.04) **<br>
38+
- ExifTool: sudo apt install libimage-exiftool-perl
39+
- libheif-examples: sudo add-apt-repository ppa:strukturag/libde265 && sudo add-apt-repository ppa:strukturag/libheif && sudo apt-get update && sudo apt-get install libheif-examples
40+
- Google Earth: wget -O ~/google-earth.deb https://dl.google.com/dl/earth/client/current/google-earth-pro-stable_current_amd64.deb && sudo dpkg -i ~/google-earth.deb
4241

43-
**#Mac OS**<br>
44-
- ExifTool: https://www.sno.phy.queensu.ca/~phil/exiftool/ (MacOS Package)
45-
- ImageMagick: brew install --with-libheif imagemagick
42+
**#Mac OS (tested with macOS Big Sur 11.0.1) **<br>
43+
- If you're having any issue while installing Pillow, try: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" && brew install libjpeg && pip3 install Pillow --user
44+
- ExifTool: https://exiftool.org/ (MacOS Package)
45+
- ImageMagick: brew install imagemagick
4646
---
4747
### How to use
4848

4949
Run the script and type the absolute path of the directory to parse. Examples:
5050

51-
- **Microsoft Windows**: python geotag2kml.py C:\MyPhotos
52-
- **Ubuntu**: python geotag2kml.py /home/username/Desktop/Photos
51+
- **Microsoft Windows**: python3 geotag2kml.py C:\MyPhotos
52+
- **Ubuntu**: python3 geotag2kml.py /home/username/Desktop/Photos
5353

5454
The output files will be saved under the given path.

geotag2kml.py

+58-57
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,27 @@
1313
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414
GNU General Public License for more details.
1515
16-
You can view the GNU General Public License at <http://www.gnu.org/licenses/>
16+
You can view the GNU General Public License at <https://www.gnu.org/licenses/>
1717
*******************************************************************************
1818
1919
geotag2kml - WARNING: This program is provided "as-is"
2020
2121
Author : Gabriele Zambelli (Twitter: @gazambelli)
22-
Blog post : http://forensenellanebbia.blogspot.it/2015/08/geotag2kml-python-script-to-create-kml.html
22+
Blog post : https://forensenellanebbia.blogspot.com/2015/08/geotag2kml-python-script-to-create-kml.html
2323
2424
This script will create a Google Earth KML file from geotagged photos and videos
2525
2626
Prerequisites (see the Readme file for more information):
27-
- Python v2.7
28-
* geopy ( https://pypi.org/project/geopy/ )
29-
* Pillow ( https://python-pillow.org/ )
30-
* randomcolor ( https://pypi.org/project/randomcolor/ )
31-
- ExifTool ( https://www.sno.phy.queensu.ca/~phil/exiftool/ )
32-
(Recommended version: 10.80+. If you're using Windows, please rename the executable of ExifTool to "exiftool.exe")
33-
- ImageMagick ( https://imagemagick.org/ )
27+
- Python v3.8+
28+
* geopy : https://pypi.org/project/geopy/
29+
* Pillow : https://python-pillow.org/
30+
* randomcolor : https://pypi.org/project/randomcolor/
31+
- ExifTool : https://exiftool.org/
32+
(If you're using Windows, please rename the executable of ExifTool to "exiftool.exe")
33+
- ImageMagick : https://imagemagick.org/
3434
3535
Version history
36+
[v0.7] 2020-12-24 Updated to Python3, fixed broken URLs
3637
[v0.6] 2018-12-19
3738
[v0.5] 2018-12-13
3839
[v0.4] 2018-12-08
@@ -41,21 +42,21 @@
4142
[v0.1] 2015-08
4243
4344
Script tested on:
44-
- Windows 10 (1803) | ExifTool 11.12 | Python 2.7.13
45-
- Ubuntu 16.04 | ExifTool 11.22 | Python 2.7.12
46-
- macOS Sierra (10.12.6) | ExifTool 10.76 | Python 2.7.10
47-
- Google Earth Pro 7.3.2.5491
45+
- Windows 10 (20H2) | ExifTool 12.12 | Python 3.8.3
46+
- Ubuntu 20.04 | ExifTool 11.88 | Python 3.8.5
47+
- macOS Big Sur (11.0.1) | ExifTool 12.12 | Python 3.8.2
48+
- Google Earth Pro 7.3.3.7786
4849
4950
References:
5051
EXIFTOOL
51-
- ExifTool GPS Tags : https://sno.phy.queensu.ca/~phil/exiftool/TagNames/GPS.html
52-
- ExifTool Application Documentation: https://sno.phy.queensu.ca/~phil/exiftool/exiftool_pod.html
52+
- ExifTool GPS Tags : https://exiftool.org/TagNames/GPS.html
53+
- ExifTool Application Documentation: https://exiftool.org/exiftool_pod.html
5354
GOOGLE EARTH
54-
- Generating a Google Earth KML file: http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,1688.msg7373.html#msg7373
55+
- Generating a Google Earth KML file: https://exiftool.org/forum/index.php/topic,1688.msg7373.html#msg7373
5556
- KML Reference : https://developers.google.com/kml/documentation/kmlreference#kmlextensions
5657
- Altitude Modes : https://developers.google.com/kml/documentation/altitudemode
5758
- Icons : https://sites.google.com/site/gmapsdevelopment/
58-
- Force to open the external browser: https://productforums.google.com/forum/#!msg/earth/q5X_DGQMpyo/b4q6g_vQ-W8J
59+
- Force to open the external browser: https://support.google.com/earth/forum/AAAA_9IoRZwq5X_DGQMpyo/
5960
GEOPY
6061
- Calculating Distance : https://geopy.readthedocs.io/en/stable/#module-geopy.distance
6162
RANDOMCOLOR
@@ -65,16 +66,16 @@
6566

6667
from collections import Counter
6768
from datetime import datetime
68-
from geopy.distance import geodesic #pip install geopy
69-
from PIL import Image, ExifTags #pip install Pillow
69+
from geopy.distance import geodesic
70+
from PIL import Image, ExifTags
7071
import csv
7172
import os
7273
import platform
73-
import randomcolor #pip install randomcolor
74+
import randomcolor
7475
import subprocess
7576
import sys
7677

77-
version = "0.6"
78+
version = "0.7"
7879
line_colors_random = []
7980

8081

@@ -85,37 +86,37 @@ def welcome():
8586
subprocess.check_output(["exiftool", "-ver"]) #check if exiftool is installed
8687
except:
8788
exceptions += 1
88-
print "\n ERROR: exiftool was not found"
89+
print ("\n ERROR: exiftool was not found")
8990
if platform.system() == "Linux":
9091
try:
9192
subprocess.check_output(["which", "heif-convert"]) #check if libheif-examples is installed
9293
except:
9394
exceptions += 1
94-
print "\n ERROR: The package libheif-examples was not found"
95+
print ("\n ERROR: The package libheif-examples was not found")
9596
else:
9697
try:
9798
subprocess.check_output(["magick", "-help"]) #check if ImageMagick is installed
9899
except:
99100
exceptions += 1
100-
print "\n ERROR: ImageMagick was not found"
101+
print ("\n ERROR: ImageMagick was not found")
101102
if exceptions > 0:
102-
print "\n"
103+
print ("\n")
103104
sys.exit()
104105
if len(sys.argv) == 1:
105-
print "\n geotag2kml (v%s)" % version
106+
print ("\n geotag2kml (v%s)" % version)
106107
exift_ver = os.popen("exiftool -ver").read()
107108
if float(exift_ver) < 10.80:
108-
print "\n !! It's recommended to use a more recent version of ExifTool !!\n"
109-
print "\n This script will create a Google Earth KML file from geotagged photos and videos"
110-
print "\n How to use:\n\n ==> python " + os.path.basename(sys.argv[0]) + " AbsolutePathToAnalyze"
111-
print "\n [The script will search recursively ]"
112-
print " [The output files will be saved under the given path]\n\n"
109+
print ("\n !! It's recommended to use a more recent version of ExifTool !!\n")
110+
print ("\n This script will create a Google Earth KML file from geotagged photos and videos")
111+
print ("\n How to use:\n\n ==> python3 " + os.path.basename(sys.argv[0]) + " AbsolutePathToAnalyze")
112+
print ("\n [The script will search recursively ]")
113+
print (" [The output files will be saved under the given path]\n\n")
113114
sys.exit()
114115
elif len(sys.argv) == 2:
115116
if os.path.exists(sys.argv[1]) == True:
116117
os.chdir(sys.argv[1])
117118
else:
118-
print "\n ERROR: the path %s doesn't exist" % sys.argv[1]
119+
print ("\n ERROR: the path %s doesn't exist") % sys.argv[1]
119120
sys.exit()
120121

121122
def os_check(exift_run):
@@ -147,7 +148,7 @@ def kml_creation(kml_type):
147148
<IconStyle>
148149
<scale>1.3</scale>
149150
<Icon>
150-
<href>http://maps.google.com/mapfiles/kml/paddle/pink-blank.png</href>
151+
<href>https://maps.google.com/mapfiles/kml/paddle/pink-blank.png</href>
151152
</Icon>
152153
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
153154
</IconStyle>
@@ -156,15 +157,15 @@ def kml_creation(kml_type):
156157
</LabelStyle>
157158
<ListStyle>
158159
<ItemIcon>
159-
<href>http://maps.google.com/mapfiles/kml/paddle/pink-blank-lv.png</href>
160+
<href>https://maps.google.com/mapfiles/kml/shapes/placemark_circle.png</href>
160161
</ItemIcon>
161162
</ListStyle>
162163
</Style>
163164
<Style id="sh_arrow">
164165
<IconStyle>
165166
<scale>1.4</scale>
166167
<Icon>
167-
<href>http://maps.google.com/mapfiles/kml/shapes/arrow.png</href>
168+
<href>https://maps.google.com/mapfiles/kml/shapes/arrow.png</href>
168169
</Icon>
169170
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
170171
</IconStyle>
@@ -188,7 +189,7 @@ def kml_creation(kml_type):
188189
<IconStyle>
189190
<scale>1.4</scale>
190191
<Icon>
191-
<href>http://maps.google.com/mapfiles/kml/shapes/man.png</href>
192+
<href>https://maps.google.com/mapfiles/kml/shapes/man.png</href>
192193
</Icon>
193194
</IconStyle>
194195
<LabelStyle>
@@ -199,7 +200,7 @@ def kml_creation(kml_type):
199200
<IconStyle>
200201
<scale>1.1</scale>
201202
<Icon>
202-
<href>http://maps.google.com/mapfiles/kml/paddle/pink-blank.png</href>
203+
<href>https://maps.google.com/mapfiles/kml/paddle/pink-blank.png</href>
203204
</Icon>
204205
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
205206
</IconStyle>
@@ -208,15 +209,15 @@ def kml_creation(kml_type):
208209
</LabelStyle>
209210
<ListStyle>
210211
<ItemIcon>
211-
<href>http://maps.google.com/mapfiles/kml/paddle/pink-blank-lv.png</href>
212+
<href>https://maps.google.com/mapfiles/kml/shapes/placemark_circle.png</href>
212213
</ItemIcon>
213214
</ListStyle>
214215
</Style>
215216
<Style id="sn_man">
216217
<IconStyle>
217218
<scale>1.2</scale>
218219
<Icon>
219-
<href>http://maps.google.com/mapfiles/kml/shapes/man.png</href>
220+
<href>https://maps.google.com/mapfiles/kml/shapes/man.png</href>
220221
</Icon>
221222
</IconStyle>
222223
<LabelStyle>
@@ -247,7 +248,7 @@ def kml_creation(kml_type):
247248
<IconStyle>
248249
<scale>1.2</scale>
249250
<Icon>
250-
<href>http://maps.google.com/mapfiles/kml/shapes/arrow.png</href>
251+
<href>https://maps.google.com/mapfiles/kml/shapes/arrow.png</href>
251252
</Icon>
252253
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
253254
</IconStyle>
@@ -266,7 +267,7 @@ def kml_creation(kml_type):
266267
# GPSAltitudeRef
267268
# 0 = Above Sea Level
268269
# 1 = Below Sea Level
269-
# http://www.sno.phy.queensu.ca/~phil/exiftool/faq.html
270+
# https://exiftool.org/faq.html#Q6
270271

271272
#PLACEMARK PREPARATION
272273
counter_wp_date = 0
@@ -340,7 +341,7 @@ def kml_creation(kml_type):
340341
thumb_path = "%s/%s.jpg" % (prefix_thumbs,thumbs_styleid)
341342
im.save(thumb_path, 'JPEG', quality=80)
342343
except:
343-
thumb_path = "http://maps.google.com/mapfiles/kml/paddle/pink-blank.png"
344+
thumb_path = "https://maps.google.com/mapfiles/kml/paddle/pink-blank.png"
344345

345346
#STYLE FOR THUMBNAILS USED AS PLACEMARK ICONS
346347
thumbs_style = ''' <Style id="sh_%s">
@@ -631,7 +632,7 @@ def kml_creation(kml_type):
631632
for csv_row in csv_rows:
632633
csv_TS = csv_row["Timestamp"] #Timestamp, in order of choice: DateTimeOriginal > CreateDate/CreationDate > ModifyDate
633634
csv_TS = csv_TS[:10] # Grab YYYY:MM:DD (first 10 characters)
634-
csv_MM = csv_row["Make"] + " " + csv_row["Model"] #MM = Make Model
635+
csv_MM = csv_row["Make"] + " " + csv_row["Model"] #MM = Make Model
635636
uniq_dates.append(csv_TS)
636637
uniq_models.append(csv_MM)
637638

@@ -659,26 +660,26 @@ def kml_creation(kml_type):
659660

660661
#script duration time
661662
end_time = datetime.now()
662-
print "\ngeotag2kml (v%s)" % version
663-
print "\nScript started : " + str(start_time)
664-
print "Script finished: " + str(end_time)
665-
print('Duration : {}'.format(end_time - start_time))
666-
print "-------------------------------------------\n"
663+
print ("\ngeotag2kml (v%s)" % version)
664+
print ("\nScript started : " + str(start_time))
665+
print ("Script finished: " + str(end_time))
666+
print ('Duration : {}'.format(end_time - start_time))
667+
print ("-------------------------------------------\n")
667668

668669
#print summary
669-
print "Geotagged file(s) found: %d" % numlines
670+
print ("Geotagged file(s) found: %d" % numlines)
670671

671672
if numlines > 0:
672-
print "Unique date(s) found : %d" % len(uniq_dates)
673+
print ("Unique date(s) found : %d" % len(uniq_dates))
673674
counter_path = 0
674675
for uniq_date_counter, freq in uniq_dates_counter.most_common():
675676
if freq > 1:
676677
counter_path +=1
677-
print "Path(s) created : %d\n" % counter_path
678-
print "Geotagged file(s) found per device type:"
678+
print ("Path(s) created : %d\n" % counter_path)
679+
print ("Geotagged file(s) found per device type:")
679680
for makemodel, freq in uniq_models_counter.most_common(): #most_common() returns a list ordered from the most common element to the least
680-
print " * %s (%d)" % (makemodel,freq)
681-
print "\nOutput files:"
682-
print " ==> %s" % file_exif
683-
print " ==> %s" % file_GoogleEarth + "icons.kml"
684-
print " ==> %s" % file_GoogleEarth + "thumbs.kml"
681+
print (" * %s (%d)" % (makemodel,freq))
682+
print ("\nOutput files:")
683+
print (" ==> %s" % file_exif)
684+
print (" ==> %s" % file_GoogleEarth + "icons.kml")
685+
print (" ==> %s" % file_GoogleEarth + "thumbs.kml")

0 commit comments

Comments
 (0)