Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Maps SDK for Android Utility Library
License
googlemaps/android-maps-utils
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
Maps SDK for Android Utility Library
This open-source library contains utilities that are useful for a wide range of applications using the Google Maps SDK for Android.
- Marker clustering — handles the display of a large number of points
- Marker animation — animates a marker from one position to another
- Heat maps — display a large number of points as a heat map
- IconGenerator — display text on your Markers
- Poly decoding and encoding — compact encoding for paths, interoperability with Maps API web services
- Spherical geometry — for example: computeDistance, computeHeading, computeArea
- KML — displays KML data
- GeoJSON — displays and styles GeoJSON data
You can also find Kotlin extensions for this library here.
The generated reference docs for a full list of classes and their methods.
Written guides for using the utilities are published in Google Maps Platform documentation.
dependencies < // Utilities for Maps SDK for Android (requires Google Play Services) implementation 'com.google.maps.android:android-maps-utils:3.4.0' >
This repository includes a demo app that illustrates the use of this library.
To run the demo app, you’ll have to:
- Get a Maps API key
- Open the file local.properties in the root project (this file should NOT be under version control to protect your API key)
- Add a single line to local.properties that looks like MAPS_API_KEY=YOUR_API_KEY , where YOUR_API_KEY is the API key you obtained in the first step
- Build and run the debug variant for the Maps SDK for Android version
Migration Guide from v0.x to 1.0
Improvements made in version 1.0.0 of the library to support multiple layers on the map caused breaking changes to versions prior to it. These changes also modify behaviors that are documented in the Maps SDK for Android Maps documentation site. This section outlines all those changes and how you can migrate to use this library since version 1.0.0.
Click events originate in the layer-specific object that added the marker/ground overlay/polyline/polygon. In each layer, the click handlers are passed to the marker, ground overlay, polyline, or polygon Collection object.
// Clustering ClusterManagerClusterItem> clusterManager = // Initialize ClusterManager - if you're using multiple maps features, use the constructor that passes in Manager objects (see next section) clusterManager.setOnClusterItemClickListener(item -> < // Listen for clicks on a cluster item here return false; >); clusterManager.setOnClusterClickListener(item -> < // Listen for clicks on a cluster here return false; >); // GeoJson GeoJsonLayer geoJsonLayer = // Initialize GeoJsonLayer - if you're using multiple maps features, use the constructor that passes in Manager objects (see next section) geoJsonLayer.setOnFeatureClickListener(feature -> < // Listen for clicks on GeoJson features here >); // KML KmlLayer kmlLayer = // Initialize KmlLayer - if you're using multiple maps features, use the constructor that passes in Manager objects (see next section) kmlLayer.setOnFeatureClickListener(feature -> < // Listen for clicks on KML features here >);
If you use one of Manager objects in the package com.google.maps.android (e.g. GroundOverlayManager , MarkerManager , etc.), say from adding a KML layer, GeoJson layer, or Clustering, you will have to rely on the Collection specific to add an object to the map rather than adding that object directly to GoogleMap . This is because each Manager sets itself as a click listener so that it can manage click events coming from multiple layers.
For example, if you have additional GroundOverlay objects:
GroundOverlayManager groundOverlayManager = // Initialize // Create a new collection first GroundOverlayManager.Collection groundOverlayCollection = groundOverlayManager.newCollection(); // Add a new ground overlay GroundOverlayOptions options = // . groundOverlayCollection.addGroundOverlay(options);
GroundOverlayOptions options = // . googleMap.addGroundOverlay(options);
This same pattern applies for Marker , Circle , Polyline , and Polygon .
Adding a Custom Info Window
If you use MarkerManager , adding an InfoWindowAdapter and/or an OnInfoWindowClickListener should be done on the MarkerManager.Collection object.
CustomInfoWindowAdapter adapter = // . OnInfoWindowClickListener listener = // . // Create a new Collection from a MarkerManager MarkerManager markerManager = // . MarkerManager.Collection collection = markerManager.newCollection(); // Set InfoWindowAdapter and OnInfoWindowClickListener collection.setInfoWindowAdapter(adapter); collection.setOnInfoWindowClickListener(listener); // Alternatively, if you are using clustering ClusterManagerClusterItem> clusterManager = // . MarkerManager.Collection markerCollection = clusterManager.getMarkerCollection(); markerCollection.setInfoWindowAdapter(adapter); markerCollection.setOnInfoWindowClickListener(listener);
CustomInfoWindowAdapter adapter = // . OnInfoWindowClickListener listener = // . googleMap.setInfoWindowAdapter(adapter); googleMap.setOnInfoWindowClickListener(listener);
Adding a Marker Drag Listener
If you use MarkerManager , adding an OnMarkerDragListener should be done on the MarkerManager.Collection object.
// Create a new Collection from a MarkerManager MarkerManager markerManager = // . MarkerManager.Collection collection = markerManager.newCollection(); // Add markers to collection MarkerOptions markerOptions = // . collection.addMarker(markerOptions); // . // Set OnMarkerDragListener GoogleMap.OnMarkerDragListener listener = // . collection.setOnMarkerDragListener(listener); // Alternatively, if you are using clustering ClusterManagerClusterItem> clusterManager = // . MarkerManager.Collection markerCollection = clusterManager.getMarkerCollection(); markerCollection.setOnMarkerDragListener(listener);
// Add markers MarkerOptions markerOptions = // . googleMap.addMarker(makerOptions); // Add listener GoogleMap.OnMarkerDragListener listener = // . googleMap.setOnMarkerDragListener(listener);
A bug was fixed in v1 to properly clear and re-add markers via the ClusterManager .
For example, this didn’t work pre-v1, but works for v1 and later:
clusterManager.clearItems(); clusterManager.addItems(items); clusterManager.cluster();
If you’re using custom clustering (i.e, if you’re extending DefaultClusterRenderer ), you must override two additional methods in v1:
- onClusterItemUpdated() — should be the same* as your onBeforeClusterItemRendered() method
- onClusterUpdated() — should be the same* as your onBeforeClusterRendered() method
*Note that these methods can’t be identical, as you need to use a Marker instead of MarkerOptions
See the CustomMarkerClusteringDemoActivity in the demo app for a complete example.
private class PersonRenderer extends DefaultClusterRendererPerson> < . @Override protected void onBeforeClusterItemRendered(Person person, MarkerOptions markerOptions) < // Draw a single person - show their profile photo and set the info window to show their name markerOptions .icon(getItemIcon(person)) .title(person.name); > /** * New in v1 */ @Override protected void onClusterItemUpdated(Person person, Marker marker) < // Same implementation as onBeforeClusterItemRendered() (to update cached markers) marker.setIcon(getItemIcon(person)); marker.setTitle(person.name); > @Override protected void onBeforeClusterRendered(ClusterPerson> cluster, MarkerOptions markerOptions) < // Draw multiple people. // Note: this method runs on the UI thread. Don't spend too much time in here (like in this example). markerOptions.icon(getClusterIcon(cluster)); > /** * New in v1 */ @Override protected void onClusterUpdated(ClusterPerson> cluster, Marker marker) < // Same implementation as onBeforeClusterRendered() (to update cached markers) marker.setIcon(getClusterIcon(cluster)); > . >
private class PersonRenderer extends DefaultClusterRendererPerson> < . @Override protected void onBeforeClusterItemRendered(Person person, MarkerOptions markerOptions) < // Draw a single person - show their profile photo and set the info window to show their name markerOptions .icon(getItemIcon(person)) .title(person.name); > @Override protected void onBeforeClusterRendered(ClusterPerson> cluster, MarkerOptions markerOptions) < // Draw multiple people. // Note: this method runs on the UI thread. Don't spend too much time in here (like in this example). markerOptions.icon(getClusterIcon(cluster)); > . >
Encounter an issue while using this library?
If you find a bug or have a feature request, please file an issue. Or, if you’d like to contribute, send us a pull request and refer to our code of conduct.
You can also reach us on our Discord channel.
For more information, check out the detailed guide on the Google Developers site.