python-map-manager/INTEGRATION.md
2025-12-02 09:09:22 +01:00

175 lines
6.9 KiB
Markdown

# INTEGRAZIONE: usare `python-map-manager` come git submodule in GeoElevation
Questo documento spiega come integrare `python-map-manager` in un progetto esistente
(ad esempio il repository `geoelevation`) come sottoprogetto (git submodule) e come
usarlo a runtime.
Nota: `python-map-manager` è pensato per essere GUI-agnostico — la logica core non
dipende da Tkinter/OpenCV; il demo `debug_tool.py` è separato e opzionale.
1) Aggiungere come git submodule
Dal repository principale (`geoelevation`) esegui (PowerShell):
```powershell
# posizionati nella root del repo geoelevation
cd C:\path\to\geoelevation
# aggiungi il submodule (sostituisci <REPO_URL> con l'URL del repo python-map-manager)
git submodule add <REPO_URL> submodules/python-map-manager
git submodule update --init --recursive
```
Se preferisci tenere il codice direttamente nella tree, puoi copiare la cartella,
ma usare un submodule mantiene la separazione e facilita aggiornamenti futuri.
2) Installare le dipendenze nell'ambiente del progetto
`python-map-manager` usa alcune librerie opzionali (Pillow, requests, mercantile, pyproj, ecc.).
Nel progetto principale, installa i requisiti del submodule nel virtualenv del progetto:
```powershell
python -m pip install -r submodules/python-map-manager/requirements.txt
```
3) Rendere importabile il package nel codice di `geoelevation`
Opzioni possibili:
- Aggiungere il submodule al `PYTHONPATH` (semplice, non richiede packaging):
- Esempio (PowerShell) per lanciare script dalla root del progetto:
```powershell
$env:PYTHONPATH = "$PWD\submodules\python-map-manager"; python -m your_app
```
- O aggiungere ad `sys.path` all'avvio dell'applicazione (es. in `geoelevation/__main__.py`):
```python
import os, sys
pkg_root = os.path.join(os.path.dirname(__file__), '..', 'submodules', 'python-map-manager')
if pkg_root not in sys.path:
sys.path.insert(0, pkg_root)
```
- (Opzionale) Se preferisci installare come pacchetto editable (richiede un `pyproject`/`setup`):
```powershell
pip install -e submodules/python-map-manager
```
4) Esempio rapido di utilizzo in `geoelevation`
```python
from map_manager.engine import MapEngine
# creare engine (cache_dir può essere un percorso gestito da geoelevation)
engine = MapEngine(service_name='osm', cache_dir='path/to/cache', enable_online=True)
# chiamata semplice (sincrona) per ottenere immagine area
img = engine.get_image_for_area((w, s, e, n), zoom=12)
# usare progress callback (esempio):
def progress_cb(done, total, last_tile_duration, from_cache, tile_coords):
# attenzione: callback può essere invocato da thread di lavoro
# se aggiornate UI dovete marshalare sull'UI thread (es. root.after in Tkinter)
print(f"{done}/{total} tiles — last {last_tile_duration:.2f}s — from_cache={from_cache} coords={tile_coords}")
img = engine.get_image_for_area((w, s, e, n), zoom=None, max_size=800, progress_callback=progress_cb)
```
5) Note su threading e UI
- `stitch_map_image` invoca il `progress_callback` dal thread dove viene eseguito
(cioè il thread che chiama `get_image_for_area` / `stitch_map_image`).
- Nel demo `debug_tool.py` le chiamate a `get_image_for_area` sono eseguite in un
worker thread e il callback marshala gli aggiornamenti con `root.after(...)`.
- Se integrate nelle GUI di `geoelevation`, assicuratevi di marshalarle similmente.
6) Dipendenze e packaging
- Se il vostro progetto usa un singolo `requirements.txt` o un `pyproject.toml`,
considerate aggiungere le dipendenze del submodule (contenute in
`submodules/python-map-manager/requirements.txt`) al file di dipendenze principale.
- Raccomando di usare un virtualenv isolato per lo sviluppo e i test.
7) Test e CI
- I test presenti in `python-map-manager/tests` possono essere eseguiti dalla root
del submodule. Quando integrate come submodule, nel CI aggiungete uno step che:
- installa le dipendenze
- esegue i test (es. `python -m pytest python-map-manager/tests`)
Domande frequenti (FAQ)
- Q: Il demo GUI è obbligatorio? A: No, è solo un tool per sviluppatori.
- Q: La libreria farà richieste in parallelo? A: Attualmente il comportamento di default
è sequenziale; possiamo abilitare download concorrenti come opzione sicura.
Se vuoi, posso aggiungere un esempio `geoelevation` che mostra come inizializzare
il `MapEngine` dal codice del progetto e integrare la pulizia della cache nei
comandi di gestione di `geoelevation`.
# Integration Guide — using `python-map-manager` from `geoelevation`
This document explains how to integrate the local `python-map-manager` package into the `geoelevation` application as a Git submodule (or as a local package) and shows example usage of the new public API (`MapEngine`, `MapVisualizer`).
1) Add as a git submodule (optional)
From the `geoelevation` repository root, add the external repo as a submodule:
```powershell
git submodule add -b master <URL_REPO> external/python-map-manager
git submodule update --init --recursive
```
If you're working locally and prefer to keep the module inside the same repo for now, copy the `python-map-manager` directory under `external/` or keep it at repo root.
2) Make the package importable
Options:
- Add the submodule path to `PYTHONPATH` at runtime, or
- Install the package into your environment (editable install) during development:
```powershell
python -m pip install -e external\python-map-manager
# or, for local-only testing
$env:PYTHONPATH+=';C:\path\to\geoelevation\external\python-map-manager'
```
3) Minimal usage example
In code, import the engine and visualizer:
```python
from map_manager.engine import MapEngine
from map_manager.visualizer import MapVisualizer
engine = MapEngine(service_name='osm', cache_dir='map_tile_cache', enable_online=True)
visual = MapVisualizer(engine)
# Example: get an image for a bbox (west,south,east,north)
bbox = (7.0, 45.0, 8.0, 46.0)
img = engine.get_image_for_area(bbox, max_size=1024) # choose zoom automatically
if img is not None:
visual.show_pil_image(img)
# For callbacks: set a click handler
def on_map_click(lat, lon):
elevation = query_elevation(lat, lon) # your app logic
print('Elevation', elevation)
visual.set_click_callback(on_map_click)
```
4) Integration points in `geoelevation`
- Replace internal `map_viewer` usage with the submodule API:
- Where `map_viewer` previously called tile download/stitching, replace with `MapEngine.get_image_for_area` or `get_image_for_point`.
- Where UI components called directly into `ElevationManager`, change to use `MapVisualizer` callbacks (subscribe your callback to `visual.set_click_callback`).
5) Notes and recommendations
- Keep `MapEngine` independent of `ElevationManager` — pass callbacks into `MapVisualizer` from `geoelevation` so the submodule does not import application business logic.
- For headless or server usage, do not import/use `MapVisualizer`; `MapEngine` works without OpenCV.
- Add `python-map-manager/requirements.txt` to your environment or include its dependencies in the main project's dependency list.