lets-plot 4.8.1rc1__cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.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.
Files changed (97) hide show
  1. lets_plot/__init__.py +382 -0
  2. lets_plot/_global_settings.py +192 -0
  3. lets_plot/_kbridge.py +197 -0
  4. lets_plot/_type_utils.py +133 -0
  5. lets_plot/_version.py +6 -0
  6. lets_plot/bistro/__init__.py +16 -0
  7. lets_plot/bistro/_plot2d_common.py +106 -0
  8. lets_plot/bistro/corr.py +448 -0
  9. lets_plot/bistro/im.py +196 -0
  10. lets_plot/bistro/joint.py +192 -0
  11. lets_plot/bistro/qq.py +207 -0
  12. lets_plot/bistro/residual.py +341 -0
  13. lets_plot/bistro/waterfall.py +332 -0
  14. lets_plot/export/__init__.py +6 -0
  15. lets_plot/export/ggsave_.py +172 -0
  16. lets_plot/frontend_context/__init__.py +8 -0
  17. lets_plot/frontend_context/_configuration.py +140 -0
  18. lets_plot/frontend_context/_dynamic_configure_html.py +115 -0
  19. lets_plot/frontend_context/_frontend_ctx.py +16 -0
  20. lets_plot/frontend_context/_html_contexts.py +223 -0
  21. lets_plot/frontend_context/_intellij_python_json_ctx.py +38 -0
  22. lets_plot/frontend_context/_isolated_webview_panel_ctx.py +81 -0
  23. lets_plot/frontend_context/_json_contexts.py +39 -0
  24. lets_plot/frontend_context/_jupyter_notebook_ctx.py +82 -0
  25. lets_plot/frontend_context/_mime_types.py +7 -0
  26. lets_plot/frontend_context/_static_html_page_ctx.py +76 -0
  27. lets_plot/frontend_context/_static_svg_ctx.py +26 -0
  28. lets_plot/frontend_context/_webbr_html_page_ctx.py +29 -0
  29. lets_plot/frontend_context/sandbox.py +5 -0
  30. lets_plot/geo_data/__init__.py +19 -0
  31. lets_plot/geo_data/core.py +335 -0
  32. lets_plot/geo_data/geocoder.py +988 -0
  33. lets_plot/geo_data/geocodes.py +512 -0
  34. lets_plot/geo_data/gis/__init__.py +0 -0
  35. lets_plot/geo_data/gis/fluent_dict.py +201 -0
  36. lets_plot/geo_data/gis/geocoding_service.py +42 -0
  37. lets_plot/geo_data/gis/geometry.py +91 -0
  38. lets_plot/geo_data/gis/json_request.py +232 -0
  39. lets_plot/geo_data/gis/json_response.py +308 -0
  40. lets_plot/geo_data/gis/request.py +492 -0
  41. lets_plot/geo_data/gis/response.py +247 -0
  42. lets_plot/geo_data/livemap_helper.py +65 -0
  43. lets_plot/geo_data/to_geo_data_frame.py +141 -0
  44. lets_plot/geo_data/type_assertion.py +34 -0
  45. lets_plot/geo_data_internals/__init__.py +4 -0
  46. lets_plot/geo_data_internals/constants.py +13 -0
  47. lets_plot/geo_data_internals/utils.py +33 -0
  48. lets_plot/mapping.py +115 -0
  49. lets_plot/package_data/lets-plot.min.js +3 -0
  50. lets_plot/plot/__init__.py +64 -0
  51. lets_plot/plot/_global_theme.py +14 -0
  52. lets_plot/plot/annotation.py +290 -0
  53. lets_plot/plot/coord.py +242 -0
  54. lets_plot/plot/core.py +1071 -0
  55. lets_plot/plot/expand_limits_.py +78 -0
  56. lets_plot/plot/facet.py +210 -0
  57. lets_plot/plot/font_features.py +71 -0
  58. lets_plot/plot/geom.py +9146 -0
  59. lets_plot/plot/geom_extras.py +53 -0
  60. lets_plot/plot/geom_function_.py +219 -0
  61. lets_plot/plot/geom_imshow_.py +393 -0
  62. lets_plot/plot/geom_livemap_.py +343 -0
  63. lets_plot/plot/ggbunch_.py +96 -0
  64. lets_plot/plot/gggrid_.py +139 -0
  65. lets_plot/plot/ggtb_.py +81 -0
  66. lets_plot/plot/guide.py +231 -0
  67. lets_plot/plot/label.py +187 -0
  68. lets_plot/plot/marginal_layer.py +181 -0
  69. lets_plot/plot/plot.py +245 -0
  70. lets_plot/plot/pos.py +344 -0
  71. lets_plot/plot/sampling.py +338 -0
  72. lets_plot/plot/sandbox_.py +26 -0
  73. lets_plot/plot/scale.py +3580 -0
  74. lets_plot/plot/scale_colormap_mpl.py +300 -0
  75. lets_plot/plot/scale_convenience.py +155 -0
  76. lets_plot/plot/scale_identity_.py +653 -0
  77. lets_plot/plot/scale_position.py +1342 -0
  78. lets_plot/plot/series_meta.py +209 -0
  79. lets_plot/plot/stat.py +585 -0
  80. lets_plot/plot/subplots.py +331 -0
  81. lets_plot/plot/subplots_util.py +24 -0
  82. lets_plot/plot/theme_.py +790 -0
  83. lets_plot/plot/theme_set.py +418 -0
  84. lets_plot/plot/tooltip.py +486 -0
  85. lets_plot/plot/util.py +267 -0
  86. lets_plot/settings_utils.py +244 -0
  87. lets_plot/tilesets.py +429 -0
  88. lets_plot-4.8.1rc1.dist-info/METADATA +221 -0
  89. lets_plot-4.8.1rc1.dist-info/RECORD +97 -0
  90. lets_plot-4.8.1rc1.dist-info/WHEEL +6 -0
  91. lets_plot-4.8.1rc1.dist-info/licenses/LICENSE +21 -0
  92. lets_plot-4.8.1rc1.dist-info/licenses/licenses/LICENSE.FreeType +166 -0
  93. lets_plot-4.8.1rc1.dist-info/licenses/licenses/LICENSE.ImageMagick +106 -0
  94. lets_plot-4.8.1rc1.dist-info/licenses/licenses/LICENSE.expat +21 -0
  95. lets_plot-4.8.1rc1.dist-info/licenses/licenses/LICENSE.fontconfig +200 -0
  96. lets_plot-4.8.1rc1.dist-info/top_level.txt +2 -0
  97. lets_plot_kotlin_bridge.cpython-311-x86_64-linux-gnu.so +0 -0
@@ -0,0 +1,492 @@
1
+ import enum
2
+ from numbers import Number
3
+ from typing import Optional, List, Tuple, Union
4
+
5
+ from .geometry import GeoRect, GeoPoint
6
+ from ..type_assertion import assert_type, assert_list_type, assert_optional_type
7
+
8
+ MISSING_SCOPE_OR_REQUEST_EXCEPTION_TEXT = 'Missing required argument: scope or request.'
9
+ MISSING_LEVEL_OR_REQUEST_EXCEPTION_TEXT = 'Missing required argument: level or request.'
10
+ MISSING_LEVEL_AND_SCOPE_OR_REQUEST_EXCEPTION_TEXT = 'Missing required argument. You must enter level and scope or request.'
11
+
12
+ GeoId = str
13
+
14
+
15
+ class PayloadKind(enum.Enum):
16
+ highlights = 'highlights'
17
+ centroids = 'centroid'
18
+ boundaries = 'boundary'
19
+ limits = 'limit'
20
+ poisitions = 'position'
21
+
22
+
23
+ class RequestKind(enum.Enum):
24
+ explicit = 'by_id'
25
+ geocoding = 'by_geocoding'
26
+ reverse = 'reverse'
27
+
28
+
29
+ class IgnoringStrategyKind(enum.Enum):
30
+ skip_all = 'skip_all'
31
+ skip_missing = 'skip_missing'
32
+ skip_ambiguous = 'skip_ambiguous'
33
+ take_namesakes = 'take_namesakes'
34
+
35
+
36
+ class LevelKind(enum.Enum):
37
+ country = 'country'
38
+ state = 'state'
39
+ county = 'county'
40
+ city = 'city'
41
+
42
+
43
+ MODE_BY_GEOCODING = 'by_geocoding'
44
+ MODE_BY_ID = 'by_id'
45
+
46
+
47
+ class MapRegionKind(enum.Enum):
48
+ id = True
49
+ name = False
50
+ place = 'place'
51
+
52
+
53
+ class MapRegion:
54
+ '''
55
+ Represents three different entities:
56
+ scope - ids of already geocoded objects. The only kind of MapRegion allowed to store multiply objects
57
+ place - already geocoded single place. In addition to id it holds administrative level and requeted name.
58
+ Used mostly as parent object for geocoding other objects.
59
+ with_name - single name, not yet geocoded.
60
+ '''
61
+ @staticmethod
62
+ def name_or_none(place: Optional['MapRegion']):
63
+ if place is None:
64
+ return None
65
+
66
+ if place.kind == MapRegionKind.place:
67
+ return place.request()
68
+
69
+ if place.kind == MapRegionKind.name:
70
+ return place.name()
71
+
72
+ raise ValueError('MapRegion with kind \'{}\' doesn\'t have a name'.format(place.kind))
73
+
74
+
75
+ @staticmethod
76
+ def place(id: str, request: Optional[str], level_kind: LevelKind):
77
+ assert_type(id, str)
78
+ assert_optional_type(request, str)
79
+ assert_type(level_kind, LevelKind)
80
+ return MapRegion(MapRegionKind.place, [id], request, level_kind)
81
+
82
+ @staticmethod
83
+ def scope(parent_ids: List[str]):
84
+ assert_list_type(parent_ids, str)
85
+ return MapRegion(MapRegionKind.id, parent_ids)
86
+
87
+ @staticmethod
88
+ def with_name(name: str):
89
+ assert_type(name, str)
90
+ return MapRegion(MapRegionKind.name, [name])
91
+
92
+ def __init__(self, kind: MapRegionKind, values: List[str], request: Optional[str] = None, level_kind: Optional[LevelKind] = None):
93
+ assert_type(kind, MapRegionKind)
94
+ assert_list_type(values, str)
95
+ assert_optional_type(request, str)
96
+ assert_optional_type(level_kind, LevelKind)
97
+
98
+ self.kind: MapRegionKind = kind
99
+ self.values: Tuple[str] = tuple(values, )
100
+ self._request:Optional[str] = request
101
+ self._level_kind: Optional[LevelKind] = level_kind
102
+ self._hash = hash((self.values, self.kind))
103
+
104
+ def request(self) -> Optional[str]:
105
+ assert self.kind == MapRegionKind.place, 'Invalid MapRegion kind. Expected \'place\', but was ' + str(self.kind)
106
+ assert_optional_type(self._request, str)
107
+ return self._request
108
+
109
+ def name(self) -> str:
110
+ assert self.kind == MapRegionKind.name, 'Invalid MapRegion kind. Expected \'name\', but was ' + str(self.kind)
111
+ assert_type(self.values[0], str)
112
+ return self.values[0]
113
+
114
+ def level_kind(self) -> Optional[LevelKind]:
115
+ assert self.kind == MapRegionKind.place, 'Invalid MapRegion kind: only place contains level_kind'
116
+ return self._level_kind
117
+
118
+ def __eq__(self, other: 'MapRegion'):
119
+ return isinstance(other, MapRegion) \
120
+ and self.kind == other.kind \
121
+ and self.values == other.values \
122
+ and self._request == other._request \
123
+ and self._level_kind == other._level_kind
124
+
125
+ def __ne__(self, o: object) -> bool:
126
+ return not self == o
127
+
128
+ def __str__(self):
129
+ if self.kind == MapRegionKind.place:
130
+ return '{} {} {}'.format(str(self.values), self._request, self._level_kind)
131
+
132
+ if self.kind == MapRegionKind.name:
133
+ return self.values[0]
134
+
135
+ if self.kind == MapRegionKind.id:
136
+ return ",".join(self.values)
137
+
138
+ return str(self.values)
139
+
140
+ def __hash__(self):
141
+ return self._hash
142
+
143
+
144
+ class AmbiguityResolver:
145
+
146
+ @staticmethod
147
+ def empty() -> 'AmbiguityResolver':
148
+ return AmbiguityResolver()
149
+
150
+ def __init__(self,
151
+ ignoring_strategy: Optional[IgnoringStrategyKind] = None,
152
+ closest_coord: Optional[GeoPoint] = None,
153
+ box: Optional[GeoRect] = None):
154
+ assert_optional_type(ignoring_strategy, IgnoringStrategyKind)
155
+ assert_optional_type(closest_coord, GeoPoint)
156
+ assert_optional_type(box, GeoRect)
157
+
158
+ self.ignoring_strategy: IgnoringStrategyKind = ignoring_strategy
159
+ self.closest_coord: Optional[GeoPoint] = closest_coord
160
+ self.box: Optional[GeoRect] = box
161
+
162
+ def __eq__(self, o):
163
+ return isinstance(o, AmbiguityResolver) \
164
+ and self.ignoring_strategy == o.ignoring_strategy \
165
+ and self.closest_coord == o.closest_coord \
166
+ and self.box == o.box
167
+
168
+ def __ne__(self, o):
169
+ return not self == o
170
+
171
+
172
+ class RegionQuery:
173
+ def __init__(self,
174
+ request: Optional[str],
175
+ scope: Optional[MapRegion] = None,
176
+ ambiguity_resolver: AmbiguityResolver = AmbiguityResolver.empty(),
177
+ country: Optional[MapRegion] = None,
178
+ state: Optional[MapRegion] = None,
179
+ county: Optional[MapRegion] = None
180
+ ):
181
+ assert_optional_type(request, str)
182
+ assert_optional_type(scope, MapRegion)
183
+ assert_type(ambiguity_resolver, AmbiguityResolver)
184
+ assert_optional_type(county, MapRegion)
185
+ assert_optional_type(state, MapRegion)
186
+ assert_optional_type(country, MapRegion)
187
+
188
+ self.request: Optional[str] = request
189
+ self.scope: Optional[MapRegion] = scope
190
+ self.ambiguity_resolver: AmbiguityResolver = ambiguity_resolver
191
+ self.country: Optional[MapRegion] = country
192
+ self.state: Optional[MapRegion] = state
193
+ self.county: Optional[MapRegion] = county
194
+
195
+ def __eq__(self, o: object) -> bool:
196
+ return isinstance(o, RegionQuery) \
197
+ and self.request == o.request \
198
+ and self.scope == o.scope \
199
+ and self.ambiguity_resolver == o.ambiguity_resolver \
200
+ and self.country == o.country \
201
+ and self.state == o.state \
202
+ and self.county == o.county
203
+
204
+ def __ne__(self, o: object) -> bool:
205
+ return not self == o
206
+
207
+ def __str__(self):
208
+ return str(self.request) + ' in ' + str(self.scope)
209
+
210
+
211
+ class Request:
212
+ def __init__(self, requested_payload: List[PayloadKind], resolution: Optional[Number]):
213
+ assert_list_type(requested_payload, PayloadKind)
214
+ assert_optional_type(resolution, Number)
215
+
216
+ assert requested_payload is not None
217
+
218
+ self.requested_payload: List[PayloadKind] = requested_payload
219
+ self.resolution: Optional[int] = resolution
220
+
221
+ def __eq__(self, o: object) -> bool:
222
+ return isinstance(o, Request) \
223
+ and self.requested_payload == o.requested_payload \
224
+ and self.resolution == o.resolution
225
+
226
+ def __ne__(self, o: object) -> bool:
227
+ return not self == o
228
+
229
+
230
+ class GeocodingRequest(Request):
231
+
232
+ @staticmethod
233
+ def _check_required_parameters(region_queries: List[RegionQuery],
234
+ level: Optional[LevelKind]) -> None:
235
+
236
+ if len(region_queries) == 0 and not level:
237
+ raise ValueError(MISSING_LEVEL_AND_SCOPE_OR_REQUEST_EXCEPTION_TEXT)
238
+
239
+ for query in region_queries:
240
+ if not query.request and not level and not query.scope:
241
+ raise ValueError(MISSING_LEVEL_AND_SCOPE_OR_REQUEST_EXCEPTION_TEXT)
242
+
243
+ if not query.request and not level and query.scope:
244
+ raise ValueError(MISSING_LEVEL_OR_REQUEST_EXCEPTION_TEXT)
245
+
246
+ if not query.request and not level and not query.scope:
247
+ raise ValueError(MISSING_SCOPE_OR_REQUEST_EXCEPTION_TEXT)
248
+
249
+ def __init__(self,
250
+ requested_payload: List[PayloadKind],
251
+ resolution: Optional[int],
252
+ region_queries: List[RegionQuery],
253
+ scope: List[MapRegion],
254
+ level: Optional[LevelKind],
255
+ namesake_example_limit: int,
256
+ allow_ambiguous: bool
257
+ ):
258
+ super().__init__(requested_payload, resolution)
259
+ assert_list_type(requested_payload, PayloadKind)
260
+ assert_optional_type(resolution, int)
261
+ assert_list_type(region_queries, RegionQuery)
262
+ assert_optional_type(level, LevelKind)
263
+ assert_type(namesake_example_limit, int)
264
+ assert_type(allow_ambiguous, bool)
265
+
266
+ self._check_required_parameters(region_queries, level)
267
+
268
+ assert region_queries is not None
269
+ assert namesake_example_limit is not None
270
+
271
+ self.region_queries: List[RegionQuery] = region_queries
272
+ self.scope: List[MapRegion] = scope
273
+ self.level: Optional[LevelKind] = level
274
+ self.namesake_example_limit: int = namesake_example_limit
275
+ self.allow_ambiguous: bool = allow_ambiguous
276
+
277
+ def __eq__(self, o: object) -> bool:
278
+ return isinstance(o, GeocodingRequest) \
279
+ and super().__eq__(o) \
280
+ and self.region_queries == o.region_queries \
281
+ and self.level == o.level \
282
+ and self.namesake_example_limit == o.namesake_example_limit \
283
+ and self.allow_ambiguous == o.allow_ambiguous
284
+
285
+ def __ne__(self, o: object) -> bool:
286
+ return not self == o
287
+
288
+
289
+ class ExplicitRequest(Request):
290
+ def __init__(self,
291
+ requested_payload: List[PayloadKind],
292
+ ids: List[GeoId],
293
+ resolution: Optional[int] = None
294
+ ):
295
+ super().__init__(requested_payload, resolution)
296
+
297
+ assert_list_type(requested_payload, PayloadKind)
298
+ assert_list_type(ids, GeoId)
299
+ assert_optional_type(resolution, int)
300
+
301
+ assert ids is not None
302
+ self.geo_object_list: List[GeoId] = ids
303
+
304
+ def __eq__(self, o: object) -> bool:
305
+ return isinstance(o, ExplicitRequest) \
306
+ and super().__eq__(o) \
307
+ and self.geo_object_list == o.geo_object_list
308
+
309
+ def __ne__(self, o: object) -> bool:
310
+ return not self == o
311
+
312
+
313
+ class ReverseGeocodingRequest(Request):
314
+ def __init__(self,
315
+ coordinates: List[GeoPoint],
316
+ level: LevelKind,
317
+ scope: Optional[MapRegion],
318
+ requested_payload: List[PayloadKind],
319
+ resolution: Optional[int] = None
320
+ ):
321
+ super().__init__(requested_payload, resolution)
322
+ assert_list_type(coordinates, GeoPoint)
323
+ assert_type(level, LevelKind)
324
+ assert_optional_type(scope, MapRegion)
325
+
326
+ self.coordinates: List[GeoPoint] = coordinates
327
+ self.level: LevelKind = level
328
+ self.scope: Optional[MapRegion] = scope
329
+
330
+ def __eq__(self, o: object) -> bool:
331
+ return isinstance(o, ReverseGeocodingRequest) \
332
+ and super().__eq__(o) \
333
+ and self.coordinates == o.coordinates \
334
+ and self.level == o.level \
335
+ and self.scope == o.scope
336
+
337
+ def __ne__(self, o: object) -> bool:
338
+ return not self == o
339
+
340
+
341
+ class RequestBuilder:
342
+ def __init__(self):
343
+ self.request_kind: Optional[RequestKind] = None
344
+ self.requested_payload: List[PayloadKind] = []
345
+ self.resolution: Optional[int] = None
346
+ self.ids: List[str] = []
347
+ self.region_queries: List[RegionQuery] = []
348
+ self.scope: List[MapRegion] = []
349
+ self.level: Optional[LevelKind] = None
350
+ self.namesake_limit: int = 10
351
+ self.allow_ambiguous: bool = False
352
+
353
+ # reverse
354
+ self.reverse_coordinates: Optional[List[GeoPoint]] = None
355
+ self.reverse_scope: Optional[MapRegion] = None
356
+
357
+ def set_reverse_coordinates(self, coordinates: List[GeoPoint]) -> 'RequestBuilder':
358
+ assert_list_type(coordinates, GeoPoint)
359
+ self.reverse_coordinates = coordinates
360
+ return self
361
+
362
+ def set_reverse_scope(self, region: Optional[MapRegion]) -> 'RequestBuilder':
363
+ assert_optional_type(region, MapRegion)
364
+ self.reverse_scope = region
365
+ return self
366
+
367
+ def set_request_kind(self, v: RequestKind) -> 'RequestBuilder':
368
+ assert_type(v, RequestKind)
369
+ self.request_kind = v
370
+ return self
371
+
372
+ def set_requested_payload(self, v: List[PayloadKind]) -> 'RequestBuilder':
373
+ assert_list_type(v, PayloadKind)
374
+ self.requested_payload = v
375
+ return self
376
+
377
+ def set_resolution(self, v: Optional[int]) -> 'RequestBuilder':
378
+ assert_optional_type(v, int)
379
+ self.resolution = v
380
+ return self
381
+
382
+ def set_ids(self, v: List[str]) -> 'RequestBuilder':
383
+ assert_list_type(v, str)
384
+ self.ids = v
385
+ return self
386
+
387
+ def set_queries(self, v: List[RegionQuery]) -> 'RequestBuilder':
388
+ assert_list_type(v, RegionQuery)
389
+ self.region_queries = v
390
+ return self
391
+
392
+ def set_scope(self, v: List[MapRegion]) -> 'RequestBuilder':
393
+ assert_list_type(v, MapRegion)
394
+ self.scope = v
395
+ return self
396
+
397
+ def set_level(self, v: LevelKind) -> 'RequestBuilder':
398
+ assert_optional_type(v, LevelKind)
399
+ self.level = v
400
+ return self
401
+
402
+ def set_namesake_limit(self, v: int) -> 'RequestBuilder':
403
+ assert_optional_type(v, int)
404
+ self.namesake_limit = v
405
+ return self
406
+
407
+ def set_allow_ambiguous(self, v: bool) -> 'RequestBuilder':
408
+ assert_optional_type(v, bool)
409
+ self.allow_ambiguous = v
410
+ return self
411
+
412
+ def build(self) -> Union[ExplicitRequest, GeocodingRequest, ReverseGeocodingRequest]:
413
+ if self.request_kind == RequestKind.explicit:
414
+ return ExplicitRequest(self.requested_payload, self.ids, self.resolution)
415
+
416
+ elif self.request_kind == RequestKind.geocoding:
417
+ return GeocodingRequest(self.requested_payload, self.resolution, self.region_queries, self.scope,
418
+ self.level, self.namesake_limit, self.allow_ambiguous)
419
+
420
+ elif self.request_kind == RequestKind.reverse:
421
+ assert self.reverse_coordinates is not None
422
+ assert self.level is not None
423
+ return ReverseGeocodingRequest(self.reverse_coordinates, self.level, self.reverse_scope,
424
+ self.requested_payload, self.resolution)
425
+
426
+ else:
427
+ raise ValueError('Unknown mode: ' + str(self.request_kind))
428
+
429
+
430
+ class MapRegionBuilder:
431
+ def __init__(self):
432
+ self.parent_kind: Optional[bool] = None
433
+ self.parent_values: List[str] = []
434
+
435
+ def set_parent_kind(self, kind: bool) -> 'MapRegionBuilder':
436
+ self.parent_kind = kind
437
+ return self
438
+
439
+ def set_parent_values(self, values: List[str]) -> 'MapRegionBuilder':
440
+ self.parent_values = values
441
+ return self
442
+
443
+ def build(self) -> Optional[MapRegion]:
444
+ if self.parent_kind is not None:
445
+ return MapRegion(MapRegionKind(self.parent_kind), self.parent_values)
446
+ else:
447
+ return None
448
+
449
+
450
+ class RegionQueryBuilder:
451
+ def __init__(self):
452
+ self.request: Optional[str] = None
453
+ self.scope: Optional[MapRegion] = None
454
+ self.ignoring_strategy: Optional[IgnoringStrategyKind] = None
455
+ self.closest_coord: Optional[GeoPoint] = None
456
+ self.box: Optional[GeoRect] = None
457
+
458
+ def set_request(self, request: Optional[str]) -> 'RegionQueryBuilder':
459
+ assert_optional_type(request, str)
460
+ self.request = request
461
+ return self
462
+
463
+ def set_scope(self, parent: Optional[MapRegion]) -> 'RegionQueryBuilder':
464
+ assert_optional_type(parent, MapRegion)
465
+ self.scope = parent
466
+ return self
467
+
468
+ def set_ignoring_strategy(self, ignoring_strategy: IgnoringStrategyKind):
469
+ assert_type(ignoring_strategy, IgnoringStrategyKind)
470
+ self.ignoring_strategy = ignoring_strategy
471
+ return self
472
+
473
+ def set_closest_coord(self, closest_coord: Optional[GeoPoint]):
474
+ assert_optional_type(closest_coord, GeoPoint)
475
+ self.closest_coord = closest_coord
476
+ return self
477
+
478
+ def set_box(self, box: Optional[GeoRect]):
479
+ assert_optional_type(box, GeoRect)
480
+ self.box = box
481
+ return self
482
+
483
+ def build(self) -> RegionQuery:
484
+ return RegionQuery(self.request, self.scope, self._build_ambiguity_resolver())
485
+
486
+ def _build_ambiguity_resolver(self) -> AmbiguityResolver:
487
+ if self.ignoring_strategy is not None \
488
+ or self.closest_coord is not None \
489
+ or self.box is not None:
490
+ return AmbiguityResolver(self.ignoring_strategy, self.closest_coord, self.box)
491
+ else:
492
+ return AmbiguityResolver.empty()