Implementation of Heatmaps in a Mobile Application
Heatmaps in a mobile app are both an analytics and navigation tool: show order density, popular zones, driver activity. The problem isn't rendering — libraries handle it — but working with large datasets on mobile screen without FPS degradation.
How Heatmaps Are Rendered
Each library builds heatmap via kernel density estimation: for each point on screen, a weighted sum of contributions from all data points in a given radius is calculated. Result — bitmap layer on top of map.
iOS: GMUHeatmapTileLayer from google-maps-ios-utils. Data — array of GMUWeightedLatLng. Gradient radius, minimum intensity, and color scheme configurable via layer properties. Tile mechanism means new tiles render on the fly when scrolling map — no lag if dataset not huge.
Android: HeatmapTileProvider from android-maps-utils. Principle is similar. Pass Collection<LatLng> or Collection<WeightedLatLng> for weighted points.
Flutter: google_maps_flutter doesn't include heatmap out of the box. Two options: native platform channel to GMSMapView/MapView with GMUHeatmapTileLayer / HeatmapTileProvider, or flutter_map + flutter_map_heatmap library based on canvas.
Working with Large Datasets
The main problem: passing 50,000 points to GMUHeatmapTileLayer and waiting for it to process on main thread — gets ANR or 3-4 second freeze.
The right approach — server-side aggregation. Instead of 50,000 raw points, server returns already aggregated data by grid (grid aggregation): each grid cell is one point with weight equal to number of events in cell. At zoom 10 — 500×500 meter grid, at zoom 14 — 50×50 meter grid. Point count reduces to 200-500 regardless of original volume.
Server aggregation via PostGIS:
SELECT
round(lat::numeric, 3) AS lat_grid,
round(lon::numeric, 3) AS lon_grid,
COUNT(*) AS weight
FROM events
WHERE created_at > now() - interval '7 days'
GROUP BY lat_grid, lon_grid;
When map zoom changes — re-request aggregation with new rounding precision. 500 ms debounce on zoom change event is mandatory.
Color Schemes and Interpretation
Standard color scheme (blue → green → yellow → red) is intuitive but doesn't work for colorblind people. For B2B analytics, single-color gradient (white → dark blue) or custom brand scheme works better.
GMUHeatmapTileLayer accepts [GMUGradient] with color array and positions — customizable without rebuild.
Timeline: two to three days — library integration, server aggregation (if needed), dynamic zoom adjustment, color scheme.







