Oeng Mengthong
Oeng Mengthong

Reputation: 75

Center poly line google maps plugin flutter fit to screen google map

want to find a center of 2 points and fit a map. I want to fit for all screen when I view on map. I draw route ready but it fit to 1 point only. please help me. this class is for map view for a flutter. I try to find plugin and solution more day but still not found.

 GoogleMap(
              mapType: MapType.normal,
              markers: _markers,
//              cameraTargetBounds: CameraTargetBounds(new LatLngBounds(
//                  northeast: LatLng(latFrom, logFrom),
//                  southwest: LatLng(latTo, logTo),
//              )),
//              minMaxZoomPreference: MinMaxZoomPreference(1, 15),
              mapToolbarEnabled: true,
              scrollGesturesEnabled: true,
              zoomGesturesEnabled: true,
              trafficEnabled: true,
              compassEnabled: true,
              indoorViewEnabled: true,
              rotateGesturesEnabled: true,
              tiltGesturesEnabled: true,
              myLocationButtonEnabled: true,
              myLocationEnabled: true,
              polylines: _polyline,
//              padding: EdgeInsets.all(20),
              initialCameraPosition:
                  CameraPosition(
                      target: LatLng(latFrom, logFrom),
                      zoom: 10,
                  ),
              onMapCreated: (GoogleMapController controller) {
                _controller.complete(controller);
              })

Upvotes: 7

Views: 7679

Answers (4)

Qwaiks
Qwaiks

Reputation: 77

Today I got the same problem and I stumbled upon your question. Looking through the answers while implementing i found a simpler approach.

The LatLangBounds class has a method in there called .fromPoint(List<LatLng> points) which takes a list of points and returns the bounds.

I used this with the MapController class and it worked perfectly showing the bounds on the map. Per my understanding of GoogleMapController it should work.

mapController.fitBounds(LatLngBounds.fromPoints(list_of_points));

Ideally this should be what the google map equivalent should be

googleMapController.moveCamera(
  CameraUpdate.newLatLngBounds(
    LatLngBounds.fromPoints(list_of_points)
  ),zoomIndex)
);

The .fromPoints(List<LatLng> points) method does what everyone has virtually implemented. Hopefully this helps anyone who needs it.

Upvotes: 3

Muhammad Tameem Rafay
Muhammad Tameem Rafay

Reputation: 4575

google_maps_flutter: ^0.5.30
flutter_polyline_points: ^0.2.2

Make sure you have used .then() function because setPolyline() is the async function and has the await keyword. Use these dependencies

class ShowMap extends StatefulWidget {
  ShowMap({Key key}) : super(key: key);

  @override
  _ShowMapState createState() => _ShowMapState();
}

class _ShowMapState extends State<ShowMap> {
  GoogleMapController _googleMapController;
  Set<Polyline> _polylines = {};
  List<LatLng> polylineCoordinates = [];
  PolylinePoints polylinePoints = PolylinePoints();
  String googleAPIKey = "YOUR_API_KEY_HERE";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: ColorUtils.bluePrimary,
      appBar: AppBar(
        // automaticallyImplyLeading: false,
        backgroundColor: ColorUtils.greenPrimary,
        title: Center(
          child: Column(
            children: [
              Text(
                'Delivery Accepted! ',
                style: TextStyle(fontSize: 18.0, letterSpacing: -0.3333),
              ),
             
            ],
          ),
        ),
      ),
      body: Column(
        children: [
          Expanded(
            flex: 5,
            child: Center(
              child: Container(
                margin: EdgeInsets.only(top: 10),
                decoration: BoxDecoration(
                    // color: Colors.white,
                    ),
                width: MediaQuery.of(context).size.width - 10,
                height: MediaQuery.of(context).size.height * 0.5,
                child: GoogleMap(
                    cameraTargetBounds: CameraTargetBounds.unbounded,
                    initialCameraPosition: _initialPosition,
                    onMapCreated: _onMapCreated,
                    tiltGesturesEnabled: true,
                    scrollGesturesEnabled: true,
                    zoomGesturesEnabled: true,
                    // trafficEnabled: true,
                    polylines: _polylines),
              ),
            ),
          ),
          ),
        ],
      ),
    );
  }

  static final CameraPosition _initialPosition = CameraPosition(
      // bearing: 192.8334901395799,
      target: LatLng(31.5204, 74.3587),
      zoom: 12);

  void _onMapCreated(GoogleMapController controller) async {
    setState(() {
      _googleMapController = controller;
      setPolylines().then((_) => _setMapFitToTour(_polylines));
    });
  }

  void _setMapFitToTour(Set<Polyline> p) {
    double minLat = p.first.points.first.latitude;
    double minLong = p.first.points.first.longitude;
    double maxLat = p.first.points.first.latitude;
    double maxLong = p.first.points.first.longitude;

    p.forEach((poly) {
      poly.points.forEach((point) {
        if (point.latitude < minLat) minLat = point.latitude;
        if (point.latitude > maxLat) maxLat = point.latitude;
        if (point.longitude < minLong) minLong = point.longitude;
        if (point.longitude > maxLong) maxLong = point.longitude;
      });
    });
    _googleMapController.animateCamera(CameraUpdate.newLatLngBounds(
        LatLngBounds(
            southwest: LatLng(minLat, minLong),
            northeast: LatLng(maxLat, maxLong)),
        20));
  }

  setPolylines() async {
    PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
      googleAPIKey,
      PointLatLng(31.5204, 74.3587),
      PointLatLng(31.4504, 74.1350),
    );
    if (result.points.isNotEmpty) {
      result.points.forEach((PointLatLng point) {
        polylineCoordinates.add(LatLng(point.latitude, point.longitude));
      });
    } else {
      print("--address not found ---");
    }
    setState(() {
      Polyline polyline = Polyline(
          polylineId: PolylineId("poly"),
          color: Color.fromARGB(255, 40, 122, 198),
          width: 5,
          points: polylineCoordinates);
      _polylines.add(polyline);
    });
  }
}

Upvotes: 5

Vit Lit
Vit Lit

Reputation: 146

void _setMapFitToTour(Set<Polyline> p) {
    double minLat = p.first.points.first.latitude;
    double minLong = p.first.points.first.longitude;
    double maxLat = p.first.points.first.latitude;
    double maxLong = p.first.points.first.longitude;
    p.forEach((poly) {
      poly.points.forEach((point) {
        if(point.latitude < minLat) minLat = point.latitude;
        if(point.latitude > maxLat) maxLat = point.latitude;
        if(point.longitude < minLong) minLong = point.longitude;
        if(point.longitude > maxLong) maxLong = point.longitude;
      });
    });
    mapController.moveCamera(CameraUpdate.newLatLngBounds(LatLngBounds(
      southwest: LatLng(minLat, minLong),
      northeast: LatLng(maxLat,maxLong)
    ), 20));
  }

Upvotes: 12

Dika
Dika

Reputation: 2442

Today I got the same problem and I stumbled upon your question. And I found two links that can help.

https://medium.com/flutter-community/drawing-route-lines-on-google-maps-between-two-locations-in-flutter-4d351733ccbe

https://stackoverflow.com/a/55990256/1537413

after combine these two links, I get perfect solution.

Here you go.

import 'dart:async';

import 'package:app/env.dart';
import 'package:flutter/material.dart';
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class RoutePage extends StatefulWidget {
  @override
  _RoutePageState createState() => _RoutePageState();
}

class _RoutePageState extends State<RoutePage> {
  Completer<GoogleMapController> _controller = Completer();
  GoogleMapController mapController;

  final Set<Marker> _markers = {};

  Set<Polyline> _polylines = {};
  List<LatLng> polylineCoordinates = [];
  PolylinePoints polylinePoints = PolylinePoints();
  String googleAPIKey = GOOGLE_MAPS_API_KEY;

  static LatLng sourceLocation = LatLng(42.7477863, -71.1699932);
  static LatLng destLocation = LatLng(42.6871386, -71.2143403);

  void _onMapCreated(GoogleMapController controller) async {
    mapController = controller;
    _controller.complete(controller);

    LatLng temp;

    if (sourceLocation.latitude > destLocation.latitude) {
      temp = sourceLocation;
      sourceLocation = destLocation;
      destLocation = temp;
    }

    LatLngBounds bound =
        LatLngBounds(southwest: sourceLocation, northeast: destLocation);

    BitmapDescriptor sourceIcon = await BitmapDescriptor.fromAssetImage(
        ImageConfiguration(devicePixelRatio: 2.5), 'assets/driving_pin.png');
    BitmapDescriptor destinationIcon = await BitmapDescriptor.fromAssetImage(
        ImageConfiguration(devicePixelRatio: 2.5),
        'assets/destination_map_marker.png');

    setState(() {
      _markers.clear();
      addMarker(sourceLocation, "Madrid", "5 Star Rating", icon: sourceIcon);
      addMarker(destLocation, "Barcelona", "7 Star Rating",
          icon: destinationIcon);
    });

    CameraUpdate u2 = CameraUpdate.newLatLngBounds(bound, 50);
    this.mapController.animateCamera(u2).then((void v) {
      check(u2, this.mapController);
    });
  }

  void addMarker(LatLng mLatLng, String mTitle, String mDescription,
      {BitmapDescriptor icon}) {
    _markers.add(Marker(
      markerId: MarkerId(
          (mTitle + "_" + _markers.length.toString()).toString()), //must unique
      position: mLatLng,
      infoWindow: InfoWindow(
        title: mTitle,
        snippet: mDescription,
      ),
      icon: icon,
    ));
  }

  void check(CameraUpdate u, GoogleMapController c) async {
    c.animateCamera(u);
    mapController.animateCamera(u);
    LatLngBounds l1 = await c.getVisibleRegion();
    LatLngBounds l2 = await c.getVisibleRegion();
    print(l1.toString());
    print(l2.toString());

    if (l1.southwest.latitude == -90 || l2.southwest.latitude == -90)
      check(u, c);
    else {
      await setPolylines();
    }
  }

  void _onCameraMove(CameraPosition position) {}

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Maps Sample App'),
          backgroundColor: Colors.green[700],
        ),
        body: GoogleMap(
          myLocationEnabled: true,
          compassEnabled: true,
          tiltGesturesEnabled: false,
          markers: _markers,
          polylines: _polylines,
          mapType: MapType.normal,
          onMapCreated: _onMapCreated,
          initialCameraPosition: CameraPosition(
            target: sourceLocation,
            zoom: 13.0,
          ),
          onCameraMove: _onCameraMove,
        ),
      ),
    );
  }

  setPolylines() async {
    List<PointLatLng> result = await polylinePoints?.getRouteBetweenCoordinates(
        googleAPIKey,
        sourceLocation.latitude,
        sourceLocation.longitude,
        destLocation.latitude,
        destLocation.longitude);
    if (result.isNotEmpty) {
      result.forEach((PointLatLng point) {
        polylineCoordinates.add(LatLng(point.latitude, point.longitude));
      });
    }

    setState(() {
      Polyline polyline = Polyline(
          polylineId: PolylineId("poly"),
          color: Color.fromARGB(255, 40, 122, 198),
          points: polylineCoordinates);

      _polylines.add(polyline);
    });
  }
}

Upvotes: 1

Related Questions