From 8f6913407c4211f8e938f66680750eb9ca5f16aa Mon Sep 17 00:00:00 2001 From: Thomas Fransolet Date: Fri, 9 Aug 2024 16:10:37 +0200 Subject: [PATCH] Added new flutter map view (based on web) --- lib/Screens/Map/flutter_map_view.dart | 136 ++++++++++++++++++++++++++ lib/Screens/Map/geo_point_filter.dart | 3 +- lib/Screens/Map/map_view.dart | 3 + lib/Screens/Map/marker_view.dart | 1 + pubspec.yaml | 4 +- 5 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 lib/Screens/Map/flutter_map_view.dart diff --git a/lib/Screens/Map/flutter_map_view.dart b/lib/Screens/Map/flutter_map_view.dart new file mode 100644 index 0000000..b7e1959 --- /dev/null +++ b/lib/Screens/Map/flutter_map_view.dart @@ -0,0 +1,136 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_map/flutter_map.dart'; +import 'package:latlong2/latlong.dart'; +import 'package:manager_api/api.dart'; +import 'package:provider/provider.dart'; +import 'package:tablet_app/Models/tabletContext.dart'; +import 'package:tablet_app/Screens/Map/map_context.dart'; +import 'package:tablet_app/app_context.dart'; +import 'package:html/parser.dart' show parse; +import 'package:latlong2/latlong.dart' as ll; + +class FlutterMapView extends StatefulWidget { + final MapDTO? mapDTO; + final List geoPoints; + final List> icons; + final String? language; + const FlutterMapView({ + Key? key, + this.mapDTO, + required this.geoPoints, + required this.icons, + this.language, + }) : super(key: key); + + @override + _FlutterMapViewState createState() => _FlutterMapViewState(); +} + +class _FlutterMapViewState extends State { + late List markersList; + late List markers; + bool filterZoneSelected = false; + MapController? mapController; + + List createPoints(mapContext) { + markersList = []; + markers = []; + + int i = 0; + widget.geoPoints.forEach((point) { + if (point.title!.where((translation) => translation.language == widget.language).isNotEmpty) { + var textSansHTML = parse(point.title!.firstWhere((translation) => translation.language == widget.language).value); + point.id = i; + point.title = point.title!.where((t) => t.language == widget.language).toList(); + markersList.add(point); + + //var icon = point.categorie == null ? BitmapDescriptor.fromBytes(widget.icons.where((i) => i['id'] == null).first['icon']) : widget.icons.any((i) => i['id'] == point.categorieId) ? BitmapDescriptor.fromBytes(widget.icons.where((i) => i['id'] == point.categorieId).first['icon']) : BitmapDescriptor.fromBytes(widget.icons.where((i) => i['id'] == null).first['icon']); //widget.selectedMarkerIcon,; + + markers.add( + Marker( + width: 80.0, + height: 80.0, + point: LatLng(double.tryParse(point.latitude!)!, double.tryParse(point.longitude!)!), + child: GestureDetector( + onTap: () { + /*final mapContext = Provider.of(context, listen: false); + mapContext.setSelectedPoint(point); + mapContext.setSelectedPointForNavigate(point);*/ + mapContext.setSelectedPoint(point); + mapContext.setSelectedPointForNavigate(point); + }, + child: widget.icons.firstWhere((i) => i['id'] == point.categorieId, orElse: () => widget.icons.first)['icon'] != null ? Image.memory(widget.icons.firstWhere((i) => i['id'] == point.categorieId, orElse: () => widget.icons.first)['icon']) : Icon(Icons.pin_drop, color: Colors.red),//widget.icons.firstWhere((i) => i['id'] == point.categorieId, orElse: () => widget.icons.first)['icon'], + ) + ), + ); + i++; + } + }); + + return markers; + } + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + final mapContext = Provider.of(context); + final appContext = Provider.of(context); + TabletAppContext tabletAppContext = appContext.getContext() as TabletAppContext; + + markers = createPoints(mapContext); + + if (mapController == null) { // mapContext.getSelectedPointForNavigate() != null + /*var geoPoint = mapContext.getSelectedPointForNavigate(); + var center = LatLng(double.tryParse(geoPoint.latitude!)!, double.tryParse(geoPoint.longitude!)!);*/ + mapController = MapController(); + + //mapController!.move(center, widget.mapDTO!.zoom != null ? widget.mapDTO!.zoom!.toDouble() : 12); + mapContext.setSelectedPointForNavigate(null); // Reset after navigation + } + + return Stack( + children: [ + FlutterMap( + mapController: mapController, + options: MapOptions( + initialCenter: widget.mapDTO!.longitude != null && widget.mapDTO!.latitude != null ? ll.LatLng(double.tryParse(widget.mapDTO!.latitude!)!, double.tryParse(widget.mapDTO!.longitude!)!) : ll.LatLng(4.865105, 50.465503), //.toJson() + initialZoom: widget.mapDTO!.zoom != null ? widget.mapDTO!.zoom!.toDouble() : 12, + onTap: (Tap, lnt) => { + mapContext.setSelectedPointForNavigate(null), + mapContext.setSelectedPoint(null), + } + ), + children: [ + TileLayer( + urlTemplate: "https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}", + userAgentPackageName: 'be.unov.myinfomate.tablet', + ), + MarkerLayer( + markers: markers + ), + ], + ), + Container( + child: Builder( + builder: (context) { + return Consumer( + builder: (context, mapContext, _) { + var geoPoint = mapContext.getSelectedPointForNavigate() as GeoPointDTO?; + if (geoPoint != null && mapController != null) { + print("COUCOU IL FAUT NAVIGATE FLUTTER MAP"); + mapController!.move(LatLng(double.tryParse(geoPoint.latitude!)!, double.tryParse(geoPoint.longitude!)!), 16); + } + return SizedBox(); + }, + ); + } + ), + ) + ], + ); + } +} diff --git a/lib/Screens/Map/geo_point_filter.dart b/lib/Screens/Map/geo_point_filter.dart index 147775d..27b74da 100644 --- a/lib/Screens/Map/geo_point_filter.dart +++ b/lib/Screens/Map/geo_point_filter.dart @@ -4,7 +4,7 @@ import 'dart:math'; //import 'package:animated_tree_view/animated_tree_view.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; + //import 'package:generate_tree/generate_tree.dart'; //import 'package:generate_tree/treeNode.dart'; import 'package:manager_api/api.dart'; @@ -260,6 +260,7 @@ class _GeoPointFilterState extends State { onPressed: () { if(_searchController.text.isNotEmpty) { _searchController.text = ""; + // TODO reset view ? } filterNodes(); if(_searchController.text.isNotEmpty) { diff --git a/lib/Screens/Map/map_view.dart b/lib/Screens/Map/map_view.dart index 7819151..fe66ab6 100644 --- a/lib/Screens/Map/map_view.dart +++ b/lib/Screens/Map/map_view.dart @@ -13,6 +13,7 @@ import 'package:tablet_app/Models/map-marker.dart'; //import 'dart:ui' as ui; import 'package:flutter/widgets.dart'; import 'package:tablet_app/Models/tabletContext.dart'; +import 'package:tablet_app/Screens/Map/flutter_map_view.dart'; import 'package:tablet_app/Screens/Map/geo_point_filter.dart'; import 'package:tablet_app/Screens/Map/map_box_view.dart'; import 'package:tablet_app/Screens/Map/marker_view.dart'; @@ -99,6 +100,8 @@ class _MapViewWidget extends State { return GoogleMapView(language: appContext.getContext().language, geoPoints: value, mapDTO: mapDTO!, icons: widget.icons); case MapProvider.MapBox: return MapBoxView(language: appContext.getContext().language, geoPoints: value, mapDTO: mapDTO, icons: widget.icons); + // If mapbox bug as 3.24 flutter, we can test via this new widget + //return FlutterMapView(language: appContext.getContext().language, geoPoints: value, mapDTO: mapDTO, icons: widget.icons); default: // By default google return GoogleMapView(language: appContext.getContext().language, geoPoints: value, mapDTO: mapDTO!, icons: widget.icons); diff --git a/lib/Screens/Map/marker_view.dart b/lib/Screens/Map/marker_view.dart index 44121d1..ff6d3e6 100644 --- a/lib/Screens/Map/marker_view.dart +++ b/lib/Screens/Map/marker_view.dart @@ -92,6 +92,7 @@ class _MarkerInfoWidget extends State { onTap: () { setState(() { mapContext.setSelectedPoint(null); + mapContext.setSelectedPointForNavigate(null); }); }, child: Container( diff --git a/pubspec.yaml b/pubspec.yaml index 318f08b..393429b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,6 +36,8 @@ dependencies: mapbox_maps_flutter: ^2.0.0 # specific mobile .. + flutter_map: ^7.0.2 #all + #ota_update: ^6.0.0 #package_info: ^2.0.2 # specific mobile package_info_plus: ^8.0.0 # chewie version casse couille @@ -46,7 +48,7 @@ dependencies: http: ^1.2.0 auto_size_text: ^3.0.0 fluttertoast: - device_info_plus: ^10.1.0 + device_info_plus: ^10.0.0 enum_to_string: ^2.0.1 mqtt_client: ^10.0.0 photo_view: ^0.15.0