Maps, directions and export
How googlymaps connects to Google Maps and Apple Maps, and how a user gets their pins out if they want them. Everything here is optional, and none of it appears in the core loop of photograph → verify → pinned.
What we do not do, and why
We do not publish pins into Google Maps or Apple Maps. No API exists for it, for anyone. Google's places come from its own data, Google Business Profile and Local Guides; Apple's from curated partners and Apple Business Connect. Both business channels require a verifiable business at a fixed address, so googly eyes on a postbox can never qualify. Signing in with a Google or Apple account changes nothing. The barrier is not authentication, it is that no third-party POI write path is exposed at all.
We do not use Google or Apple as the basemap. Google Maps Platform bills per map load, and a map users pan and zoom constantly is the worst possible cost shape. Apple's MapKit is free but needs native code on iOS and does not exist on Android, which would fracture the single-codebase property. MapTiler tiles rendered by MapLibre GL stay the choice: one renderer, three platforms, predictable cost.
1. Directions: deep links out
The genuinely useful connection, and it costs nothing. From a pin, one button hands the coordinates to whichever map app the user already has.
| Platform | Target | URL |
|---|---|---|
| iOS | Apple Maps | maps://?daddr=<lat>,<lng>&dirflg=w |
| iOS | Google Maps, if installed | comgooglemaps://?daddr=<lat>,<lng>&directionsmode=walking |
| Android | Any map app (chooser) | geo:<lat>,<lng>?q=<lat>,<lng>(Googly%20eyes) |
| Web | Google Maps | https://www.google.com/maps/dir/?api=1&destination=<lat>,<lng>&travelmode=walking |
| Web | Apple Maps | https://maps.apple.com/?daddr=<lat>,<lng>&dirflg=w |
| Fallback | Universal | https://maps.google.com/?q=<lat>,<lng> |
Notes that matter in implementation:
- Walking is the right default. These are objects on a street; nobody drives to a googly eye.
- On iOS,
comgooglemaps://only opens if Google Maps is installed. Capacitor can test that withcanOpenURL; if it fails, fall through to Apple Maps rather than showing a dead button. - On Android,
geo:deliberately opens the system chooser, so the user's own default wins. Do not hard-code Google Maps there. - The web fallback works everywhere including desktop, so it is the safe default when platform detection is uncertain.
2. Export: KML and GPX
For a user who wants their pins in another tool: a walking route, a GPS device, their own Google My Maps layer.
| Format | For |
|---|---|
| KML | Google My Maps, Google Earth |
| GPX | GPS units, hiking and cycling apps |
Scope is deliberately limited, and this is a security control rather than a
product limitation. An unbounded "download every pin" endpoint would hand any
caller the entire dataset in one request, which is exactly the bulk-scrape the
500-row cap on public_pins exists to prevent. Export is therefore restricted to:
- Your own pins, the full set, since they are already yours.
- The current viewport, bounded by the same rules as
pins_in_bbox, with the same row cap.
There is no "export everything" and there should never be one.
Exported files carry the photo URL, coordinates and the date. They carry no user identifier, consistent with pins being anonymous to the public.
3. Optional: getting pins into Google My Maps
Offered as a help page, reached from the export screen, never pushed at anyone. This produces a separate custom layer the user opens deliberately. It does not put anything on the map they use day to day, and the page says so, so nobody expects otherwise.
- Export your pins as KML from googlymaps.
- Open google.com/mymaps and sign in.
- Create a new map.
- Click Import under the untitled layer.
- Select the downloaded
.kmlfile. - The pins appear as a layer you can name, restyle and share.
Worth stating on that page: this layer is visible only to you unless you share it, and it will not update when you add new pins, because it is a snapshot, so re-import to refresh.
4. Location permission: instructions when it is actually needed
A pin requires a precise fix. When the app cannot get one, the message must distinguish two states that feel identical to the user and need opposite advice.
Permission denied, meaning the user said no or never chose:
| Platform | Where to send them |
|---|---|
| iOS | Settings → Privacy & Security → Location Services → googlymaps → While Using the App, and Precise Location on |
| Android | Settings → Apps → googlymaps → Permissions → Location → Allow only while using, and Use precise location |
| Web | The padlock or ⓘ in the address bar → Site settings → Location → Allow |
Location unavailable, or not precise enough. Permission is granted but the fix is poor. Telling someone to grant permission they already granted is maddening, so this path says something different: "Getting a precise location…", retry for about 15 seconds while accuracy improves, and only then suggest moving somewhere with a clearer view of the sky. See verification-pipeline.md for the accuracy threshold.
iOS has a specific trap worth handling. A user can grant location while leaving Precise Location off, which returns a deliberately coarse fix, good enough to pass a naive permission check and never good enough to pass the accuracy gate. Detect that case and name it, or the user will toggle permission on and off forever wondering why it still fails.
Last update: 2026-08-25 AWST