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

1import geojson.geometry 

2import geojson 

3from typing import Union 

4 

5 

6class ImagePlane(dict): 

7 """ 

8 An additional property of a geometry containing z and t indices. 

9 """ 

10 

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) 

17 

18 def __getattr__(self, name): 

19 try: 

20 return self[name] 

21 except KeyError: 

22 raise AttributeError(name) 

23 

24 def __setattr__(self, name, value): 

25 raise AttributeError('ImagePlane is immutable') 

26 

27 def __delattr__(self, name): 

28 raise AttributeError('ImagePlane is immutable') 

29 

30 

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. 

39 

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. 

44 

45 The 'plane' property is immutable. 

46 

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 

58 

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') 

67 

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) 

74 

75 geometry = geojson.GeoJSON.to_instance(geometry, strict=False) 

76 geometry.plane = ImagePlane(z, t) 

77 return geometry