AI-generated Key Takeaways
-
Heatmaps visualize the density of data points on a map using color, offering an alternative to markers for large datasets.
-
The
GMUHeatmapTileLayerclass is used to create heatmaps, acceptingGMUWeightedLatLngobjects for data points. -
Heatmaps can be customized by adjusting properties like radius, gradient, and opacity using the
GMUHeatmapTileLayerinstance. -
To update the heatmap's data or options, modify the relevant properties and then call
clearTileCache()to refresh the display. -
Heatmaps can be removed from the map by setting the
mapproperty of theGMUHeatmapTileLayertonil.
This page describes the heatmap utility that's available in the utility library for the Maps SDK for iOS. Heatmaps are useful for representing the distribution and density of data points on a map.
This video discusses the use of heatmaps as an alternative to markers, when your data requires a large number of data points on the map.
Heatmaps make it easy for viewers to understand the distribution and relative intensity of data points on a map. Rather than placing a marker at each location, heatmaps use color to represent the distribution of the data.
In the example below, red represents areas of high concentration of police stations in Victoria, Australia.
If you haven't yet set up the library, follow the setup guide before reading the rest of this page.
Adding a simple heatmap
To add a heatmap to your map, you will need a dataset consisting of the
coordinates for each location of interest. First, create a
GMUHeatmapTileLayer instance, setting the map property to a GMSMapView.
Do this in your app's viewDidLoad() function, to ensure that the base map is
loaded before working with the heatmap. Then pass a collection of
GMUWeightedLatLng objects to the GMUHeatmapTileLayer instance.
The utility supplies the GMUHeatmapTileLayer class, which accepts a
collection of GMUWeightedLatLng objects. It creates the tile images for
various zoom levels, based on the radius, gradient and opacity options
supplied.
Looking at the steps in more detail:
- Create a
GMUHeatmapTileLayerinstance, setting themapproperty to aGMSMapView(do this in your app'sviewDidLoad()function). - Pass a collection of
GMUWeightedLatLngobjects to theGMUHeatmapTileLayerinstance. - Call
GMUHeatmapTileLayer.map, passing the map view.Swift
class Heatmap: UIViewController { private var mapView: GMSMapView! private var heatmapLayer: GMUHeatmapTileLayer! override func viewDidLoad() { super.viewDidLoad() heatmapLayer = GMUHeatmapTileLayer() heatmapLayer.map = mapView } // ... func addHeatmap() { // Get the data: latitude/longitude positions of police stations. guard let path = Bundle.main.url(forResource: "police_stations", withExtension: "json") else { return } guard let data = try? Data(contentsOf: path) else { return } guard let json = try? JSONSerialization.jsonObject(with: data, options: []) else { return } guard let object = json as? [[String: Any]] else { print("Could not read the JSON.") return } var list = [GMUWeightedLatLng]() for item in object { let lat = item["lat"] as! CLLocationDegrees let lng = item["lng"] as! CLLocationDegrees let coords = GMUWeightedLatLng( coordinate: CLLocationCoordinate2DMake(lat, lng), intensity: 1.0 ) list.append(coords) } // Add the latlngs to the heatmap layer. heatmapLayer.weightedData = list } }
Objective-C
@implementation Heatmap { GMSMapView *_mapView; GMUHeatmapTileLayer *_heatmapLayer; } - (void)viewDidLoad { [super viewDidLoad]; _heatmapLayer = [[GMUHeatmapTileLayer alloc] init]; _heatmapLayer.map = _mapView; } // ... - (void) addHeatmap { // Get the data: latitude/longitude positions of police stations. NSURL *path = [NSBundle.mainBundle URLForResource:@"police_stations" withExtension:@"json"]; NSData *data = [NSData dataWithContentsOfURL:path]; NSArray *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; NSMutableArray<GMUWeightedLatLng *> *list = [[NSMutableArray alloc] init]; [json enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { NSDictionary *item = (NSDictionary *)obj; CLLocationDegrees lat = [(NSNumber *) [item valueForKey:@"lat"] doubleValue]; CLLocationDegrees lng = [(NSNumber *) [item valueForKey:@"lng"] doubleValue]; GMUWeightedLatLng *coords = [[GMUWeightedLatLng alloc] initWithCoordinate:CLLocationCoordinate2DMake(lat, lng) intensity:1.0]; [list addObject:coords]; }]; // Add the latlngs to the heatmap layer. _heatmapLayer.weightedData = list; } @end
For this example, the data is stored in a JSON file, police_stations.json.
Here is an extract from the file:
[
{"lat" : -37.1886, "lng" : 145.708 } ,
{"lat" : -37.8361, "lng" : 144.845 } ,
{"lat" : -38.4034, "lng" : 144.192 } ,
{"lat" : -38.7597, "lng" : 143.67 } ,
{"lat" : -36.9672, "lng" : 141.083 }
]
Customizing the heatmap
The heatmap has several customizable properties. You can set the options when
initially creating the GMUHeatmapTileLayer instance, or at any time by
setting a new value for the option.
The following options are available:
Radius: The size of the Gaussian blur applied to the heatmap, expressed in pixels. The default is 20. Must be between 10 and 50. Use
GMUHeatmapTileLayer.radiusto set the radius.Gradient: A range of colors that the heatmap uses to generate its color map, ranging from lowest to highest intensity. A
GMUGradientis created using an integer array containing the colors, and a float array indicating the starting point for each color, given as a percentage of the maximum intensity, and expressed as a fraction from 0 to 1. You need to specify only one color for a single-colored gradient, or a minimum of two colors for a multi-colored gradient. The color map is generated using interpolation between those colors. The default gradient has two colors. ThecolorMapSizeparameter defines the number of steps in the gradient. Larger numbers will result in a smoother gradient, while smaller numbers will give sharper transitions similar to a contour graph. UseGMUHeatmapTileLayer.gradientto set the gradient.Opacity: This is the opacity of the entire heatmap layer, and ranges from 0 to 1. The default is 0.7. Use
GMUHeatmapTileLayer.opacityto set the opacity value.
For example, create a Gradient:
Swift
let gradientColors: [UIColor] = [.green, .red] let gradientStartPoints: [NSNumber] = [0.2, 1.0] heatmapLayer.gradient = GMUGradient( colors: gradientColors, startPoints: gradientStartPoints, colorMapSize: 256 )
Objective-C
NSArray<UIColor *> *gradientColors = @[UIColor.greenColor, UIColor.redColor]; NSArray<NSNumber *> *gradientStartPoints = @[@0.2, @1.0]; _heatmapLayer.gradient = [[GMUGradient alloc] initWithColors:gradientColors startPoints:gradientStartPoints colorMapSize:256];
To change the opacity of an existing heatmap:
Swift
heatmapLayer.opacity = 0.7
Objective-C
_heatmapLayer.opacity = 0.7;
Update an existing option
To update an option that has already been set, take these steps:
- Update the option to the desired value.
- Call
GMUHeatmapTileLayer.clearTileCache().
Changing the dataset
To change the dataset upon which a heatmap is built:
- Update your data collection. Use
GMUHeatmapTileLayer.weightedData, passing an array ofGMUWeightedLatLng. - Call
GMUHeatmapTileLayer.clearTileCache().
Removing a heatmap
To remove a heatmap, call GMUHeatmapTileLayer.map, passing nil.
Swift
heatmapLayer.map = nil
Objective-C
_heatmapLayer.map = nil;
See the demo app
For another example of a heatmap implementation, take a look at the
HeatmapViewController in the demo app that ships with the utility library.
The setup guide shows you how to
run the demo app.