# 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 con l'URL del repo python-map-manager) git submodule add 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 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.