Awesome Maps

I’d like to introduce the results of a project I’ve been working on for some time.  Maps have always been a passion of mine (so much that I went to university to be a cartographer; ended up studying as a geodesist and have worked in related fields ever since).  It was fun to reapply some old theory and build on my understanding of Garmin image management and the infrastructure I put together for my high-resolution Rain Radar app.

The aim was to bring on-demand mapping to *all* devices, not just those Garmin deemed worthy of offline mapping.  To deliver an app with different, zoomable cartography using Open Hiking Map and satellite imagery and unique capabilities with Ordnance Survey (GB) maps on a cached tiled map display.

App Store Link (with YouTube video): https://apps-developer.garmin.com/apps/f0ffb7a3-dc56-4ac2-9428-08250c816474

(as usual, be nice with direct feedback, not critical reviews)

There are plenty of ideas on how to add capabilities to this, but for this forum here are some points that might be interesting to developers were;

Maxing the Storage Cache: this was a real win for tiled maps – delivering decent performance and reducing web requests.  Maintaining the cache and gracefully handling usage limits was work but through my Exception catching web service I'll (hopefully) get to build a pattern of devices and storage size limits.

No-Input Payment Authorisation: I don’t like Garmin’s (or other’s) terrible on-device UI’s for inputting alphanumeric authorisation codes or email addresses for registration and licensing – so I worked out a couple of web services for seamless (no user input on the device) integration and updates with a Merchant of Record handler.

QR Code (ScanCode) Experiment: I quite liked adding the ability to scan a code for my license info / payment, rather than just opening a openWebPage () link via GC.  This allows any third-party devices to open the links.

Annoying Different Exceptions Thrown on Imagery: across 54 devices, the same code is used to handle the same (or similar) images, but 5 devices decide to do different things!  The following x2 exception messages are thrown by a handful of devices;

     "Source must be native color format" - reported by Forerunner165 and EdgeMTB

     “Source must not use a color palette" - reported by InstinctCrossover, Venu4-41 and Forerunner570

Another ongoing issue I still have is that the codebase that runs on the Sim for 54 devices, fails for only (if I tested them all!) the Edge 850.  I can observe via breakpoints and console that my glance view text is being updated in code, however there is just no screen update at all.  I would blame the Sim but in my server logs I have 1000’s of requests and none are from an 850 so I assume it’s a real-world fail as well.  Nothing in Era either, as there is no crash (Sim runs, just no UI update) even with forced requestUpdate().  Anyone with an Edge850 pls let me know...

Finally, my wishlist;

 * better access to info/exceptions on graphics memory pool

 * more standardisation between devices for image handling

 * more storage on devices which could be easily provide more

 * better information on connectivity (vehicles connected to mobile phones know signal strength and battery of the connected device so a watch/head unit should also be able to know in order to allow user to make informed decisions without independently looking at the phone)

 * proper API access to the stack-trace other than println() which then requires extraction off the device (put it in an extended exception)

  • Awesome Maps v2.0

    Update – addition of USGS, IGN France and IGN España (Spain) local mapping data.  And a datafield version in parallel.  And more integrated menus and touch-screen controls. And YouTube videos, phew!

    Notes of interest for the developer community…

    Shared licensing: as per a recent, pertinent discussion started on a sister thread (https://forums.garmin.com/developer/connect-iq/f/discussion/434145/unique) I wanted to have a no-data-entry seamless licence option without the use of Garmin Pay – to support a wide range of devices and have control (because we all want control).  It was only after reading the post above that I fully understood that the uniqueIdentifier property was not device; but device+app and hence unable to use that to generate a common ID from 2 distinct apps.  The discussion give various innovative and clever approaches, but none matching my needs.  Instead I use part of the uniqueIdentifier which, based on research, is still pretty unique in the grand scale of things, and a shared-space hack on the devices (completely valid and exposed on the API) that is readable from 2+ apps to generate and share the same ID/license.

    Datafield optimisation: having started with a glance app/widget, I thought sharing the code to a datafield would be easy. Ha!  Unfortunately, due to a couple of bits of complex maths with lots of variables (coordinate system projections and intersects on rotated overlapping rectangles on every compute()!) I hit the stack limit.  There is a very useful post here https://forums.garmin.com/developer/connect-iq/f/discussion/409273/stack-overflow

    Is it because datafields run compute() and onUpdate() pretty much simultaneously – hence requiring a better approached to managing that stack?  Or just because there are less memory in datafields than apps [that have no compute()] because you can have multiple-simultaneous data fields and therefore need run with smaller stack allocation?  Anyway, combining many member variables into arrays helped and the datafield version came out this week;

    https://apps-developer.garmin.com/apps/7a4f45d8-c126-459a-a81c-1071bf09c33c

    One thing I may ask in the other forum pages – is it better to pass objects around in function calls and reference them as variables - or instead reference global objects without using function parameters and use $ instead?

  • Awesome Maps continues to develop with the addition of dedicated per-country maps from LINZ (New Zealand), Kartverket (Norway), BGDI swisstopo (Switzerland) and NGI (Belgium).

    There are also now touch-screen controls for North-up or heading-based orientation options, multiple zoom levels with pan/drag to move the map for exploring and an optional show "snail trail" menu for the route recently followed.

    For developer interest, I have seen continued odd behaviour with drawBitmap2 and a Transform matrix applied to the images.  With (ONLY) the Forerunner70, Forerunner165 and Instinct3 these three devices thrown an exception “Source must be native color format”.  This is replicable in the Sim, BUT for the Forerunner70, Forerunner165 it looks like this is a false-positive error (maybe from a previous firmware version that did not support the format?).  So for the FR165 and 70 I see my images are actually rotated, but the exception is still thrown – which I then need to handle in the catch with per-device logic to manage the Instinct3 differently with a fallback drawing approach!

    Of course, I can only test this in the Sim and really would like anyone with a FR70 or 165 to confirm they can actually see maps OK.  There is also a new “Safe Mode” switch in the settings/properties (exposed through CIQ and on-device menus) to use the alternative behaviour on handling the exception if required; but requires real-world validation.  Please DM me or use the app contact pages for a test license if interested.

  • I really enjoyed reading about the passion and technical expertise that went into this mapping project. Making advanced, on-demand maps available across more devices is an impressive achievement that could benefit many outdoor enthusiasts.

    Slope Rider

  • I really enjoyed reading about the passion and technical expertise that went into this mapping project. Making advanced, on-demand maps available across more devices is an impressive achievement that could benefit many outdoor enthusiasts.

    Slope Rider