Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BenchMark — Urban Amenity Explorer

Find and explore urban amenities around you

A clean, interactive web map that helps you discover benches, water fountains, bike parking, and other useful amenities in your neighborhood. Built with real-time OpenStreetMap data and high-resolution aerial imagery from PDOK.

BenchMark Interface

Features

🎯 Two Ways to Explore

  • Find My Location: Use your phone's GPS to see what's around you
  • Click Anywhere: Click on the map to explore any location you're curious about

🗺️ High-Quality Maps

  • Light: CartoDB Positron
  • Dark: CartoDB DarkMatter
  • Smart clustering keeps the map readable at all zoom levels

🏗️ What You Can Find

  • 🪑 Benches — core focus
  • 🚰 Water Fountains — stay hydrated
  • 🚻 Toilets — essential facilities

🎛️ Easy Controls

  • Adjust search radius from 200m to 2km
  • Filter which types of amenities you want to see
  • Real-time counts showing how many amenities were found

🗂️ Saved Neighborhoods

  • Capture the benches you find under a neighborhood name
  • Reload saved benches later without hitting Overpass again
  • Manage saved sets right from the analysis panel (load or remove)

Quick Start

Deploy to GitHub Pages

  1. Fork this repository to your GitHub account
  2. Enable Pages: Go to Settings → Pages → Deploy from branch → main
  3. Visit your site: https://yourusername.github.io/BenchMark

Run Locally

# Clone the repo
git clone https://github.com/lukasbeuster/BenchMark.git
cd BenchMark

# Start a simple web server
python -m http.server 8000

# Open in your browser
open http://localhost:8000

How to Use

  1. Open the app in your web browser
  2. Click "Locate Me" to find amenities near you (allow location access)
  3. Or switch to "Click-to-query" and click anywhere on the map
  4. Adjust the search radius with the slider if needed
  5. Toggle amenity types on/off using the checkboxes
  6. Name & save benches for a neighborhood to keep a local copy
  7. Load a saved neighborhood later to revisit benches without re-querying
  8. Click on markers to see details about each amenity
  9. Zoom in close to see exactly where things are located

Design & Theme

  • Theme tokens live under :root[data-theme="light"] and :root[data-theme="dark"] in style.css.
  • Palette (Studio Matter):
    • Light — Background #fcf4ed, Text #1B1B1B, Muted #5A5550, Lines #E6DAC7, Accents #FFD23F (primary), #D96831 (secondary)
    • Dark — Background #111827, Surface #0B1220–#141A22, Text #F6F2E9, Muted #C9C1B6, Lines #2A3440
  • Toggle the theme using the header control; it switches UI and basemap together.

Shade (MVP)

Click “Check Shade Now” to estimate if benches are currently in sun or shade. Use the Shade Time slider to simulate different hours of the day.

  • How it works (client-side):
    1. Uses SunCalc to get sun azimuth/altitude for the selected local time and map center (night = all shaded; indicator shows “below horizon”)
    2. Fetches building footprints within the current bounds from Overpass (OSM)
    3. Estimates height from building:height or building:levels (fallback to 12 m; configurable in code)
    4. Translates each footprint opposite the sun azimuth by height / tan(altitude) and buffers slightly to approximate shadow
    5. Fetches OSM natural=tree points and approximates crown shadows (default height 9 m, crown diameter 7 m)
    6. Tests bench points against all shadow shapes (via Turf) → shaded or sunlit
  • Notes:
    • This is a first-order approximation (no occlusion stacking, terrain, or façade shape)
    • Confidence increases when explicit heights exist (buildings/trees) and the sun is low
    • Optional tree shading is not included in MVP

Data Sources

  • Amenities and buildings: OpenStreetMap via Overpass API
  • Trees: OpenStreetMap (natural=tree) via Overpass API

Defaults

  • Building height default: 12 m (DEFAULT_BUILDING_HEIGHT_M)
  • Level-to-meters factor: 3.2 (LEVEL_TO_METERS)
  • Tree height default: 9 m (DEFAULT_TREE_HEIGHT_M)
  • Crown diameter default: 7 m (DEFAULT_CROWN_DIAM_M)
  • Minimum solar altitude clamp: 1.5° (MIN_SOLAR_ALT_DEG)

Time & Timezone

  • On first load, the app initializes analysis time to the user’s current local time (rounded to nearest 15 minutes), sets the slider/minutes, and stores it in localStorage (bm-shade-time).
  • All SunCalc calls are made using a local Date constructed from the selected time on the current day.
  • The header shows a compact solar altitude indicator (Alt: XX.X° ↑/↓ or “below horizon”).

Trees Layer

  • Trees are shown as subtle dots (fill #CFE7D1, stroke #B9D6BC) by default. Toggle visibility via the “Show trees” checkbox.
  • Basemaps: CARTO (Positron/DarkMatter)

Limitations

  • Overpass responses depend on OSM coverage and may omit heights
  • Shadow model is a planar 2D approximation
  • Trees are modeled as circles; forests aren’t yet included
  • 3D BAG: not integrated yet — hooks are in code to substitute its geometry/height source
  • Saved neighborhoods live in your browser storage; clearing it removes the saved benches

Future integration: 3DBAG

  • To substitute 3DBAG, implement a fetchBuildings3DBAG(bounds) function that returns Turf polygons with a building:height (meters) tag, then swap it in checkShadeNow() instead of fetchBuildings().
  • Heavy views are capped for performance; recompute as needed

Pro Tips

  • Press Esc to clear your current search
  • Click on cluster numbers to zoom in and see individual markers
  • The app works great on mobile devices too!

Technical Details

Built With

  • Leaflet.js: Interactive maps
  • OpenStreetMap: Crowd-sourced amenity data via Overpass API
  • PDOK: High-resolution aerial imagery from the Dutch government
  • Modern CSS & JavaScript: Clean, responsive design

Performance

  • Shows up to 250 amenities per search (to keep things fast)
  • Smart marker clustering prevents map clutter
  • Optimized for both desktop and mobile devices

Customization

Adding New Amenity Types

Want to find something else? Easy! Just edit script.js:

// Add your new amenity type
this.amenityTypes = {
    // ... existing amenities
    playground: { 
        icon: '🛝', 
        color: '#ff6b6b', 
        name: 'Playgrounds',
        category: 'recreation',
        size: 'large'
    }
};

Then add a checkbox in index.html:

<label class="filter-item">
    <input type="checkbox" data-amenity="playground" checked>
    <span class="filter-marker" style="background-color: #ff6b6b;">🛝</span>
    <span class="filter-label">Playgrounds</span>
    <span class="filter-count" data-type="playground">0</span>
</label>

Changing the Look

The design uses CSS variables for easy customization:

:root {
  --primary-navy: #1a1f36;      /* Header background */
  --accent-cyan: #16a085;       /* Interactive elements */
  --golden-yellow: #FFD23F;     /* Your location marker */
}

Using in Other Countries

Currently optimized for the Netherlands (uses PDOK aerial imagery), but you can adapt it for anywhere:

// Replace PDOK with standard OpenStreetMap tiles
pdokTileUrl: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
defaultCenter: [40.7128, -74.0060], // New York, for example

Use Cases

For Individuals

  • New in town? Quickly find essential amenities in your neighborhood
  • Planning a bike ride? See where you can park and grab water
  • Out and about? Find the nearest public toilet or bench

For Communities

  • Identify gaps: See which areas lack certain amenities
  • Plan improvements: Use data to advocate for more benches, bins, etc.
  • Accessibility mapping: Check wheelchair accessibility info where available

For Professionals

  • Urban planners: Get a quick overview of amenity distribution
  • City officials: Identify areas that might need more infrastructure
  • Accessibility advocates: Map barrier-free amenities

Browser Support

Works on all modern browsers including:

  • Chrome, Firefox, Safari, Edge
  • Mobile browsers (iOS Safari, Chrome Mobile)
  • Requires location permissions for "Find My Location" feature

Troubleshooting

Map not loading?

  • Check your internet connection
  • Try refreshing the page
  • Make sure JavaScript is enabled

Location not working?

  • Allow location permissions when prompted
  • Try the "Click-to-query" mode instead
  • Make sure you're using HTTPS (required for location services)

No amenities showing?

  • Try increasing the search radius
  • Check if you're in an area covered by OpenStreetMap
  • Some rural areas may have limited data

Contributing

Found a bug or want to add a feature? Contributions are welcome!

  1. Fork the repository
  2. Create a feature branch: git checkout -b cool-new-feature
  3. Make your changes and test them
  4. Submit a pull request

Data & Privacy

  • Your location: Only used locally in your browser, never stored or sent anywhere
  • Map data: Comes from OpenStreetMap contributors (thanks! 🙏)
  • Aerial imagery: Provided by PDOK (Dutch national spatial data infrastructure)
  • No tracking: This app doesn't collect any personal data

License

MIT License - feel free to use this code for your own projects!

Credits

  • OpenStreetMap Community: For the amazing crowd-sourced map data
  • PDOK: For providing high-quality aerial imagery
  • Leaflet: For making interactive maps easy
  • GitHub Pages: For free hosting

Made with ♥ for exploring cities

Have suggestions or found this useful? Let us know!

Iconography & Colors

  • Custom minimal SVG icons are used for amenities (bench, water fountain, toilets) so they render crisply on Positron at all zoom levels. Colors come from CSS variables and remain accessible:
    • Benches (sunlit): #FFD23F (fill), stroke #1B1B1B
    • Benches (shaded/night): #4FA3B6 (fill), stroke #1B1B1B
    • Water: #607CAA
    • Toilet: #002666
    • Marker sizing is constant (bench 18px; water/toilet 16px); hit area includes 4px padding.

Trees: Styling and Query Scope

  • Trees are fetched by current bounds in Click-to-query mode, or by radius around the analysis point in Location mode. Requests are rate-limited, retried on 429, and cached by bounds/point keys.
  • Trees render as circle markers sized from tags where available:
    • Prefer diameter_crown (m); else circumference_crown/π; else 0.6 × height; else default 7 m.
    • Diameter is mapped to pixels using current latitude/zoom, clamped to 12–22 px. Fill #A7D7B3, stroke #6FB789.
    • A cap (~1500 trees) applies for performance; counts overlay shows totals.

Bench symbology

  • Benches use two minimal SVG variants with identical footprint so there’s no layout shift on swap:
    • Sunlit: benchSunlitIcon — a bench with a small sun disk cue in the corner; fill #FFD23F, stroke #1B1B1B.
    • Shaded/Night: benchShadedIcon — the same bench with a subtle diagonal slab cue; fill #4FA3B6, stroke #1B1B1B.
  • The Amenity Types legend renders the exact same SVGs (at ~14px) so legend and map remain consistent.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages