13
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
14
GNU General Public License for more details.
15
15
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/>
17
17
*******************************************************************************
18
18
19
19
geotag2kml - WARNING: This program is provided "as-is"
20
20
21
21
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
23
23
24
24
This script will create a Google Earth KML file from geotagged photos and videos
25
25
26
26
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/
34
34
35
35
Version history
36
+ [v0.7] 2020-12-24 Updated to Python3, fixed broken URLs
36
37
[v0.6] 2018-12-19
37
38
[v0.5] 2018-12-13
38
39
[v0.4] 2018-12-08
41
42
[v0.1] 2015-08
42
43
43
44
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
48
49
49
50
References:
50
51
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
53
54
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
55
56
- KML Reference : https://developers.google.com/kml/documentation/kmlreference#kmlextensions
56
57
- Altitude Modes : https://developers.google.com/kml/documentation/altitudemode
57
58
- 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/
59
60
GEOPY
60
61
- Calculating Distance : https://geopy.readthedocs.io/en/stable/#module-geopy.distance
61
62
RANDOMCOLOR
65
66
66
67
from collections import Counter
67
68
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
70
71
import csv
71
72
import os
72
73
import platform
73
- import randomcolor #pip install randomcolor
74
+ import randomcolor
74
75
import subprocess
75
76
import sys
76
77
77
- version = "0.6 "
78
+ version = "0.7 "
78
79
line_colors_random = []
79
80
80
81
@@ -85,37 +86,37 @@ def welcome():
85
86
subprocess .check_output (["exiftool" , "-ver" ]) #check if exiftool is installed
86
87
except :
87
88
exceptions += 1
88
- print "\n ERROR: exiftool was not found"
89
+ print ( "\n ERROR: exiftool was not found" )
89
90
if platform .system () == "Linux" :
90
91
try :
91
92
subprocess .check_output (["which" , "heif-convert" ]) #check if libheif-examples is installed
92
93
except :
93
94
exceptions += 1
94
- print "\n ERROR: The package libheif-examples was not found"
95
+ print ( "\n ERROR: The package libheif-examples was not found" )
95
96
else :
96
97
try :
97
98
subprocess .check_output (["magick" , "-help" ]) #check if ImageMagick is installed
98
99
except :
99
100
exceptions += 1
100
- print "\n ERROR: ImageMagick was not found"
101
+ print ( "\n ERROR: ImageMagick was not found" )
101
102
if exceptions > 0 :
102
- print "\n "
103
+ print ( "\n " )
103
104
sys .exit ()
104
105
if len (sys .argv ) == 1 :
105
- print "\n geotag2kml (v%s)" % version
106
+ print ( "\n geotag2kml (v%s)" % version )
106
107
exift_ver = os .popen ("exiftool -ver" ).read ()
107
108
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 " )
113
114
sys .exit ()
114
115
elif len (sys .argv ) == 2 :
115
116
if os .path .exists (sys .argv [1 ]) == True :
116
117
os .chdir (sys .argv [1 ])
117
118
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 ]
119
120
sys .exit ()
120
121
121
122
def os_check (exift_run ):
@@ -147,7 +148,7 @@ def kml_creation(kml_type):
147
148
<IconStyle>
148
149
<scale>1.3</scale>
149
150
<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>
151
152
</Icon>
152
153
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
153
154
</IconStyle>
@@ -156,15 +157,15 @@ def kml_creation(kml_type):
156
157
</LabelStyle>
157
158
<ListStyle>
158
159
<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>
160
161
</ItemIcon>
161
162
</ListStyle>
162
163
</Style>
163
164
<Style id="sh_arrow">
164
165
<IconStyle>
165
166
<scale>1.4</scale>
166
167
<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>
168
169
</Icon>
169
170
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
170
171
</IconStyle>
@@ -188,7 +189,7 @@ def kml_creation(kml_type):
188
189
<IconStyle>
189
190
<scale>1.4</scale>
190
191
<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>
192
193
</Icon>
193
194
</IconStyle>
194
195
<LabelStyle>
@@ -199,7 +200,7 @@ def kml_creation(kml_type):
199
200
<IconStyle>
200
201
<scale>1.1</scale>
201
202
<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>
203
204
</Icon>
204
205
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
205
206
</IconStyle>
@@ -208,15 +209,15 @@ def kml_creation(kml_type):
208
209
</LabelStyle>
209
210
<ListStyle>
210
211
<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>
212
213
</ItemIcon>
213
214
</ListStyle>
214
215
</Style>
215
216
<Style id="sn_man">
216
217
<IconStyle>
217
218
<scale>1.2</scale>
218
219
<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>
220
221
</Icon>
221
222
</IconStyle>
222
223
<LabelStyle>
@@ -247,7 +248,7 @@ def kml_creation(kml_type):
247
248
<IconStyle>
248
249
<scale>1.2</scale>
249
250
<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>
251
252
</Icon>
252
253
<hotSpot x="32" y="1" xunits="pixels" yunits="pixels"/>
253
254
</IconStyle>
@@ -266,7 +267,7 @@ def kml_creation(kml_type):
266
267
# GPSAltitudeRef
267
268
# 0 = Above Sea Level
268
269
# 1 = Below Sea Level
269
- # http ://www.sno.phy.queensu.ca/~phil/exiftool/ faq.html
270
+ # https ://exiftool.org/ faq.html#Q6
270
271
271
272
#PLACEMARK PREPARATION
272
273
counter_wp_date = 0
@@ -340,7 +341,7 @@ def kml_creation(kml_type):
340
341
thumb_path = "%s/%s.jpg" % (prefix_thumbs ,thumbs_styleid )
341
342
im .save (thumb_path , 'JPEG' , quality = 80 )
342
343
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"
344
345
345
346
#STYLE FOR THUMBNAILS USED AS PLACEMARK ICONS
346
347
thumbs_style = ''' <Style id="sh_%s">
@@ -631,7 +632,7 @@ def kml_creation(kml_type):
631
632
for csv_row in csv_rows :
632
633
csv_TS = csv_row ["Timestamp" ] #Timestamp, in order of choice: DateTimeOriginal > CreateDate/CreationDate > ModifyDate
633
634
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
635
636
uniq_dates .append (csv_TS )
636
637
uniq_models .append (csv_MM )
637
638
@@ -659,26 +660,26 @@ def kml_creation(kml_type):
659
660
660
661
#script duration time
661
662
end_time = datetime .now ()
662
- print "\n geotag2kml (v%s)" % version
663
- print "\n Script started : " + str (start_time )
664
- print "Script finished: " + str (end_time )
665
- print ('Duration : {}' .format (end_time - start_time ))
666
- print "-------------------------------------------\n "
663
+ print ( "\n geotag2kml (v%s)" % version )
664
+ print ( "\n Script started : " + str (start_time ) )
665
+ print ( "Script finished: " + str (end_time ) )
666
+ print ('Duration : {}' .format (end_time - start_time ))
667
+ print ( "-------------------------------------------\n " )
667
668
668
669
#print summary
669
- print "Geotagged file(s) found: %d" % numlines
670
+ print ( "Geotagged file(s) found: %d" % numlines )
670
671
671
672
if numlines > 0 :
672
- print "Unique date(s) found : %d" % len (uniq_dates )
673
+ print ( "Unique date(s) found : %d" % len (uniq_dates ) )
673
674
counter_path = 0
674
675
for uniq_date_counter , freq in uniq_dates_counter .most_common ():
675
676
if freq > 1 :
676
677
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:" )
679
680
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 "\n Output 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 ( "\n Output files:" )
683
+ print ( " ==> %s" % file_exif )
684
+ print ( " ==> %s" % file_GoogleEarth + "icons.kml" )
685
+ print ( " ==> %s" % file_GoogleEarth + "thumbs.kml" )
0 commit comments