Skip to content

fparri/ThomLive

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ThomLive PWA — Municipalities Only

ThomLive is a production-ready Progressive Web App for ranking nearby administrative municipalities by perceived heat discomfort. It combines OpenStreetMap/Overpass municipality boundaries, live Open-Meteo temperature and humidity data, the Thom Index, an offline-capable PWA shell, semantic UI colors, maps, and a multilingual interface.

The app is designed to answer a simple question: where does heat feel heavier nearby, and where does discomfort ease off?

This version intentionally excludes hamlets, districts, neighborhoods, suburbs, quarters, and minor localities. It uses OpenStreetMap administrative boundaries with boundary=administrative and admin_level=8, which usually correspond to municipalities in Italy.

Features

  • Search for a place with autocomplete.
  • Rank administrative municipalities within a fixed radius.
  • Fetch live temperature and relative humidity from Open-Meteo.
  • Calculate the Thom Index for each municipality.
  • Highlight discomfort levels with a clear semantic palette.
  • Show a mobile-first interactive map with heat/discomfort layers.
  • Show the coolest nearby municipalities separately.
  • Save the latest result for offline reopening.
  • Provide a PWA manifest, service worker, favicon set, and installable app icons.
  • Support multiple UI languages through JSON locale files.
  • Automatically prune stale backend cache files.

Requirements

  • PHP 7.4+ or PHP 8+ hosting.
  • PHP cURL extension enabled, or allow_url_fopen available.
  • A writable api/cache directory.
  • HTTPS recommended for PWA installation and browser geolocation.
  • Internet access to Leaflet and leaflet.heat CDN assets for the interactive map.
  • No Open-Meteo API key is required for public/non-commercial usage.

Installation

  1. Upload all project files to your PHP hosting space.
  2. Make sure api/cache is writable by the web server.
  3. Open the app domain in a browser.

When upgrading from an older release that included minor localities, you can safely clear api/cache. This version uses municipality-specific cache keys, but clearing old cache files keeps the installation tidy.

Project Structure

thomlive-pwa/
├─ index.html
├─ styles.css
├─ app.js
├─ manifest.json
├─ sw.js
├─ locales/
│  ├─ it.json
│  └─ en.json
├─ assets/
│  ├─ app-icon.png
│  ├─ favicon.svg
│  └─ icons/
│     ├─ favicon-16.png
│     ├─ favicon-32.png
│     ├─ apple-touch-icon.png
│     ├─ icon-192.png
│     └─ icon-512.png
└─ api/
   ├─ config.php
   ├─ config.sample.php
   ├─ _bootstrap.php
   ├─ geocode.php
   ├─ ranking.php
   └─ cache/

Internal API Endpoints

Place Autocomplete

GET api/geocode.php?q=Rimini&limit=5

Uses Open-Meteo Geocoding and returns candidate coordinates.

Live Municipality Ranking

GET api/ranking.php?lat=44.0678&lon=12.5695&label=Rimini&radiusKm=70

The endpoint performs the following steps:

  1. Queries Overpass for OpenStreetMap municipalities within the selected radius.
  2. Also retrieves the municipality containing the search center through is_in().
  3. Calls the Open-Meteo Forecast API in batches for current temperature and humidity.
  4. Calculates the Thom Index.
  5. Sorts municipalities by descending discomfort.
  6. Returns the data used by the ranking cards and map UI.

Discomfort Map and Coolest Municipalities

The UI includes a Discomfort and coolest municipalities section below the summary. The map uses:

  • Leaflet for the interactive mobile-friendly map.
  • OpenStreetMap tiles.
  • leaflet.heat for heatmap rendering.
  • An automatic marker fallback if the heatmap plugin cannot be loaded.

Available map modes:

  • Scenario: default mode. Shows the heatmap where Thom is at least 24 and overlays clear markers for municipalities below 24.
  • Discomfort: highlights only municipalities with a Thom Index of at least 24.
  • Points: shows every municipality as a tappable marker with a popup containing name, distance, temperature, humidity, and Thom Index.

A dedicated Where discomfort drops list is sorted by ascending Thom Index.

PWA Assets

The release includes the optimized main visual icon at assets/app-icon.png in 512×512, PNG favicons, apple-touch-icon.png, and PWA icons at 192×192 and 512×512.

The previous 1024×1024 icon variant was removed because it is not required by the manifest and was too heavy for a lightweight PWA.

The icon displayed in the hero is rendered inside a square container with aspect-ratio: 1 / 1 and object-fit: contain, so it does not stretch when the hero layout changes size.

Cache

Cache values can be configured in api/config.php:

define('PLACES_CACHE_TTL', 60 * 60 * 24 * 14); // 14 days
define('GEOCODE_CACHE_TTL', 60 * 60 * 24);     // 1 day
define('WEATHER_CACHE_TTL', 60 * 10);          // 10 minutes
define('CACHE_PRUNE_INTERVAL', 60 * 60);       // prune at most once per hour
define('CACHE_PRUNE_MAX_AGE', PLACES_CACHE_TTL + 60 * 60 * 24); // 15 days
define('MAX_WEATHER_PLACES', 250);             // weather municipality limit

The backend exposes cache_prune() and calls it through cache_maybe_prune() from the API endpoints. It removes .json cache files older than CACHE_PRUNE_MAX_AGE and uses api/cache/.last-prune to avoid scanning the cache directory on every request.

If pruning fails, the endpoints keep responding normally.

Thom Index Formula and UI Legend

The app includes an explanatory section at the bottom of the UI describing the Thom Index and the legend used across cards, badges, rankings, and maps.

Thom = T - (0.55 - 0.0055 × RH) × (T - 14.5)

Where:

  • T = air temperature in °C.
  • RH = relative humidity in percent.

Scale used by the backend, ranking, badges, and map:

Thom Label UI Color
< 21 Comfort Blue/cyan
21–23.9 Slight discomfort Green
24–26.9 Moderate discomfort Yellow/amber
27–28.9 Strong discomfort Orange
≥ 29 Very strong discomfort Red

Summary and Ranking Consistency

The summary card displays the Thom value of the selected municipality when that municipality is present in the ranking.

If the search point comes from GPS coordinates or cannot be safely matched to an administrative municipality, the badge is explicitly labeled as an area peak instead. The selected municipality is also highlighted in the ranking to avoid confusion between the local value and the maximum value in the surrounding area.

Localization

The UI is ready for community localization without changing the main application logic.

Current locale files:

locales/it.json
locales/en.json

The language selector is available in the top bar and stores the selected language in localStorage.

To add a new language:

  1. Copy locales/it.json or locales/en.json to a new file, for example locales/fr.json.
  2. Translate the values, keeping the keys unchanged.
  3. Keep placeholders exactly as they are, for example {count}, {place}, {score}, {radius}, and {time}.
  4. Register the new locale code in SUPPORTED_LOCALES inside app.js.
  5. Add the locale file to the service worker pre-cache list in sw.js.
  6. Update the service worker cache name in sw.js to force clients to refresh the PWA shell.

Quick Customization

  • UI colors, map colors, and visual tone: edit CSS variables in styles.css and THOM_LEVELS in app.js.
  • Search radius: edit RADIUS_KM in app.js and DEFAULT_RADIUS_KM in api/config.php.
  • Discomfort thresholds: edit thom_level() in api/_bootstrap.php.
  • Administrative entity type: edit the Overpass query in api/ranking.php.
  • Cache duration and pruning behavior: edit constants in api/config.php.

Operational Notes

  • The Overpass query uses administrative boundaries with admin_level=8. This is appropriate for Italian municipalities, but administrative levels may differ in other countries.
  • Open-Meteo is called server-side through PHP.
  • Dense areas are limited by MAX_WEATHER_PLACES to protect response times.
  • The PWA works offline for the app shell and can reopen the last saved ranking from the browser. Live weather data, map tiles, and CDN libraries still require a connection.

About

An open-source multilingual PWA for mapping and ranking heat discomfort with the Thom Index.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors