flet-map 0.0.1__py3-none-any.whl → 0.1.0__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 (39) hide show
  1. flet_map/__init__.py +30 -1
  2. flet_map/circle_layer.py +156 -0
  3. flet_map/map.py +674 -0
  4. flet_map/map_layer.py +26 -0
  5. flet_map/marker_layer.py +183 -0
  6. flet_map/polygon_layer.py +262 -0
  7. flet_map/polyline_layer.py +292 -0
  8. flet_map/rich_attribution.py +141 -0
  9. flet_map/simple_attribution.py +86 -0
  10. flet_map/text_source_attribution.py +87 -0
  11. flet_map/tile_layer.py +278 -0
  12. flet_map-0.1.0.dist-info/METADATA +168 -0
  13. flet_map-0.1.0.dist-info/RECORD +34 -0
  14. {flet_map-0.0.1.dist-info → flet_map-0.1.0.dist-info}/WHEEL +2 -1
  15. flet_map-0.1.0.dist-info/top_level.txt +2 -0
  16. flutter/flet_map/CHANGELOG.md +3 -0
  17. flutter/flet_map/LICENSE +201 -0
  18. flutter/flet_map/README.md +3 -0
  19. flutter/flet_map/analysis_options.yaml +4 -0
  20. flutter/flet_map/lib/flet_map.dart +3 -0
  21. flutter/flet_map/lib/src/circle_layer.dart +43 -0
  22. flutter/flet_map/lib/src/create_control.dart +70 -0
  23. flutter/flet_map/lib/src/map.dart +140 -0
  24. flutter/flet_map/lib/src/marker_layer.dart +50 -0
  25. flutter/flet_map/lib/src/polygon_layer.dart +68 -0
  26. flutter/flet_map/lib/src/polyline_layer.dart +80 -0
  27. flutter/flet_map/lib/src/rich_attribution.dart +61 -0
  28. flutter/flet_map/lib/src/simple_attribution.dart +37 -0
  29. flutter/flet_map/lib/src/text_source_attribution.dart +29 -0
  30. flutter/flet_map/lib/src/tile_layer.dart +80 -0
  31. flutter/flet_map/lib/src/utils/attribution_alignment.dart +12 -0
  32. flutter/flet_map/lib/src/utils/map.dart +280 -0
  33. flutter/flet_map/pubspec.lock +831 -0
  34. flutter/flet_map/pubspec.yaml +21 -0
  35. .DS_Store +0 -0
  36. flet_map/.DS_Store +0 -0
  37. flet_map-0.0.1.dist-info/.DS_Store +0 -0
  38. flet_map-0.0.1.dist-info/METADATA +0 -14
  39. flet_map-0.0.1.dist-info/RECORD +0 -7
@@ -0,0 +1,61 @@
1
+ import 'package:flet/flet.dart';
2
+ import 'package:flutter/material.dart';
3
+ import 'package:flutter_map/flutter_map.dart';
4
+
5
+ import 'utils/attribution_alignment.dart';
6
+
7
+ class RichAttributionControl extends StatefulWidget {
8
+ final Control? parent;
9
+ final Control control;
10
+ final FletControlBackend backend;
11
+
12
+ const RichAttributionControl(
13
+ {super.key,
14
+ this.parent,
15
+ required this.control,
16
+ required this.backend});
17
+
18
+ @override
19
+ State<RichAttributionControl> createState() => _RichAttributionControlState();
20
+ }
21
+
22
+ class _RichAttributionControlState extends State<RichAttributionControl>
23
+ with FletStoreMixin {
24
+ @override
25
+ Widget build(BuildContext context) {
26
+ debugPrint("RichAttributionControl build: ${widget.control.id}");
27
+
28
+ return withControls(widget.control.childIds, (context, attributionsView) {
29
+ debugPrint("RichAttributionControlState build: ${widget.control.id}");
30
+
31
+ var attributions = attributionsView.controlViews
32
+ .map((v) => v.control)
33
+ .where((c) => c.type == "map_text_source_attribution" && c.isVisible)
34
+ .map((Control itemCtrl) {
35
+ return TextSourceAttribution(
36
+ itemCtrl.attrs["text"] ?? "Placeholder Text",
37
+ textStyle: parseTextStyle(Theme.of(context), itemCtrl, "textStyle"),
38
+ onTap: () {
39
+ widget.backend.triggerControlEvent(itemCtrl.id, "click");
40
+ },
41
+ prependCopyright: itemCtrl.attrBool("prependCopyright", true)!,
42
+ );
43
+ }).toList();
44
+
45
+ return RichAttributionWidget(
46
+ attributions: attributions,
47
+ permanentHeight: widget.control.attrDouble("permanentHeight", 24)!,
48
+ popupBackgroundColor: widget.control.attrColor("popupBgColor", context),
49
+ showFlutterMapAttribution:
50
+ widget.control.attrBool("showFlutterMapAttribution", true)!,
51
+ alignment: parseAttributionAlignment(
52
+ widget.control.attrString("alignment"),
53
+ AttributionAlignment.bottomRight)!,
54
+ popupBorderRadius:
55
+ parseBorderRadius(widget.control, "popupBorderRadius"),
56
+ popupInitialDisplayDuration: Duration(
57
+ seconds: widget.control.attrInt("popupInitialDisplayDuration", 0)!),
58
+ );
59
+ });
60
+ }
61
+ }
@@ -0,0 +1,37 @@
1
+ import 'package:flet/flet.dart';
2
+ import 'package:flutter/material.dart';
3
+ import 'package:flutter/widgets.dart';
4
+ import 'package:flutter_map/flutter_map.dart';
5
+
6
+ class SimpleAttributionControl extends StatefulWidget {
7
+ final Control? parent;
8
+ final Control control;
9
+ final FletControlBackend backend;
10
+
11
+ const SimpleAttributionControl(
12
+ {super.key,
13
+ this.parent,
14
+ required this.control,
15
+ required this.backend});
16
+
17
+ @override
18
+ State<SimpleAttributionControl> createState() =>
19
+ _SimpleAttributionControlState();
20
+ }
21
+
22
+ class _SimpleAttributionControlState extends State<SimpleAttributionControl> {
23
+ @override
24
+ Widget build(BuildContext context) {
25
+ debugPrint("SimpleAttributionControl build: ${widget.control.id}");
26
+
27
+ return SimpleAttributionWidget(
28
+ source: Text(widget.control.attrString("text", "Placeholder Text")!),
29
+ onTap: () {
30
+ widget.backend.triggerControlEvent(widget.control.id, "click");
31
+ },
32
+ backgroundColor: widget.control.attrColor("backgroundColor", context),
33
+ alignment:
34
+ parseAlignment(widget.control, "alignment", Alignment.bottomRight)!,
35
+ );
36
+ }
37
+ }
@@ -0,0 +1,29 @@
1
+ import 'package:flet/flet.dart';
2
+ import 'package:flutter/material.dart';
3
+ import 'package:flutter_map/flutter_map.dart';
4
+
5
+ class TextSourceAttributionControl extends StatelessWidget {
6
+ final Control? parent;
7
+ final Control control;
8
+ final FletControlBackend backend;
9
+
10
+ const TextSourceAttributionControl(
11
+ {super.key,
12
+ required this.parent,
13
+ required this.control,
14
+ required this.backend});
15
+
16
+ @override
17
+ Widget build(BuildContext context) {
18
+ debugPrint("TextSourceAttributionControl build: ${control.id}");
19
+
20
+ return TextSourceAttribution(
21
+ control.attrString("text", "Placeholder Text")!,
22
+ textStyle: parseTextStyle(Theme.of(context), control, "textStyle"),
23
+ onTap: () {
24
+ backend.triggerControlEvent(control.id, "click");
25
+ },
26
+ prependCopyright: control.attrBool("prependCopyright", true)!,
27
+ );
28
+ }
29
+ }
@@ -0,0 +1,80 @@
1
+ import 'dart:convert';
2
+
3
+ import 'package:flet/flet.dart';
4
+ import 'package:flutter/material.dart';
5
+ import 'package:flutter/widgets.dart';
6
+ import 'package:flutter_map/flutter_map.dart';
7
+ import 'package:flutter_map_cancellable_tile_provider/flutter_map_cancellable_tile_provider.dart';
8
+
9
+ import './utils/map.dart';
10
+
11
+ class TileLayerControl extends StatelessWidget with FletStoreMixin {
12
+ final Control? parent;
13
+ final Control control;
14
+ final FletControlBackend backend;
15
+
16
+ const TileLayerControl(
17
+ {super.key,
18
+ required this.parent,
19
+ required this.control,
20
+ required this.backend});
21
+
22
+ @override
23
+ Widget build(BuildContext context) {
24
+ debugPrint("TileLayerControl build: ${control.id}");
25
+
26
+ return withPageArgs((context, pageArgs) {
27
+ var errorImageSrc = control.attrString("errorImageSrc");
28
+
29
+ ImageProvider<Object>? errorImage;
30
+
31
+ if (errorImageSrc != null) {
32
+ var assetSrc =
33
+ getAssetSrc((errorImageSrc), pageArgs.pageUri!, pageArgs.assetsDir);
34
+
35
+ if (assetSrc.isFile) {
36
+ // from File
37
+ errorImage = AssetImage(assetSrc.path);
38
+ } else {
39
+ // URL
40
+ errorImage = NetworkImage(assetSrc.path);
41
+ }
42
+ }
43
+ var subdomains = control.attrString("subdomains");
44
+ var additionalOptions = control.attrString("additionalOptions");
45
+ Widget tile = TileLayer(
46
+ urlTemplate: control.attrString("urlTemplate", "")!,
47
+ fallbackUrl: control.attrString("fallbackUrl", "")!,
48
+ subdomains: subdomains != null
49
+ ? jsonDecode(subdomains).cast<String>()
50
+ : ['a', 'b', 'c'],
51
+ tileProvider: CancellableNetworkTileProvider(),
52
+ tileDisplay: const TileDisplay.fadeIn(),
53
+ tileSize: control.attrDouble("tileSize", 256)!,
54
+ minNativeZoom: control.attrInt("minNativeZoom", 0)!,
55
+ maxNativeZoom: control.attrInt("maxNativeZoom", 19)!,
56
+ zoomReverse: control.attrBool("zoomReverse", false)!,
57
+ zoomOffset: control.attrDouble("zoomOffset", 0)!,
58
+ keepBuffer: control.attrInt("keepBuffer", 2)!,
59
+ panBuffer: control.attrInt("panBuffer", 1)!,
60
+ tms: control.attrBool("enableTms", false)!,
61
+ tileBounds: parseLatLngBounds(control, "tileBounds"),
62
+ retinaMode: control.attrBool("enableRetinaMode"),
63
+ maxZoom: control.attrDouble("maxZoom", double.infinity)!,
64
+ minZoom: control.attrDouble("minZoom", 0)!,
65
+ evictErrorTileStrategy: parseEvictErrorTileStrategy(
66
+ control.attrString("evictErrorTileStrategy"),
67
+ EvictErrorTileStrategy.none)!,
68
+ errorImage: errorImage,
69
+ errorTileCallback: (TileImage t, Object o, StackTrace? s) {
70
+ backend.triggerControlEvent(control.id, "imageError");
71
+ },
72
+ additionalOptions: additionalOptions != null
73
+ ? (jsonDecode(additionalOptions) as Map)
74
+ .map((k, v) => MapEntry(k.toString(), v.toString()))
75
+ : const {});
76
+
77
+ return constrainedControl(context, tile, parent, control);
78
+ });
79
+ }
80
+ }
@@ -0,0 +1,12 @@
1
+ import 'package:collection/collection.dart';
2
+ import 'package:flutter_map/flutter_map.dart';
3
+
4
+ AttributionAlignment? parseAttributionAlignment(String? value,
5
+ [AttributionAlignment? defValue]) {
6
+ if (value == null) {
7
+ return defValue;
8
+ }
9
+ return AttributionAlignment.values.firstWhereOrNull(
10
+ (e) => e.name.toLowerCase() == value.toLowerCase()) ??
11
+ defValue;
12
+ }
@@ -0,0 +1,280 @@
1
+ import 'dart:convert';
2
+
3
+ import 'package:collection/collection.dart';
4
+ import 'package:flet/flet.dart';
5
+ import 'package:flutter/gestures.dart';
6
+ import 'package:flutter/material.dart';
7
+ import 'package:flutter_map/flutter_map.dart';
8
+ import 'package:latlong2/latlong.dart';
9
+
10
+ LatLng? parseLatLng(Control control, String propName, [LatLng? defValue]) {
11
+ var v = control.attrString(propName, null);
12
+ if (v == null) {
13
+ return defValue;
14
+ }
15
+
16
+ final j1 = json.decode(v);
17
+ return latLngFromJson(j1, defValue);
18
+ }
19
+
20
+ LatLng? latLngFromJson(Map<String, dynamic>? j, [LatLng? defValue]) {
21
+ if (j == null) {
22
+ return defValue;
23
+ }
24
+ return LatLng(
25
+ parseDouble(j['latitude'], 0)!, parseDouble(j['longitude'], 0)!);
26
+ }
27
+
28
+ LatLngBounds? parseLatLngBounds(Control control, String propName,
29
+ [LatLngBounds? defValue]) {
30
+ var v = control.attrString(propName, null);
31
+ if (v == null) {
32
+ return defValue;
33
+ }
34
+
35
+ final j1 = json.decode(v);
36
+ return latLngBoundsFromJson(j1, defValue);
37
+ }
38
+
39
+ LatLngBounds? latLngBoundsFromJson(Map<String, dynamic>? j,
40
+ [LatLngBounds? defValue]) {
41
+ if (j == null ||
42
+ j['corner_1'] == null ||
43
+ j['corner_2'] == null ||
44
+ latLngFromJson(j['corner_1']) == null ||
45
+ latLngFromJson(j['corner_2']) == null) {
46
+ return defValue;
47
+ }
48
+ return LatLngBounds(
49
+ latLngFromJson(j['corner_1'])!, latLngFromJson(j['corner_2'])!);
50
+ }
51
+
52
+ PatternFit? parsePatternFit(String? value,
53
+ [PatternFit? defValue = PatternFit.none]) {
54
+ if (value == null) {
55
+ return defValue;
56
+ }
57
+ return PatternFit.values.firstWhereOrNull(
58
+ (e) => e.name.toLowerCase() == value.toLowerCase()) ??
59
+ defValue;
60
+ }
61
+
62
+ StrokePattern? parseStrokePattern(Control control, String propName,
63
+ [StrokePattern? defValue]) {
64
+ var v = control.attrString(propName, null);
65
+ if (v == null) {
66
+ return defValue;
67
+ }
68
+
69
+ final j1 = json.decode(v);
70
+ return strokePatternFromJson(j1, defValue);
71
+ }
72
+
73
+ StrokePattern? strokePatternFromJson(Map<String, dynamic>? j,
74
+ [StrokePattern? defValue]) {
75
+ if (j == null) {
76
+ return defValue;
77
+ }
78
+ if (j['type'] == 'dotted') {
79
+ return StrokePattern.dotted(
80
+ spacingFactor: parseDouble(j['spacing_factor'], 1)!,
81
+ patternFit: parsePatternFit(j['pattern_fit'], PatternFit.none)!,
82
+ );
83
+ } else if (j['type'] == 'solid') {
84
+ return const StrokePattern.solid();
85
+ } else if (j['type'] == 'dash') {
86
+ var segments = j['segments'];
87
+ return StrokePattern.dashed(
88
+ patternFit: parsePatternFit(j['pattern_fit'], PatternFit.none)!,
89
+ segments: segments != null
90
+ ? (jsonDecode(segments) as List)
91
+ .map((e) => parseDouble(e))
92
+ .whereNotNull()
93
+ .toList()
94
+ : [],
95
+ );
96
+ }
97
+ return defValue;
98
+ }
99
+
100
+ InteractionOptions? parseInteractionOptions(Control control, String propName,
101
+ [InteractionOptions? defValue]) {
102
+ var v = control.attrString(propName);
103
+ if (v == null) {
104
+ return defValue;
105
+ }
106
+ final j1 = json.decode(v);
107
+ return interactionOptionsFromJSON(j1, defValue);
108
+ }
109
+
110
+ InteractionOptions? interactionOptionsFromJSON(dynamic j,
111
+ [InteractionOptions? defValue]) {
112
+ if (j == null) {
113
+ return defValue;
114
+ }
115
+ return InteractionOptions(
116
+ enableMultiFingerGestureRace:
117
+ parseBool(j["enable_multi_finger_gesture_race"], false)!,
118
+ pinchMoveThreshold: parseDouble(j["pinch_move_threshold"], 40.0)!,
119
+ scrollWheelVelocity: parseDouble(j["scroll_wheel_velocity"], 0.005)!,
120
+ pinchZoomThreshold: parseDouble(j["pinch_zoom_threshold"], 0.5)!,
121
+ rotationThreshold: parseDouble(j["rotation_threshold"], 20.0)!,
122
+ flags: parseInt(j["flags"], InteractiveFlag.all)!,
123
+ rotationWinGestures:
124
+ parseInt(j["rotation_win_gestures"], MultiFingerGesture.rotate)!,
125
+ pinchMoveWinGestures: parseInt(j["pinch_move_win_gestures"],
126
+ MultiFingerGesture.pinchZoom | MultiFingerGesture.pinchMove)!,
127
+ pinchZoomWinGestures: parseInt(j["pinch_zoom_win_gestures"],
128
+ MultiFingerGesture.pinchZoom | MultiFingerGesture.pinchMove)!);
129
+ }
130
+
131
+ EvictErrorTileStrategy? parseEvictErrorTileStrategy(String? strategy,
132
+ [EvictErrorTileStrategy? defValue]) {
133
+ if (strategy == null) {
134
+ return defValue;
135
+ }
136
+ return EvictErrorTileStrategy.values.firstWhereOrNull(
137
+ (e) => e.name.toLowerCase() == strategy.toLowerCase()) ??
138
+ defValue;
139
+ }
140
+
141
+ MapOptions? parseConfiguration(
142
+ Control control, FletControlBackend backend, BuildContext context,
143
+ [MapOptions? defValue]) {
144
+ void triggerEvent(String name, dynamic eventData) {
145
+ var d = "";
146
+ if (eventData is String) {
147
+ d = eventData;
148
+ } else if (eventData is Map) {
149
+ d = json.encode(eventData);
150
+ }
151
+
152
+ backend.triggerControlEvent(control.id, name, d);
153
+ }
154
+
155
+ return MapOptions(
156
+ initialCenter:
157
+ parseLatLng(control, "initialCenter", const LatLng(50.5, 30.51))!,
158
+ interactionOptions: parseInteractionOptions(
159
+ control, "interactionConfiguration", const InteractionOptions())!,
160
+ backgroundColor:
161
+ control.attrColor("bgColor", context, const Color(0x00000000))!,
162
+ initialRotation: control.attrDouble("initialRotation", 0.0)!,
163
+ initialZoom: control.attrDouble("initialZoom", 13.0)!,
164
+ keepAlive: control.attrBool("keepAlive", false)!,
165
+ maxZoom: control.attrDouble("maxZoom"),
166
+ minZoom: control.attrDouble("minZoom"),
167
+ onPointerHover: control.attrBool("onHover", false)!
168
+ ? (PointerHoverEvent e, LatLng latlng) {
169
+ triggerEvent("hover", {
170
+ "lat": latlng.latitude,
171
+ "long": latlng.longitude,
172
+ "gx": e.position.dx,
173
+ "gy": e.position.dy,
174
+ "lx": e.localPosition.dx,
175
+ "ly": e.localPosition.dy,
176
+ "kind": e.kind.name,
177
+ });
178
+ }
179
+ : null,
180
+ onTap: control.attrBool("onTap", false)!
181
+ ? (TapPosition pos, LatLng latlng) {
182
+ triggerEvent("tap", {
183
+ "lat": latlng.latitude,
184
+ "long": latlng.longitude,
185
+ "gx": pos.global.dx,
186
+ "gy": pos.global.dy,
187
+ "lx": pos.relative?.dx,
188
+ "ly": pos.relative?.dy,
189
+ });
190
+ }
191
+ : null,
192
+ onLongPress: control.attrBool("onLongPress", false)!
193
+ ? (TapPosition pos, LatLng latlng) {
194
+ triggerEvent("long_press", {
195
+ "lat": latlng.latitude,
196
+ "long": latlng.longitude,
197
+ "gx": pos.global.dx,
198
+ "gy": pos.global.dy,
199
+ "lx": pos.relative?.dx,
200
+ "ly": pos.relative?.dy,
201
+ });
202
+ }
203
+ : null,
204
+ onPositionChanged: control.attrBool("onPositionChange", false)!
205
+ ? (MapCamera camera, bool hasGesture) {
206
+ triggerEvent("position_change", {
207
+ "lat": camera.center.latitude,
208
+ "long": camera.center.longitude,
209
+ "min_zoom": camera.minZoom,
210
+ "max_zoom": camera.maxZoom,
211
+ "rot": camera.rotation,
212
+ });
213
+ }
214
+ : null,
215
+ onPointerDown: control.attrBool("onPointerDown", false)!
216
+ ? (PointerDownEvent e, LatLng latlng) {
217
+ triggerEvent("pointer_down", {
218
+ "lat": latlng.latitude,
219
+ "long": latlng.longitude,
220
+ "gx": e.position.dx,
221
+ "gy": e.position.dy,
222
+ "kind": e.kind.name,
223
+ });
224
+ }
225
+ : null,
226
+ onPointerCancel: control.attrBool("onPointerCancel", false)!
227
+ ? (PointerCancelEvent e, LatLng latlng) {
228
+ triggerEvent("pointer_cancel", {
229
+ "lat": latlng.latitude,
230
+ "long": latlng.longitude,
231
+ "gx": e.position.dx,
232
+ "gy": e.position.dy,
233
+ "kind": e.kind.name,
234
+ });
235
+ }
236
+ : null,
237
+ onPointerUp: control.attrBool("onPointerUp", false)!
238
+ ? (PointerUpEvent e, LatLng latlng) {
239
+ triggerEvent("pointer_up", {
240
+ "lat": latlng.latitude,
241
+ "long": latlng.longitude,
242
+ "gx": e.position.dx,
243
+ "gy": e.position.dy,
244
+ "kind": e.kind.name,
245
+ });
246
+ }
247
+ : null,
248
+ onSecondaryTap: control.attrBool("onSecondaryTap", false)!
249
+ ? (TapPosition pos, LatLng latlng) {
250
+ triggerEvent("secondary_tap", {
251
+ "lat": latlng.latitude,
252
+ "long": latlng.longitude,
253
+ "gx": pos.global.dx,
254
+ "gy": pos.global.dy,
255
+ "lx": pos.relative?.dx,
256
+ "ly": pos.relative?.dy,
257
+ });
258
+ }
259
+ : null,
260
+ onMapEvent: control.attrBool("onEvent", false)!
261
+ ? (MapEvent e) {
262
+ triggerEvent("event", {
263
+ "src": e.source.name,
264
+ "c_lat": e.camera.center.latitude,
265
+ "c_long": e.camera.center.longitude,
266
+ "zoom": e.camera.zoom,
267
+ "min_zoom": e.camera.minZoom,
268
+ "max_zoom": e.camera.maxZoom,
269
+ "rot": e.camera.rotation,
270
+ });
271
+ }
272
+ : null,
273
+ onMapReady: control.attrBool("onInit", false)!
274
+ ? () {
275
+ debugPrint("Map ${control.id} init");
276
+ backend.triggerControlEvent(control.id, "init");
277
+ }
278
+ : null,
279
+ );
280
+ }