diff --git a/mapas/deployments/deployment.yaml b/mapas/deployments/deployment.yaml new file mode 100644 index 0000000..f3636f9 --- /dev/null +++ b/mapas/deployments/deployment.yaml @@ -0,0 +1,51 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: tileserver-gl + namespace: maps +spec: + replicas: 1 + selector: + matchLabels: + app: tileserver-gl + template: + metadata: + labels: + app: tileserver-gl + spec: + containers: + - name: tileserver + image: maptiler/tileserver-gl:latest + imagePullPolicy: IfNotPresent + env: + - name: UPLOAD_DIR + value: /data + ports: + - containerPort: 8080 + name: http + volumeMounts: + - name: tiles-data + mountPath: /data + readinessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 10 + periodSeconds: 10 + livenessProbe: + httpGet: + path: / + port: http + initialDelaySeconds: 30 + periodSeconds: 20 + resources: + requests: + cpu: "250m" + memory: "512Mi" + limits: + cpu: "2" + memory: "2Gi" + volumes: + - name: tiles-data + persistentVolumeClaim: + claimName: tiles-data diff --git a/mapas/ingress/ingress.yaml b/mapas/ingress/ingress.yaml new file mode 100644 index 0000000..c1f075b --- /dev/null +++ b/mapas/ingress/ingress.yaml @@ -0,0 +1,24 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: tileserver + namespace: maps + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod +spec: + ingressClassName: nginx + tls: + - hosts: + - mapas.c2et.net + secretName: tileserver-tls + rules: + - host: mapas.c2et.net + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: tileserver + port: + number: 8080 diff --git a/mapas/namespace.yaml b/mapas/namespace.yaml new file mode 100644 index 0000000..ede564a --- /dev/null +++ b/mapas/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: maps diff --git a/mapas/pvc/pvc.yaml b/mapas/pvc/pvc.yaml new file mode 100644 index 0000000..3353e1a --- /dev/null +++ b/mapas/pvc/pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: tiles-data + namespace: maps +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 80Gi + storageClassName: ceph-rbd diff --git a/mapas/readme.md b/mapas/readme.md new file mode 100644 index 0000000..dec1e33 --- /dev/null +++ b/mapas/readme.md @@ -0,0 +1,214 @@ +# Generar y Servir Mapas Vectoriales Offline con OpenMapTiles + +Este README documenta el proceso completo para generar mapas vectoriales MBTiles a partir de datos OpenStreetMap, usando [OpenMapTiles](https://github.com/openmaptiles/openmaptiles), y servirlos localmente en un clúster Kubernetes. + +--- + +## Requisitos previos + +### Software necesario + +```bash +sudo apt update && sudo apt install -y osmium-tool curl docker docker-compose +``` + +--- + +## 1. Obtener los archivos `.osm.pbf` + +Desde la web de [Geofabrik](https://download.geofabrik.de/): + +* Descarga los `.osm.pbf` necesarios. +* Por ejemplo, para cubrir toda España incluyendo Canarias: + +```bash +wget https://download.geofabrik.de/europe/spain-latest.osm.pbf -P ./data/ +wget https://download.geofabrik.de/africa/canary-islands-latest.osm.pbf -P ./data/ +``` + +--- + +## 2. Unir los archivos `.osm.pbf` (si aplica) + +```bash +osmium merge \ + ./data/spain-latest.osm.pbf \ + ./data/canary-islands-latest.osm.pbf \ + -o ./data/spain_extended.osm.pbf +``` + +--- + +## 3. Configurar el entorno `.env` + +Edita el archivo `.env` y asegúrate de que las siguientes variables estén definidas correctamente: + +```env +BBOX=-18.5,26.0,5.0,44.5 +MIN_ZOOM=0 +MAX_ZOOM=15 +MBTILES_FILE=espana.mbtiles +``` + +También crea un archivo de bounding box si quieres usar uno personalizado: + +```bash +echo "-18.5,26.0,5.0,44.5" > data/spain_extended.bbox +``` + +--- + +## 4. Crear y lanzar script de generación + +### Script `run_openmaptiles.sh` + +```bash +#!/bin/bash + +set -e # Salir al primer error +export area=spain_extended + +LOGFILE="openmaptiles.log" +echo "=== INICIANDO GENERACIÓN DE TILES ===" | tee "$LOGFILE" +date | tee -a "$LOGFILE" + +echo "1. Limpiando..." | tee -a "$LOGFILE" +make clean >> "$LOGFILE" 2>&1 + +echo "2. Generando archivos..." | tee -a "$LOGFILE" +make >> "$LOGFILE" 2>&1 + +echo "3. Iniciando base de datos..." | tee -a "$LOGFILE" +make start-db >> "$LOGFILE" 2>&1 + +echo "4. Importando datos externos (Natural Earth, etc)..." | tee -a "$LOGFILE" +make import-data >> "$LOGFILE" 2>&1 + +echo "5. Importando archivo OSM..." | tee -a "$LOGFILE" +make import-osm >> "$LOGFILE" 2>&1 + +echo "6. Importando Wikidata..." | tee -a "$LOGFILE" +make import-wikidata >> "$LOGFILE" 2>&1 + +echo "7. Importando SQL para capas..." | tee -a "$LOGFILE" +make import-sql >> "$LOGFILE" 2>&1 + +echo "8. Calculando BBOX real (opcional)..." | tee -a "$LOGFILE" +make generate-bbox-file >> "$LOGFILE" 2>&1 + +echo "9. Generando MBTiles final..." | tee -a "$LOGFILE" +make generate-tiles-pg >> "$LOGFILE" 2>&1 + +echo "=== FINALIZADO ===" | tee -a "$LOGFILE" +date | tee -a "$LOGFILE" +``` + +Hazlo ejecutable: + +```bash +chmod +x run_openmaptiles.sh +``` + +Lánzalo con `nohup` (para que quede funcionando aunque cerremos la terminal, va a tardar unas cuantas horas): + +```bash +nohup ./run_openmaptiles.sh & +``` + +Verifica con: + +```bash +tail -f openmaptiles.log +``` + +--- + +## 5. Desplegar en Kubernetes + +### Manifiestos necesarios + +En lugar de `docker-compose`, el despliegue se realiza en Kubernetes con los siguientes recursos (todos dentro del namespace `maps`): + +* **PersistentVolumeClaim** (`tiles-data`) para almacenar los ficheros `.mbtiles`. +* **Deployment** con la imagen `maptiler/tileserver-gl`, montando el PVC en `/data`. +* **Service** tipo ClusterIP para exponer el puerto interno 8080. +* **Ingress** (opcional) para exponerlo con TLS a través de cert-manager. + +### Copiar los mapas al PVC + +Para cargar los archivos `.mbtiles` generados dentro del PVC: + +1. Lanza un pod temporal "uploader" que monte el PVC. + +```bash +kubectl apply -f namespace.yaml +kubectl apply -f pvc/pvc.yaml +kubectl apply -f uploader-pod.yaml +``` + +2. Copia los ficheros locales al pod: + +```bash +kubectl cp ./data/espana.mbtiles maps/tiles-uploader:/data/espana.mbtiles +``` + +3. Verifica que están en el PVC: + +```bash +kubectl -n maps exec -it tiles-uploader -- ls -lh /data +``` + +4. Una vez confirmada la copia, elimina el pod uploader: + +```bash +kubectl -n maps delete pod tiles-uploader +``` + +### Lanzamiento + +Aplica los manifiestos de Kubernetes: + +```bash +kubectl apply -f deployments/deployment.yaml +kubectl apply -f services/service.yaml +kubectl apply -f ingress/ingress.yaml # si quieres exponerlo con dominio y TLS +``` + +Accede a: + +``` +http://tileserver. +``` + +--- + +## Rendimiento y optimización + +### Parámetros útiles en `.env` + +```dotenv +# Aprovecha tus recursos +COPY_CONCURRENCY=16 +MAX_PARALLEL_PSQL=8 +``` + +#### ¿Qué significan? + +* `COPY_CONCURRENCY`: número de hilos paralelos usados para generar tiles. +* `MAX_PARALLEL_PSQL`: número de conexiones paralelas a la base de datos al importar SQL. + +Con una CPU potente (por ejemplo, 16-32 hilos), puedes aumentar estos valores: + +* `COPY_CONCURRENCY=20` o más si tu CPU va sobrada. +* `MAX_PARALLEL_PSQL=10` si tu RAM y disco lo permiten. + +## Recursos adicionales + +* Documentación original de OpenMapTiles: [https://github.com/openmaptiles/openmaptiles](https://github.com/openmaptiles/openmaptiles) +* Tileserver-GL (maptiler): [https://github.com/maptiler/tileserver-gl](https://github.com/maptiler/tileserver-gl) + +--- + +## Ver también + +Consulta el archivo [`info.md`](./info.md) para documentación técnica adicional y ejemplos avanzados. diff --git a/mapas/services/service.yaml b/mapas/services/service.yaml new file mode 100644 index 0000000..2a9459c --- /dev/null +++ b/mapas/services/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: tileserver + namespace: maps +spec: + selector: + app: tileserver-gl + ports: + - name: http + port: 8080 + targetPort: http + type: ClusterIP diff --git a/mapas/uploader-pod.yaml b/mapas/uploader-pod.yaml new file mode 100644 index 0000000..7a5101f --- /dev/null +++ b/mapas/uploader-pod.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: Pod +metadata: + name: tiles-uploader + namespace: maps +spec: + restartPolicy: Never + containers: + - name: uploader + image: alpine:latest + command: ["sh","-c","sleep 86400"] + volumeMounts: + - name: tiles-data + mountPath: /data + volumes: + - name: tiles-data + persistentVolumeClaim: + claimName: tiles-data