Files
breakpilot-lehrer/geo-service/scripts/generate_tiles.sh
Benjamin Boenisch 5a31f52310 Initial commit: breakpilot-lehrer - Lehrer KI Platform
Services: Admin-Lehrer, Backend-Lehrer, Studio v2, Website,
Klausur-Service, School-Service, Voice-Service, Geo-Service,
BreakPilot Drive, Agent-Core

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:47:26 +01:00

185 lines
5.9 KiB
Bash
Executable File

#!/bin/bash
# ============================================
# PMTiles Generation Script for GeoEdu Service
# ============================================
#
# Generiert PMTiles Vector Tiles aus PostGIS OSM Daten
# Verwendet tippecanoe fuer die Tile-Generierung
#
# Voraussetzungen:
# - OSM Daten in PostGIS importiert
# - tippecanoe installiert
# - ogr2ogr (GDAL) installiert
#
# Nutzung:
# ./generate_tiles.sh [--min-zoom 0] [--max-zoom 14]
#
# ============================================
set -e
# Configuration
DATA_DIR="${OSM_DATA_DIR:-/app/data/osm}"
OUTPUT_FILE="${DATA_DIR}/germany.pmtiles"
DATABASE_URL="${DATABASE_URL:-postgresql://breakpilot:breakpilot123@postgres:5432/breakpilot_db}"
MIN_ZOOM="${MIN_ZOOM:-0}"
MAX_ZOOM="${MAX_ZOOM:-14}"
# Parse DATABASE_URL
DB_USER=$(echo $DATABASE_URL | sed -n 's|.*://\([^:]*\):.*|\1|p')
DB_PASS=$(echo $DATABASE_URL | sed -n 's|.*://[^:]*:\([^@]*\)@.*|\1|p')
DB_HOST=$(echo $DATABASE_URL | sed -n 's|.*@\([^:]*\):.*|\1|p')
DB_PORT=$(echo $DATABASE_URL | sed -n 's|.*:\([0-9]*\)/.*|\1|p')
DB_NAME=$(echo $DATABASE_URL | sed -n 's|.*/\([^?]*\).*|\1|p')
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${YELLOW}============================================${NC}"
echo -e "${YELLOW}GeoEdu Service - PMTiles Generation${NC}"
echo -e "${YELLOW}============================================${NC}"
echo ""
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--min-zoom)
MIN_ZOOM="$2"
shift 2
;;
--max-zoom)
MAX_ZOOM="$2"
shift 2
;;
*)
echo "Unbekannte Option: $1"
exit 1
;;
esac
done
echo "Zoom Level: $MIN_ZOOM - $MAX_ZOOM"
echo "Output: $OUTPUT_FILE"
echo ""
# Estimate output size
if [ "$MAX_ZOOM" -le 14 ]; then
ESTIMATED_SIZE="200-500 GB"
elif [ "$MAX_ZOOM" -le 16 ]; then
ESTIMATED_SIZE="500-800 GB"
else
ESTIMATED_SIZE="2-4 TB"
fi
echo -e "${YELLOW}Geschaetzte Groesse: $ESTIMATED_SIZE${NC}"
echo -e "${YELLOW}Geschaetzte Dauer: 12-24 Stunden (Zoom 0-14)${NC}"
echo ""
# Check for required tools
for tool in tippecanoe ogr2ogr; do
if ! command -v $tool &> /dev/null; then
echo -e "${RED}Fehler: $tool nicht installiert!${NC}"
echo ""
if [ "$tool" == "tippecanoe" ]; then
echo "Installation:"
echo " git clone https://github.com/felt/tippecanoe.git"
echo " cd tippecanoe && make -j && sudo make install"
else
echo "Installation:"
echo " apt-get install gdal-bin # Debian/Ubuntu"
echo " brew install gdal # macOS"
fi
exit 1
fi
done
echo "tippecanoe: $(tippecanoe --version 2>&1 | head -1)"
echo "ogr2ogr: $(ogr2ogr --version | head -1)"
echo ""
read -p "Tile-Generierung starten? (j/N) " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[JjYy]$ ]]; then
echo "Abgebrochen."
exit 1
fi
# Create temporary directory for GeoJSON
TEMP_DIR=$(mktemp -d)
trap "rm -rf $TEMP_DIR" EXIT
echo ""
echo -e "${GREEN}[1/5] Exportiere Landuse/Landcover...${NC}"
PGPASSWORD="$DB_PASS" ogr2ogr -f GeoJSONSeq \
"$TEMP_DIR/landuse.geojsonseq" \
"PG:host=$DB_HOST port=$DB_PORT user=$DB_USER dbname=$DB_NAME password=$DB_PASS" \
-sql "SELECT way AS geometry, landuse, natural, name FROM planet_osm_polygon WHERE landuse IS NOT NULL OR natural IS NOT NULL"
echo -e "${GREEN}[2/5] Exportiere Gebaude...${NC}"
PGPASSWORD="$DB_PASS" ogr2ogr -f GeoJSONSeq \
"$TEMP_DIR/building.geojsonseq" \
"PG:host=$DB_HOST port=$DB_PORT user=$DB_USER dbname=$DB_NAME password=$DB_PASS" \
-sql "SELECT way AS geometry, building, name, addr_housenumber FROM planet_osm_polygon WHERE building IS NOT NULL"
echo -e "${GREEN}[3/5] Exportiere Strassen...${NC}"
PGPASSWORD="$DB_PASS" ogr2ogr -f GeoJSONSeq \
"$TEMP_DIR/transportation.geojsonseq" \
"PG:host=$DB_HOST port=$DB_PORT user=$DB_USER dbname=$DB_NAME password=$DB_PASS" \
-sql "SELECT way AS geometry, highway, railway, name, ref FROM planet_osm_line WHERE highway IS NOT NULL OR railway IS NOT NULL"
echo -e "${GREEN}[4/5] Exportiere Gewaesser...${NC}"
PGPASSWORD="$DB_PASS" ogr2ogr -f GeoJSONSeq \
"$TEMP_DIR/water.geojsonseq" \
"PG:host=$DB_HOST port=$DB_PORT user=$DB_USER dbname=$DB_NAME password=$DB_PASS" \
-sql "SELECT way AS geometry, waterway, water, name FROM planet_osm_polygon WHERE water IS NOT NULL OR waterway IS NOT NULL
UNION ALL
SELECT way AS geometry, waterway, NULL as water, name FROM planet_osm_line WHERE waterway IS NOT NULL"
echo -e "${GREEN}[5/5] Exportiere Orte (POIs)...${NC}"
PGPASSWORD="$DB_PASS" ogr2ogr -f GeoJSONSeq \
"$TEMP_DIR/place.geojsonseq" \
"PG:host=$DB_HOST port=$DB_PORT user=$DB_USER dbname=$DB_NAME password=$DB_PASS" \
-sql "SELECT way AS geometry, place, name, population FROM planet_osm_point WHERE place IS NOT NULL"
echo ""
echo -e "${GREEN}Generiere PMTiles...${NC}"
echo "Dies kann mehrere Stunden dauern!"
echo ""
# Run tippecanoe
tippecanoe \
--output="$OUTPUT_FILE" \
--force \
--name="GeoEdu Germany" \
--description="Self-hosted OSM tiles for DSGVO-compliant education" \
--attribution="© OpenStreetMap contributors" \
--minimum-zoom="$MIN_ZOOM" \
--maximum-zoom="$MAX_ZOOM" \
--drop-densest-as-needed \
--extend-zooms-if-still-dropping \
--layer=landuse:"$TEMP_DIR/landuse.geojsonseq" \
--layer=building:"$TEMP_DIR/building.geojsonseq" \
--layer=transportation:"$TEMP_DIR/transportation.geojsonseq" \
--layer=water:"$TEMP_DIR/water.geojsonseq" \
--layer=place:"$TEMP_DIR/place.geojsonseq"
echo ""
echo -e "${GREEN}============================================${NC}"
echo -e "${GREEN}PMTiles Generierung abgeschlossen!${NC}"
echo -e "${GREEN}============================================${NC}"
echo ""
echo "Ausgabe: $OUTPUT_FILE"
echo "Groesse: $(du -h "$OUTPUT_FILE" | cut -f1)"
echo ""
echo "Die Tiles sind jetzt bereit fuer den geo-service."