Skip to content

About

Visualize and rank locations by proximity to a destination

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Geoproximity

Visualize and rank multiple locations by proximity to a destination.

Live demo

Geoproximity helps you compare locations geographically. Add where people are starting from, add the candidate places, and see them visualized and ranked together.

It is designed for problems where comparing many locations at once is more useful than checking distances one by one.

image

Use cases

Choosing a travel hub

You're going to Bandung and different travel agencies have different drop-off hubs.

Instead of checking each hub individually in Google Maps, add them all to Geoproximity and immediately see which ones are closest to your destination.

Finding a meeting point

Add everyone under Where we are, then the candidate venues under Places to compare.

With one person, places are ranked by distance to that person — the travel-hub case.

With several people, places are ranked by the farthest person for straight-line distance, or the longest trip for driving and walking, then by total travel. Select a place to highlight its routes while keeping the comparison overview. Choose Zoom to route for a closer view, or open Trip details to see each person's journey. The ranking is a hint; the map is how you decide.

People can share a starting point, and a meeting place can be at someone's starting point. Loaded comparisons keep the people section collapsed; choose Edit to add or change people. On phones the map sits above the comparison, switching to a side-by-side layout in short landscape viewports.

To try a group comparison, open the sample button in the bottom toolbar and choose Group meetup. It loads three fictional people around Bandung and three illustrative meeting points, using straight-line distance. Default sample returns to the original example (or the host application's custom sample).

Choosing a restaurant

Same shape as the travel-hub case: one place you care about (home, office, hotel) and several restaurant options ranked to it.

More generally

Any problem that looks like:

"I have several locations. Which one makes the most sense geographically?"

can potentially be modeled with Geoproximity.

Why not just use Google Maps?

Google Maps is already great at answering:

"How far is A from B?"

The problem becomes different when you have many candidates:

A → B
A → C
A → D
A → E
...

You have to repeat the same workflow and mentally compare the results.

Geoproximity turns those individual checks into one visualization:

              B
              │
              │
       C ───── A ───── D
              │
              │
              E

        ↓

     ranked by distance

The goal isn't to replace Google Maps. It's to make multi-location comparison easier.

How it works

  1. Add where people are — one person, or several. Search, click on the map, or use your current location.
  2. Add places to compare — the options you want to rank.
  3. Visualize — locations are plotted and connected to the destination.
  4. Rank — candidates are sorted by proximity.

The result gives you both the ranking and the geographic context behind it.

Runs entirely in the browser

Geoproximity performs its core geospatial calculations client-side.

There is no application server required to calculate or rank the locations. The browser handles the coordinates, visualization, and distance calculations.

This makes the core application:

  • Serverless — no backend required
  • Client-side — calculations happen locally
  • Lightweight — the problem can be solved directly from coordinates
  • Privacy-friendly ranking — distance and sort order are computed in the browser, not on an application server

Search, map tiles, routing, and reverse geocoding still call third parties. Clicking the map or using Use my location sends that precise coordinate to Nominatim (then Photon) so the pin can be named. Pasting coordinates or a Maps URL does not. The last comparison is also stored in localStorage on this device.

Distance

Geoproximity supports three distance modes:

  • Straight line — great-circle distance calculated locally from the coordinates
  • Driving — road distance returned by the OSRM routing service
  • Walking — walking route distance returned by the FOSSGIS pedestrian OSRM service

In driving and walking modes, Travel direction chooses People → places or Places → destinations. For drop-off hubs, choose Places → destinations, add your destination under Where we’re going, then add the candidate hubs under Places to compare. Direction affects road distance, time, route geometry, and ranking. Shared links and the saved comparison retain it; older links default to People → places. Straight-line distances are the same in either direction.

Driving and walking modes also draw the returned route geometry on the map, show travel time next to distance, and rank by time. Comparisons with unavailable routes follow complete results. Times are typical uncongested estimates from the router, not live traffic. Advanced settings holds an Animate routes switch that flows dashes along those routes, and Reverse animation to reverse the visual flow without changing travel direction. Both are unavailable for straight-line distance and stay off when the system prefers reduced motion. Walking uses the dedicated routing.openstreetmap.de/routed-foot backend, with requests limited to one per second. Routing requests run in the browser, so they depend on the external routing service and may fall back to straight-line estimates when a route cannot be fetched.

Limitations

The built-in location data is not yet comprehensive.

For better accuracy, paste coordinates or a Google Maps URL into the search box:

latitude, longitude
https://www.google.com/maps/@-6.9205,107.6099,17z

Shortened Maps links and URLs without usable coordinates show guidance instead of being sent to the geocoder. Empty searches suggest a city name, coordinates, or placing a pin on the map.

Coordinates and supported Maps URLs show an Add preview; press Enter or choose that preview to confirm. Pasting several coordinate lines opens a review before adding them.

The application also relies on external services for some functionality, so availability may occasionally be affected by external rate limits, particularly during high traffic.

The distance ranking itself only considers distance. It does not account for traffic, road conditions, population density, or other real-world factors.

Roadmap

Proximity

  • Network-based driving and walking distance
  • Dijkstra-based routing
  • Animated connections
  • Optional map-less view showing only nodes and connections
  • Improve location coverage and accuracy
  • Better handling and messaging around external service limits

Sharing

  • Share comparisons through URL parameters without import/export

Use as a library

Geoproximity can be embedded into another web application:

Leaflet is a peer dependency. Import the widget styles (and Leaflet's CSS if the host does not already):

import 'leaflet/dist/leaflet.css';
import 'geoproximity/styles.css';
import { mountProximity } from 'geoproximity';

const host = document.querySelector('[data-proximity-host]');

if (host instanceof HTMLElement) {
  const app = mountProximity(host, { basePath: '/map', sample: true });
  app.onChange((state) => console.log(state.distanceMode));
  // app.getState() / app.setState({ ... }) / app.destroy()
}

For faster initial tiles, add this connection hint to the host page's <head> so the browser can connect while the widget's JavaScript loads:

<link rel="preconnect" href="https://a.basemaps.cartocdn.com" />

The host element needs a defined height. Geoproximity fills the available space and inherits the host's font and color tokens.

Pass sample: true to load the bundled Bandung example when the map is empty, so a first visit is a comparison instead of a blank form. Pass your own GeoJSON-like { destination, locations } object instead of true to ship a different default. Override UI copy with labels: { driving: 'Mobil', ... }.

Pass share: true to enable sharing comparisons through a URL hash. The standalone demo enables this option; library consumers opt in explicitly.

Development

npm install
npm test
npm run dev

CARTO raster tiles need an API key or the map shows an “API key required” watermark. Copy .env.example to .env and set VITE_CARTO_API_KEY. That file is gitignored. Restart the dev server after changing it.

When embedding the library in another Vite app, set the same variable there, or pass it explicitly:

mountProximity(host, {
  cartoApiKey: import.meta.env.VITE_CARTO_API_KEY,
});

Vite inlines VITE_* values into the client bundle, and the browser sends the key on every tile request. That is how CARTO authenticates raster tiles — keep the key out of git, but do not treat it as a server secret.


Geoproximity started from a simple repetitive workflow:

copy location → check Google Maps → compare → repeat.

This project turns that workflow into a single geographic comparison.

About

Visualize and rank locations by proximity to a destination

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages