# Overpass

# Déployer instance OverPass API avec Docker

Documentation d'utilisation du service Overpass API (image `b1tw153/overpass-api`) déployé via Docker Compose, avec extrait France.

## Architecture

Le `docker-compose.yml` définit deux services :

| Service | Rôle | Usage |
|---|---|---|
| `overpass-init` | Télécharge et importe l'extrait OSM (une seule fois) | `docker compose run --rm overpass-init` |
| `overpass` | Sert l'API + applique les diffs minute par minute | `docker compose up -d overpass` |

Les deux services partagent les mêmes **volumes Docker externes et nommés explicitement** (`overpass-db`, `overpass-backup`), ce qui garantit qu'ils pointent toujours sur les mêmes données, peu importe le dossier depuis lequel les commandes sont lancées.

> **Point important** : les volumes sont déclarés en `external: true`. Cela signifie qu'ils doivent **exister avant** de lancer `docker compose up` - Compose ne les créera pas automatiquement.

---

## Fichier docker-compose.yml

```yaml
services:
  # ----------------------------------------------------------------------
  # Service d'INITIALISATION (à lancer une seule fois, en amont)
  # Télécharge + importe l'extrait France, puis s'arrête (--rm).
  # Usage : docker compose run --rm overpass-init
  # ----------------------------------------------------------------------
  overpass-init:
    image: b1tw153/overpass-api:latest
    container_name: overpass-init
    entrypoint: /opt/overpass/bin/import_osm_data.sh
    command:
      - --diff-url=https://download.openstreetmap.fr/replication/europe/france/minute/
      - --data-source=https://download.geofabrik.de/europe/france-latest.osm.pbf
      - --meta=yes
    volumes:
      - overpass-db:/opt/overpass/db
    profiles:
      - init

  # ----------------------------------------------------------------------
  # Service PRINCIPAL (utilisation normale au quotidien)
  # Usage : docker compose up -d overpass
  # ----------------------------------------------------------------------
  overpass:
    image: b1tw153/overpass-api:latest
    container_name: overpass
    restart: unless-stopped
    ports:
      - "8080:8080"
    environment:
      - OVERPASS_REPLICATE_ID=auto
      - OVERPASS_DIFF_URL=https://download.openstreetmap.fr/replication/europe/france/minute/
      - OVERPASS_UPDATE_FREQUENCY=60
      - OVERPASS_META_MODE=yes
      - OVERPASS_AREAS=yes
    volumes:
      - overpass-db:/opt/overpass/db
      - overpass-backup:/opt/overpass/backup
    mem_limit: 8g
    stop_grace_period: 5m

volumes:
  overpass-db:
    name: overpass-db
    external: true
  overpass-backup:
    name: overpass-backup
    external: true
```

---

## Prérequis

- Docker + Docker Compose v2
- Espace disque suffisant sur le volume Docker (compter large pour un extrait France + croissance dans le temps - prévoir plusieurs dizaines de Gio minimum)

---

## Premier déploiement

### 1. Créer les volumes externes

```bash
docker volume create overpass-db
docker volume create overpass-backup
```


### 2. Lancer l'import initial

```bash
docker compose run --rm overpass-init
```

Ce que fait ce service :
- télécharge l'extrait `france-latest.osm.pbf` depuis Geofabrik
- importe les données de base (nodes/ways/relations) avec métadonnées (`--meta=yes`)
- initialise le point de reprise pour la réplication (`--diff-url`)

⏱ **Durée estimée** : plusieurs heures selon la machine (CPU/disque). Le conteneur se supprime automatiquement à la fin (`--rm`), les données restent dans le volume `overpass-db`.

Pour suivre la progression :
```bash
docker compose logs -f overpass-init
```

### 3. Démarrer le service principal

Une fois l'import terminé :

```bash
docker compose up -d overpass
```

Vérifier que ça démarre sans erreur (en particulier l'absence de `Database directory does not contain required base files`) :

```bash
docker compose logs -f overpass
```

---

## Utilisation au quotidien

| Action | Commande |
|---|---|
| Démarrer | `docker compose up -d overpass` |
| Arrêter proprement | `docker compose stop overpass` |
| Voir les logs en direct | `docker compose logs -f overpass` |
| Redémarrer | `docker compose restart overpass` |
| Statut | `docker compose ps` |

⚠️ **Ne jamais faire `docker compose down -v`** - cela supprimerait aussi les volumes (et donc toutes les données importées). Un simple `docker compose down` (sans `-v`) est sans danger pour les données.

Le service applique automatiquement les diffs OSM toutes les `OVERPASS_UPDATE_FREQUENCY` secondes (actuellement 60s) via `OVERPASS_DIFF_URL`. Aucune action manuelle n'est nécessaire pour rester à jour.

---

## Tester l'API

```bash
curl -sg 'http://localhost:8080/api/interpreter' --data-urlencode 'data=[out:json];out count;'
```
*(adapter le port si vous exposez le service sur un port différent dans `ports:`)*

Une requête géographique simple (mairie de Toulouse) :

```bash
curl -sg 'http://localhost:8080/api/interpreter' --data-urlencode 'data=
[out:json][timeout:25];
node["amenity"="townhall"]["name"~"Toulouse"];
out center;
'
```

---

## Tester les areas

Les *areas* (utilisées par exemple pour `area["name"="..."]->.a;`) sont calculées en arrière-plan après l'import initial et **peuvent prendre plusieurs heures** à être disponibles, même une fois l'import de base terminé.

### Vérifier si le calcul a produit des résultats

```bash
curl -sg 'http://localhost:8080/api/interpreter' --data-urlencode 'data=[out:json];out count;' | jq
```
La présence du champ `osm3s.timestamp_areas_base` indique qu'au moins un cycle de calcul des areas s'est terminé. Son absence = pas encore de areas disponibles.

### Tester une area précise

L'ID d'une area = ID de la relation OSM `+ 3600000000` :

```bash
curl -sg 'http://localhost:8080/api/interpreter' --data-urlencode 'data=
[out:json][timeout:25];
area(3600035738);
out;
' | jq
```
*(exemple : `3600035738` = relation Toulouse, `admin_level=8`)*


---

## Sauvegardes

Pour activer les sauvegardes automatiques (désactivées par défaut - voir le log `INFO: Specify OVERPASS_BACKUP_TIME or OVERPASS_BACKUP_DAY to enable backups`), ajouter dans `environment:` du service `overpass` :

```yaml
- OVERPASS_BACKUP_TIME=03:00
# et/ou
- OVERPASS_BACKUP_DAY=SUN
```

Les sauvegardes sont écrites dans le volume `overpass-backup` (déjà monté). La base est temporairement mise en pause pendant la copie.

---

## Fichiers de référence

- Image Docker : [`b1tw153/overpass-api`](https://hub.docker.com/r/b1tw153/overpass-api)
- Dépôt source : [`b1tw153/Overpass-API`](https://github.com/b1tw153/Overpass-API)
- Documentation Overpass QL : https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL
- Extraits France : https://download.geofabrik.de/europe/france.html
- Réplication France : https://download.openstreetmap.fr/replication/europe/france/minute/

# Requêtes #completetescommerces

## Extraction des commerces sans horaires à par ville

<div class="qMYqUG_convSearchResultHighlightRoot" id="bkmrk-cette-requ%C3%AAte-overpa"><div><div class="relative w-full overflow-visible"><section class="text-token-text-primary w-full focus:outline-none [--shadow-height:45px] has-data-writing-block:pointer-events-none has-data-writing-block:-mt-(--shadow-height) has-data-writing-block:pt-(--shadow-height) [&:has([data-writing-block])>*]:pointer-events-auto R6Vx5W_threadScrollVars scroll-mb-[calc(var(--scroll-root-safe-area-inset-bottom,0px)+var(--thread-response-height))] scroll-mt-[calc(var(--header-height)+min(200px,max(70px,20svh)))]" dir="auto">Cette requête Overpass permet d’extraire, un ensemble de commerces, services, établissements et activités (restaurants, magasins, bureaux, artisans, hébergements, etc.) tout en filtrant ceux qui possèdent déjà la clé `opening_hours`. Elle repose sur plusieurs catégories OSM (amenity, shop, office, craft, tourism) afin de couvrir un large spectre de points d’intérêt, puis ne conserve que les objets nommés et potentiellement ouverts au public. L’objectif est d’identifier les lieux dont les horaires d’ouverture ne sont pas renseignés dans OpenStreetMap, afin d’améliorer la complétude et la qualité des données.

</section><div class="contents">  
</div></div></div></div>```json
[out:json][timeout:60];

area["name"="<NOM DE LA VILLE>"]->.ville;

(
  nw["amenity"]
    ["amenity"~"restaurant|fast_food|cafe|fuel|pharmacy|bank|bar|hospital|post_office|clinic|pub|car_wash|ice_cream|driving_school|cinema|car_rental|nightclub|bureau_de_change|studio|internet_cafe|money_transfer|casino|vehicle_inspection|frozen_food|boat_rental|coworking_space|workshop|personal_service|dancing_school|training|ski_school|ski_rental|dive_centre|driver_training|nursing_home|funeral_hall|doctors|dentist|theatre|kindergarten|language_school|stripclub|veterinary"]
    ["amenity"!~"public_bookcase|public_building"]
    ["name"]
    ["name:signed"!~"no"]
    ["noname"!~"yes"]
    [!"opening_hours"]
    (area.ville);

  nw["shop"]
    ["shop"~"convenience|supermarket|clothes|hairdresser|car_repair|bakery|beauty|car|hardware|mobile_phone|butcher|furniture|car_parts|alcohol|florist|scooter|variety_store|electronics|shoes|optician|jewelry|mall|gift|doityourself|greengrocer|books|bicycle|chemist|department_store|laundry|travel_agency|stationery|pet|sports|confectionery|tyres|cosmetics|computer|tailor|tobacco|storage_rental|dry_cleaning|trade|copyshop|motorcycle|funeral_directors|beverages|newsagent|garden_centre|massage|pastry|interior_decoration|general|deli|toys|houseware|wine|seafood|pawnbroker|tattoo|paint|wholesale|photo|second_hand|bed|kitchen|outdoor|fabric|antiques|coffee|gas|e-cigarette|perfumery|craft|hearing_aids|money_lender|appliance|electrical|tea|motorcycle_repair|boutique|baby_goods|bag|musical_instrument|dairy|pet_grooming|music|carpet|rental|fashion_accessories|cheese|cannabis|chocolate|medical_supply|leather|sewing|locksmith|games|video_games|hifi|window_blind|caravan|tool_hire|household_linen|bathroom_furnishing|shoe_repair|watches|nutrition_supplements|fishing|frame|grocery|boat|repair|gold_buyer|lighting|pottery|security|groundskeeping|herbalist|curtain|health_food|flooring|printer_ink|camera|candles|printing|garden_furniture|food|yes"]
    ["shop"!~"kiosk|vacant"]
    ["name"]
    ["name:signed"!~"no"]
    ["noname"!~"yes"]
    [!"opening_hours"]
    (area.ville);

  nw["office"]
    ["office"~"company|estate_agent|insurance|telecommunication|it|accountant|employment_agency|tax_advisor|financial|advertising_agency|logistics|newspaper|financial_advisor|consulting|travel_agent|coworking|moving_company|lawyer|architect|construction_company|developer|credit_broker|graphic_design|construction|property_management|cleaning|notary"]
    ["name"]
    ["name:signed"!~"no"]
    ["noname"!~"yes"]
    [!"opening_hours"]
    (area.ville);

  nw["craft"]
    ["craft"~"carpenter|winery|metal_construction|electronics_repair|photographer|electrician|brewery|hvac|plumber|tailor|shoemaker|sawmill|caterer|window_construction|gardener|dressmaker|confectionery|stonemason|glaziery|painter|roofer|builder|key_cutter|upholsterer|cleaning|pottery|distillery|jeweller|handicraft|joiner|agricultural_engines|tiler|insulation|clockmaker|sculptor|printer|cabinet_maker"]
    ["name"]
    ["name:signed"!~"no"]
    ["noname"!~"yes"]
    [!"opening_hours"]
    (area.ville);

  nw["tourism"]
    ["tourism"~"hotel|hostel|guest_house|motel"]
    ["name"]
    ["name:signed"!~"no"]
    ["noname"!~"yes"]
    [!"opening_hours"]
    (area.ville);
);

out body;
>;
out skel qt;
```

<div class="qMYqUG_convSearchResultHighlightRoot" id="bkmrk-sans-site-web"><div><div class="relative w-full overflow-visible"><div class="contents">Sans site web</div><div class="contents"></div></div><div class="contents"></div></div></div>```json
[out:json][timeout:60];

// Zone
area["name"="<NOM DE LA VILLE>"]->.searchArea;

// Nœuds + ways + relations utiles
(
  // POI principaux
  nwr["amenity"~"restaurant|fast_food|cafe|bar|pub|nightclub|cinema|hospital|clinic|doctors|dentist|pharmacy|bank|post_office|fuel|car_wash|car_rental|driving_school"]
    ["website"!~"."]
    (area.searchArea);

  // Shops
  nwr["shop"~"supermarket|bakery|butcher|hairdresser|car_repair|electronics|bicycle|clothes|convenience|butcher|pharmacy"]
    ["website"!~"."]
    (area.searchArea);

  // Offices
  nwr["office"~"it|insurance|estate_agent|lawyer|accountant|consulting|coworking|travel_agent"]
    ["website"!~"."]
    (area.searchArea);

  // Crafts
  nwr["craft"~"electrician|plumber|carpenter|builder|roofer|painter"]
    ["website"!~"."]
    (area.searchArea);

  // Tourism
  nwr["tourism"~"hotel|hostel|guest_house|motel"]
    ["website"!~"."]
    (area.searchArea);
);

// Sortie
out body;
>;
out skel qt;
```