如何在一张 Google 地图上显示 Flutter 中的多组折线

问题描述

我正在尝试显示多组不同的多段线(每组多段线代表一条具有自己起点和终点的骑行路线)。

我从 JSON 文件中引入的路由总共有 10 条。问题是 map 正在将所有 10 条路线合并为一条巨大的折线。

所以这有点像将它们连接在一起(你可以找出连接每条路线的直线和只有一个 startCapendCap 图标)。

我希望/希望看到十个不同的 startCapendCap 图标,以及每个折线集之间的空格

那么如何让 map 将每条折线路线显示为不同的路线?

我正在使用 flutter_polyline_points 解码到 google map 的折线路线。

下面的代码和 JSON 位于实时链接上,如果有帮助,可以轻松模仿。

本质上是步骤

  1. 我创建了谷歌地图并在其上放置了一个主要的中央标记。

  2. 然后我从 JSON 文件中引入十个路由。这些是称为 Segments 的数组中的十个对象。每个对象都有我用于 PolyLineid 的唯一 id 和字符串中唯一的多段线点集。所以我引入了 JSON 然后。

  3. 遍历每个对象并将折线字符串解码为折线坐标,然后我尝试将其作为多条折线添加到地图中。

这里还有我看到的将问题变为现实的输出。

enter image description here


import 'package:flutter_polyline_points/flutter_polyline_points.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Multiple Polylines',theme: ThemeData(
        primarySwatch: Colors.orange,),home: MapScreen(),);
  }
}

class MapScreen extends StatefulWidget {
  @override
  _MapScreenState createState() => _MapScreenState();
}

class _MapScreenState extends State<MapScreen> {
  GoogleMapController mapController;
  final Set<Marker> _marker = {};
  List<LatLng> polylineCoordinates = [];
  final Set<Polyline> _polylines = {};
  PolylinePoints polylinePoints = PolylinePoints();
  String lat = '51.200000';
  String long = '-0.440000';
  String title = 'Surrey Hills Mountain Biking';
  String location = 'Walking Bottom Car Park,Peaslake,Surrey';

  Future fetchStrava() async {
    final response = await http.get(
      'https://ibikeride.com/strava.json',);
    return parseStrava(response.body);
  }

  Future parseStrava(String responseBody) async {
    final Map<String,dynamic> parsed = await jsonDecode(responseBody);
    parsed['segments'].forEach((parse) {
      drawStrava(parse['points'],parse['id'].toString());
    });
  }

  Future drawStrava(points,polyid) async {
    var result = await polylinePoints.decodePolyline(points);

    if (result.isNotEmpty) {
      result.forEach((PointLatLng point) {
        polylineCoordinates.add(LatLng(point.latitude,point.longitude));
      });
    }

    _getPolyLine(polyid,polylineCoordinates);
  }

  void _getPolyLine(polyid,polyCord) {
    var id = PolylineId(polyid);
    _polylines.add(Polyline(
      polylineId: id,color: Colors.blue,width: 2,jointType: JointType.round,startCap: Cap.customCapFromBitmap(BitmapDescriptor.defaultMarker),endCap:
          Cap.customCapFromBitmap(BitmapDescriptor.defaultMarkerWithHue(90)),points: polyCord,));
    setState(() {});
  }

  @override
  void initState() {
    super.initState();
    polylineCoordinates.clear();
    _marker.add(
      Marker(
          markerId: MarkerId('t'),infoWindow: InfoWindow(
            title: (title),snippet: (location),position: LatLng(double.parse(lat),double.parse(long)),icon: BitmapDescriptor.defaultMarker),);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        child: GoogleMap(
          polylines: _polylines,mapType: MapType.hybrid,myLocationEnabled: true,initialCameraPosition: CameraPosition(
            target: LatLng(double.parse(lat),zoom: 13,markers: _marker,onMapCreated: (GoogleMapController controller) async {
            mapController = controller;
            await fetchStrava();
          },);
  }
}

JSON 文件内容(位于代码中的链接上)https://ibikeride.com/strava.json 在这里供参考:

{
    "segments": [
        {
            "id": 3592388,"name": "Barry Knows Best","points": "uokwHvdtA@hAR`B^bBRnAQp@c@^w@b@o@t@Uv@c@r@c@hAsAxDOd@y@lDk@t@WVw@VeCl@u@\\@^k@jAKNi@b@iCVFBj@Cx@WpBKpA_@d@@Fn@W^c@RYBIHJ^"
        },{
            "id": 10925800,"name": "Combe Ln ","points": "eauwHhezAHR@ZSlE?zDB|ALxAz@tGf@lCb@pA^|@j@l@XPvBf@bCL~BAdCMxA@Z?XDr@RTBT@h@?b@KLIPo@TuAJYPYz@u@~@aAn@]bAc@tCaA"
        },{
            "id": 22105173,"name": "Charlie & Mai's Rollercoast","points": "wblwHfqvA_@@e@Es@Le@CI@]?YEE@CD@HT\\@H?HEHm@PWAKBW@G?KGIAOFWMQEQD_@@OCc@?MBEFYHI?KFGEE?ARVNFCj@B^?`@LR?HCJHX@NCXDg@TEEi@PS?WHGBEJOJE@GAOT[HG?K@KFCBKTBDSXg@F[ZECWZCP"
        },{
            "id": 2575161,"name": "Yoghurt Pots.","points": "wljwHdoqASQKa@QIGSHOj@SHg@I[Ha@G[W[WiAa@Yc@UU_@k@UWE[Fg@Wc@OQQ_AC_AGa@He@Iy@Ii@AUSOAk@BSd@a@TS@MR"
        },{
            "id": 21544370,"name": "Shere to Gomshall","points": "caswH`lxA?iCImCU{DM_DS_ICeKPiCJuCPwCZiAVe@X_@fBmBz@eA"
        },{
            "id": 14062811,"name": "Shere to Little London","points": "ysrwHjxyAVVr@~AHL`@Xb@Hd@CVGd@G~Bg@z@YjAOl@Kl@Gt@O~@?f@G|@E~@MZIf@GtAWdA?b@N"
        },{
            "id": 20763954,"name": "All the Novas","points": "uckwHvvwAc@Gk@MmB{@q@KSK[Yc@s@OS[SQEQCSUQIGIIOSiA[aAGKa@_@OKmA{A_Ai@w@q@[Qi@MgA?i@IUOg@Qe@IUOWUWMK?UFSBG?[Oq@Di@MYB]CK@MD[\\GDI?q@MKB"
        },{
            "id": 11514010,"name": "Captain Clunk (before the drops)","points": "yqiwH|kwAMWGAg@NaA@}@VM@MCk@UOCs@@i@[ME_@EYFe@XQF_AJ"
        },{
            "id": 23855128,"name": "Abinger - Hammer to Sutton","points": "{{qwH|hsA~@K`Bw@hA_@nAO`CCbAJ\\H~CbAjCxAh@RZFn@@rAKnAUhBk@j@KZ@ZJdAp@ND\\@NC\\KfAs@r@u@v@uARg@|@iDn@yAt@iA|AiBp@cAXq@lAcERa@VYZQt@Y|@UTQ`@w@t@qBPu@L{@\\wIH}@pBeM"
        },{
            "id": 13501471,"name": "Whitedown,turnoff till switchback","points": "garwHbxoAsAaA_A]uA[yC_@UG_@Ys@u@kAy@eA{@mAq@k@e@eCkCiBuBu@w@e@m@_A_AaAqAgAqAu@Us@BcBViADeACqC]}A?k@F"
        }
    ]
}

我对编码很陌生,但很享受这段旅程。

我已经在此处针对该问题 Medium 进行了大量搜索,并没有看完 youtube 视频,但仍然感到困惑。任何指针表示赞赏。

我感觉这与创建一个 list 的独特 Polyines 迭代添加有关。非常感谢

解决方法

您必须创建一个包含经纬度的对象列表。将折线坐标和标记添加到列表中。如link中所示。

,
  1. 创建一个生成折线的方法:

     Future<Polyline> _getRoutePolyline(
       {required LatLng start,required LatLng finish,required Color color,required String id,int width = 6}) async {
     // Generates every polyline between start and finish
     final polylinePoints = PolylinePoints();
     // Holds each polyline coordinate as Lat and Lng pairs
     final List<LatLng> polylineCoordinates = [];
    
     final startPoint = PointLatLng(start.latitude,start.longitude);
     final finishPoint = PointLatLng(finish.latitude,finish.longitude);
    
     final result = await polylinePoints.getRouteBetweenCoordinates(
       _googleApiKey,startPoint,finishPoint,);
     if (result.points.isNotEmpty) {
       // loop through all PointLatLng points and convert them
       // to a list of LatLng,required by the Polyline
       result.points.forEach((PointLatLng point) {
         polylineCoordinates.add(
           LatLng(point.latitude,point.longitude),);
       });
     }
     final polyline = Polyline(
       polylineId: PolylineId(id),color: color,points: polylineCoordinates,width: width,);
     return polyline;
     }
    
  2. 生成任意多的折线:

     Future<Set<Polyline>> _getTwoPolylines() async {
     // Use your location.
     const firstPolylineStart = LatLng(49.818453,24.076606);
     const firstPolylineFinish = LatLng(49.834409,24.067875);
    
     final firsPolyline = await _getRoutePolyline(
       start: firstPolylineStart,finish: firstPolylineFinish,color: Colors.green,id: 'firstPolyline',);
    
     // Use your location.
     const secondPolylineStart = LatLng(49.836510,24.064096);
     const secondPolylineFinish = LatLng(49.840191,24.043384);
    
     final secondPolyline = await _getRoutePolyline(
       start: secondPolylineStart,finish: secondPolylineFinish,color: Colors.red,id: 'secondPolyline',);
    
     final Set<Polyline> polylines = {};
     polylines.add(firsPolyline);
     polylines.add(secondPolyline);
    
     return polylines;
     }
    
  3. 将生成的多段线设置为 GoogleMappolylines 字段)。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...