import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_map_location_marker/flutter_map_location_marker.dart'; import 'package:flutter_map_marker_cluster/flutter_map_marker_cluster.dart'; import 'package:flutter_polyline_points/flutter_polyline_points.dart'; import 'package:geojson_vi/geojson_vi.dart'; import 'package:get/get.dart'; import 'package:latlong2/latlong.dart'; import 'package:rogapp/model/destination.dart'; import 'package:rogapp/pages/destination/destination_controller.dart'; import 'package:rogapp/pages/index/index_controller.dart'; import 'package:rogapp/utils/database_helper.dart'; import 'package:rogapp/utils/location_controller.dart'; import 'package:rogapp/utils/text_util.dart'; import 'package:rogapp/widgets/base_layer_widget.dart'; import 'package:rogapp/widgets/bottom_sheet_new.dart'; import 'package:rogapp/widgets/current_position_widget.dart'; import 'package:rogapp/widgets/game_state_view.dart'; class MapWidget extends StatefulWidget { MapWidget({Key? key}) : super(key: key); @override State createState() => _MapWidgetState(); } class _MapWidgetState extends State { final IndexController indexController = Get.find(); final DestinationController destinationController = Get.find(); final LocationController locationController = Get.find(); StreamSubscription? subscription; Timer? _timer; Widget getMarkerShape(GeoJSONFeature i, BuildContext context) { GeoJSONMultiPoint p = i.geometry as GeoJSONMultiPoint; //print("lat is ${p.geoSerie!.geoPoints[0].latitude} and lon is ${p.geoSerie!.geoPoints[0].longitude}"); //RegExp regex = RegExp(r'([.]*0)(?!.*\d)'); return InkWell( onTap: () { GeoJSONFeature? fs = indexController.getFeatureForLatLong( p.coordinates[0][1], p.coordinates[0][0]); //print("------- fs $fs------"); if (fs != null) { indexController.currentFeature.clear(); indexController.currentFeature.add(fs); //print("----- fs is ${fs.properties!['photos']}"); Destination des = destinationController.festuretoDestination(fs); DatabaseHelper db = DatabaseHelper.instance; db.getDestinationByLatLon(des.lat!, des.lon!).then((value) { destinationController.shouldShowBottomSheet = false; showModalBottomSheet( constraints: BoxConstraints.loose(Size(Get.width, Get.height * 0.85)), context: context, isScrollControlled: true, isDismissible: true, builder: ((context) => BottomSheetNew( destination: des, isAlreadyCheckedIn: value.isNotEmpty)) //builder:((context) => BottomSheetWidget()) ).whenComplete(() { destinationController.shouldShowBottomSheet = true; destinationController.skipGps = false; }); }); } }, child: Stack( fit: StackFit.expand, //mainAxisAlignment: MainAxisAlignment.center, children: [ Container( height: 32, width: 32, decoration: BoxDecoration( shape: BoxShape.circle, color: Colors.transparent, border: Border.all( color: i.properties!['buy_point'] > 0 ? Colors.blue : Colors.red, width: 3, style: BorderStyle.solid)), child: Stack( alignment: Alignment.center, children: [ const Icon( Icons.circle, size: 6.0, ), i.properties!['cp'] == -1 ? Transform.translate( offset: Offset(18, 0), child: Transform.rotate( alignment: Alignment.centerLeft, origin: Offset.fromDirection(1, 26), angle: 270 * pi / 180, child: const Icon( Icons.play_arrow_outlined, color: Colors.red, size: 70, )), ) : Container( color: Colors.transparent, ), ], )), Transform.translate( offset: Offset(45, 0), child: Align( alignment: Alignment.center, child: Container( color: Colors.purple.withOpacity(0.2), // child: Text(TextUtils.getDisplayTextFeture(i), // style: const TextStyle( // fontSize: 16, // fontWeight: FontWeight.bold, // color: Colors.red, // ))), child: Stack( children: [ // Text with white outline Text( TextUtils.getDisplayTextFeture(i), style: TextStyle( fontSize: 16, fontWeight: FontWeight.w700, foreground: Paint() ..style = PaintingStyle.stroke ..strokeWidth = 1 ..color = Colors.white, ), ), // Text with black fill Text( TextUtils.getDisplayTextFeture(i), style: TextStyle( fontSize: 16, fontWeight: FontWeight.w700, color: Colors.black, ), ), ], )), ), ) ], ), ); } List? getPoints() { //print("##### --- route point ${indexController.routePoints.length}"); List pts = []; for (PointLatLng p in indexController.routePoints) { LatLng l = LatLng(p.latitude, p.longitude); pts.add(l); } return pts; } @override void initState() { super.initState(); _startIdleTimer(); } void _startIdleTimer() { _timer = Timer(const Duration(milliseconds: (1000 * 10)), _centerMapOnUser); } void _resetTimer() { _timer?.cancel(); _startIdleTimer(); } void _centerMapOnUser() { assert(() { print("showBottomSheet ${destinationController.shouldShowBottomSheet}"); return true; }()); // 2024-04-03 Akira Log enabled only debug mode.. // //if (destinationController.shouldShowBottomSheet) { destinationController.centerMapToCurrentLocation(); //} } @override Widget build(BuildContext context) { // print( // "---------- rog mode is ${indexController.rog_mode.value.toString()}----------"); final PopupController popupController = PopupController(); return Stack( children: [ Obx(() => indexController.isLoading.value == true ? const Padding( padding: EdgeInsets.only(top: 60.0), child: CircularProgressIndicator(), ) : FlutterMap( mapController: indexController.mapController, options: MapOptions( maxZoom: 18.4, onMapReady: () { subscription = indexController.mapController.mapEventStream .listen((MapEvent mapEvent) { if (mapEvent is MapEventMoveStart) { // print(DateTime.now().toString() + // ' [MapEventMoveStart] START'); // do something } if (mapEvent is MapEventMoveEnd) {} }); }, //center: LatLng(37.15319600454702, 139.58765950528198), bounds: indexController.currentBound.isNotEmpty ? indexController.currentBound[0] : LatLngBounds.fromPoints([ LatLng(35.03999881162295, 136.40587119778962), LatLng(36.642756778706904, 137.95226720406063) ]), zoom: 1, interactiveFlags: InteractiveFlag.pinchZoom | InteractiveFlag.drag, onPositionChanged: (MapPosition pos, hasGesture) { //print("map position changed ${pos.center!.latitude}"); if (hasGesture) { _resetTimer(); } indexController.currentBound = [pos.bounds!]; }, onTap: (_, __) => popupController .hideAllPopups(), // Hide popup when the map is tapped. ), children: [ const BaseLayer(), Obx( () => indexController.routePointLenght > 0 ? PolylineLayer( polylines: [ Polyline( points: getPoints()!, strokeWidth: 6.0, color: Colors.indigo), ], ) : Container(), ), CurrentLocationLayer( positionStream: locationController .locationMarkerPositionStreamController.stream, alignDirectionOnUpdate: AlignOnUpdate.never, turnOnHeadingUpdate: TurnOnHeadingUpdate.never, style: const LocationMarkerStyle( marker: DefaultLocationMarker( child: Icon( Icons.navigation, color: Colors.yellowAccent, ), ), markerSize: Size(27, 27), markerDirection: MarkerDirection.heading, ), ), indexController.locations.isNotEmpty && indexController.locations[0].features.isNotEmpty ? MarkerLayer( markers: indexController.locations[0].features.map((i) { //print("i si ${i.properties!['location_id']}"); RegExp regex = RegExp(r'([.]*0)(?!.*\d)'); GeoJSONMultiPoint p = i!.geometry as GeoJSONMultiPoint; //print( // "lat is ${p.geoSerie!.geoPoints[0].latitude} and lon is ${p.geoSerie!.geoPoints[0].longitude}"); return Marker( alignment: Alignment.center, height: 27.0, width: 127.0, point: LatLng( p.coordinates[0][1], p.coordinates[0][0]), child: getMarkerShape(i, context)); }).toList(), ) : const Center(child: CircularProgressIndicator()), ], )), const Positioned(top: 0, left: 0, child: GameStateWidget()), const Positioned(bottom: 10, right: 10, child: CurrentPosition()) // const Positioned( // bottom: 10, // left: 0, // child: DebugWidget(), // ) ], ); } }