Coverage for gws-app/gws/base/search/finder.py: 0%

74 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-17 01:37 +0200

1from typing import Optional, cast 

2 

3import gws 

4import gws.base.model 

5import gws.base.template 

6import gws.base.shape 

7import gws.config.util 

8import gws.lib.uom 

9 

10 

11class SpatialContext(gws.Enum): 

12 map = 'map' 

13 """search in the map extent""" 

14 view = 'view' 

15 """search in the client view extent""" 

16 

17 

18class Config(gws.ConfigWithAccess): 

19 models: Optional[list[gws.ext.config.model]] 

20 """data models for features""" 

21 spatialContext: Optional[SpatialContext] = SpatialContext.map 

22 """spatial context for keyword searches""" 

23 templates: Optional[list[gws.ext.config.template]] 

24 """feature formatting templates""" 

25 title: Optional[str] 

26 """provider title""" 

27 withGeometry: bool = True 

28 """enable geometry search""" 

29 withKeyword: bool = True 

30 """enable keyword search""" 

31 withFilter: bool = True 

32 """enable filter search""" 

33 

34 

35class Object(gws.Finder): 

36 spatialContext: SpatialContext 

37 

38 def configure(self): 

39 self.templates = [] 

40 self.models = [] 

41 

42 self.withKeyword = self.cfg('withKeyword', default=True) 

43 self.withGeometry = self.cfg('withGeometry', default=True) 

44 self.withFilter = self.cfg('withFilter', default=True) 

45 

46 self.spatialContext = self.cfg('spatialContext', default=SpatialContext.map) 

47 self.title = self.cfg('title', default='') 

48 

49 ## 

50 

51 def configure_models(self): 

52 return gws.config.util.configure_models_for(self) 

53 

54 def configure_templates(self): 

55 return gws.config.util.configure_templates_for(self) 

56 

57 ## 

58 

59 def can_run(self, search, user): 

60 has_param = False 

61 

62 if search.keyword: 

63 if not self.supportsKeywordSearch or not self.withKeyword: 

64 gws.log.debug(f'can run: False: {self} {search.keyword=} {self.supportsKeywordSearch=} {self.withKeyword=}') 

65 return False 

66 has_param = True 

67 

68 if search.shape: 

69 if not self.supportsGeometrySearch or not self.withGeometry: 

70 gws.log.debug(f'can run: False: {self} <shape> {self.supportsGeometrySearch=} {self.withGeometry=}') 

71 return False 

72 has_param = True 

73 

74 if search.ogcFilter: 

75 if not self.supportsFilterSearch or not self.withFilter: 

76 gws.log.debug(f'can run: False: {self} {search.ogcFilter=} {self.supportsFilterSearch=} {self.withFilter=}') 

77 return False 

78 has_param = True 

79 

80 return has_param 

81 

82 def context_shape(self, search: gws.SearchQuery) -> gws.Shape: 

83 if search.shape: 

84 return search.shape 

85 if self.spatialContext == SpatialContext.view and search.bounds: 

86 return gws.base.shape.from_bounds(search.bounds) 

87 if search.project: 

88 return gws.base.shape.from_bounds(search.project.map.bounds) 

89 

90 def run(self, search, user, layer=None): 

91 model = self.root.app.modelMgr.find_model(self, layer, user=user, access=gws.Access.read) 

92 if not model: 

93 gws.log.debug(f'no model for {user.uid=} in finder {self.uid!r}') 

94 return [] 

95 search = cast(gws.SearchQuery, gws.u.merge(search, shape=self.context_shape(search))) 

96 mc = gws.ModelContext(op=gws.ModelOperation.read, target=gws.ModelReadTarget.searchResults, user=user) 

97 return model.find_features(search, mc)