WhereRoulette is a web application designed to randomly select a point of interest (POI) within a specified area. This tool solves the problem of choosing a place to go when you need somewhere to meet with friends, but the specific location isn't that important.
- Choose a POI randomly in a region specified by:
- District name
- Central point and a radius
- Bounding box
- The equidistance between your and your friends' locations
- Encode your location into a URL to quickly share with friends and find "somewhere in the middle."
- Quickly filter POIs for bars, restaurants, or cafes.
- Subcategory filters for when you're more picky about where you want to go.
- Access information about each POI through map interactions.
- Share the selected location via a URL with encoded data.
- SPIN THE WHEEL animation + sound effects ๐ฐ
The application heavily relies on open data from OpenStreetMap.
WhereRoulette uses several external libraries and resources:
- Nominatim for geocoding
- Overpass API for serving OpenStreetMap data
- Maplibre-gl for rendering interactive maps
- Maplibre-gl-directions for directions
- osmtogeojson for converting OpenStreetMap data to GeoJSON
- FontAwesome for icons
- Webpack for bundling assets
- Umami for privacy-focused analytics
- Postgres for storing analytics data
The project is structured as follows:
app/
: Webapp..github/
: CI config..env
: Variables to be set as secrets.
To serve the webapp frontend locally, navigate to the app/
directory, install the requirements, and run a development server:
cd app/
npm install
npm run serve
The site should now be served on http://localhost:8080/
.
To bundle the frontend, change into the app/
directory and run the build command:
cd app/
npm install
npm run build
WhereRoulette provides a simple API using Netlify Edge Functions to retrieve POIs within a specified region. Mix some randomness into your apps or get details about specific locations! โจ
GET https://whereroulette.com/api
Parameter | Description | Required | Default |
---|---|---|---|
region | OpenStreetMap region ID | Yes | - |
type | POI category (drinks, cafe, food, park, climb) | No | drinks |
id | Specific OSM node ID (e.g., "node/11967421222" or just "11967421222") | No | - |
Random POI:
https://whereroulette.com/api?region=62422&type=climb
Specific POI by ID:
https://whereroulette.com/api?region=62422&type=climb&id=node%2F11967421222
{
"osm_node": "11967421222",
"name": "Bouldergarten",
"type": "climb",
"emoji": "๐ง",
"opening_hours": "Mo-Fr 10:00-23:00, Sa,Su 10:00-22:00",
"url": "https://whereroulette.com/?region=62422&type=climb&id=node%2F11967421222",
"coordinates": [13.4567, 52.4890]
}
Missing Region:
{
"error": "Missing required parameter: region"
}
Invalid Category:
{
"error": "Invalid type. Must be one of: drinks, cafe, food, park, climb"
}
No POIs Found:
{
"error": "No climb found in region 62422"
}
Node Not Found:
{
"error": "Node with ID node/12345678 not found"
}
The API is implemented as a Netlify Edge Function, which provides fast, globally distributed response times. It directly queries the Overpass API to fetch OpenStreetMap data and converts it to a simplified format optimized for POI information.
The configuration in netlify.toml
maps the /api
path to the Edge Function:
[[edge_functions]]
function = "json"
path = "/api"
The site is hosted using GitHub Pages. A GitHub action bundles the site and deploys all content in the app/dist
subdirectory for the main
branch.
The site gets deployed to https://whereroulette.com.
The site uses Umami for privacy-focused analytics.
An instance is hosted on fly.io. The configuration is defined in the analytics repository.
A DNS record is set up such that the stats.whereroulette.com
subdomain points to the Umami instance.
The analytics script is available at https://stats.whereroulette.com/script.js, which is downloaded and stored in this repository in src/assets/analytics.js
.
Webpack is configured to include the analytics script in the build and it is used in the index.html
file.
To update the script, run the following command:
curl https://stats.whereroulette.com/script.js -o src/assets/analytics.js
Thanks to Casper Ashdown (github.com/surelybassy) for creating a amazing logo!