Benutzer-Werkzeuge

Webseiten-Werkzeuge


osrm

Dies ist eine alte Version des Dokuments!


Open Source Routing Machine. Siehe auch OpenStreetMap

Demo https://router.project-osrm.org/route/v1/driving/16.3725,48.2082;16.3738,48.2100?overview=false

Setup

WSL

Nur zur Demo, nach Neustart ist alles weg!

#!/usr/bin/env bash
set -euo pipefail
 
PBF_PATH="${1:-}"
PROFILE="${2:-car}"
PORT="${PORT:-5000}"
CONTAINER_NAME="${CONTAINER_NAME:-osrm-demo}"
WORKDIR="${WORKDIR:-/tmp/osrm-demo-data}"
 
need_root() {
  if [[ "${EUID}" -ne 0 ]]; then
    echo "Bitte mit sudo starten:"
    echo "  sudo bash setup-osrm.sh /pfad/zur/datei.osm.pbf car"
    exit 1
  fi
}
 
check_args() {
  if [[ -z "$PBF_PATH" ]]; then
    echo "Fehler: Bitte Pfad zur .osm.pbf angeben."
    exit 1
  fi
 
  if [[ ! -f "$PBF_PATH" ]]; then
    echo "Fehler: Datei nicht gefunden: $PBF_PATH"
    exit 1
  fi
 
  case "$PROFILE" in
    car)  LUA_PROFILE="/opt/car.lua" ;;
    bike) LUA_PROFILE="/opt/bicycle.lua" ;;
    foot) LUA_PROFILE="/opt/foot.lua" ;;
    *)
      echo "Fehler: Unbekanntes Profil '$PROFILE'. Erlaubt: car | bike | foot"
      exit 1
      ;;
  esac
 
  export LUA_PROFILE
}
 
install_docker_if_missing() {
  if command -v docker >/dev/null 2>&1; then
    echo "Docker ist bereits vorhanden: $(docker --version || true)"
    return
  fi
 
  echo "==> Docker wird installiert"
 
  apt-get update
  apt-get install -y ca-certificates curl
 
  install -m 0755 -d /etc/apt/keyrings
  curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
  chmod a+r /etc/apt/keyrings/docker.asc
 
  . /etc/os-release
  echo \
    "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu ${UBUNTU_CODENAME:-$VERSION_CODENAME} stable" \
    > /etc/apt/sources.list.d/docker.list
 
  apt-get update
  apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
 
  if command -v service >/dev/null 2>&1; then
    service docker start || true
  fi
 
  if [[ -n "${SUDO_USER:-}" ]]; then
    usermod -aG docker "$SUDO_USER" || true
  fi
}
 
start_docker_if_needed() {
  if docker info >/dev/null 2>&1; then
    echo "Docker läuft bereits."
    return
  fi
 
  echo "==> Docker-Daemon wird gestartet"
  if command -v service >/dev/null 2>&1; then
    service docker start || true
  fi
 
  for _ in $(seq 1 20); do
    if docker info >/dev/null 2>&1; then
      echo "Docker läuft."
      return
    fi
    sleep 1
  done
 
  echo "Fehler: Docker ist installiert, aber der Daemon läuft nicht."
  exit 1
}
 
prepare_paths() {
  PBF_ABS="$(readlink -f "$PBF_PATH")"
  PBF_BASENAME="$(basename "$PBF_ABS")"
  PBF_NAME="${PBF_BASENAME%.osm.pbf}"
 
  mkdir -p "$WORKDIR"
 
  export PBF_ABS PBF_BASENAME PBF_NAME
}
 
cleanup_old_files() {
  echo "==> Alte OSRM-Dateien entfernen in $WORKDIR"
  find "$WORKDIR" -maxdepth 1 -type f \( \
    -name "${PBF_NAME}.osrm*" -o \
    -name "${PBF_NAME}.timestamp" -o \
    -name "${PBF_BASENAME}" \
  \) -print -delete || true
 
  if docker ps -a --format '{{.Names}}' | grep -qx "$CONTAINER_NAME"; then
    echo "==> Alten Container entfernen: $CONTAINER_NAME"
    docker rm -f "$CONTAINER_NAME" >/dev/null 2>&1 || true
  fi
}
 
prepare_input_file() {
  echo "==> Kopiere Eingabedatei nach $WORKDIR"
  cp -f "$PBF_ABS" "$WORKDIR/$PBF_BASENAME"
}
 
run_osrm_pipeline() {
  echo "==> Eingabedatei: $PBF_ABS"
  echo "==> Arbeitsverzeichnis: $WORKDIR"
  echo "==> Profil: $PROFILE"
  echo "==> Port: $PORT"
 
  echo "==> OSRM-Image laden"
  docker pull osrm/osrm-backend
 
  echo "==> osrm-extract"
  docker run --rm -t \
    -v "$WORKDIR:/data" \
    osrm/osrm-backend \
    osrm-extract -p "$LUA_PROFILE" "/data/$PBF_BASENAME"
 
  echo "==> osrm-partition"
  docker run --rm -t \
    -v "$WORKDIR:/data" \
    osrm/osrm-backend \
    osrm-partition "/data/${PBF_NAME}.osrm"
 
  echo "==> osrm-customize"
  docker run --rm -t \
    -v "$WORKDIR:/data" \
    osrm/osrm-backend \
    osrm-customize "/data/${PBF_NAME}.osrm"
 
  echo "==> osrm-routed starten"
  docker run -d \
    --name "$CONTAINER_NAME" \
    -p "$PORT:5000" \
    -v "$WORKDIR:/data" \
    osrm/osrm-backend \
    osrm-routed --algorithm mld "/data/${PBF_NAME}.osrm" >/dev/null
}
 
print_done() {
  echo
  echo "Fertig."
  echo "Test:"
  echo "  http://localhost:${PORT}/route/v1/driving/16.3725,48.2082;16.3370,48.1980?overview=false"
  echo
  echo "Logs:"
  echo "  sudo docker logs -f $CONTAINER_NAME"
  echo
  echo "Stoppen:"
  echo "  sudo docker rm -f $CONTAINER_NAME"
}
 
need_root
check_args
install_docker_if_missing
start_docker_if_needed
prepare_paths
cleanup_old_files
prepare_input_file
run_osrm_pipeline
print_done
sudo bash setup-osrm.sh wien.osm.pbf car

Ubuntu 22.04

#!/usr/bin/env bash
set -Eeuo pipefail
 
# ============================================================
# Nominatim Setup für Ubuntu 22.04 + austria-latest.osm.pbf
# Getestetes Ziel: frische Ubuntu-22.04-Maschine
#
# Aufrufbeispiel:
#   sudo bash setup-nominatim-ubuntu2204.sh /pfad/zu/austria-latest.osm.pbf
#
# Optional per Env überschreiben:
#   NOMINATIM_USER=nominatim
#   NOMINATIM_HOME=/srv/nominatim
#   PROJECT_DIR=/srv/nominatim/nominatim-project
#   VENV_DIR=/srv/nominatim/nominatim-venv
#   FLATNODE_FILE=/srv/nominatim/flatnode/flatnode.file
#   INSTALL_FRONTEND=1
#   SETUP_UPDATES=0
# ============================================================
 
if [[ "${EUID}" -ne 0 ]]; then
  echo "Bitte als root ausführen: sudo bash $0 /pfad/zu/austria-latest.osm.pbf"
  exit 1
fi
 
OSM_PBF="${1:-}"
if [[ -z "${OSM_PBF}" ]]; then
  echo "Fehler: Bitte Pfad zur .osm.pbf-Datei angeben."
  echo "Beispiel: sudo bash $0 /data/austria-latest.osm.pbf"
  exit 1
fi
 
if [[ ! -f "${OSM_PBF}" ]]; then
  echo "Fehler: Datei nicht gefunden: ${OSM_PBF}"
  exit 1
fi
 
NOMINATIM_USER="${NOMINATIM_USER:-nominatim}"
NOMINATIM_HOME="${NOMINATIM_HOME:-/srv/nominatim}"
PROJECT_DIR="${PROJECT_DIR:-${NOMINATIM_HOME}/nominatim-project}"
VENV_DIR="${VENV_DIR:-${NOMINATIM_HOME}/nominatim-venv}"
FLATNODE_FILE="${FLATNODE_FILE:-${NOMINATIM_HOME}/flatnode/flatnode.file}"
INSTALL_FRONTEND="${INSTALL_FRONTEND:-1}"   # 1 = gunicorn/uvicorn + systemd
SETUP_UPDATES="${SETUP_UPDATES:-0}"         # 1 = Geofabrik Austria daily updates initialisieren
OSM2PGSQL_REPO="${OSM2PGSQL_REPO:-https://github.com/osm2pgsql-dev/osm2pgsql.git}"
OSM2PGSQL_SRC="${NOMINATIM_HOME}/osm2pgsql"
OSM2PGSQL_BUILD="${NOMINATIM_HOME}/osm2pgsql-build"
 
POSTGRES_VER="14"
 
log() { echo -e "\n>>> $*\n"; }
 
require_cmd() {
  command -v "$1" >/dev/null 2>&1 || {
    echo "Fehlendes Kommando: $1"
    exit 1
  }
}
 
# ------------------------------------------------------------
# 1) Pakete installieren
# ------------------------------------------------------------
log "Installiere Systempakete"
apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y \
  build-essential cmake g++ git curl ca-certificates lsb-release \
  libboost-dev libboost-system-dev libboost-filesystem-dev \
  libexpat1-dev zlib1g-dev libbz2-dev libpq-dev \
  liblua5.3-dev lua5.3 lua-dkjson \
  nlohmann-json3-dev libicu-dev virtualenv \
  postgresql-${POSTGRES_VER}-postgis-3 \
  postgresql-contrib-${POSTGRES_VER} \
  postgresql-${POSTGRES_VER}-postgis-3-scripts
 
require_cmd git
require_cmd cmake
require_cmd psql
require_cmd virtualenv
 
# ------------------------------------------------------------
# 2) User anlegen
# ------------------------------------------------------------
log "Lege Systembenutzer ${NOMINATIM_USER} an"
if ! id -u "${NOMINATIM_USER}" >/dev/null 2>&1; then
  useradd -d "${NOMINATIM_HOME}" -s /bin/bash -m "${NOMINATIM_USER}"
fi
 
chmod a+x "${NOMINATIM_HOME}"
mkdir -p "${PROJECT_DIR}" "$(dirname "${FLATNODE_FILE}")"
chown -R "${NOMINATIM_USER}:${NOMINATIM_USER}" "${NOMINATIM_HOME}"
 
# ------------------------------------------------------------
# 3) PostgreSQL vorbereiten
#    Minimal-invasive Änderungen an postgresql.conf
# ------------------------------------------------------------
log "Konfiguriere PostgreSQL grob für den Import"
 
PGCONF="/etc/postgresql/${POSTGRES_VER}/main/postgresql.conf"
if [[ ! -f "${PGCONF}" ]]; then
  echo "postgresql.conf nicht gefunden: ${PGCONF}"
  exit 1
fi
 
cp -n "${PGCONF}" "${PGCONF}.bak"
 
TOTAL_MEM_MB="$(awk '/MemTotal/ {print int($2/1024)}' /proc/meminfo)"
CPU_CORES="$(nproc)"
 
# Konservative Heuristik:
# shared_buffers: ~25% RAM, cap 8GB
# maintenance_work_mem: ~15% RAM, cap 4GB
# autovacuum_work_mem: 512MB oder 1GB
# work_mem: 32MB
shared_buffers_mb=$(( TOTAL_MEM_MB / 4 ))
(( shared_buffers_mb > 8192 )) && shared_buffers_mb=8192
(( shared_buffers_mb < 512 )) && shared_buffers_mb=512
 
maintenance_work_mem_mb=$(( TOTAL_MEM_MB * 15 / 100 ))
(( maintenance_work_mem_mb > 4096 )) && maintenance_work_mem_mb=4096
(( maintenance_work_mem_mb < 256 )) && maintenance_work_mem_mb=256
 
autovacuum_work_mem_mb=1024
(( TOTAL_MEM_MB < 8192 )) && autovacuum_work_mem_mb=512
 
work_mem_mb=32
max_wal_size_gb=2
(( TOTAL_MEM_MB >= 32768 )) && max_wal_size_gb=4
(( TOTAL_MEM_MB >= 65536 )) && max_wal_size_gb=8
 
set_pgconf() {
  local key="$1"
  local value="$2"
  if grep -Eq "^[#[:space:]]*${key}[[:space:]]*=" "${PGCONF}"; then
    sed -ri "s|^[#[:space:]]*(${key})[[:space:]]*=.*|\1 = ${value}|g" "${PGCONF}"
  else
    echo "${key} = ${value}" >> "${PGCONF}"
  fi
}
 
# Angelehnt an die Nominatim-Doku, aber auf Host-RAM angepasst
set_pgconf "shared_buffers" "'${shared_buffers_mb}MB'"
set_pgconf "maintenance_work_mem" "'${maintenance_work_mem_mb}MB'"
set_pgconf "autovacuum_work_mem" "'${autovacuum_work_mem_mb}MB'"
set_pgconf "work_mem" "'${work_mem_mb}MB'"
set_pgconf "synchronous_commit" "off"
set_pgconf "max_wal_size" "'${max_wal_size_gb}GB'"
set_pgconf "checkpoint_timeout" "'60min'"
set_pgconf "checkpoint_completion_target" "0.9"
set_pgconf "random_page_cost" "1.0"
set_pgconf "wal_level" "minimal"
set_pgconf "max_wal_senders" "0"
 
if (( TOTAL_MEM_MB < 8192 )); then
  set_pgconf "autovacuum_max_workers" "1"
fi
 
systemctl restart postgresql
 
# DB-User anlegen
log "Lege PostgreSQL-User an"
if ! sudo -u postgres psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='${NOMINATIM_USER}'" | grep -q 1; then
  sudo -u postgres createuser -s "${NOMINATIM_USER}"
fi
 
if ! sudo -u postgres psql -tAc "SELECT 1 FROM pg_roles WHERE rolname='www-data'" | grep -q 1; then
  sudo -u postgres createuser www-data
fi
 
# ------------------------------------------------------------
# 4) osm2pgsql bauen
# ------------------------------------------------------------
log "Baue aktuelle osm2pgsql-Version aus Git"
if [[ ! -d "${OSM2PGSQL_SRC}" ]]; then
  sudo -u "${NOMINATIM_USER}" git clone "${OSM2PGSQL_REPO}" "${OSM2PGSQL_SRC}"
else
  sudo -u "${NOMINATIM_USER}" git -C "${OSM2PGSQL_SRC}" fetch --all --tags
  sudo -u "${NOMINATIM_USER}" git -C "${OSM2PGSQL_SRC}" pull --ff-only
fi
 
mkdir -p "${OSM2PGSQL_BUILD}"
chown -R "${NOMINATIM_USER}:${NOMINATIM_USER}" "${OSM2PGSQL_BUILD}"
 
sudo -u "${NOMINATIM_USER}" bash -lc "
  set -Eeuo pipefail
  cd '${OSM2PGSQL_BUILD}'
  cmake '${OSM2PGSQL_SRC}'
  make -j'${CPU_CORES}'
"
make -C "${OSM2PGSQL_BUILD}" install
ldconfig
 
# ------------------------------------------------------------
# 5) Python venv + Nominatim installieren
# ------------------------------------------------------------
log "Installiere Nominatim in Virtualenv"
if [[ ! -d "${VENV_DIR}" ]]; then
  sudo -u "${NOMINATIM_USER}" virtualenv "${VENV_DIR}"
fi
 
sudo -u "${NOMINATIM_USER}" "${VENV_DIR}/bin/pip" install --upgrade pip wheel setuptools
sudo -u "${NOMINATIM_USER}" "${VENV_DIR}/bin/pip" install "psycopg[binary]" nominatim-db nominatim-api
 
if [[ "${INSTALL_FRONTEND}" == "1" ]]; then
  sudo -u "${NOMINATIM_USER}" "${VENV_DIR}/bin/pip" install falcon uvicorn gunicorn
fi
 
# ------------------------------------------------------------
# 6) Projektverzeichnis + .env
# ------------------------------------------------------------
log "Erstelle Projektkonfiguration"
mkdir -p "${PROJECT_DIR}"
chown -R "${NOMINATIM_USER}:${NOMINATIM_USER}" "${PROJECT_DIR}"
 
cat > "${PROJECT_DIR}/.env" <<EOF
NOMINATIM_DATABASE_DSN=pgsql:dbname=nominatim
NOMINATIM_DATABASE_WEBUSER=www-data
NOMINATIM_FLATNODE_FILE=${FLATNODE_FILE}
EOF
 
chown "${NOMINATIM_USER}:${NOMINATIM_USER}" "${PROJECT_DIR}/.env"
chmod 640 "${PROJECT_DIR}/.env"
 
# ------------------------------------------------------------
# 7) Import ausführen
# ------------------------------------------------------------
log "Starte Nominatim-Import"
sudo -u "${NOMINATIM_USER}" bash -lc "
  set -Eeuo pipefail
  export PATH='${VENV_DIR}/bin:/usr/local/bin:/usr/bin:/bin'
  cd '${PROJECT_DIR}'
  nominatim import --osm-file '${OSM_PBF}' 2>&1 | tee '${PROJECT_DIR}/setup.log'
"
 
# ------------------------------------------------------------
# 8) Optional: einfacher Frontend-Service
# ------------------------------------------------------------
if [[ "${INSTALL_FRONTEND}" == "1" ]]; then
  log "Richte systemd-Service für Nominatim-Frontend ein"
 
  cat > /etc/systemd/system/nominatim.socket <<EOF
[Unit]
Description=Gunicorn socket for Nominatim
 
[Socket]
ListenStream=/run/nominatim.sock
SocketUser=www-data
 
[Install]
WantedBy=multi-user.target
EOF
 
  cat > /etc/systemd/system/nominatim.service <<EOF
[Unit]
Description=Nominatim running as a gunicorn application
After=network.target
Requires=nominatim.socket
 
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=${PROJECT_DIR}
Environment="PATH=${VENV_DIR}/bin:/usr/local/bin:/usr/bin:/bin"
ExecStart=${VENV_DIR}/bin/gunicorn -b unix:/run/nominatim.sock -w 4 -k uvicorn.workers.UvicornWorker "nominatim_api.server.falcon.server:run_wsgi()"
ExecReload=/bin/kill -s HUP \$MAINPID
PrivateTmp=true
TimeoutStopSec=5
KillMode=mixed
 
[Install]
WantedBy=multi-user.target
EOF
 
  systemctl daemon-reload
  systemctl enable nominatim.socket
  systemctl start nominatim.socket
  systemctl enable nominatim.service
  systemctl start nominatim.service
 
  # Optional: Apache als Reverse Proxy
  if ! dpkg -s apache2 >/dev/null 2>&1; then
    apt-get install -y apache2
  fi
  a2enmod proxy_http >/dev/null
  cat > /etc/apache2/conf-available/nominatim.conf <<'EOF'
ProxyPass /nominatim "unix:/run/nominatim.sock|http://localhost/"
EOF
  a2enconf nominatim >/dev/null
  systemctl restart apache2
fi
 
# ------------------------------------------------------------
# 9) Optional: Austria-Updates über Geofabrik initialisieren
# ------------------------------------------------------------
if [[ "${SETUP_UPDATES}" == "1" ]]; then
  log "Initialisiere Replikation für Austria-Updates"
  cat >> "${PROJECT_DIR}/.env" <<EOF
 
NOMINATIM_REPLICATION_URL=https://download.geofabrik.de/europe/austria-updates
NOMINATIM_REPLICATION_UPDATE_INTERVAL=86400
NOMINATIM_REPLICATION_RECHECK_INTERVAL=900
EOF
 
  sudo -u "${NOMINATIM_USER}" "${VENV_DIR}/bin/pip" install --user osmium
 
  sudo -u "${NOMINATIM_USER}" bash -lc "
    set -Eeuo pipefail
    export PATH='${VENV_DIR}/bin:${HOME}/.local/bin:/usr/local/bin:/usr/bin:/bin'
    cd '${PROJECT_DIR}'
    nominatim replication --init
  "
fi
 
# ------------------------------------------------------------
# 10) Ausgabe
# ------------------------------------------------------------
log "Fertig"
 
cat <<EOF
 
Nominatim wurde eingerichtet.
 
Wichtige Pfade:
  PBF:            ${OSM_PBF}
  Projekt:        ${PROJECT_DIR}
  Virtualenv:     ${VENV_DIR}
  Flatnode:       ${FLATNODE_FILE}
  Log:            ${PROJECT_DIR}/setup.log
 
Prüfen:
  sudo -u ${NOMINATIM_USER} bash -lc "cd ${PROJECT_DIR} && ${VENV_DIR}/bin/nominatim admin --check-database"
 
API lokal testen:
  curl "http://127.0.0.1/nominatim/search?q=Vienna&format=jsonv2"
 
Mit Apache-Proxy:
  curl "http://127.0.0.1/nominatim/search?q=Vienna&format=jsonv2"
 
Service-Status:
  systemctl status nominatim.socket
  systemctl status nominatim.service
 
EOF
sudo bash setup-osrm.sh wien.osm.pbf car

Ubuntu

  • foot.lua
  • bicycle.lua
  • car.lua

Walking

Nur foot, auf WAF getestet)

#!/usr/bin/env bash
set -Eeuo pipefail
 
OSRM_DIR="/opt/osrm-austria"
DATA_DIR="${OSRM_DIR}/data"
SERVICE_FILE="/etc/systemd/system/osrm-austria.service"
PBF_URL="https://download.geofabrik.de/europe/austria-latest.osm.pbf"
PBF_FILE="${DATA_DIR}/austria-latest.osm.pbf"
CONTAINER_IMAGE="ghcr.io/project-osrm/osrm-backend:latest"
CONTAINER_NAME="osrm-austria"
PORT="5000"
DATASET="austria-latest"
ROUTED_PATH="/data/${DATASET}"
 
log() {
    echo "[+] $*"
}
 
fail() {
    echo "[!] FEHLER: $*" >&2
    exit 1
}
 
require_root() {
    [[ "${EUID}" -eq 0 ]] || fail "Bitte als root ausführen."
}
 
on_error() {
    local exit_code=$?
    echo
    echo "[!] Das Skript ist fehlgeschlagen. Exit-Code: ${exit_code}"
    echo "[!] Diagnose:"
    echo "    free -h"
    echo "    df -h"
    echo "    ls -lh ${DATA_DIR}"
    echo "    journalctl -u osrm-austria.service -n 100 --no-pager"
    exit "${exit_code}"
}
trap on_error ERR
 
install_packages() {
    log "Installiere Basis-Pakete ..."
    apt-get update
    apt-get install -y \
        ca-certificates \
        curl \
        gnupg \
        lsb-release \
        wget \
        systemd
}
 
install_docker() {
    if command -v docker >/dev/null 2>&1; then
        log "Docker ist bereits installiert."
        systemctl enable docker >/dev/null 2>&1 || true
        systemctl start docker
        return
    fi
 
    log "Installiere Docker ..."
    install -m 0755 -d /etc/apt/keyrings
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
    chmod a+r /etc/apt/keyrings/docker.asc
 
    cat > /etc/apt/sources.list.d/docker.list <<EOF
deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable
EOF
 
    apt-get update
    apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
 
    systemctl enable docker
    systemctl start docker
}
 
prepare_dirs() {
    log "Erzeuge Verzeichnisse ..."
    mkdir -p "${DATA_DIR}"
}
 
download_data() {
    if [[ -s "${PBF_FILE}" ]]; then
        log "PBF-Datei existiert bereits: ${PBF_FILE}"
        return
    fi
 
    log "Lade Österreich-OSM-Daten herunter ..."
    wget -O "${PBF_FILE}" "${PBF_URL}"
    [[ -s "${PBF_FILE}" ]] || fail "Download fehlgeschlagen: ${PBF_FILE} fehlt oder ist leer."
}
 
pull_image() {
    log "Lade OSRM-Container-Image ..."
    docker pull "${CONTAINER_IMAGE}"
}
 
cleanup_old_artifacts() {
    log "Entferne alte OSRM-Artefakte ..."
 
    rm -f \
        "${DATA_DIR}/${DATASET}.osrm"* \
        "${DATA_DIR}/${DATASET}.osrm."* \
        "${DATA_DIR}/${DATASET}.osrm"
 
    [[ -s "${PBF_FILE}" ]] || fail "PBF-Datei fehlt nach Cleanup: ${PBF_FILE}"
}
 
run_extract() {
    log "Starte osrm-extract (walking, 1 Thread) ..."
    OMP_NUM_THREADS=1 docker run --rm -t \
        -e OMP_NUM_THREADS=1 \
        -v "${DATA_DIR}:/data" \
        "${CONTAINER_IMAGE}" \
        osrm-extract \
        -p /opt/foot.lua \
        "${ROUTED_PATH}.osm.pbf"
 
    [[ -f "${DATA_DIR}/${DATASET}.osrm.ebg" ]] || fail "osrm-extract unvollständig: ${DATASET}.osrm.ebg fehlt."
    [[ -f "${DATA_DIR}/${DATASET}.osrm.properties" ]] || fail "osrm-extract unvollständig: ${DATASET}.osrm.properties fehlt."
    [[ -f "${DATA_DIR}/${DATASET}.osrm.timestamp" ]] || fail "osrm-extract unvollständig: ${DATASET}.osrm.timestamp fehlt."
}
 
run_partition() {
    log "Starte osrm-partition ..."
    docker run --rm -t \
        -v "${DATA_DIR}:/data" \
        "${CONTAINER_IMAGE}" \
        osrm-partition \
        "${ROUTED_PATH}"
 
    [[ -f "${DATA_DIR}/${DATASET}.osrm.partition" ]] || fail "osrm-partition unvollständig: ${DATASET}.osrm.partition fehlt."
}
 
run_customize() {
    log "Starte osrm-customize ..."
    docker run --rm -t \
        -v "${DATA_DIR}:/data" \
        "${CONTAINER_IMAGE}" \
        osrm-customize \
        "${ROUTED_PATH}"
 
    [[ -f "${DATA_DIR}/${DATASET}.osrm.cells" ]] || fail "osrm-customize unvollständig: ${DATASET}.osrm.cells fehlt."
    [[ -f "${DATA_DIR}/${DATASET}.osrm.mldgr" ]] || fail "osrm-customize unvollständig: ${DATASET}.osrm.mldgr fehlt."
}
 
create_service() {
    log "Erzeuge systemd-Service ..."
 
    cat > "${SERVICE_FILE}" <<EOF
[Unit]
Description=OSRM Austria Walking Server
After=docker.service network-online.target
Requires=docker.service
Wants=network-online.target
 
[Service]
Type=simple
Restart=always
RestartSec=5
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker rm -f ${CONTAINER_NAME}
ExecStart=/usr/bin/docker run --rm --name ${CONTAINER_NAME} -p ${PORT}:5000 -v ${DATA_DIR}:/data ${CONTAINER_IMAGE} osrm-routed --algorithm mld ${ROUTED_PATH}
ExecStop=/usr/bin/docker stop ${CONTAINER_NAME}
 
[Install]
WantedBy=multi-user.target
EOF
 
    systemctl daemon-reload
    systemctl enable osrm-austria.service
}
 
start_service() {
    log "Starte OSRM-Service ..."
    systemctl restart osrm-austria.service
    sleep 3
    systemctl --no-pager --full status osrm-austria.service
}
 
show_result() {
    echo
    log "Fertig."
    echo
    echo "Test:"
    echo "curl 'http://127.0.0.1:${PORT}/route/v1/walking/16.3725,48.2082;16.3738,48.2100?overview=false'"
    echo
    echo "Status:"
    echo "systemctl status osrm-austria.service --no-pager -l"
    echo
    echo "Logs:"
    echo "journalctl -u osrm-austria.service -f"
}
 
main() {
    require_root
    install_packages
    install_docker
    prepare_dirs
    download_data
    pull_image
    cleanup_old_artifacts
    run_extract
    run_partition
    run_customize
    create_service
    start_service
    show_result
}
 
main "$@"

Walking, Bycicle, Driving

#!/usr/bin/env bash
set -Eeuo pipefail
 
OSRM_BASE="/opt/osrm-austria"
SERVICE_DIR="/etc/systemd/system"
PBF_URL="https://download.geofabrik.de/europe/austria-latest.osm.pbf"
CONTAINER_IMAGE="ghcr.io/project-osrm/osrm-backend:latest"
 
declare -A PROFILE_LUA=(
  [driving]="/opt/car.lua"
  [bicycle]="/opt/bicycle.lua"
  [foot]="/opt/foot.lua"
)
 
declare -A PROFILE_PORT=(
  [driving]="5000"
  [bicycle]="5001"
  [foot]="5002"
)
 
log() { echo "[+] $*"; }
fail() { echo "[!] FEHLER: $*" >&2; exit 1; }
 
require_root() {
  [[ "${EUID}" -eq 0 ]] || fail "Bitte als root ausführen."
}
 
install_packages() {
  apt-get update
  apt-get install -y ca-certificates curl gnupg lsb-release wget systemd
}
 
install_docker() {
  if command -v docker >/dev/null 2>&1; then
    systemctl enable docker >/dev/null 2>&1 || true
    systemctl start docker
    return
  fi
 
  install -m 0755 -d /etc/apt/keyrings
  curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
  chmod a+r /etc/apt/keyrings/docker.asc
 
  cat > /etc/apt/sources.list.d/docker.list <<EOF
deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable
EOF
 
  apt-get update
  apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  systemctl enable docker
  systemctl start docker
}
 
prepare_profile_dir() {
  local profile="$1"
  mkdir -p "${OSRM_BASE}/${profile}"
}
 
download_pbf() {
  local profile="$1"
  local pbf_file="${OSRM_BASE}/${profile}/austria-latest.osm.pbf"
 
  if [[ ! -s "${pbf_file}" ]]; then
    wget -O "${pbf_file}" "${PBF_URL}"
  fi
 
  [[ -s "${pbf_file}" ]] || fail "PBF fehlt für ${profile}"
}
 
build_profile() {
  local profile="$1"
  local lua="${PROFILE_LUA[$profile]}"
  local dir="${OSRM_BASE}/${profile}"
 
  log "Baue Profil ${profile} ..."
 
  rm -f "${dir}/austria-latest.osrm"*
 
  docker run --rm -t \
    -e OMP_NUM_THREADS=1 \
    -v "${dir}:/data" \
    "${CONTAINER_IMAGE}" \
    osrm-extract -p "${lua}" /data/austria-latest.osm.pbf
 
  docker run --rm -t \
    -v "${dir}:/data" \
    "${CONTAINER_IMAGE}" \
    osrm-partition /data/austria-latest.osrm
 
  docker run --rm -t \
    -v "${dir}:/data" \
    "${CONTAINER_IMAGE}" \
    osrm-customize /data/austria-latest.osrm
 
  [[ -f "${dir}/austria-latest.osrm.cells" ]] || fail "Build fehlgeschlagen für ${profile}"
}
 
create_service() {
  local profile="$1"
  local port="${PROFILE_PORT[$profile]}"
  local dir="${OSRM_BASE}/${profile}"
  local service="${SERVICE_DIR}/osrm-austria-${profile}.service"
  local container="osrm-austria-${profile}"
 
  cat > "${service}" <<EOF
[Unit]
Description=OSRM Austria ${profile} Server
After=docker.service network-online.target
Requires=docker.service
Wants=network-online.target
 
[Service]
Type=simple
Restart=always
RestartSec=5
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker rm -f ${container}
ExecStart=/usr/bin/docker run --rm --name ${container} -p ${port}:5000 -v ${dir}:/data ${CONTAINER_IMAGE} osrm-routed --algorithm mld /data/austria-latest.osrm
ExecStop=/usr/bin/docker stop ${container}
 
[Install]
WantedBy=multi-user.target
EOF
}
 
start_service() {
  local profile="$1"
  systemctl daemon-reload
  systemctl enable "osrm-austria-${profile}.service"
  systemctl restart "osrm-austria-${profile}.service"
}
 
main() {
  require_root
  install_packages
  install_docker
  docker pull "${CONTAINER_IMAGE}"
 
  for profile in driving bicycle foot; do
    prepare_profile_dir "${profile}"
    download_pbf "${profile}"
    build_profile "${profile}"
    create_service "${profile}"
    start_service "${profile}"
  done
 
  echo
  echo "Fertig."
  echo "driving: http://127.0.0.1:5000"
  echo "bicycle: http://127.0.0.1:5001"
  echo "foot:    http://127.0.0.1:5002"
}
main "$@"
osrm.1774807029.txt.gz · Zuletzt geändert: 2026/03/29 19:57 von jango