Coverage for qubalab/objects/geometry.py: 88%

34 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-10-07 15:29 +0000

1import geojson.geometry 

2import geojson 

3from typing import Union, Optional 

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: Optional[int] = None, 

34 t: Optional[int] = None, 

35 preferred_geometry_key: Optional[str] = None, 

36) -> Optional[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 isinstance(geometry, geojson.Feature): 

60 feature = geometry 

61 if ( 

62 preferred_geometry_key is not None 

63 and "extra_geometries" in feature.properties 

64 ): 

65 geometry = feature.properties["extra_geometries"].get( 

66 preferred_geometry_key, feature.geometry 

67 ) 

68 else: 

69 geometry = feature.geometry 

70 elif isinstance(geometry, geojson.FeatureCollection): 

71 raise ValueError("Cannot convert FeatureCollection to single Geometry") 

72 

73 if z is None or t is None: 

74 plane = getattr(geometry, "plane", None) 

75 if z is None: 

76 z = ( 

77 getattr(plane, "z", 0) 

78 if plane is not None 

79 else getattr(geometry, "z", 0) 

80 ) 

81 if t is None: 

82 t = ( 

83 getattr(plane, "t", 0) 

84 if plane is not None 

85 else getattr(geometry, "t", 0) 

86 ) 

87 

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

89 geometry.plane = ImagePlane(z, t) 

90 return geometry