iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🌐

[Flutter] Drawing Lines on Google Maps with Polyline

に公開

Overview

I would like to explore how to implement drawing lines on Google Maps using Polylines in Flutter.

Method

Based on my research, I found the following two packages on Pub, so I will try each one and compare them.

  1. How to specify polyline with google_maps_flutter

https://pub.dev/documentation/google_maps_flutter/latest/google_maps_flutter/GoogleMap/polylines.html

  1. How to use the flutter_polyline_points package

https://pub.dev/packages/flutter_polyline_points

Trying out Polyline with google_maps_flutter

I will try the polyline feature of google_maps_flutter right away.

Package Installation

dependencies:
  google_maps_flutter: ^2.7.0

First, Create a Screen That Just Displays a Map

Create google_maps_flutter_polyline.dart with the following content:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class GoogleMapsFlutterPolyline extends StatefulWidget {
  const GoogleMapsFlutterPolyline({super.key});

  @override
  State<GoogleMapsFlutterPolyline> createState() =>
      GoogleMapsFlutterPolylineState();
}

class GoogleMapsFlutterPolylineState extends State<GoogleMapsFlutterPolyline> {
  final Completer<GoogleMapController> _controller =
      Completer<GoogleMapController>();

  static const CameraPosition _initialCameraPosition = CameraPosition(
    target: LatLng(35.68123428932672, 139.76714355230686),
    zoom: 14.4746,
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Google Maps Flutter Polyline')),
      body: GoogleMap(
        mapType: MapType.normal,
        initialCameraPosition: _initialCameraPosition,
        onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
        },
      ),
    );
  }
}

When you run this, a screen that just displays the map as shown below should appear.

image1.png

Actually using Polyline

Next, let's try drawing lines using Polyline, which is the main topic. Modify google_maps_flutter_polyline.dart as follows:

import 'dart:async';

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class GoogleMapsFlutterPolyline extends StatefulWidget {
  const GoogleMapsFlutterPolyline({super.key});

  @override
  State<GoogleMapsFlutterPolyline> createState() =>
      GoogleMapsFlutterPolylineState();
}

class GoogleMapsFlutterPolylineState extends State<GoogleMapsFlutterPolyline> {
  final Completer<GoogleMapController> _controller =
      Completer<GoogleMapController>();

  static const CameraPosition _initialCameraPosition = CameraPosition(
    target: LatLng(35.68123428932672, 139.76714355230686),
    zoom: 14.4746,
  );
  final Set<Polyline> _polylines = {};

  @override
  void initState() {
    super.initState();
    _setPolylines();
  }

  void _setPolylines() {
    setState(() {
      _polylines.add(
        const Polyline(
          polylineId: PolylineId('polyline_1'),
          points: [
            LatLng(35.681236, 139.767125),
            LatLng(35.680959, 139.767552),
            LatLng(35.680583, 139.767998),
          ],
          color: Colors.red,
          width: 5,
        ),
      );
      _polylines.add(
        const Polyline(
          polylineId: PolylineId('polyline_2'),
          points: [
            LatLng(35.681236, 139.767125),
            LatLng(35.682839, 139.769435),
            LatLng(35.683342, 139.770674),
          ],
          color: Colors.green,
          width: 5,
        ),
      );
      _polylines.add(
        const Polyline(
          polylineId: PolylineId('polyline_3'),
          points: [
            LatLng(35.681236, 139.767125),
            LatLng(35.680178, 139.766273),
            LatLng(35.679694, 139.765451),
          ],
          color: Colors.blue,
          width: 5,
        ),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Google Maps Flutter Polyline')),
      body: GoogleMap(
        mapType: MapType.normal,
        initialCameraPosition: _initialCameraPosition,
        polylines: _polylines,
        onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
        },
      ),
    );
  }
}

When you run this, you should see three lines of different colors as shown below.

image2.png

Polyline Class

https://pub.dev/documentation/google_maps_flutter/latest/google_maps_flutter/Polyline-class.html

As you can see from the sample implementation, lines are drawn by setting a Set of Polyline to the polylines property of the GoogleMap class.

The main properties to set are as follows:

  • polylineId
    • Specify PolylineId.
    • As stated, "This does not need to be globally unique. It only needs to be unique within the list," it just needs to be unique within the Polyline Set.
  • points
    • Specify a List<LatLng> representing the vertices of the polyline to be drawn.
  • color
    • Specify the color of the line segment in ARGB format.
  • width
    • The width of the line segment to be drawn.

Making it a dotted line

You can create a dotted line by setting PatternItem's dash in the patterns property.

Polyline(
  // ...
  patterns: [PatternItem.dash(20), PatternItem.gap(20)], // ← Added
),

The above configuration creates a dotted line by repeating a 20px line and a 20px gap.

image3.png

Trying out Polyline with flutter_polyline_points

Next, I will try out flutter_polyline_points.

Package Installation

dependencies:
  flutter_polyline_points: ^2.0.1

Actually using it

Create a file named flutter_polyline_points.dart with the following content:

import 'dart:async';

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

class FlutterPolylinePoints extends StatefulWidget {
  const FlutterPolylinePoints({super.key});

  @override
  State<FlutterPolylinePoints> createState() => FlutterPolylinePointsState();
}

class FlutterPolylinePointsState extends State<FlutterPolylinePoints> {
  final Completer<GoogleMapController> _controller =
      Completer<GoogleMapController>();

  static const CameraPosition _initialCameraPosition = CameraPosition(
    target: LatLng(35.68123428932672, 139.76714355230686),
    zoom: 14.4746,
  );
  final Set<Polyline> _polylines = {};
  final PolylinePoints polylinePoints = PolylinePoints();

  @override
  void initState() {
    super.initState();
    _setPolylines();
  }

  void _setPolylines() async {
    PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
      request: PolylineRequest(
        origin: const PointLatLng(26.48424, 50.04551),
        destination: const PointLatLng(26.46423, 50.06358),
        mode: TravelMode.walking,
        wayPoints: [PolylineWayPoint(location: "Sabo, Yaba Lagos Nigeria")],
      ),
      googleApiKey: 'YOUR_API_KEY',
    );
    if (result.points.isNotEmpty) {
      setState(() {
        _polylines.add(
          Polyline(
            polylineId: const PolylineId('polyline_1'),
            points: result.points
                .map((p) => LatLng(p.latitude, p.longitude))
                .toList(),
            color: Colors.red,
            width: 5,
          ),
        );
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('FlutterPolylinePoints')),
      body: GoogleMap(
        mapType: MapType.normal,
        initialCameraPosition: _initialCameraPosition,
        onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
        },
        polylines: _polylines,
      ),
    );
  }
}

Set the API Key you obtained in advance in googleApiKey. Running the code above will result in the following:

image4.gif

It seems this package uses Google Maps Platform's Routes API. By specifying the origin and destination coordinates in advance, it calculates the route between them and returns each point as an array.

flutter_polyline_points doesn't draw the Polyline itself; rather, it serves to calculate the points required for drawing a Polyline with google_maps_flutter.

Summary

My impression was that it is generally best to use google_maps_flutter, and if you have requirements such as finding routes between specific points, then flutter_polyline_points would be the right choice.

Reference URLs

https://zenn.dev/10_tofu_01/articles/271b5b338734e7

Discussion