flutter_map Docs
Project Links💝 Support Us
v7
v7
  • flutter_map
  • 🏗️Why Choose flutter_map?
  • 💝Supporters
  • ✏️Credits & Contributing
  • Getting Started
    • How Does It Work?
      • Raster vs Vector Tiles
    • Installation
    • Examples
    • v7 Information
  • Usage
    • Base Widget
    • Options
      • Interaction Options
      • Custom CRSs
    • Layers
    • Programmatic Interaction
      • Controllers & Cameras
      • External Custom Controllers
      • Listen To Events
    • Full API Reference
  • Layers
    • Tile Layer
      • Tile Providers
      • WMS Usage
    • Marker Layer
    • Polygon Layer
    • Polyline Layer
    • Circle Layer
    • Overlay Image Layer
    • Attribution Layer
    • Layer Interactivity
      • Hit Testing Behaviour
  • Tile Servers
    • Using Google Maps
    • Using Mapbox
    • Using Thunderforest
    • Using Tracestrack
    • Using Stadia Maps
    • Using Lima Labs
    • Using Bing Maps
    • Offline Mapping
    • Other Options
  • Plugins
    • Plugins List
    • Creating A Plugin
      • Creating New Tile Providers
      • Creating New Layers
Powered by GitBook

© flutter_map Authors & Maintainers

On this page
  • Pattern
  • Interactivity
  • Performance Optimizations
  • Culling
  • Simplification
  • Routing/Navigation
  • Converting Formats

Was this helpful?

Export as PDF
  1. Layers

Polyline Layer

PreviousPolygon LayerNextCircle Layer

Last updated 5 months ago

Was this helpful?

You can add lines to maps by making them out of individual coordinates using PolylineLayer and Polylines.

PolylineLayer(
  polylines: [
    Polyline(
      points: [LatLng(30, 40), LatLng(20, 50), LatLng(25, 45)],
      color: Colors.blue,
    ),
  ],
),

Pattern

Polylines support a solid, dotted, and dashed style, through a StrokePatternpassed as an argument toPolyline.pattern. These are flexible, and spacing and sizing may be customized.

dotted and dashed patterns should 'fit' the Polyline they are applied to, otherwise the final point in that line may not be visually clear. The fit can be adjusted when defining the pattern through the PatternFit enum.

Interactivity

PolylineLayers and Polylines support hit detection and interactivity.

If any polylines are very thin, it is recommended for accessibility reasons to increase the size of the 'hitbox' (the area where a hit is detected on a polyline) to larger than the line itself in order to make it easier to tap/interact with the polyline.

The minimumHitbox argument adjusts the minimum size of the hitbox - the size of the hitbox will usually be the entire visual area/thickness of the polyline (and border), but will be no less than this value. It defaults to 10.

Performance Optimizations

The example application includes a stress test which generates a Polyline with 200,000 points.

Culling

To improve performance, line segments that are entirely offscreen are effectively removed - they are not processed or painted/rendered. This is enabled by default and disabling it is not recommended.

Polylines that are particularly wide (due to their strokeWidth/borderStrokeWidth may be improperly culled if using the default configuration. This is because culling decisions are made on the 'infinitely thin line' joining the points, not the visible line, for performance reasons.

Therefore, the cullingMargin parameter is provided, which effectively increases the distance a segement needs to be from the viewport edges before it can be culled. Increase this value from its default if line segements are visibly disappearing unexpectedly.

Culling cannot be applied to polylines with a gradient fill, as this would cause inconsistent gradients.

These will be automatically internally excluded from culling: it is not necessary to disable it layer-wide - unless all polylines have gradient fills, in which case that may yield better performance.

Avoid using these if performance is of importance. Instead, try using multiple polylines with coarser color differences.

Simplification

Simplification algorithms reduce the number of points in each line by removing unnecessary points that are 'too close' to other points which create tiny line segements invisible to the eye. This reduces the number of draw calls and strain on the raster/render thread. This should have minimal negative visual impact (high quality), but should drastically improve performance.

For this reason, polylines can be more simplified at lower zoom levels (more zoomed out) and less simplified at higher zoom levels (more zoomed in), where the effect of culling on performance improves and trades-off. This is done by scaling the simplificationTolerance parameter (see below) automatically internally based on the zoom level.

To adjust the quality and performance of the simplification, the maximum distance between removable points can be adjusted through the simplificationTolerance parameter. Increasing this value (from its default of 0.4) results in a more jagged, less accurate (lower quality) simplification, with improved performance; and vice versa. Many applications use a value in the range 0 - 1.

To disable simplification, set simplificationTolerance to 0.

The simplification step must run before culling, to avoid the polyline appearing to change when interacting with the map (due to the first and last points of the polyline changing, influencing the rest of the simplified points).

Therefore, reducing/disabling simplification will yield better performance on complex polylines that are out of the camera view (and therefore culled without requiring the potentially expensive simplification). However, using simplification will likely improve performance overall - it does this by reducing the load on the raster thread and slightly increasing the load on the UI/build/widget thread.

On layers with (many) only 'short' polylines (those with few points), disabling simplification may yield better performance.

Routing/Navigation

Routing is out of scope for 'flutter_map'. However, if you can get a list of coordinates from a 3rd party, then you can use polylines to show them!

Converting Formats

You may have a polyline with 'Google Polyline Encoding' (which is a lossy compression algorithm to convert coordinates into a string and back). These are often returned from routing engines, for example. In this case, you'll need to decode the polyline to the correct format first, before you can use it in a Polyline's points argument.

unpack_polyline.dart
import 'package:latlong2/latlong.dart';
export 'package:google_polyline_algorithm/google_polyline_algorithm.dart'
    show decodePolyline;

extension PolylineExt on List<List<num>> {
  List<LatLng> unpackPolyline() =>
      map((p) => LatLng(p[0].toDouble(), p[1].toDouble())).toList();
}

You can then use the package and the above snippet by doing:

import 'unpack_polyline.dart';

decodePolyline('<encoded-polyline>').unpackPolyline(); // Returns `List<LatLng>` for a map polyline

To improve performance, polylines are 'simplified' before being culled and painted/rendered. The well-known is used to perform this, and is enabled by default.

Good open source options that can be self-hosted include (which includes a public demo server) and . You can also use a commercial solution such as Mapbox or Google Maps - these can often give more accurate/preferable results because they can use their traffic data when routing.

One way to accomplish this is to use another Flutter library called , together with a custom method. You can use the code snippet below, which can just be pasted into a file and imported whenever needed:

Layer Interactivity
Ramer–Douglas–Peucker algorithm
OSRM
Valhalla
'google_polyline_algorithm'
LogoPolylineLayer class - flutter_map library - Dart API
LogoPolyline class - flutter_map library - Dart API
An example Polyline
Illustration of the 5 types of PatternFit applied to a dashed Polyline From left to right: none, appendDot, extendFinalDash, scaleUp (default), scaleDown