Soumya Manthri
Soumya Manthri

Reputation: 31

polylines are not getting cleared in flutter map

When the user is outside of the building the polyline should disappear. But polyline still visible even if the user is outside of the building:

`map_view.dart`
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:provider/provider.dart';
import '../view_model/map_view_model.dart';
class MapViewWidget extends StatefulWidget {
  const MapViewWidget({Key? key}) : super(key: key);

  @override
  State<MapViewWidget> createState() => _MapViewWidgetState();
}

class _MapViewWidgetState extends State<MapViewWidget>{
  late MapViewModel viewModel;



  @override
  void initState() {
    super.initState();
    viewModel = Provider.of<MapViewModel>(context, listen: false);
    print("viewModel.position:::::${viewModel.getCurrentLocation()}");
    WidgetsBinding.instance.addPostFrameCallback((_) {
      viewModel.getCurrentLocation();
      viewModel.initializeCompass();
      viewModel.initializeMapController();
    });
  }


  @override
  Widget build(BuildContext context) {
   return Consumer<MapViewModel>(
     builder: (context, viewModel, _){
    return viewModel.position!= null ? Stack(
      children: [
        FlutterMap(
          mapController: viewModel.mapController,
          options: MapOptions(
            zoom: 10.0,
            // center: LatLng(17.441990,78.381939),
            center: LatLng(viewModel.position!.latitude, viewModel.position!.longitude),
            maxZoom: 20.0,
            onPositionChanged: viewModel.handlePositionChanged,
            interactiveFlags: ~InteractiveFlag.rotate,
          ),
          layers: viewModel.mapLayers,
        ),
        StreamBuilder(
          stream: viewModel.channel.stream,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              viewModel.polylineCoordinates.clear();
              Map<String, dynamic> data = json.decode(snapshot.data);
              List<dynamic> coordinates = data['coordinates'][0];
              for (var coordinate in coordinates) {
                double longitude = coordinate[0];
                double latitude = coordinate[1];
                viewModel.polylineCoordinates.add(LatLng(latitude, longitude));
              }
              print("polylineCoordinates::${viewModel.polylineCoordinates.length}");
              return const Align(
                  alignment: Alignment.bottomCenter,
                  child: Text('data Received',style: TextStyle(color: Colors.white,decoration: TextDecoration.none,fontSize: 10.0),)
              );
            } else if (snapshot.hasError) {
              return const Text('Error');
            } else {
              viewModel.polylineCoordinates.clear();
              return const Text('');
              // return Text('Waiting for messages...');
            }
          },
        ),
      ],
    ) : Dialog(
      backgroundColor: Colors.blue[100],
      child: Padding(
        padding: const EdgeInsets.all(10.0),
        child:  Column(
          mainAxisSize: MainAxisSize.min,
          children: const [
            CircularProgressIndicator(),
            Padding(
              padding: EdgeInsets.all(8.0),
              child: Center(child: Text("Please wait..Map is Loading")),
            ),
          ],
        ),
      ),
    );
     }
     );
  }
}
`map_view_model.dart`

import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter_compass/flutter_compass.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:geolocator/geolocator.dart';
import 'package:latlong2/latlong.dart';
import 'package:maps_soumya/loading_view_model.dart';
import 'package:web_socket_channel/io.dart';

import '../../map_util.dart';
import '../../rotation_marker.dart';

class MapViewModel extends LoadingViewModel {

  final channel = IOWebSocketChannel.connect('ws://aims.vassarlabs.com/webSocket');

  Position? position;
  late MapController mapController;

  //Map Layers
  List<LatLng> polylineCoordinates=[];
  List<Marker> mapMarkers = [];
  List<CircleMarker> circles = [];
  List<Polygon> polygons = [];
  final List<Polyline> polylines = [];
  List<LayerOptions> mapLayers = [];

  double lat = -1;
  double lng = -1;
  double compassHeading = 0.0;
  double circleRadius = 50.0;
  double rotation = 0.0;
  double accuracy = 0.0;

  initializeMapController() {
    mapController = MapController();
    notifyListeners();
  }

  // getCurrentLocation() async{
  //   await Geolocator.checkPermission();
  //   await Geolocator.requestPermission();
  //   position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
  //   notifyListeners();
  //   rotation = position.heading;
  //
  //   createMapLayers();
  // }
  getCurrentLocation() async {
    mapController=MapController();
    LocationPermission permission = await Geolocator.checkPermission();
    if (permission == LocationPermission.denied) {
      permission = await Geolocator.requestPermission();
    }
    if (permission == LocationPermission.deniedForever) {
      // Handle denied permission case
      return;
    }
    position = await Geolocator.getCurrentPosition(
      desiredAccuracy: LocationAccuracy.high,
    );
    print("position:::$position");
    lat = position!.latitude;
    print("position.latitude and position.longitude${position!.latitude} ${position!.longitude}");
    lng = position!.longitude;
    await getUserPositionStream();
    rotation = position!.heading;
    notifyListeners();
    createMapLayers();
  }

  getUserPositionStream() async {
    var locationOptions=const LocationSettings(accuracy: LocationAccuracy.high, distanceFilter: 0);
    Geolocator.getPositionStream(locationSettings: locationOptions).listen((Position position) {
      if(this.position != position) {
          this.position = position;
          accuracy=position.accuracy;
          _updateMarker();
          createMapLayers();
          notifyListeners();
          // getCurrentLocation();
      }
    });
    // double lat = 17.441990;
    // double lon = 78.381939;
    //westin::::cordinates(17.44257,78.38165)
    // double lat=17.44257;
    // double lon=78.38165;

    double lat = position!.latitude;
    double lon=  position!.longitude;

    String latLonString = '$lon,$lat';
    print("latLonString:::$latLonString");
    print("lat:::$lat");
    print("lon:::$lon");

    // channel.sink.add(latLonString);

    bool isInPolylines = MapUtil.containsLocation(LatLng(lat, lon), polylineCoordinates, false);
    if (!isInPolylines) {
      polylineCoordinates.clear();
      polylines.clear();
      _buildPolylines(polylineCoordinates);
      getCurrentLocation();
      channel.sink.add(latLonString);
      notifyListeners();
    }
  }


  List<Polyline> _buildPolylines(List<LatLng> polylineCoordinates) {
    Polyline polyline = Polyline(
      points: polylineCoordinates,
      color: Colors.yellow, // Customize the color of the polyline
      strokeWidth: 2, // Customize the width of the polyline
    );
    polylines.add(polyline);
    return polylines;
  }

  void handlePositionChanged(MapPosition position, bool hasGesture) {
    if (hasGesture) {
      final zoomLevel = position.zoom;
      final newRadius = calculateCircleRadius(zoomLevel!);
      circleRadius = newRadius;
      notifyListeners();
    }
  }

  double calculateCircleRadius(double zoomLevel) {
    return 50.0 * pow(2, 13 - zoomLevel);
  }

  initializeCompass() {
    FlutterCompass.events!.listen((event) {
      compassHeading = event.heading ?? 0.0;
      notifyListeners();
    });
  }

  createMapLayers() {
    mapLayers.clear();
    mapLayers.addAll([
      TileLayerOptions(
          urlTemplate: 'http://mt3.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',
          subdomains: ['a', 'b', 'c'],
          maxZoom: 20
      ),
      MarkerLayerOptions(
          markers: [
            Marker(
                point: LatLng(position!.latitude, position!.longitude),
                // point: LatLng(17.441990,78.381939),
                builder: (context)=> RotationMarker(
                  rotation: compassHeading,
                  builder: (context)=> Stack(
                    children: [
                      const Icon(Icons.tornado_sharp,size: 30,color: Colors.lightBlue,),
                      Positioned(
                        top:10,left: 4.1,bottom:0,
                        child: Image.asset(
                          "assets/images/current_location_gif.gif",
                        ),
                      )
                    ],
                  ),
                  color: Colors.blue,
                  size: 50.0,
                )
            ),

          ]
      ),
      PolygonLayerOptions(
        polygons: [
          Polygon(
            points: _createCirclePoints(LatLng(position!.latitude, position!.longitude), 0.001), // Adjust the radius as per your preference
            color: Colors.blue.withOpacity(0.2),
            borderColor: Colors.transparent,
          ),
        ],
      ),
      PolylineLayerOptions(
          polylines: polylines
      ),
      ]
    );
  }


  List<LatLng> _createCirclePoints(LatLng center, double radius) {
    const int numberOfPoints = 100;
    final List<LatLng> points = [];

    for (int i = 0; i < numberOfPoints; i++) {
      final double angle = 2 * pi * i / numberOfPoints;
      final double x = center.latitude + radius * cos(angle);
      final double y = center.longitude + radius * sin(angle);
      points.add(LatLng(x, y));
    }
    return points;
  }

  void _updateMarker() {
    mapMarkers.clear();
    circles.clear();
    if (position != null) {
      mapMarkers.add(
        Marker(
          point: LatLng(position!.latitude, position!.longitude),
          // point: LatLng(17.441990,78.381939),
          // point: LatLng(17.44257,78.38165),
          builder: (context)=>RotationMarker(
            rotation: position!.heading,
            builder: (context)=> Stack(
              children: [
                const Icon(Icons.tornado_sharp,size: 30,color: Colors.lightBlue,),
                Positioned(
                  top:10,left: 4.1,bottom:0,
                  child: Image.asset(
                    "assets/images/current_location_gif.gif",
                  ),
                )
              ],
            ),
            color: Colors.blue,
            size: 50.0,
          ),
        ),
      );
      circles.add(
          CircleMarker(
            point: LatLng(position!.latitude, position!.longitude),
            radius: circleRadius,
            color: Colors.lightBlue.shade50.withOpacity(0.2),
            borderColor: Colors.red,
            borderStrokeWidth: 2,)
      );
      notifyListeners();
    }
    // mapMarkers.add();
  }
}

example image

What to happen: If the user is outside of the building the polyline should disappear. and if the user enters another building the building should highlight with polyline. And polyline coordinates are obtained from a WebSocket stream that receives data from the server.

Upvotes: 1

Views: 420

Answers (1)

Prince Nna
Prince Nna

Reputation: 23

I had a similar issue today(polygons not updating correctly) on flutter: 3.10.6. Updating to latest stable flutter: 3.13.7 fixed the issue for me.

Upvotes: 0

Related Questions