geopic-tag-reader 1.1.0__py3-none-any.whl → 1.1.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.
@@ -2,4 +2,4 @@
2
2
  GeoPicTagReader
3
3
  """
4
4
 
5
- __version__ = "1.1.0"
5
+ __version__ = "1.1.1"
geopic_tag_reader/main.py CHANGED
@@ -29,6 +29,8 @@ def read(
29
29
  print("Model:", metadata.model)
30
30
  print("Focal length:", metadata.focal_length)
31
31
  print("Crop parameters:", metadata.crop)
32
+ print("Pitch:", metadata.pitch)
33
+ print("Roll:", metadata.roll)
32
34
 
33
35
  if len(metadata.tagreader_warnings) > 0:
34
36
  print("Warnings raised by reader:")
@@ -46,7 +46,7 @@ class GeoPicTags:
46
46
  lat (float): GPS Latitude (in WGS84)
47
47
  lon (float): GPS Longitude (in WGS84)
48
48
  ts (datetime): The capture date (date & time with timezone)
49
- heading (int): Picture heading (in degrees, North = 0°, East = 90°, South = 180°, West = 270°)
49
+ heading (int): Picture heading/yaw (in degrees, North = 0°, East = 90°, South = 180°, West = 270°)
50
50
  type (str): The kind of picture (flat, equirectangular)
51
51
  make (str): The camera manufacturer name
52
52
  model (str): The camera model name
@@ -55,6 +55,8 @@ class GeoPicTags:
55
55
  exif (dict[str, str]): Raw EXIF tags from picture (following Exiv2 naming scheme, see https://exiv2.org/metadata.html)
56
56
  tagreader_warnings (list[str]): List of thrown warnings during metadata reading
57
57
  altitude (float): altitude (in m) (optional)
58
+ pitch (float): Picture pitch angle, compared to horizon (in degrees, bottom = -90°, horizon = 0°, top = 90°)
59
+ roll (float): Picture roll angle, on a right/left axis (in degrees, left-arm down = -90°, flat = 0°, right-arm down = 90°)
58
60
 
59
61
 
60
62
  Implementation note: this needs to be sync with the PartialGeoPicTags structure
@@ -72,6 +74,8 @@ class GeoPicTags:
72
74
  exif: Dict[str, str] = field(default_factory=lambda: {})
73
75
  tagreader_warnings: List[str] = field(default_factory=lambda: [])
74
76
  altitude: Optional[float] = None
77
+ pitch: Optional[float] = None
78
+ roll: Optional[float] = None
75
79
 
76
80
 
77
81
  class InvalidExifException(Exception):
@@ -100,6 +104,8 @@ class PartialGeoPicTags:
100
104
  exif: Dict[str, str] = field(default_factory=lambda: {})
101
105
  tagreader_warnings: List[str] = field(default_factory=lambda: [])
102
106
  altitude: Optional[float] = None
107
+ pitch: Optional[float] = None
108
+ roll: Optional[float] = None
103
109
 
104
110
 
105
111
  class PartialExifException(Exception):
@@ -213,7 +219,7 @@ def readPictureMetadata(picture: bytes) -> GeoPicTags:
213
219
  except Exception as e:
214
220
  warnings.append("Skipping Mapillary date/time as it was not recognized:\n\t" + str(e))
215
221
 
216
- # Heading
222
+ # Heading/Yaw
217
223
  heading = None
218
224
  if isExifTagUsable(data, "Xmp.GPano.PoseHeadingDegrees", float) and isExifTagUsable(data, "Exif.GPSInfo.GPSImgDirection", Fraction):
219
225
  gpsDir = int(round(float(Fraction(data["Exif.GPSInfo.GPSImgDirection"]))))
@@ -236,6 +242,35 @@ def readPictureMetadata(picture: bytes) -> GeoPicTags:
236
242
  elif "MAPCompassHeading" in data and isExifTagUsable(data["MAPCompassHeading"], "TrueHeading", float):
237
243
  heading = int(round(float(data["MAPCompassHeading"]["TrueHeading"])))
238
244
 
245
+ # Pitch & roll
246
+ pitch = None
247
+ roll = None
248
+ exifPRFields = ["Xmp.Camera.$$", "Exif.GPSInfo.GPS$$", "Xmp.GPano.Pose$$Degrees", "Xmp.GPano.InitialView$$Degrees"]
249
+ # For each potential EXIF field
250
+ for exifField in exifPRFields:
251
+ # Try out both Pitch & Roll variants
252
+ for checkField in ["Pitch", "Roll"]:
253
+ exifCheckField = exifField.replace("$$", checkField)
254
+ foundValue = None
255
+ # Look for float or fraction
256
+ if isExifTagUsable(data, exifCheckField, float):
257
+ foundValue = float(data[exifCheckField])
258
+ elif isExifTagUsable(data, exifCheckField, Fraction):
259
+ foundValue = float(Fraction(data[exifCheckField]))
260
+
261
+ # Save to correct variable (if not already set)
262
+ if foundValue is not None:
263
+ if checkField == "Pitch":
264
+ if pitch is None:
265
+ pitch = foundValue
266
+ else:
267
+ continue
268
+ elif checkField == "Roll":
269
+ if roll is None:
270
+ roll = foundValue
271
+ else:
272
+ continue
273
+
239
274
  # Make and model
240
275
  make = data.get("Exif.Image.Make") or data.get("MAPDeviceMake")
241
276
  model = data.get("Exif.Image.Model") or data.get("MAPDeviceModel")
@@ -332,6 +367,8 @@ def readPictureMetadata(picture: bytes) -> GeoPicTags:
332
367
  exif=data,
333
368
  tagreader_warnings=warnings,
334
369
  altitude=altitude,
370
+ pitch=pitch,
371
+ roll=roll,
335
372
  ),
336
373
  )
337
374
 
@@ -349,6 +386,8 @@ def readPictureMetadata(picture: bytes) -> GeoPicTags:
349
386
  exif=data,
350
387
  tagreader_warnings=warnings,
351
388
  altitude=altitude,
389
+ pitch=pitch,
390
+ roll=roll,
352
391
  )
353
392
 
354
393
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: geopic-tag-reader
3
- Version: 1.1.0
3
+ Version: 1.1.1
4
4
  Summary: GeoPicTagReader
5
5
  Author-email: Adrien PAVIE <panieravide@riseup.net>
6
6
  Requires-Python: >=3.8
@@ -0,0 +1,12 @@
1
+ geopic_tag_reader/__init__.py,sha256=7hT1At7Ce4FtNeMuBZa7cDah_cJoIhJrnQWbEAF0BE8,47
2
+ geopic_tag_reader/camera.py,sha256=2Sr0jAt3RXUWazYMnkwF6J6lVnKvSp7Ac8g7yOHehVA,1643
3
+ geopic_tag_reader/main.py,sha256=ZEZaZEeaDxRjrVMwhR5lUYJWKkUcjd8avjqm7JxJdhM,3219
4
+ geopic_tag_reader/model.py,sha256=rsWVE3T1kpNsKXX8iv6xb_3PCVY6Ea7iU9WOqUgXklU,129
5
+ geopic_tag_reader/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ geopic_tag_reader/reader.py,sha256=4yoQU-ljOgLmaH_hc1m4o1YkSNgaPfM38NVmiM7rpbE,24543
7
+ geopic_tag_reader/writer.py,sha256=QmQqQpWgb6AL3Y0Kuzy7PF1asUsTVDq9buwJXfFSRq8,8672
8
+ geopic_tag_reader-1.1.1.dist-info/entry_points.txt,sha256=c9YwjCNhxveDf-61_aSRlzcpoutvM6KQCerlzaVt_JU,64
9
+ geopic_tag_reader-1.1.1.dist-info/LICENSE,sha256=oHWDwXkJJb9zJzThMN3F9Li4yFhz1qxOUByouY7L3bI,1070
10
+ geopic_tag_reader-1.1.1.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
11
+ geopic_tag_reader-1.1.1.dist-info/METADATA,sha256=iMhClAI5r1h2jpB_o-dwcSP3QVz4PuBPf4jWmZ_10Ks,6303
12
+ geopic_tag_reader-1.1.1.dist-info/RECORD,,
@@ -1,12 +0,0 @@
1
- geopic_tag_reader/__init__.py,sha256=o8d20yL96tGKyj_0NXyBn_HJ2i1hofM-qTuKouf4ZkE,47
2
- geopic_tag_reader/camera.py,sha256=2Sr0jAt3RXUWazYMnkwF6J6lVnKvSp7Ac8g7yOHehVA,1643
3
- geopic_tag_reader/main.py,sha256=a0RmJIA0R5dTK1vzDZD3Q4MFFAiDv6pnRiFHjfIjeJU,3141
4
- geopic_tag_reader/model.py,sha256=rsWVE3T1kpNsKXX8iv6xb_3PCVY6Ea7iU9WOqUgXklU,129
5
- geopic_tag_reader/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- geopic_tag_reader/reader.py,sha256=w19zJ9CvdJyk_UxWcYX2T0DkhdQmw2xMzlAo1sR1ir0,22867
7
- geopic_tag_reader/writer.py,sha256=QmQqQpWgb6AL3Y0Kuzy7PF1asUsTVDq9buwJXfFSRq8,8672
8
- geopic_tag_reader-1.1.0.dist-info/entry_points.txt,sha256=c9YwjCNhxveDf-61_aSRlzcpoutvM6KQCerlzaVt_JU,64
9
- geopic_tag_reader-1.1.0.dist-info/LICENSE,sha256=oHWDwXkJJb9zJzThMN3F9Li4yFhz1qxOUByouY7L3bI,1070
10
- geopic_tag_reader-1.1.0.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
11
- geopic_tag_reader-1.1.0.dist-info/METADATA,sha256=DJ9OiZyvVGNMdveGev-V33kO9sqPPo-V9SADIezd0I4,6303
12
- geopic_tag_reader-1.1.0.dist-info/RECORD,,