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

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


Premier déploiement

1. Créer les volumes externes

docker volume create overpass-db
docker volume create overpass-backup

2. Lancer l'import initial

docker compose run --rm overpass-init

Ce que fait ce service :

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 :

docker compose logs -f overpass-init

3. Démarrer le service principal

Une fois l'import terminé :

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) :

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

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) :

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

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 :

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 :

- 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

Requêtes #completetescommerces

Extraction des commerces sans horaires à par ville

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. 


[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;
Sans site web
[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;