Coverage for qubalab/objects/geometry.py: 88%
34 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-31 11:24 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-31 11:24 +0000
1import geojson.geometry
2import geojson
3from typing import Union
6class ImagePlane(dict):
7 """
8 An additional property of a geometry containing z and t indices.
9 """
11 def __init__(self, z: int = 0, t: int = 0):
12 """
13 :param z: the z-stack of the geometry
14 :param t: the time point of the geometry
15 """
16 dict.__init__(self, z=z, t=t)
18 def __getattr__(self, name):
19 try:
20 return self[name]
21 except KeyError:
22 raise AttributeError(name)
24 def __setattr__(self, name, value):
25 raise AttributeError('ImagePlane is immutable')
27 def __delattr__(self, name):
28 raise AttributeError('ImagePlane is immutable')
31def add_plane_to_geometry(
32 geometry: Union[geojson.geometry.Geometry, geojson.Feature],
33 z: int = None,
34 t: int = None,
35 preferred_geometry_key: str =None
36) -> geojson.geometry.Geometry:
37 """
38 Create a GeoJSON Geometry object with an additional 'plane' property containing z and t indices.
40 If indices are unspecified, they will be taken from the geometry's 'plane' property, if present,
41 or else z or t attributes otherwise.
42 If z and t values cannot be found in either of these locations, defaults (z=0 and t=0) will be
43 used instead.
45 The 'plane' property is immutable.
47 :param geometry: a GeoJSON feature or geometry. It must not be a FeatureCollection
48 :param z: the z-stack index this geometry should have
49 :param t: the timepoint this geometry should have
50 :param preferred_geometry_key: if the provided geometry is a feature, and this feature has a 'extra_geometries'
51 property, then this parameter can be used as a key to retrieve the geometry to
52 consider from the 'extra_geometries' dictionnary
53 :return: a GeoJSON Geometry containing an additional 'plane' property containing z and t indices
54 :raises ValueError: when the provided geometry is a FeatureCollection
55 """
56 if geometry is None:
57 return None
59 if geometry['type'] == 'Feature':
60 feature = geometry
61 if preferred_geometry_key is not None and 'extra_geometries' in feature.properties:
62 geometry = feature.properties['extra_geometries'].get(preferred_geometry_key, feature.geometry)
63 else:
64 geometry = feature.geometry
65 elif geometry['type'] == 'FeatureCollection':
66 raise ValueError('Cannot convert FeatureCollection to single Geometry')
68 if z is None or t is None:
69 plane = getattr(geometry, 'plane', None)
70 if z is None:
71 z = getattr(plane, 'z', 0) if plane is not None else getattr(geometry, 'z', 0)
72 if t is None:
73 t = getattr(plane, 't', 0) if plane is not None else getattr(geometry, 't', 0)
75 geometry = geojson.GeoJSON.to_instance(geometry, strict=False)
76 geometry.plane = ImagePlane(z, t)
77 return geometry