flet-map 0.1.0.dev2__py3-none-any.whl → 0.2.0.dev45__py3-none-any.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.

Potentially problematic release.


This version of flet-map might be problematic. Click here for more details.

Files changed (37) hide show
  1. flet_map/__init__.py +30 -19
  2. flet_map/circle_layer.py +46 -139
  3. flet_map/map.py +462 -604
  4. flet_map/map_layer.py +14 -20
  5. flet_map/marker_layer.py +83 -169
  6. flet_map/polygon_layer.py +95 -232
  7. flet_map/polyline_layer.py +85 -262
  8. flet_map/rich_attribution.py +48 -126
  9. flet_map/simple_attribution.py +24 -75
  10. flet_map/source_attribution.py +73 -0
  11. flet_map/tile_layer.py +224 -266
  12. flet_map/types.py +953 -0
  13. flet_map-0.2.0.dev45.dist-info/METADATA +66 -0
  14. flet_map-0.2.0.dev45.dist-info/RECORD +35 -0
  15. {flet_map-0.1.0.dev2.dist-info → flet_map-0.2.0.dev45.dist-info}/WHEEL +1 -1
  16. flet_map-0.2.0.dev45.dist-info/licenses/LICENSE +201 -0
  17. flutter/flet_map/CHANGELOG.md +4 -0
  18. flutter/flet_map/lib/flet_map.dart +1 -1
  19. flutter/flet_map/lib/src/circle_layer.dart +15 -25
  20. flutter/flet_map/lib/src/extension.dart +37 -0
  21. flutter/flet_map/lib/src/map.dart +93 -105
  22. flutter/flet_map/lib/src/marker_layer.dart +21 -33
  23. flutter/flet_map/lib/src/polygon_layer.dart +32 -52
  24. flutter/flet_map/lib/src/polyline_layer.dart +41 -64
  25. flutter/flet_map/lib/src/rich_attribution.dart +34 -34
  26. flutter/flet_map/lib/src/simple_attribution.dart +9 -23
  27. flutter/flet_map/lib/src/tile_layer.dart +47 -60
  28. flutter/flet_map/lib/src/utils/attribution_alignment.dart +1 -3
  29. flutter/flet_map/lib/src/utils/map.dart +257 -203
  30. flutter/flet_map/pubspec.lock +179 -130
  31. flutter/flet_map/pubspec.yaml +10 -5
  32. flet_map/text_source_attribution.py +0 -87
  33. flet_map-0.1.0.dev2.dist-info/METADATA +0 -168
  34. flet_map-0.1.0.dev2.dist-info/RECORD +0 -34
  35. flutter/flet_map/lib/src/create_control.dart +0 -70
  36. flutter/flet_map/lib/src/text_source_attribution.dart +0 -29
  37. {flet_map-0.1.0.dev2.dist-info → flet_map-0.2.0.dev45.dist-info}/top_level.txt +0 -0
flet_map/map_layer.py CHANGED
@@ -1,26 +1,20 @@
1
- from typing import Any, Optional
1
+ import flet as ft
2
2
 
3
- from flet.core.control import Control
4
- from flet.core.ref import Ref
3
+ __all__ = ["MapLayer"]
5
4
 
6
5
 
7
- class MapLayer(Control):
6
+ @ft.control("MapLayer")
7
+ class MapLayer(ft.Control):
8
8
  """
9
9
  Abstract class for all map layers.
10
- """
11
10
 
12
- def __init__(
13
- self,
14
- #
15
- # Control
16
- #
17
- ref: Optional[Ref] = None,
18
- visible: Optional[bool] = None,
19
- data: Any = None,
20
- ):
21
- Control.__init__(
22
- self,
23
- ref=ref,
24
- visible=visible,
25
- data=data,
26
- )
11
+ The following layers are available:
12
+
13
+ - [`CircleLayer`][(p).]
14
+ - [`MarkerLayer`][(p).]
15
+ - [`PolygonLayer`][(p).]
16
+ - [`PolylineLayer`][(p).]
17
+ - [`RichAttribution`][(p).]
18
+ - [`SimpleAttribution`][(p).]
19
+ - [`TileLayer`][(p).]
20
+ """
flet_map/marker_layer.py CHANGED
@@ -1,183 +1,97 @@
1
- from typing import Any, List, Optional
2
-
3
- from flet.core.alignment import Alignment
4
- from flet.core.control import Control, OptionalNumber
5
- from flet_map.map import MapLatitudeLongitude
6
- from flet_map.map_layer import MapLayer
7
- from flet.core.ref import Ref
8
-
9
-
10
- class Marker(Control):
11
- """
12
- A marker displayed on the Map at the specified location through the MarkerLayer.
13
-
14
- -----
15
-
16
- Online docs: https://flet.dev/docs/controls/mapmarker
17
- """
18
-
19
- def __init__(
20
- self,
21
- content: Control,
22
- coordinates: MapLatitudeLongitude,
23
- rotate: Optional[bool] = None,
24
- height: OptionalNumber = None,
25
- width: OptionalNumber = None,
26
- alignment: Optional[Alignment] = None,
27
- #
28
- # Control
29
- #
30
- ref: Optional[Ref] = None,
31
- visible: Optional[bool] = None,
32
- data: Any = None,
33
- ):
34
- Control.__init__(
35
- self,
36
- ref=ref,
37
- visible=visible,
38
- data=data,
39
- )
40
-
41
- self.content = content
42
- self.coordinates = coordinates
43
- self.rotate = rotate
44
- self.height = height
45
- self.width = width
46
- self.alignment = alignment
47
-
48
- def _get_control_name(self):
49
- return "map_marker"
50
-
51
- def _get_children(self):
52
- return [self.__content]
1
+ from dataclasses import field
2
+ from typing import List, Optional
53
3
 
54
- def before_update(self):
55
- super().before_update()
56
- self._set_attr_json("alignment", self.__alignment)
57
- self._set_attr_json("coordinates", self.__coordinates)
58
-
59
- # content
60
- @property
61
- def content(self) -> Optional[Alignment]:
62
- return self.__content
63
-
64
- @content.setter
65
- def content(self, value: Optional[Alignment]):
66
- self.__content = value
67
-
68
- # rotate
69
- @property
70
- def rotate(self) -> bool:
71
- return self._get_attr("rotate", data_type="bool", def_value=False)
72
-
73
- @rotate.setter
74
- def rotate(self, value: Optional[bool]):
75
- self._set_attr("rotate", value)
76
-
77
- # height
78
- @property
79
- def height(self) -> float:
80
- return self._get_attr("height", data_type="float", def_value=30.0)
81
-
82
- @height.setter
83
- def height(self, value: OptionalNumber):
84
- assert value is None or value >= 0, "height cannot be negative"
85
- self._set_attr("height", value)
86
-
87
- # width
88
- @property
89
- def width(self) -> float:
90
- return self._get_attr("width", data_type="float", def_value=30.0)
91
-
92
- @width.setter
93
- def width(self, value: OptionalNumber):
94
- assert value is None or value >= 0, "width cannot be negative"
95
- self._set_attr("width", value)
96
-
97
- # alignment
98
- @property
99
- def alignment(self) -> Optional[Alignment]:
100
- return self.__alignment
101
-
102
- @alignment.setter
103
- def alignment(self, value: Optional[Alignment]):
104
- self.__alignment = value
105
-
106
- # coordinates
107
- @property
108
- def coordinates(self) -> MapLatitudeLongitude:
109
- return self.__coordinates
110
-
111
- @coordinates.setter
112
- def coordinates(self, value: MapLatitudeLongitude):
113
- self.__coordinates = value
4
+ import flet as ft
114
5
 
6
+ from .map_layer import MapLayer
7
+ from .types import MapLatitudeLongitude
115
8
 
116
- class MarkerLayer(MapLayer):
9
+ __all__ = ["Marker", "MarkerLayer"]
10
+
11
+
12
+ @ft.control("Marker")
13
+ class Marker(ft.Control):
117
14
  """
118
- A layer to display Markers.
15
+ A marker displayed on the Map at the specified location through the [`MarkerLayer`][(p).].
119
16
 
120
- -----
17
+ Raises:
18
+ AssertionError: If the [`content`][(c).] is not visible, or if [`height`][(c).] or [`width`][(c).] are negative.
19
+ """
121
20
 
122
- Online docs: https://flet.dev/docs/controls/mapmarkerlayer
21
+ content: ft.Control
22
+ """
23
+ The content to be displayed at [`coordinates`][..].
24
+
25
+ Note:
26
+ Must be provided and visible.
123
27
  """
124
28
 
125
- def __init__(
126
- self,
127
- markers: List[Marker],
128
- alignment: Optional[Alignment] = None,
129
- rotate: Optional[bool] = None,
130
- #
131
- # MapLayer
132
- #
133
- ref: Optional[Ref] = None,
134
- visible: Optional[bool] = None,
135
- data: Any = None,
136
- ):
137
- MapLayer.__init__(
138
- self,
139
- ref=ref,
140
- visible=visible,
141
- data=data,
142
- )
29
+ coordinates: MapLatitudeLongitude
30
+ """
31
+ The coordinates of the marker.
32
+
33
+ This will be the center of the marker, if `alignment=ft.Alignment.center()`.
34
+ """
35
+
36
+ rotate: Optional[bool] = None
37
+ """
38
+ Whether to counter rotate this marker to the map's rotation, to keep a fixed orientation.
39
+ So, when `True`, this marker will always appear upright and vertical from the user's perspective.
40
+
41
+ Note: this is not used to apply a custom rotation in degrees to the marker.
42
+
43
+ Defaults to the value of the parent [`MarkerLayer.rotate`][(p).].
44
+ """
143
45
 
144
- self.markers = markers
145
- self.alignment = alignment
146
- self.rotate = rotate
46
+ height: ft.Number = 30.0
47
+ """
48
+ The height of the [`content`][..] Control.
49
+
50
+ Note:
51
+ Must be non-negative.
52
+ """
147
53
 
148
- def _get_control_name(self):
149
- return "map_marker_layer"
54
+ width: ft.Number = 30.0
55
+ """
56
+ The width of the [`content`][..] Control.
57
+
58
+ Note:
59
+ Must be non-negative.
60
+ """
150
61
 
151
- def _get_children(self):
152
- return self.__markers
62
+ alignment: Optional[ft.Alignment] = None
63
+ """
64
+ Alignment of the marker relative to the normal center at [`coordinates`][..].
65
+
66
+ Defaults to the value of the parent [`MarkerLayer.alignment`][(m).].
67
+ """
153
68
 
154
69
  def before_update(self):
155
70
  super().before_update()
156
- self._set_attr_json("alignment", self.__alignment)
157
-
158
- # alignment
159
- @property
160
- def alignment(self) -> Optional[Alignment]:
161
- return self.__alignment
162
-
163
- @alignment.setter
164
- def alignment(self, value: Optional[Alignment]):
165
- self.__alignment = value
166
-
167
- # markers
168
- @property
169
- def markers(self) -> List[Marker]:
170
- return self.__markers
171
-
172
- @markers.setter
173
- def markers(self, value: List[Marker]):
174
- self.__markers = value
175
-
176
- # rotate
177
- @property
178
- def rotate(self) -> bool:
179
- return self._get_attr("rotate", data_type="bool", def_value=False)
180
-
181
- @rotate.setter
182
- def rotate(self, value: Optional[bool]):
183
- self._set_attr("rotate", value)
71
+ assert self.content.visible, "content must be visible"
72
+ assert self.height >= 0, "height must be greater than or equal to 0"
73
+ assert self.width >= 0, "width must be greater than or equal to 0"
74
+
75
+
76
+ @ft.control("MarkerLayer")
77
+ class MarkerLayer(MapLayer):
78
+ """
79
+ A layer to display Markers.
80
+ """
81
+
82
+ markers: List[Marker]
83
+ """
84
+ List of [`Marker`][(m).]s to display.
85
+ """
86
+
87
+ alignment: Optional[ft.Alignment] = field(
88
+ default_factory=lambda: ft.Alignment.center()
89
+ )
90
+ """
91
+ Alignment of each marker relative to its normal center at `Marker.coordinates`.
92
+ """
93
+
94
+ rotate: bool = False
95
+ """
96
+ Whether to counter-rotate `markers` to the map's rotation, to keep a fixed orientation.
97
+ """
flet_map/polygon_layer.py CHANGED
@@ -1,262 +1,125 @@
1
- from typing import Any, List, Optional
1
+ from typing import List, Optional
2
2
 
3
- from flet.core.control import Control, OptionalNumber
4
- from flet_map.map import MapLatitudeLongitude
5
- from flet_map.map_layer import MapLayer
6
- from flet.core.ref import Ref
7
- from flet.core.text_style import TextStyle
8
- from flet.core.types import ColorEnums, ColorValue, StrokeCap, StrokeJoin
3
+ import flet as ft
9
4
 
5
+ from .map_layer import MapLayer
6
+ from .types import MapLatitudeLongitude
10
7
 
11
- class PolygonMarker(Control):
12
- """
13
- A marker for the PolygonLayer.
8
+ __all__ = ["PolygonMarker", "PolygonLayer"]
14
9
 
15
- -----
16
10
 
17
- Online docs: https://flet.dev/docs/controls/mappolygonmarker
11
+ @ft.control("PolygonMarker")
12
+ class PolygonMarker(ft.Control):
13
+ """
14
+ A marker for the [`PolygonLayer`][(p).].
18
15
  """
19
16
 
20
- def __init__(
21
- self,
22
- coordinates: List[MapLatitudeLongitude],
23
- label: Optional[str] = None,
24
- label_text_style: Optional[TextStyle] = None,
25
- border_color: Optional[ColorValue] = None,
26
- color: Optional[ColorValue] = None,
27
- border_stroke_width: OptionalNumber = None,
28
- disable_holes_border: Optional[bool] = None,
29
- rotate_label: Optional[bool] = None,
30
- stroke_cap: Optional[StrokeCap] = None,
31
- stroke_join: Optional[StrokeJoin] = None,
32
- #
33
- # Control
34
- #
35
- ref: Optional[Ref] = None,
36
- visible: Optional[bool] = None,
37
- data: Any = None,
38
- ):
39
- Control.__init__(
40
- self,
41
- ref=ref,
42
- visible=visible,
43
- data=data,
44
- )
45
-
46
- self.coordinates = coordinates
47
- self.label = label
48
- self.label_text_style = label_text_style
49
- self.border_color = border_color
50
- self.color = color
51
- self.border_stroke_width = border_stroke_width
52
- self.disable_holes_border = disable_holes_border
53
- self.rotate_label = rotate_label
54
- self.stroke_cap = stroke_cap
55
- self.stroke_join = stroke_join
56
-
57
- def _get_control_name(self):
58
- return "map_polygon_marker"
59
-
60
- def before_update(self):
61
- super().before_update()
62
- self._set_attr_json("coordinates", self.__coordinates)
63
- if isinstance(self.__label_text_style, TextStyle):
64
- self._set_attr_json("labelTextStyle", self.__label_text_style)
65
-
66
- # stroke_cap
67
- @property
68
- def stroke_cap(self) -> Optional[StrokeCap]:
69
- return self.__stroke_cap
70
-
71
- @stroke_cap.setter
72
- def stroke_cap(self, value: Optional[StrokeCap]):
73
- self.__stroke_cap = value
74
- self._set_enum_attr("strokeCap", value, StrokeCap)
75
-
76
- # stroke_join
77
- @property
78
- def stroke_join(self) -> Optional[StrokeJoin]:
79
- return self.__stroke_join
80
-
81
- @stroke_join.setter
82
- def stroke_join(self, value: Optional[StrokeJoin]):
83
- self.__stroke_join = value
84
- self._set_enum_attr("strokeJoin", value, StrokeJoin)
85
-
86
- # label_text_style
87
- @property
88
- def label_text_style(self) -> Optional[TextStyle]:
89
- return self.__label_text_style
90
-
91
- @label_text_style.setter
92
- def label_text_style(self, value: Optional[TextStyle]):
93
- self.__label_text_style = value
94
-
95
- # rotate_label
96
- @property
97
- def rotate_label(self) -> bool:
98
- return self._get_attr("rotateLabel", data_type="bool", def_value=False)
99
-
100
- @rotate_label.setter
101
- def rotate_label(self, value: Optional[bool]):
102
- self._set_attr("rotateLabel", value)
103
-
104
- # label
105
- @property
106
- def label(self) -> Optional[str]:
107
- return self._get_attr("label")
17
+ coordinates: List[MapLatitudeLongitude]
18
+ """
19
+ The points for the outline of this polygon.
20
+ """
108
21
 
109
- @label.setter
110
- def label(self, value: Optional[str]):
111
- self._set_attr("label", value)
22
+ label: Optional[str] = None
23
+ """
24
+ An optional label for this polygon.
112
25
 
113
- # disable_holes_border
114
- @property
115
- def disable_holes_border(self) -> bool:
116
- return self._get_attr("disableHolesBorder", data_type="bool", def_value=False)
26
+ Note: specifying a label will reduce performance, as the internal
27
+ canvas must be drawn to and 'saved' more frequently to ensure the proper
28
+ stacking order is maintained. This can be avoided, potentially at the
29
+ expense of appearance, by setting [`PolygonLayer.draw_labels_last`][(p).].
30
+ """
117
31
 
118
- @disable_holes_border.setter
119
- def disable_holes_border(self, value: Optional[bool]):
120
- self._set_attr("disableHolesBorder", value)
32
+ label_text_style: Optional[ft.TextStyle] = None
33
+ """
34
+ The text style for the label.
35
+ """
121
36
 
122
- # color
123
- @property
124
- def color(self) -> Optional[ColorValue]:
125
- return self.__color
37
+ border_color: ft.ColorValue = ft.Colors.GREEN
38
+ """
39
+ The color of the border outline.
40
+ """
126
41
 
127
- @color.setter
128
- def color(self, value: Optional[ColorValue]):
129
- self.__color = value
130
- self._set_enum_attr("color", value, ColorEnums)
42
+ color: ft.ColorValue = ft.Colors.GREEN
43
+ """
44
+ The color of the polygon.
45
+ """
131
46
 
132
- # border_color
133
- @property
134
- def border_color(self) -> Optional[ColorValue]:
135
- return self.__border_color
47
+ border_stroke_width: ft.Number = 0.0
48
+ """
49
+ The width of the border outline.
50
+
51
+ Note:
52
+ Must be non-negative.
53
+ """
136
54
 
137
- @border_color.setter
138
- def border_color(self, value: Optional[ColorValue]):
139
- self.__border_color = value
140
- self._set_enum_attr("borderColor", value, ColorEnums)
55
+ disable_holes_border: bool = False
56
+ """
57
+ Whether holes should have borders.
58
+ """
141
59
 
142
- # border_stroke_width
143
- @property
144
- def border_stroke_width(self) -> float:
145
- return self._get_attr("borderStrokeWidth", data_type="float", def_value=0.0)
60
+ rotate_label: bool = False
61
+ """
62
+ Whether to rotate the label counter to the camera's rotation,
63
+ to ensure it remains upright.
64
+ """
146
65
 
147
- @border_stroke_width.setter
148
- def border_stroke_width(self, value: OptionalNumber):
149
- assert value is None or value >= 0, "border_stroke_width cannot be negative"
150
- self._set_attr("borderStrokeWidth", value)
66
+ stroke_cap: ft.StrokeCap = ft.StrokeCap.ROUND
67
+ """
68
+ Style to use for line endings.
69
+ """
151
70
 
152
- # coordinates
153
- @property
154
- def coordinates(self) -> List[MapLatitudeLongitude]:
155
- return self.__coordinates
71
+ stroke_join: ft.StrokeJoin = ft.StrokeJoin.ROUND
72
+ """
73
+ Style to use for line segment joins.
74
+ """
156
75
 
157
- @coordinates.setter
158
- def coordinates(self, value: List[MapLatitudeLongitude]):
159
- self.__coordinates = value
76
+ def before_update(self):
77
+ super().before_update()
78
+ assert (
79
+ self.border_stroke_width >= 0
80
+ ), "border_stroke_width must be greater than or equal to 0"
160
81
 
161
82
 
83
+ @ft.control("PolygonLayer")
162
84
  class PolygonLayer(MapLayer):
163
85
  """
164
86
  A layer to display PolygonMarkers.
165
-
166
- -----
167
-
168
- Online docs: https://flet.dev/docs/controls/mappolygonlayer
169
87
  """
170
88
 
171
- def __init__(
172
- self,
173
- polygons: List[PolygonMarker],
174
- polygon_culling: Optional[bool] = None,
175
- polygon_labels: Optional[bool] = None,
176
- draw_labels_last: Optional[bool] = None,
177
- simplification_tolerance: OptionalNumber = None,
178
- use_alternative_rendering: Optional[bool] = None,
179
- #
180
- # MapLayer
181
- #
182
- ref: Optional[Ref] = None,
183
- visible: Optional[bool] = None,
184
- data: Any = None,
185
- ):
186
- MapLayer.__init__(
187
- self,
188
- ref=ref,
189
- visible=visible,
190
- data=data,
191
- )
192
-
193
- self.polygons = polygons
194
- self.polygon_culling = polygon_culling
195
- self.polygon_labels = polygon_labels
196
- self.draw_labels_last = draw_labels_last
197
- self.simplification_tolerance = simplification_tolerance
198
- self.use_alternative_rendering = use_alternative_rendering
199
-
200
- def _get_control_name(self):
201
- return "map_polygon_layer"
202
-
203
- def _get_children(self):
204
- return self.__polygons
205
-
206
- # polygons
207
- @property
208
- def polygons(self) -> List[PolygonMarker]:
209
- return self.__polygons
210
-
211
- @polygons.setter
212
- def polygons(self, value: List[PolygonMarker]):
213
- self.__polygons = value
214
-
215
- # polygon_culling
216
- @property
217
- def polygon_culling(self) -> bool:
218
- return self._get_attr("polygonCulling", data_type="bool", def_value=False)
219
-
220
- @polygon_culling.setter
221
- def polygon_culling(self, value: Optional[bool]):
222
- self._set_attr("polygonCulling", value)
223
-
224
- # use_alternative_rendering
225
- @property
226
- def use_alternative_rendering(self) -> bool:
227
- return self._get_attr(
228
- "useAlternativeRendering", data_type="bool", def_value=False
229
- )
230
-
231
- @use_alternative_rendering.setter
232
- def use_alternative_rendering(self, value: Optional[bool]):
233
- self._set_attr("useAlternativeRendering", value)
234
-
235
- # polygon_labels
236
- @property
237
- def polygon_labels(self) -> bool:
238
- return self._get_attr("polygonLabels", data_type="bool", def_value=True)
89
+ polygons: List[PolygonMarker]
90
+ """
91
+ A list of [`PolygonMarker`][(p).]s to display.
92
+ """
239
93
 
240
- @polygon_labels.setter
241
- def polygon_labels(self, value: Optional[bool]):
242
- self._set_attr("polygonLabels", value)
94
+ polygon_culling: bool = True
95
+ """
96
+ Whether to cull polygons and polygon sections that are outside of the viewport.
97
+ """
243
98
 
244
- # simplification_tolerance
245
- @property
246
- def simplification_tolerance(self) -> float:
247
- return self._get_attr(
248
- "simplificationTolerance", data_type="float", def_value=0.5
249
- )
99
+ polygon_labels: bool = True
100
+ """
101
+ Whether to draw per-polygon labels.
102
+ """
250
103
 
251
- @simplification_tolerance.setter
252
- def simplification_tolerance(self, value: OptionalNumber):
253
- self._set_attr("simplificationTolerance", value)
104
+ draw_labels_last: bool = False
105
+ """
106
+ Whether to draw labels last and thus over all the polygons.
107
+ """
254
108
 
255
- # draw_labels_last
256
- @property
257
- def draw_labels_last(self) -> bool:
258
- return self._get_attr("drawLabelsLast", data_type="bool", def_value=False)
109
+ simplification_tolerance: ft.Number = 0.3
110
+ """
111
+
112
+ """
259
113
 
260
- @draw_labels_last.setter
261
- def draw_labels_last(self, value: Optional[bool]):
262
- self._set_attr("drawLabelsLast", value)
114
+ use_alternative_rendering: bool = False
115
+ """
116
+ Whether to use an alternative rendering pathway to draw polygons onto the
117
+ underlying `Canvas`, which can be more performant in 'some' circumstances.
118
+
119
+ This will not always improve performance, and there are other important
120
+ considerations before enabling it. It is intended for use when prior
121
+ profiling indicates more performance is required after other methods are
122
+ already in use. For example, it may worsen performance when there are a
123
+ huge number of polygons to triangulate - and so this is best used in
124
+ conjunction with simplification, not as a replacement.
125
+ """