Spaces:
Sleeping
Sleeping
File size: 5,673 Bytes
01a6a9e 284e818 01a6a9e 284e818 01a6a9e 4ccb3e1 01a6a9e 284e818 b02f256 71c08ae 284e818 b02f256 284e818 71c08ae 284e818 71c08ae 284e818 71c08ae 284e818 71c08ae 284e818 71c08ae 284e818 4ccb3e1 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | ---
title: Prix des Carburants France
emoji: ⛽
colorFrom: green
colorTo: red
sdk: docker
app_port: 7860
pinned: false
license: apache-2.0
---
# ⛽ Petrol Map — live French fuel prices (PWA)
An installable, mobile-friendly map of every petrol station in France,
colour-coded by price and refreshed twice a day from the official open-data feed.
**Data source:** [`prix_des_carburants_j_7`](https://public.opendatasoft.com/explore/dataset/prix_des_carburants_j_7)
on opendatasoft (the last 7 days of prices reported by ~9 800 stations).
## Features
- **Installable PWA** — add it to your phone's home screen and launch it like a
native app; works offline (shows the last cached prices) via a service worker.
- **Responsive** — full-screen map with touch-friendly controls and safe-area
handling for notched phones.
- **One layer per fuel** — Gazole, SP95, SP98, E10, E85, GPLc — via the selector.
- **Price colour scale** — green = cheaper, red = pricier, scaled to each fuel's
national 5th–95th percentile; the legend updates per fuel.
- **Search by postal code / city** — type e.g. `75011` or `Lyon` to filter the
map to that area and zoom to it.
- **Itinerary maker** — enter a *ville de départ* and *ville d'arrivée* (with city
autocomplete via the Base Adresse Nationale); the route is drawn (OSRM) and the
map shows only the stations along the way, flagging the cheapest for the fuel.
- **Real vehicle picker + journey cost** — choose an actual model (≈550 from the
ADEME database, with their exact WLTP L/100 km, hybrids included) to estimate the
trip's fuel cost from the cheapest along-route price.
- **Electric vehicles** — pick an EV (WLTP range), see the number of recharge stops
needed and energy used, with stops placed at real chargers along the route.
- **EV charging stations** — toggle the national IRVE layer (≈224 000 points, loaded
live by viewport), colour-coded by power (fast ≥ 50 kW).
- **Marker clustering** keeps ~10 000 stations smooth; zoom in to split clusters.
- **Click a station** for all prices, address, last-reported date, and a
one-click *Directions* link, plus hover tooltips.
Data sources: fuel prices [`prix_des_carburants_j_7`](https://public.opendatasoft.com/explore/dataset/prix_des_carburants_j_7),
vehicle consumption [ADEME Car Labelling](https://data.ademe.fr/datasets/ademe-car-labelling),
chargers [IRVE via ODRE](https://odre.opendatasoft.com/explore/dataset/bornes-irve),
geocoding [BAN](https://adresse.data.gouv.fr/), routing [OSRM](https://project-osrm.org/),
basemap [IGN Plan v2](https://geoservices.ign.fr/).
## Run locally
```bash
pip install -r requirements.txt
python app.py # builds, then serves http://localhost:7860
```
Open <http://localhost:7860> — on a phone (same network or behind HTTPS) you can
then "Add to Home Screen" to install it.
Other entrypoints:
```bash
python build_map.py # build output/index.html once, no server
python scheduler.py # rebuild twice daily without serving (for static hosting)
python scheduler.py --once
```
> **PWA note:** install/offline features need a secure context — i.e. `https://`
> or `http://localhost`. Opening the file directly (`file://`) shows the map but
> not the installable app.
## Deploy to Hugging Face Spaces (Docker)
1. Create a new Space → **SDK: Docker**.
2. Push these files to the Space repo (the YAML header above configures it):
```bash
git init && git add . && git commit -m "Petrol map PWA"
git remote add origin https://huggingface.co/spaces/<user>/<space>
git push origin main
```
3. The Space builds the `Dockerfile`, serves on port `7860`, and rebuilds the
prices twice a day. The public Space URL is HTTPS, so the PWA is installable
straight from your phone.
Run the same container anywhere else:
```bash
docker build -t petrol-map .
docker run -p 7860:7860 petrol-map # http://localhost:7860
```
## Files
**Backend (Python, build/serve):**
| File | Purpose |
|------|---------|
| `fuel_data.py` | Fetch + normalise fuel prices (drops implausible values) |
| `car_data.py` | Fetch real vehicle models + WLTP L/100 km from ADEME |
| `build_map.py` | Inject the dataset into the HTML shell, copy static assets |
| `app.py` | Build + serve on `$PORT` + twice-daily refresh (container entrypoint) |
| `scheduler.py` | Twice-daily rebuild without serving |
| `generate_icons.py` | One-off PWA icon generator (needs Pillow; not used at runtime) |
| `Dockerfile` | Container image for Hugging Face Spaces / anywhere |
**Frontend (served from `static/`, separated for clean architecture):**
| File | Purpose |
|------|---------|
| `map_template.html` | Slim HTML shell; injects the build's data as `window.APP_DATA` |
| `static/app.js` | All map logic (one IIFE, sectioned by concern) |
| `static/styles.css` | All styles |
| `static/sw.js` | Service worker (offline + installable) |
| `static/manifest.webmanifest`, icons | PWA metadata |
| `output/` | Generated site (`index.html` + copied static assets + `stations.json`) |
## How the refresh works
The upstream dataset is updated continuously by the French administration.
`app.py` re-fetches the full feed and regenerates the page twice daily (07:00 and
19:00, container local time — set `TZ`), so the map always reflects a recent
snapshot. Change `REFRESH_TIMES` to refresh on a different cadence.
## License
Licensed under the [Apache License, Version 2.0](LICENSE) — see the `LICENSE`
file for the full text. © 2026 Samuel Adone.
Open data used by this project remains under its own licences (Licence Ouverte /
Etalab for the French government feeds).
|