Skip to content
PremPoddarPublic

About

Drop a pin and walk back to the exact spot. It waits for your GPS to sharpen, then points you back with one arrow. No map, no account.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation


Mark where you left the car on level 3, where the trailhead was, where the tent is. Hours or weeks later, open the pin and walk: one arrow, one distance, no map tiles, no signal needed.

Loadstone does one thing, and the whole app is built around doing it honestly — telling you not just where to walk but how sure it is, because a confident arrow pointing at the wrong bench is worse than no arrow at all.

Finding a pin, saving one, the radar and Appearance

Drawn by the app's own code; the pins and readings are samples.

✨ What it does

🧭 Follow-back arrow True north, corrected for magnetic declination. Works standing still.
📍 Honest accuracy Every pin carries the radius you may have to search, and the app refuses to overstate it.
✨ Sharpen a pin Stand on the spot again and fold that visit in — the only thing that fixes a pin saved badly.
📷 Photos Snap the parking level or the trail marker. They sit on the card; tap for a swipeable gallery.
💬 Share as words Seven funny words instead of a link. Travels through any chat app, or down a phone line.
📌 Pin to top Swipe a card right to hold it above the distance sort, left to let it go.
🏷️ Categories Car, home, camp, trail, star — and every card draws its own icon from the family.
📡 Radar Every pin around you at its true direction and scaled distance. No map tiles.
🔔 Guide with the screen off A notification keeps the distance and direction, and the phone buzzes as you close in.
🧵 Trail back Retrace the path you walked, step by step.
🌅 Sunset warning Worked out on the phone, so you know when daylight is running out.
🎙️ Voice notes "Third pillar from the gate, blue door", kept with the pin.
🗂️ Folders File pins by trip, place or anything else.
📦 Backup & export One file with every pin, photo and voice note; GPX and KML for map apps; QR codes.
🏠 Widget The pinned spot on your home screen, with how far it is.
🔒 App lock Fingerprint, face or the phone's screen lock.
🎨 Appearance Light, dark, dusk or OLED black, Material You, fonts, shapes and haptics. Metric or imperial.

Location is used only while the app is open. Nothing is tracked in the background, and nothing leaves the phone unless you share a pin yourself.

💬 Sharing a place as a sentence

A shared link is only as good as whatever opens it. A sentence needs nothing:

Grumpy walruses quietly juggle soggy waffles backwards.

That is a position, to within about three metres, anywhere on Earth. Seven words drawn from four frozen 128-word vocabularies in a fixed grammar — adjective, noun, adverb, verb, adjective, noun, adverb — carrying 49 bits: 23 each for latitude and longitude, plus a checksum so a sentence misremembered by one word is refused rather than quietly pointing at a different street.

The grammar does two jobs. It makes the result funny every time rather than now and then, because any adjective in the list sits happily on any noun in the list. And it makes a word in the wrong position wrong by construction, before any arithmetic runs.

Read one back with the import button in the toolbar. It accepts the whole forwarded message, not just the seven words, and tells you which word it doesn't recognise as you type.

🎯 How it stays accurate

flowchart LR
    F[GPS fixes<br/>each with its own radius] --> K[Kalman filter<br/>in a local east/north frame]
    K --> P[Pin<br/>a position and an honest radius]
    P --> A[One arrow<br/>to true north, steadied]
    V[A later visit] -. sharpen .-> P
Loading

A phone's GPS doesn't report one true point — each fix comes with an accuracy radius that shrinks as the receiver settles. Loadstone runs those fixes through a recursive Bayesian (Kalman) filter in a local east/north frame: position is a mean and a variance, each fix is weighted by its own accuracy, and the gap between fixes widens the variance by however far you could have walked in it.

Standing still converges. Walking up to the spot decays the approach out of the estimate on its own. A multipath spike fails a gate stated in standard deviations rather than in hand-tuned metres.

Why the uncertainty number is the whole point

Fixes that are all wrong by the same thirty metres — bounced off a wall, taken under bad satellite geometry — agree perfectly with each other. An estimate built from scatter alone calls that tight, which is how a pin saved at "±2 m" could put you on the wrong side of a car park. The filter propagates variance explicitly and then refuses to claim better than the part of GPS error that repeated measurements cannot remove at all.

Nothing you do while saving removes that shared error. Coming back does: hours or weeks later the satellites and the atmosphere have moved on, so a second measurement is wrong in a genuinely independent direction, and the two together land closer than either. That is what sharpen this pin does, and it is the only way to correct a pin that was already saved badly.

Why the arrow is steady

One fixed smoothing strength cannot be both still at rest and quick into a turn, and splitting the difference gives you a shiver and a lag. A dead band kills sub-degree sensor noise, and the gain opens up as you turn, so the arrow is still when you are still and immediate when you move.

Navigation also runs on the filtered estimate rather than raw fixes, which hop several metres a second — at close range that hop is most of the bearing. And once you are nearer the pin than the combined uncertainty, the arrow stops pointing and says so: a five-metre error seen from four metres away swings the direction through tens of degrees, and pointing anyway is a confident guess.

🛠️ Build and run

Requires the Android SDK and JDK 17.

Command What it does
./gradlew :app:installDebug Build and install on a connected device or emulator
./gradlew :app:testDebugUnitTest Unit tests: the filter, the word codec, geo maths, formatting, backup files. ScreensTest draws the pictures above to app/build/screens
./gradlew :app:connectedDebugAndroidTest Room persistence tests (needs a device)
./gradlew bundleRelease Signed release bundle for Play (see keystore.properties.sample)

minSdk 26 (Android 8.0) · targetSdk 36 · package com.prempoddar.loadstone

🗂️ Architecture

Single-activity Jetpack Compose, MVVM with StateFlow, Hilt for DI.

Loadstone source packages and what each one does

As text
core/geo       PositionEstimator  the filter every pin comes from
               LocalFrame         east/north tangent plane
               HeadingFilter      adaptive compass smoothing
               PinRefinement      merging a return visit into a stored pin
               GeoMath            distance, bearing, arrow angle
core/format    distance and coordinate formatting
data/location  LocationRepository (fused provider) · CompassRepository (true north)
data/pin       pin model and repository
data/db        Room entities, DAO and migrations
data/settings  DataStore-backed preferences
share          WordCode and its frozen vocabularies · AppLinks · QR codes · GPX/KML files
guide          the screen-off guide service
widget         the home screen widget
ui/            one package per screen, plus components —
               AccuracyDial and CompassArrow are custom-drawn

Everything in core/ is free of Android dependencies, so the parts worth being sure about are covered by plain JVM tests.

📄 License

Apache 2.0

About

Drop a pin and walk back to the exact spot. It waits for your GPS to sharpen, then points you back with one arrow. No map, no account.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages