geopic-tag-reader 1.2.0__py3-none-any.whl → 1.3.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. geopic_tag_reader/__init__.py +1 -1
  2. geopic_tag_reader/main.py +4 -1
  3. geopic_tag_reader/reader.py +77 -32
  4. geopic_tag_reader/sequence.py +45 -4
  5. geopic_tag_reader/translations/de/LC_MESSAGES/geopic_tag_reader.mo +0 -0
  6. geopic_tag_reader/translations/de/LC_MESSAGES/geopic_tag_reader.po +5 -1
  7. geopic_tag_reader/translations/en/LC_MESSAGES/geopic_tag_reader.mo +0 -0
  8. geopic_tag_reader/translations/en/LC_MESSAGES/geopic_tag_reader.po +39 -27
  9. geopic_tag_reader/translations/es/LC_MESSAGES/geopic_tag_reader.mo +0 -0
  10. geopic_tag_reader/translations/es/LC_MESSAGES/geopic_tag_reader.po +58 -22
  11. geopic_tag_reader/translations/fi/LC_MESSAGES/geopic_tag_reader.mo +0 -0
  12. geopic_tag_reader/translations/fi/LC_MESSAGES/geopic_tag_reader.po +146 -0
  13. geopic_tag_reader/translations/fr/LC_MESSAGES/geopic_tag_reader.mo +0 -0
  14. geopic_tag_reader/translations/fr/LC_MESSAGES/geopic_tag_reader.po +14 -2
  15. geopic_tag_reader/translations/geopic_tag_reader.pot +38 -26
  16. geopic_tag_reader/translations/ko/LC_MESSAGES/geopic_tag_reader.mo +0 -0
  17. geopic_tag_reader/translations/ko/LC_MESSAGES/geopic_tag_reader.po +158 -0
  18. {geopic_tag_reader-1.2.0.dist-info → geopic_tag_reader-1.3.1.dist-info}/LICENSE +1 -1
  19. {geopic_tag_reader-1.2.0.dist-info → geopic_tag_reader-1.3.1.dist-info}/METADATA +9 -8
  20. geopic_tag_reader-1.3.1.dist-info/RECORD +27 -0
  21. geopic_tag_reader-1.2.0.dist-info/RECORD +0 -23
  22. {geopic_tag_reader-1.2.0.dist-info → geopic_tag_reader-1.3.1.dist-info}/WHEEL +0 -0
  23. {geopic_tag_reader-1.2.0.dist-info → geopic_tag_reader-1.3.1.dist-info}/entry_points.txt +0 -0
@@ -2,4 +2,4 @@
2
2
  GeoPicTagReader
3
3
  """
4
4
 
5
- __version__ = "1.2.0"
5
+ __version__ = "1.3.1"
geopic_tag_reader/main.py CHANGED
@@ -25,7 +25,10 @@ def read(
25
25
  _ = i18n_init(lang)
26
26
  print(_("Latitude:"), metadata.lat)
27
27
  print(_("Longitude:"), metadata.lon)
28
- print(_("Timestamp:"), metadata.ts.isoformat())
28
+ print(_("Timestamp:"), metadata.ts)
29
+ if metadata.ts_by_source is not None:
30
+ print(" -", (metadata.ts_by_source.gps or _("not set")), _("(GPS)"))
31
+ print(" -", (metadata.ts_by_source.camera or _("not set")), _("(Camera)"))
29
32
  print(_("Heading:"), metadata.heading)
30
33
  print(_("Type:"), metadata.type)
31
34
  print(_("Make:"), metadata.make)
@@ -39,6 +39,32 @@ class CropValues:
39
39
  top: int
40
40
 
41
41
 
42
+ @dataclass
43
+ class TimeBySource:
44
+ """All datetimes read from available sources
45
+
46
+ Attributes:
47
+ gps (datetime): Time read from GPS clock
48
+ camera (datetime): Time read from camera clock (DateTimeOriginal)
49
+ """
50
+
51
+ gps: Optional[datetime.datetime] = None
52
+ camera: Optional[datetime.datetime] = None
53
+
54
+ def getBest(self) -> Optional[datetime.datetime]:
55
+ """Get the best available datetime to use"""
56
+ if self.gps is not None and self.camera is None:
57
+ return self.gps
58
+ elif self.gps is None and self.camera is not None:
59
+ return self.camera
60
+ elif self.gps is None and self.camera is None:
61
+ return None
62
+ elif self.camera.microsecond > 0 and self.gps.microsecond == 0: # type: ignore
63
+ return self.camera
64
+ else:
65
+ return self.gps
66
+
67
+
42
68
  @dataclass
43
69
  class GeoPicTags:
44
70
  """Tags associated to a geolocated picture
@@ -59,6 +85,7 @@ class GeoPicTags:
59
85
  pitch (float): Picture pitch angle, compared to horizon (in degrees, bottom = -90°, horizon = 0°, top = 90°)
60
86
  roll (float): Picture roll angle, on a right/left axis (in degrees, left-arm down = -90°, flat = 0°, right-arm down = 90°)
61
87
  yaw (float): Picture yaw angle, on a vertical axis (in degrees, front = 0°, right = 90°, rear = 180°, left = 270°). This offsets the center image from GPS direction for a correct 360° sphere correction
88
+ ts_by_source (TimeBySource): all read timestamps from image, for finer processing.
62
89
 
63
90
 
64
91
  Implementation note: this needs to be sync with the PartialGeoPicTags structure
@@ -79,6 +106,7 @@ class GeoPicTags:
79
106
  pitch: Optional[float] = None
80
107
  roll: Optional[float] = None
81
108
  yaw: Optional[float] = None
109
+ ts_by_source: Optional[TimeBySource] = None
82
110
 
83
111
 
84
112
  class InvalidExifException(Exception):
@@ -114,6 +142,7 @@ class PartialGeoPicTags:
114
142
  pitch: Optional[float] = None
115
143
  roll: Optional[float] = None
116
144
  yaw: Optional[float] = None
145
+ ts_by_source: Optional[TimeBySource] = None
117
146
 
118
147
 
119
148
  class PartialExifException(Exception):
@@ -145,7 +174,10 @@ def readPictureMetadata(picture: bytes, lang_code: str = "en") -> GeoPicTags:
145
174
  img = pyexiv2.ImageData(picture)
146
175
  data = {}
147
176
  data.update(img.read_exif())
177
+ data.update(img.read_iptc())
148
178
  data.update(img.read_xmp())
179
+ width = img.get_pixel_width()
180
+ height = img.get_pixel_height()
149
181
 
150
182
  imgComment = img.read_comment()
151
183
  if imgComment is not None and len(imgComment.strip()) > 0:
@@ -187,35 +219,21 @@ def readPictureMetadata(picture: bytes, lang_code: str = "en") -> GeoPicTags:
187
219
  if lon is not None and (lon < -180 or lon > 180):
188
220
  raise InvalidExifException(_("Read longitude is out of WGS84 bounds (should be in [-180, 180])"))
189
221
 
190
- # Parse date/time
191
- d, llw = decodeGPSDateTime(data, "Exif.GPSInfo", _, lat, lon)
222
+ # Parse GPS date/time
223
+ gpsTs, llw = decodeGPSDateTime(data, "Exif.GPSInfo", _, lat, lon)
192
224
 
193
225
  if len(llw) > 0:
194
226
  warnings.extend(llw)
195
227
 
196
- if d is None:
197
- d, llw = decodeGPSDateTime(data, "Xmp.exif", _, lat, lon)
228
+ if gpsTs is None:
229
+ gpsTs, llw = decodeGPSDateTime(data, "Xmp.exif", _, lat, lon)
198
230
  if len(llw) > 0:
199
231
  warnings.extend(llw)
200
232
 
201
- for exifField in [
202
- "Exif.Image.DateTimeOriginal",
203
- "Exif.Photo.DateTimeOriginal",
204
- "Exif.Image.DateTime",
205
- "Xmp.GPano.SourceImageCreateTime",
206
- ]:
207
- if d is None:
208
- d, llw = decodeDateTimeOriginal(data, exifField, _, lat, lon)
209
- if len(llw) > 0:
210
- warnings.extend(llw)
211
-
212
- if d is not None:
213
- break
214
-
215
- if d is None and isExifTagUsable(data, "MAPGpsTime"):
233
+ if gpsTs is None and isExifTagUsable(data, "MAPGpsTime"):
216
234
  try:
217
235
  year, month, day, hour, minutes, seconds, milliseconds = [int(dp) for dp in data["MAPGpsTime"].split("_")]
218
- d = datetime.datetime(
236
+ gpsTs = datetime.datetime(
219
237
  year,
220
238
  month,
221
239
  day,
@@ -229,6 +247,25 @@ def readPictureMetadata(picture: bytes, lang_code: str = "en") -> GeoPicTags:
229
247
  except Exception as e:
230
248
  warnings.append(_("Skipping Mapillary date/time as it was not recognized: {v}").format(v=data["MAPGpsTime"]))
231
249
 
250
+ # Parse camera date/time
251
+ cameraTs = None
252
+ for exifGroup, dtField, subsecField in [
253
+ ("Exif.Photo", "DateTimeOriginal", "SubSecTimeOriginal"),
254
+ ("Exif.Image", "DateTimeOriginal", "SubSecTimeOriginal"),
255
+ ("Exif.Image", "DateTime", "SubSecTimeOriginal"),
256
+ ("Xmp.GPano", "SourceImageCreateTime", "SubSecTimeOriginal"),
257
+ ("Xmp.exif", "DateTimeOriginal", "SubsecTimeOriginal"), # Case matters
258
+ ]:
259
+ if cameraTs is None:
260
+ cameraTs, llw = decodeDateTimeOriginal(data, exifGroup, dtField, subsecField, _, lat, lon)
261
+ if len(llw) > 0:
262
+ warnings.extend(llw)
263
+
264
+ if cameraTs is not None:
265
+ break
266
+ tsSources = TimeBySource(gps=gpsTs, camera=cameraTs) if gpsTs or cameraTs else None
267
+ d = tsSources.getBest() if tsSources is not None else None
268
+
232
269
  # GPS Heading
233
270
  heading = None
234
271
  if isExifTagUsable(data, "Exif.GPSInfo.GPSImgDirection", Fraction):
@@ -318,7 +355,7 @@ def readPictureMetadata(picture: bytes, lang_code: str = "en") -> GeoPicTags:
318
355
  if isExifTagUsable(data, "Xmp.GPano.ProjectionType"):
319
356
  pic_type = data["Xmp.GPano.ProjectionType"]
320
357
  # 360° based on known models
321
- elif camera.is_360(make, model, data.get("Exif.Photo.PixelXDimension"), data.get("Exif.Photo.PixelYDimension")):
358
+ elif camera.is_360(make, model, width, height):
322
359
  pic_type = "equirectangular"
323
360
  # Flat by default
324
361
  else:
@@ -370,6 +407,7 @@ def readPictureMetadata(picture: bytes, lang_code: str = "en") -> GeoPicTags:
370
407
  pitch=pitch,
371
408
  roll=roll,
372
409
  yaw=yaw,
410
+ ts_by_source=tsSources,
373
411
  ),
374
412
  )
375
413
 
@@ -390,6 +428,7 @@ def readPictureMetadata(picture: bytes, lang_code: str = "en") -> GeoPicTags:
390
428
  pitch=pitch,
391
429
  roll=roll,
392
430
  yaw=yaw,
431
+ ts_by_source=tsSources,
393
432
  )
394
433
 
395
434
 
@@ -480,20 +519,28 @@ def decodeLatLon(data: dict, group: str, _: Callable[[str], str]) -> Tuple[Optio
480
519
 
481
520
 
482
521
  def decodeDateTimeOriginal(
483
- data: dict, datetimeField: str, _: Callable[[str], str], lat: Optional[float] = None, lon: Optional[float] = None
522
+ data: dict,
523
+ exifGroup: str,
524
+ datetimeField: str,
525
+ subsecField: str,
526
+ _: Callable[[str], str],
527
+ lat: Optional[float] = None,
528
+ lon: Optional[float] = None,
484
529
  ) -> Tuple[Optional[datetime.datetime], List[str]]:
485
530
  d = None
486
531
  warnings = []
532
+ dtField = f"{exifGroup}.{datetimeField}"
533
+ ssField = f"{exifGroup}.{subsecField}"
487
534
 
488
- if d is None and isExifTagUsable(data, datetimeField):
535
+ if d is None and isExifTagUsable(data, dtField):
489
536
  try:
490
- dateRaw = data[datetimeField][:10].replace(":", "-")
491
- timeRaw = data[datetimeField][11:].split(":")
537
+ dateRaw = data[dtField][:10].replace(":", "-")
538
+ timeRaw = data[dtField][11:].split(":")
492
539
  hourRaw = int(timeRaw[0])
493
540
  minutesRaw = int(timeRaw[1])
494
541
  secondsRaw, microsecondsRaw, msw = decodeSecondsAndMicroSeconds(
495
- timeRaw[2],
496
- data["Exif.Photo.SubSecTimeOriginal"] if isExifTagUsable(data, "Exif.Photo.SubSecTimeOriginal", float) else "0",
542
+ timeRaw[2] if len(timeRaw) >= 3 else "0",
543
+ data[ssField] if isExifTagUsable(data, ssField, float) else "0",
497
544
  _,
498
545
  )
499
546
  warnings += msw
@@ -510,7 +557,7 @@ def decodeDateTimeOriginal(
510
557
 
511
558
  # Timezone handling
512
559
  # Try to read from EXIF
513
- tz = decodeTimeOffset(data, f"Exif.Photo.OffsetTime{'Original' if 'DateTimeOriginal' in datetimeField else ''}")
560
+ tz = decodeTimeOffset(data, f"{exifGroup}.OffsetTime{'Original' if 'DateTimeOriginal' in dtField else ''}")
514
561
  if tz is not None:
515
562
  d = d.replace(tzinfo=tz)
516
563
 
@@ -531,9 +578,7 @@ def decodeDateTimeOriginal(
531
578
 
532
579
  except ValueError as e:
533
580
  warnings.append(
534
- _("Skipping original date/time (from {datefield}) as it was not recognized: {v}").format(
535
- datefield=datetimeField, v=data[datetimeField]
536
- )
581
+ _("Skipping original date/time (from {datefield}) as it was not recognized: {v}").format(datefield=dtField, v=data[dtField])
537
582
  )
538
583
 
539
584
  return (d, warnings)
@@ -571,7 +616,7 @@ def decodeGPSDateTime(
571
616
  if timeRaw:
572
617
  seconds, microseconds, msw = decodeSecondsAndMicroSeconds(
573
618
  str(float(timeRaw[2])),
574
- data["Exif.Photo.SubSecTimeOriginal"] if isExifTagUsable(data, "Exif.Photo.SubSecTimeOriginal", float) else "0",
619
+ "0", # No SubSecTimeOriginal, it's only for DateTimeOriginal
575
620
  _,
576
621
  )
577
622
 
@@ -143,7 +143,35 @@ def sort_pictures(pictures: List[Picture], method: Optional[SortMethod] = SortMe
143
143
 
144
144
  # Sort based on picture ts
145
145
  elif strat == "time":
146
- pictures.sort(key=lambda p: p.metadata.ts.isoformat() if p.metadata is not None else "0000-00-00T00:00:00Z")
146
+ # Check if all pictures have GPS ts set
147
+ missingGpsTs = next(
148
+ (p for p in pictures if p.metadata is None or p.metadata.ts_by_source is None or p.metadata.ts_by_source.gps is None), None
149
+ )
150
+ if missingGpsTs:
151
+ # Check if all pictures have camera ts set
152
+ missingCamTs = next(
153
+ (p for p in pictures if p.metadata is None or p.metadata.ts_by_source is None or p.metadata.ts_by_source.camera is None),
154
+ None,
155
+ )
156
+ # Sort by best ts available
157
+ if missingCamTs:
158
+ pictures.sort(key=lambda p: p.metadata.ts.isoformat() if p.metadata is not None else "0000-00-00T00:00:00Z")
159
+ # Sort by camera ts
160
+ else:
161
+ pictures.sort(
162
+ key=lambda p: (
163
+ p.metadata.ts_by_source.camera.isoformat(), # type: ignore
164
+ p.metadata.ts_by_source.gps.isoformat() if p.metadata.ts_by_source.gps else "0000-00-00T00:00:00Z", # type: ignore
165
+ )
166
+ )
167
+ # Sort by GPS ts
168
+ else:
169
+ pictures.sort(
170
+ key=lambda p: (
171
+ p.metadata.ts_by_source.gps.isoformat(), # type: ignore
172
+ p.metadata.ts_by_source.camera.isoformat() if p.metadata.ts_by_source.camera else "0000-00-00T00:00:00Z", # type: ignore
173
+ )
174
+ )
147
175
 
148
176
  if order == "desc":
149
177
  pictures.reverse()
@@ -244,9 +272,22 @@ def split_in_sequences(pictures: List[Picture], splitParams: Optional[SplitParam
244
272
  continue
245
273
 
246
274
  # Time delta
247
- timeOutOfDelta = (
248
- False if splitParams.maxTime is None else (abs(lastPic.metadata.ts - pic.metadata.ts)).total_seconds() > splitParams.maxTime
249
- )
275
+ timeDelta = lastPic.metadata.ts - pic.metadata.ts
276
+ if (
277
+ lastPic.metadata.ts_by_source
278
+ and lastPic.metadata.ts_by_source.gps
279
+ and pic.metadata.ts_by_source
280
+ and pic.metadata.ts_by_source.gps
281
+ ):
282
+ timeDelta = lastPic.metadata.ts_by_source.gps - pic.metadata.ts_by_source.gps
283
+ elif (
284
+ lastPic.metadata.ts_by_source
285
+ and lastPic.metadata.ts_by_source.camera
286
+ and pic.metadata.ts_by_source
287
+ and pic.metadata.ts_by_source.camera
288
+ ):
289
+ timeDelta = lastPic.metadata.ts_by_source.camera - pic.metadata.ts_by_source.camera
290
+ timeOutOfDelta = False if splitParams.maxTime is None else (abs(timeDelta)).total_seconds() > splitParams.maxTime
250
291
 
251
292
  # Distance delta
252
293
  distance = lastPic.distance_to(pic)
@@ -8,7 +8,7 @@ msgstr ""
8
8
  "Project-Id-Version: PACKAGE VERSION\n"
9
9
  "Report-Msgid-Bugs-To: \n"
10
10
  "POT-Creation-Date: 2024-07-10 13:05+0200\n"
11
- "PO-Revision-Date: 2024-07-13 20:42+0000\n"
11
+ "PO-Revision-Date: 2024-08-07 13:42+0000\n"
12
12
  "Last-Translator: Bastian Greshake Tzovaras <bastian@gedankenstuecke.de>\n"
13
13
  "Language-Team: German <http://weblate.panoramax.xyz/projects/panoramax/"
14
14
  "tag-reader/de/>\n"
@@ -163,3 +163,7 @@ msgstr ""
163
163
  #, python-brace-format
164
164
  msgid "Unsupported key in additional tags ({k})"
165
165
  msgstr "Nicht unterstützter Schlüssel in den zusätzlichen Attributen ({k})"
166
+
167
+ #: geopic_tag_reader/main.py:37
168
+ msgid "Yaw:"
169
+ msgstr "Gierwinkel:"
@@ -7,8 +7,8 @@ msgid ""
7
7
  msgstr ""
8
8
  "Project-Id-Version: PACKAGE VERSION\n"
9
9
  "Report-Msgid-Bugs-To: \n"
10
- "POT-Creation-Date: 2024-07-30 16:49+0200\n"
11
- "PO-Revision-Date: 2024-07-30 16:49+0200\n"
10
+ "POT-Creation-Date: 2024-10-09 10:49+0200\n"
11
+ "PO-Revision-Date: 2024-10-09 10:49+0200\n"
12
12
  "Last-Translator: Automatically generated\n"
13
13
  "Language-Team: none\n"
14
14
  "Language: en\n"
@@ -29,88 +29,100 @@ msgstr "Longitude:"
29
29
  msgid "Timestamp:"
30
30
  msgstr "Timestamp:"
31
31
 
32
- #: geopic_tag_reader/main.py:29
32
+ #: geopic_tag_reader/main.py:30 geopic_tag_reader/main.py:31
33
+ msgid "not set"
34
+ msgstr "not set"
35
+
36
+ #: geopic_tag_reader/main.py:30
37
+ msgid "(GPS)"
38
+ msgstr "(GPS)"
39
+
40
+ #: geopic_tag_reader/main.py:31
41
+ msgid "(Camera)"
42
+ msgstr "(Camera)"
43
+
44
+ #: geopic_tag_reader/main.py:32
33
45
  msgid "Heading:"
34
46
  msgstr "Heading:"
35
47
 
36
- #: geopic_tag_reader/main.py:30
48
+ #: geopic_tag_reader/main.py:33
37
49
  msgid "Type:"
38
50
  msgstr "Type:"
39
51
 
40
- #: geopic_tag_reader/main.py:31
52
+ #: geopic_tag_reader/main.py:34
41
53
  msgid "Make:"
42
54
  msgstr "Make:"
43
55
 
44
- #: geopic_tag_reader/main.py:32
56
+ #: geopic_tag_reader/main.py:35
45
57
  msgid "Model:"
46
58
  msgstr "Model:"
47
59
 
48
- #: geopic_tag_reader/main.py:33
60
+ #: geopic_tag_reader/main.py:36
49
61
  msgid "Focal length:"
50
62
  msgstr "Focal length:"
51
63
 
52
- #: geopic_tag_reader/main.py:34
64
+ #: geopic_tag_reader/main.py:37
53
65
  msgid "Crop parameters:"
54
66
  msgstr "Crop parameters:"
55
67
 
56
- #: geopic_tag_reader/main.py:35
68
+ #: geopic_tag_reader/main.py:38
57
69
  msgid "Pitch:"
58
70
  msgstr "Pitch:"
59
71
 
60
- #: geopic_tag_reader/main.py:36
72
+ #: geopic_tag_reader/main.py:39
61
73
  msgid "Roll:"
62
74
  msgstr "Roll:"
63
75
 
64
- #: geopic_tag_reader/main.py:37
76
+ #: geopic_tag_reader/main.py:40
65
77
  msgid "Yaw:"
66
78
  msgstr "Yaw:"
67
79
 
68
- #: geopic_tag_reader/main.py:40
80
+ #: geopic_tag_reader/main.py:43
69
81
  msgid "Warnings raised by reader:"
70
82
  msgstr "Warnings raised by reader:"
71
83
 
72
- #: geopic_tag_reader/reader.py:186
84
+ #: geopic_tag_reader/reader.py:218
73
85
  msgid "Read latitude is out of WGS84 bounds (should be in [-90, 90])"
74
86
  msgstr "Read latitude is out of WGS84 bounds (should be in [-90, 90])"
75
87
 
76
- #: geopic_tag_reader/reader.py:188
88
+ #: geopic_tag_reader/reader.py:220
77
89
  msgid "Read longitude is out of WGS84 bounds (should be in [-180, 180])"
78
90
  msgstr "Read longitude is out of WGS84 bounds (should be in [-180, 180])"
79
91
 
80
- #: geopic_tag_reader/reader.py:230
92
+ #: geopic_tag_reader/reader.py:248
81
93
  #, python-brace-format
82
94
  msgid "Skipping Mapillary date/time as it was not recognized: {v}"
83
95
  msgstr "Skipping Mapillary date/time as it was not recognized: {v}"
84
96
 
85
- #: geopic_tag_reader/reader.py:337
97
+ #: geopic_tag_reader/reader.py:374
86
98
  msgid "No GPS coordinates or broken coordinates in picture EXIF tags"
87
99
  msgstr "No GPS coordinates or broken coordinates in picture EXIF tags"
88
100
 
89
- #: geopic_tag_reader/reader.py:343
101
+ #: geopic_tag_reader/reader.py:380
90
102
  msgid "No valid date in picture EXIF tags"
91
103
  msgstr "No valid date in picture EXIF tags"
92
104
 
93
- #: geopic_tag_reader/reader.py:348
105
+ #: geopic_tag_reader/reader.py:385
94
106
  msgid "The picture is missing mandatory metadata:"
95
107
  msgstr "The picture is missing mandatory metadata:"
96
108
 
97
- #: geopic_tag_reader/reader.py:437 geopic_tag_reader/reader.py:466
109
+ #: geopic_tag_reader/reader.py:476 geopic_tag_reader/reader.py:505
98
110
  msgid "GPSLatitudeRef not found, assuming GPSLatitudeRef is North"
99
111
  msgstr "GPSLatitudeRef not found, assuming GPSLatitudeRef is North"
100
112
 
101
- #: geopic_tag_reader/reader.py:445
113
+ #: geopic_tag_reader/reader.py:484
102
114
  msgid "Broken GPS coordinates in picture EXIF tags"
103
115
  msgstr "Broken GPS coordinates in picture EXIF tags"
104
116
 
105
- #: geopic_tag_reader/reader.py:448 geopic_tag_reader/reader.py:472
117
+ #: geopic_tag_reader/reader.py:487 geopic_tag_reader/reader.py:511
106
118
  msgid "GPSLongitudeRef not found, assuming GPSLongitudeRef is East"
107
119
  msgstr "GPSLongitudeRef not found, assuming GPSLongitudeRef is East"
108
120
 
109
- #: geopic_tag_reader/reader.py:525
121
+ #: geopic_tag_reader/reader.py:572
110
122
  msgid "Precise timezone information not found, fallback to UTC"
111
123
  msgstr "Precise timezone information not found, fallback to UTC"
112
124
 
113
- #: geopic_tag_reader/reader.py:530
125
+ #: geopic_tag_reader/reader.py:577
114
126
  msgid ""
115
127
  "Precise timezone information not found (and no GPS coordinates to help), "
116
128
  "fallback to UTC"
@@ -118,14 +130,14 @@ msgstr ""
118
130
  "Precise timezone information not found (and no GPS coordinates to help), "
119
131
  "fallback to UTC"
120
132
 
121
- #: geopic_tag_reader/reader.py:534
133
+ #: geopic_tag_reader/reader.py:581
122
134
  #, python-brace-format
123
135
  msgid ""
124
136
  "Skipping original date/time (from {datefield}) as it was not recognized: {v}"
125
137
  msgstr ""
126
138
  "Skipping original date/time (from {datefield}) as it was not recognized: {v}"
127
139
 
128
- #: geopic_tag_reader/reader.py:568
140
+ #: geopic_tag_reader/reader.py:613
129
141
  #, python-brace-format
130
142
  msgid ""
131
143
  "GPSTimeStamp and GPSDateTime don't contain supported time format (in {group} "
@@ -134,12 +146,12 @@ msgstr ""
134
146
  "GPSTimeStamp and GPSDateTime don't contain supported time format (in {group} "
135
147
  "group)"
136
148
 
137
- #: geopic_tag_reader/reader.py:599
149
+ #: geopic_tag_reader/reader.py:644
138
150
  #, python-brace-format
139
151
  msgid "Skipping GPS date/time ({group} group) as it was not recognized: {v}"
140
152
  msgstr "Skipping GPS date/time ({group} group) as it was not recognized: {v}"
141
153
 
142
- #: geopic_tag_reader/reader.py:625
154
+ #: geopic_tag_reader/reader.py:670
143
155
  #, python-brace-format
144
156
  msgid ""
145
157
  "Microseconds read from decimal seconds value ({microsecondsFromSeconds}) is "