Search code examples
jsonfluttergoogle-mapsgoogle-polyline

How to show multiple sets of polylines in Flutter on one Google map


I am trying to show multiple sets of different polylines (each set represents one cycling route with its own start and endpoint).

There are ten routes in total I am bringing in from a JSON file. The problem is the map is consolidating all the individual ten routes into one mammoth polyline.

So It is sort of connecting them all together (you can just make out the very straight line connecting between each route and only one startCap and endCap icon).

I would expect/want to see ten different startCap and endCap icons and spaces between each polyline set.

So how do I make the map show each polyline route as distinct routes?

I am using flutter_polyline_points to decode the polyline route to the google map.

Code below and the JSON is on the live link to make it easy to emulate if that helps.

In essence in terms of steps :

  1. I create the google map and have one main central marker on it.

  2. I then bring in ten routes from a JSON file. These are ten objects in an array called Segments. Each object has a unique id I use for the PolyLineid and a unique polyline set of points in a string. So I bring in the JSON and then.

  3. iterate over each object and decode the polyline string to polyline coordinates which I attempt to then add to the map as multiple PolyLines.

Also to here is the output I am seeing to bring the issue to life.

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), double.parse(long)),
            zoom: 13,
          ),
          markers: _marker,
          onMapCreated: (GoogleMapController controller) async {
            mapController = controller;
            await fetchStrava();
          },
        ),
      ),
    );
  }
}

The JSON file contents (live on the link in the code) https://ibikeride.com/strava.json is here for reference:

{
    "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"
        }
    ]
}

I'm pretty new to coding but enjoying the journey.

I have done a number of searches on here for the issue, Medium, and watched no end of youtube videos but still flummoxed. Any pointers appreciated.

I sense it is something to do with creating a list of unique Polyines one adds to iteratively. Big Thanks


Solution

  • You have to create a list of object which contains lat long. Add polylines coordinates and markers into the list. As showing in the link.