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?