clustering_google_maps 0.1.2

  • Readme
  • Changelog
  • Example
  • Installing
  • 87

Clustering for Flutter Google Maps #

pub package

A Flutter package that recreate clustering technique in a Google Maps widget.

Developers Preview Status #

The package recreate the CLUSTERING technique in a Google Maps. It's work with data recordered in a dababase SQLite. I use sqflite (DB TECHNIQUE) It's work with a list of LatLngAndGeohash object. (MEMORY TECHNIQUE)

Usage #

To use this package, add clustering_google_maps as a dependency in your pubspec.yaml file.

For a better performance, at every zoom variation on the map, the package performs a specific query on the SQLite database, but you can force update with updateMap() method.

Getting Started #


To work properly, you must have the data of the points saved in a SQLite database. Latitude, longitude and the string of geohash. These three parameters are necessary for correct operation. If you have not saved the GEOHASH, I suggest you install GEOHASH plugin and save the value of Geohash in the points table of db.

For this solution you must use the db constructor of ClusteringHelper:



To work properly you must have a list of LatLngAndGeohash object. LatLngAndGeohash is a simple object with Location and Geohash property, the last is generated automatically; you need only location of the point.

For this solution you must use the MEMORY constructor of ClusteringHelper:


Aggregation Setup #

Yuo can customize color, range count and zoom limit of aggregation. See this class: AggregationSetup.

Future Implementations #

  • To further improve performance I am creating a way to perform sql queries only on the latlng bounding box displayed on the map.
  • I will insert custom marker with number of points.

Quick Example for both solution #

import 'package:example/app_db.dart';
import 'package:example/fake_point.dart';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
import 'package:clustering_google_maps/clustering_google_maps.dart';

class HomeScreen extends StatefulWidget {
  final List<LatLngAndGeohash> list;

  HomeScreen({Key key, this.list}) : super(key: key);

  _HomeScreenState createState() => _HomeScreenState();

class _HomeScreenState extends State<HomeScreen> {
  ClusteringHelper clusteringHelper;
  final CameraPosition initialCameraPosition =
      CameraPosition(target: LatLng(0.000000, 0.000000), zoom: 0.0);

  Set<Marker> markers = Set();

  void _onMapCreated(GoogleMapController mapController) async {
    clusteringHelper.mapController = mapController;
    if (widget.list == null) {
      clusteringHelper.database = await AppDatabase.get().getDb();

  updateMarkers(Set<Marker> markers) {
    setState(() {
      this.markers = markers;

  void initState() {
    if (widget.list != null) {
    } else {


  // For db solution
  initDatabaseClustering() {
    clusteringHelper = ClusteringHelper.forDB(
      dbGeohashColumn: FakePoint.dbGeohash,
      dbLatColumn: FakePoint.dbLat,
      dbLongColumn: FakePoint.dbLong,
      dbTable: FakePoint.tblFakePoints,
      updateMarkers: updateMarkers,
      aggregationSetup: AggregationSetup(),

  // For memory solution
  initMemoryClustering() {
    clusteringHelper = ClusteringHelper.forMemory(
      list: widget.list,
      updateMarkers: updateMarkers,
      aggregationSetup: AggregationSetup(markerSize: 150),

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Clustering Example"),
      body: GoogleMap(
        onMapCreated: _onMapCreated,
        initialCameraPosition: initialCameraPosition,
        markers: markers,
        onCameraMove: (newPosition) =>
            clusteringHelper.onCameraMove(newPosition, forceUpdate: false),
        onCameraIdle: clusteringHelper.onMapIdle,
      floatingActionButton: FloatingActionButton(
            widget.list == null ? Icon(Icons.content_cut) : Icon(Icons.update),
        onPressed: () {
          if (widget.list == null) {
            //Test WHERE CLAUSE
            clusteringHelper.whereClause = "WHERE ${FakePoint.dbLat} > 42.6";
          //Force map update

See the example directory for a complete sample app.

0.1.2 #

  • Migrate to google_maps_flutter: 0.5.21+3
  • Remove print in releaseMode

0.1.0+19 #

  • Migrate to google_maps_flutter: 0.5.19
  • Performance improvement: now sql query and memory filter are made in visible bounding box
  • New bitmap descriptor from bytes of canvas image
  • Now the count of aggregation points is showed on marker
  • Now you can setup your configuration: colors, aggregation range, zoom aggregation limits

0.0.5+16 #

  • Migrate to google_maps_flutter: 0.5.16
  • Update path_provider package to 1.1.0

0.0.5+13 #

  • Migrate to google_maps_flutter: 0.5.13

0.0.4+2 #

  • Add secure MarkerId to marker

0.0.4+1 #

  • Add memory clustering fuction, now you can use clustering with a list of LatLngAndGeohash object
  • Add memory clustering to example
  • Now you can update the map during the user move or zoom the map (NOT RECOMMENDED)
  • Update Readme

0.0.4 #

  • Migrate to google_maps_flutter: 0.4.0
  • Remove rangeZoomUpdate properties (now the map will update with onMoveIdle callback)

0.0.3 #

  • Add optional WHERE clause for SQL query

0.0.2 #

  • Migrate to google_maps_flutter: 0.3.0+2

0.0.1+2 #

  • Add new marker for new level of aggregation.
  • Fix level for aggregation/disgregation
  • Add InfoWindowText on aggregated marker with number of points

0.0.1 #

  • Initial developers preview release.


import 'package:example/splash.dart';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
      home: Splash(),

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:

  clustering_google_maps: ^0.1.2

2. Install it

You can install packages from the command line:

with Flutter:

$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:clustering_google_maps/clustering_google_maps.dart';
Describes how popular the package is relative to other packages. [more]
Code health derived from static analysis. [more]
Reflects how tidy and up-to-date the package is. [more]
Weighted score of the above. [more]
Learn more about scoring.

We analyzed this package on Apr 4, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.6
  • Flutter: 1.12.13+hotfix.8

Health suggestions

Fix lib/src/clustering_helper.dart. (-1.49 points)

Analysis of lib/src/clustering_helper.dart reported 3 hints:

line 228 col 33: Set literals weren't supported until version 2.2, but this code is required to be able to run on earlier versions.

line 242 col 32: 'fromAsset' is deprecated and shouldn't be used. Use fromAssetImage instead.

line 294 col 34: 'fromAsset' is deprecated and shouldn't be used. Use fromAssetImage instead.

Maintenance issues and suggestions

Support latest dependencies. (-10 points)

The version constraint in pubspec.yaml does not support the latest published versions for 1 dependency (google_maps_flutter).


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
geohash ^0.2.1 0.2.1
google_maps_flutter 0.5.21+3 0.5.21+3 0.5.25+3
meta ^1.1.6 1.1.8
path_provider ^1.1.0 1.6.5
sqflite ^1.1.5 1.3.0
Transitive dependencies
collection 1.14.11 1.14.12
path 1.6.4
path_provider_macos 0.0.4
path_provider_platform_interface 1.0.1
platform 2.2.1
plugin_platform_interface 1.0.2
sky_engine 0.0.99
sqflite_common 1.0.0+1
synchronized 2.2.0
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies