I’ve been looking at rewriting my Pennine Way app, it currently uses GoogleMaps and was written at full tilt in a couple of days so the code is messy proof of concept and also made heavy use of an Event Bus (Otto). Coming back to the code after a couple of years really highlights the problems with the Event Bus pattern - it’s tricky to debug when the logic flow is not fresh in the mind. I also want to move to Open Street Map and store tiles locally so there’s no dependency on having cellular coverage. I’m using OSMDroid which offers a similar API to GoogleMaps. For drawing the Pennine Way path I’m using the OSMBonusPack which has been endorsed by the OSMDroid maintainers.
There’s a difference in the way GoogleMaps and OSMDroid (plus Bonus Pack) handle Polylines, GoogleMaps takes care of only drawing the path in the viewport to save memory, while OSMDroid renders the entire texture, for a path with ~9000 points this causes OOM exceptions when using hardware acceleration:
OpenGLRenderer﹕ Path too large to be rendered into a texture (see this issue and this one and various others), some StackOverflow posts suggest turning off hardware acceleration for the OSM view:
but this kills performance and will cause issues on lower powered devices. In order to use OSMDroid with large paths you need to use a different strategy than you’d use with GoogleMaps; only render the points that will appear on screen, and thin the number of points so there’s less drawing work to do.
- Attach zoom and drag listeners to your MapView:
- Do the work off the main event thread:
- Remove any points outside of the view port, then thin the remaining points so there’s a sane number to draw (where routeGeoPoints is the full array of ~9000 geopoints):
The result is very smooth but not perfect with occasional glitches along the viewport boundary, this example has MAX_POINTS set to 150: