【问题标题】:How to draw polyline in google maps flutter between user location and a marker in flutter?如何在谷歌地图中绘制折线在用户位置和颤动中的标记之间颤动?
【发布时间】:2022-11-02 17:19:40
【问题描述】:

这是我在这个网站上的第一篇文章,所以我希望能得到我需要的帮助。

我是 Flutter 新手,我正在尝试使用 flutter_polyline_points 插件在用户位置和 const marker 之间绘制折线或路线。路线不显示。

那么有人可以帮助我实现这一目标吗?

提前致谢!

这些是我的代码:

class OrderTrackingPageState extends State<OrderTrackingPage> {
  final Completer<GoogleMapController> _controller = Completer();

  Set<Polyline> _polylines = Set<Polyline>();
  List<LatLng> polylineCoordinates = [];
  PolylinePoints polylinePoints = PolylinePoints();
  late LatLng currentLocation;
  late Position currentPosition;
  final List<Marker> _markers = <Marker>[
    Marker(
        markerId: MarkerId('1'),
        position: LatLng(33.31271476080750, 44.35060022264830),
        infoWindow: InfoWindow(
          title: 'sourceLocation',
        )),
    Marker(
        markerId: MarkerId('2'),
        position: LatLng(33.305691, 44.369390),
        infoWindow: InfoWindow(
          title: 'destination',
        )),
  ];
  void setPolylines() async {
    PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
      'AIzaSyBzQAiu2jCU10HxZYHcxEHTKlEOWB8zJLg', // Your Google Map Key
      PointLatLng(
          _markers[0].position.latitude, _markers[0].position.longitude),
      PointLatLng(
          _markers[1].position.latitude, _markers[1].position.longitude),
    );
    if (result.status == 'ok') {
      result.points.forEach((PointLatLng point) {
        polylineCoordinates.add(LatLng(point.latitude, point.longitude));
      });
      setState(() {
        _polylines.add(
          Polyline(
            polylineId: PolylineId("polyline"),
            points: polylineCoordinates,
            color: const Color(0xFF7B61FF),
            width: 6,
          ),
        );
      });
    }
  }

  @override
  void initState() {
    polylinePoints = PolylinePoints();
    setPolylines();
    getUserCurrentLocation().then((value) async {
      CameraPosition cameraPosition = new CameraPosition(
        target: LatLng(value.latitude, value.longitude),
        zoom: 14,
      );

      final GoogleMapController controller = await _controller.future;
      controller.animateCamera(CameraUpdate.newCameraPosition(cameraPosition));
      setState(() {});
    });
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        backgroundColor: Colors.grey,
        child: Icon(Icons.my_location),
        onPressed: () async {
          getUserCurrentLocation().then((value) async {
            print(value.latitude.toString() + " " + value.longitude.toString());
            // sourceLocation=LatLng(value.latitude, value.longitude);

            setState(() {
              _markers[0] = Marker(
                markerId: MarkerId("1"),
                position: LatLng(value.latitude, value.longitude),
                infoWindow: InfoWindow(
                  title: 'My first Location',
                ),
              );
            });

            // specified current users location
            CameraPosition cameraPosition = new CameraPosition(
              target: LatLng(value.latitude, value.longitude),
              zoom: 14,
            );

            final GoogleMapController controller = await _controller.future;
            controller
                .animateCamera(CameraUpdate.newCameraPosition(cameraPosition));
            setState(() {});
          });
        },
      ),
      body: GoogleMap(
        initialCameraPosition: CameraPosition(
          target: LatLng(
              _markers[0].position.latitude, _markers[0].position.longitude),
          zoom: 13.5,
        ),
        polylines: _polylines,
        markers: Set<Marker>.of(_markers),
        onMapCreated: (mapController) {
          _controller.complete(mapController);
          setPolylines();
        },
        myLocationEnabled: true,
        myLocationButtonEnabled: false,
        zoomGesturesEnabled: true,
        zoomControlsEnabled: true,
      ),
    );
  }

  Future<Position> getUserCurrentLocation() async {
    await Geolocator.requestPermission().then((value) {
      print(value);
    }).onError((error, stackTrace) async {
      await Geolocator.requestPermission();
      print("ERROR" + error.toString());
    });
    return await Geolocator.getCurrentPosition();
  }
}

【问题讨论】:

  • 您遇到了哪些错误导致您在这里寻求帮助?社区也会非常感激。
  • 我没有任何错误,但是当我运行我的应用程序时,折线没有显示在地图上

标签: flutter dart google-maps


【解决方案1】:

我使用自动完成位置和折线的完整代码。

import 'package:flutter/material.dart';
import 'package:flutter_google_places_hoc081098/flutter_google_places_hoc081098.dart';
import 'package:google_api_headers/google_api_headers.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:google_maps_webservice/places.dart';
import 'package:goplus/screens/mapsPickLocation.dart';
import 'package:goplus/widget/app_button.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:geolocator/geolocator.dart';
import 'package:toast/toast.dart';
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
import '../main.dart';
import '../utils/global_variable.dart';
import '../utils/app_colors.dart';

class HomePage extends StatefulWidget{
  HomePage({super.key});

  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return _HomePage();
  }
}

class _HomePage extends State<HomePage>{

  Set<Marker> markers = {};
  PolylinePoints polylinePoints = PolylinePoints();
  Map<PolylineId, Polyline> polylines = {};
  List<LatLng> polylineCoordinates = [];

  late Size size;
  String? destination;
  LatLng? destinationLatLng;
  CameraPosition? cam;

  void requestPermission() async{
    Map<Permission, PermissionStatus> request =  await [
      Permission.location
    ].request();
  }

  addPolyLine(List<LatLng> polylineCoordinates) {
    PolylineId id = const PolylineId("Trajet une");
    Polyline polyline = Polyline(
      polylineId: id,
      color: Colors.deepPurpleAccent,
      points: polylineCoordinates,
      width: 8,
    );
    polylines[id] = polyline;
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    size = MediaQuery.of(context).size;
    ToastContext().init(context);
    readBitconMarkerPinner();
    return Scaffold(
      body: FutureBuilder<bool>(
        future: Permission.location.serviceStatus.isEnabled,
        builder: (context, snapshot) {
          if(snapshot.hasData){
            if(snapshot.data!){
              return FutureBuilder<PermissionStatus>(
                  future: Permission.location.status,
                  builder: (context, status){
                    if(status.hasData){
                      if(status.data!.isGranted){
                        showLoader("Recherche de votre position
Veuillez patienter...");
                        return FutureBuilder<Position>(
                          future: Geolocator.getCurrentPosition(),
                          builder: (context, location){
                            if(location.hasData){
                              disableLoader();
                              position = LatLng(location.data!.latitude, location.data!.longitude);
                              return FutureBuilder<BitmapDescriptor>(
                                future: bitmap("assets/images/pictogramme.png", 90),
                                builder: (context, pictogramme){
                                  if(pictogramme.hasData){
                                    return body(position, pictogramme.data!);
                                  } else {
                                    return Container();
                                  }
                                },
                              );
                            } else {
                              return Container();
                            }
                          },
                        );
                      } else{
                        requestPermission();
                        return Center(
                          child: Padding(
                            padding: const EdgeInsets.all(16.0),
                            child: Column(
                              mainAxisAlignment: MainAxisAlignment.center,
                              children: [
                                const Text(
                                  "Autorisé l'aplication à utiliser votre position. 
Allez dans les paramètres pour forcer l'autorisation.",
                                  textAlign: TextAlign.center,
                                ),

                                const SizedBox(height: 16.0,),

                                AppButton(
                                  onTap: ()=>openAppSettings(),
                                  name: "Paramètre",
                                  color: AppColors.primaryColor,
                                )
                              ],
                            ),
                          ),
                        );
                      }
                    } else {
                      requestPermission();
                      return Container();
                    }
                  }
              );
            } else {
              return const Center(
                child: Padding(
                  padding: EdgeInsets.all(16.0),
                  child: Text(
                    "Activez la localisation puis relancer l'application pour utiliser GoPlus",
                    textAlign: TextAlign.center,
                  ),
                ),
              );
            }
          } else {
            return Container();
          }
        }
      ),
    );
  }

  Widget body(LatLng pos, BitmapDescriptor? picto){
    markers.add(
        Marker(
          markerId: const MarkerId('Ma Position'),
          position: position,
          infoWindow: const InfoWindow(
            title: 'Ma Position',
            snippet: 'Moi',
          ),
          icon: picto!,
        )
    );
    cam = CameraPosition(
        target: pos,
        zoom: zoom
    );

    return Stack(
      children: [
        GoogleMap(
          initialCameraPosition: cam!,
          markers: markers,
          polylines: Set<Polyline>.of(polylines.values),
          onMapCreated: (GoogleMapController _controller){
            _controller.animateCamera(
              CameraUpdate.newCameraPosition(
                CameraPosition(
                    target: pos,
                    zoom: zoom
                ),
              ),
            );
          },
        ),
        Stack(
          children: [
            Align(
              alignment: Alignment.topRight,
              child: Padding(
                padding: const EdgeInsets.only(top: 16.0, right: 16.0),
                child: Container(
                  height: 48,
                  width: 48,
                  decoration: BoxDecoration(
                      color: AppColors.primaryColor,
                      borderRadius: BorderRadius.circular(48.0)
                  ),
                  child: IconButton(
                    onPressed: () {
                      logOut();
                      Navigator.pushAndRemoveUntil(
                          context,
                          MaterialPageRoute(
                              builder: (BuildContext context) => const MyApp()
                          ),
                              (Route<dynamic> route) => false
                      );
                    },
                    icon: const Icon(
                      Icons.logout,
                    ),
                  ),
                ),
              ),
            ),

            Align(
              alignment: Alignment.bottomCenter,
              child: Padding(
                padding: const EdgeInsets.only(left: 16.0, right: 16.0, bottom: 16.0),
                child: Container(
                  height: destination != null ? size.width / 1.2 : size.width / 1.5,
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(size.width / 15),
                    color: AppColors.primaryColor,
                    boxShadow: [
                      BoxShadow(
                        color: Colors.grey.withOpacity(0.5),
                        spreadRadius: 5,
                        blurRadius: 7,
                        offset: const Offset(0, 3), // changes position of shadow
                      ),
                    ],
                  ),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    children: [
                      Padding(
                        padding: const EdgeInsets.only(left: 16.0, top: 16.0, right: 16.0),
                        child: Image.asset(
                          'assets/images/bonjour.png',
                          height: size.width / 9,
                          fit: BoxFit.fitWidth,
                        ),
                      ),

                      Padding(
                        padding: const EdgeInsets.only(left: 36.0, bottom: 16.0),
                        child: Text(
                            "OU ALLEZ-VOUS?",
                            style: TextStyle(
                                fontSize: size.width / 15,
                              fontFamily: 'Anton',
                              color: Colors.white
                            )
                        ),
                      ),

                      Padding(
                        padding: const EdgeInsets.only(left: 16.0, right: 16.0),
                        child: GestureDetector(
                          onTap: () async {
                            var place = await PlacesAutocomplete.show(
                                context: context,
                                apiKey: androidApiKey,
                                mode: Mode.overlay,
                                types: [],
                                strictbounds: false,
                                components: [Component(Component.country, 'cd')],
                                //google_map_webservice package
                                onError: (err){
                                  print(err);
                                }
                            );

                            if(place != null){
                              final plist = GoogleMapsPlaces(apiKey:androidApiKey,
                                apiHeaders: await const GoogleApiHeaders().getHeaders(),
                              );
                              String placeid = place.placeId ?? "0";
                              final detail = await plist.getDetailsByPlaceId(placeid);
                              final geometry = detail.result.geometry!;
                              final lat = geometry.location.lat;
                              final lang = geometry.location.lng;

                              PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
                                androidApiKey,
                                PointLatLng(position.latitude, position.longitude),
                                PointLatLng(lat, lang)
                              );

                              if (result.points.isNotEmpty) {
                                for (var point in result.points) {
                                  polylineCoordinates.add(LatLng(point.latitude, point.longitude));
                                }
                                setState(() {
                                  addPolyLine(polylineCoordinates);
                                });
                              }

                              setState(() {
                                destinationLatLng = LatLng(lat, lang);
                                destination = place.description.toString();
                                CameraPosition cameraPosition = CameraPosition(
                                  target: LatLng(lat, lang),
                                  zoom: 13,
                                );
                                cam = cameraPosition;
                                markers.add(
                                    Marker(
                                      markerId: const MarkerId('Destination'),
                                      position: destinationLatLng!,
                                      infoWindow: InfoWindow(
                                        title: 'Votre Destination',
                                        snippet: '$destination!',
                                      ),
                                      icon: pinner!,
                                    )
                                );
                              });
                            }
                          },
                          child: Container(
                            padding: const EdgeInsets.all(16.0),
                            decoration: const BoxDecoration(
                              border: Border(
                                bottom: BorderSide(width: 1.0, color: Colors.black),
                              )
                            ),
                            child: Row(
                              children: [
                                const Icon(
                                  Icons.search
                                ),

                                const SizedBox(
                                  width: 8.0,
                                ),

                                Flexible(
                                  child: Text(
                                    destination != null ? '$destination!' : "Entrez votre destination"
                                  ),
                                )
                              ],
                            ),
                          ),
                        ),
                      ),

                      Padding(
                          padding: const EdgeInsets.only(left: 0, top: 16.0, right: 0, bottom: 16.0),
                          child: AppButton(
                            color: Colors.black,
                            name: 'SUIVANT',
                            onTap: (){
                              if(destination == null){
                                Toast.show('Veuillez entrée une destination', duration: Toast.lengthLong, gravity: Toast.bottom);
                                return;
                              }
                              Navigator.push(
                                context,
                                MaterialPageRoute(
                                    builder: (BuildContext context) =>
                                        PickLocation(
                                          destination: true,
                                        )
                                ),
                              );
                            },
                          )
                      ),
                    ],
                  ),
                ),
              ),
            ),
          ],
        ),
      ],
    );
  }
}

【讨论】:

    猜你喜欢
    • 2022-01-10
    • 2019-10-03
    • 2021-07-10
    • 2023-03-13
    • 2021-09-23
    • 1970-01-01
    • 2020-10-23
    • 2019-09-23
    • 2019-12-16
    相关资源
    最近更新 更多