461bb77298
12 issues nuevos para implementacion paralela: text_editor, file_watcher, gl_texture_load, gl_compute+pingpong+DAG Compute, ImPlot3D, mesh_viewer, audio reactivo, animation curves, sql_workbench, http+ws inspector, scientific viz (5 charts), map_tiles, image_canvas + webcam_texture. Cada issue añade funciones al registry y un demo propio en primitives_gallery/demos_<feature>.cpp para minimizar conflictos en paralelo. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
123 lines
4.5 KiB
Markdown
123 lines
4.5 KiB
Markdown
# 0035 — C++ map_tiles (slippy map OSM)
|
|
|
|
## APP Metadata
|
|
|
|
| Campo | Valor |
|
|
|-------|-------|
|
|
| **ID** | 0035 |
|
|
| **Estado** | pendiente |
|
|
| **Prioridad** | baja |
|
|
| **Tipo** | feature — C++ viz (cpp/functions/viz) |
|
|
|
|
## Dependencias
|
|
|
|
`gl_texture_load_cpp_gfx` (issue 0026), `gl_loader_cpp_gfx`. Vendor: `cpp-httplib` (si ya esta vendoreado por 0033) o reusar.
|
|
|
|
**Desbloquea:** apps GIS minimas, dashboards con localizacion (entities con lat/lon), debugging de scrapers geograficos.
|
|
|
|
---
|
|
|
|
## Objetivo
|
|
|
|
Componente ImGui que renderiza un slippy map estilo Leaflet sobre OpenStreetMap tiles, con pan/zoom y soporte para markers + polylines.
|
|
|
|
## Contexto
|
|
|
|
Hay datos geograficos en varios proyectos (registry de proveedores, viajes, infrastructura). No hay forma de visualizarlos en C++; se exporta a una notebook con folium o se monta un frontend React.
|
|
|
|
## Arquitectura
|
|
|
|
```
|
|
cpp/functions/viz/
|
|
├── map_tiles.h # NEW
|
|
├── map_tiles.cpp # NEW
|
|
└── map_tiles.md # NEW (impure)
|
|
cpp/apps/primitives_gallery/
|
|
├── demos_map.cpp # NEW
|
|
├── demos.h # MOD
|
|
├── main.cpp # MOD
|
|
└── CMakeLists.txt # MOD
|
|
```
|
|
|
|
### API propuesta
|
|
|
|
```cpp
|
|
namespace fn {
|
|
|
|
struct MapMarker { double lat, lon; ImU32 color; const char* label; };
|
|
struct MapPolyline { std::vector<ImVec2> latlon; ImU32 color; float thickness = 2.f; }; // ImVec2 = (lat, lon)
|
|
struct MapState {
|
|
double lat = 40.4168; // Madrid default
|
|
double lon = -3.7038;
|
|
int zoom = 6; // 0..18
|
|
std::string tile_url = "https://tile.openstreetmap.org/{z}/{x}/{y}.png";
|
|
std::string user_agent = "fn-registry-map/0.1 (egutierrez@aurgi.com)";
|
|
bool show_attribution = true; // OSM atribucion obligatoria
|
|
};
|
|
|
|
void map_tiles(const char* id, MapState&,
|
|
const MapMarker* markers, int n_markers,
|
|
const MapPolyline* polylines, int n_polylines,
|
|
ImVec2 size = {-1, -1});
|
|
}
|
|
```
|
|
|
|
## Tareas
|
|
|
|
### Fase 1 — Tile cache
|
|
|
|
- 1.1 Cache en disco bajo `~/.cache/fn-registry/tiles/{z}/{x}/{y}.png`. Crear directorio si no existe.
|
|
- 1.2 Cache en RAM (LRU) de `GlTexture` ya subidas, max 256 entradas.
|
|
- 1.3 Funcion `tile_get_or_fetch(z, x, y)`: si en RAM → return; si en disco → load (gl_texture_load); si no → spawn thread que descarga via cpp-httplib y guarda en disco. Mientras tanto, devolver placeholder.
|
|
|
|
### Fase 2 — Proyeccion + interaction
|
|
|
|
- 2.1 Funciones puras `lonlat_to_xy(lat, lon, zoom) -> (px, py)` y `xy_to_lonlat`.
|
|
- 2.2 `map_tiles_handle_input`: drag pan, wheel zoom (clamp 0-18), mantener punto bajo cursor durante zoom.
|
|
|
|
### Fase 3 — Render
|
|
|
|
- 3.1 Calcular tiles visibles dado el viewport y zoom.
|
|
- 3.2 Para cada tile visible: `ImGui::Image(texture, screen_rect)` o `AddImage` en el DrawList.
|
|
- 3.3 Markers: `AddCircleFilled` + texto.
|
|
- 3.4 Polylines: convertir lat/lon a screen y `AddPolyline`.
|
|
- 3.5 Atribucion en esquina inferior derecha: `"© OpenStreetMap contributors"`.
|
|
|
|
### Fase 4 — User-Agent + ToS
|
|
|
|
- 4.1 Enviar `User-Agent` custom (OSM lo exige). Documentar en `.md` que el usuario debe poner su contacto.
|
|
- 4.2 Cap a 2 requests/segundo simultaneos para no abusar del tile server.
|
|
|
|
### Fase 5 — Gallery demo
|
|
|
|
- 5.1 `demos_map.cpp` con `demo_map_tiles()`: mapa centrado en Espana, 5 markers en ciudades, polyline conectandolas.
|
|
- 5.2 Registrar.
|
|
|
|
### Fase 6 — Tests + docs
|
|
|
|
- 6.1 Tests puros de proyeccion (Madrid → conocidos pixels a zoom 10).
|
|
- 6.2 `./fn index` + `./fn show map_tiles_cpp_viz`.
|
|
|
|
## Ejemplo de uso
|
|
|
|
```cpp
|
|
fn::MapState m;
|
|
fn::MapMarker markers[] = {
|
|
{40.4168, -3.7038, IM_COL32(255,80,80,255), "Madrid"},
|
|
{41.3851, 2.1734, IM_COL32(80,150,255,255), "Barcelona"},
|
|
};
|
|
fn::map_tiles("##m", m, markers, 2, nullptr, 0);
|
|
```
|
|
|
|
## Decisiones de diseño
|
|
|
|
- **OSM tile server por defecto**: gratis, sin API key. Documentar limite y alternativa (carto, stamen) cambiando `tile_url`.
|
|
- **Cache en `~/.cache/fn-registry/tiles/`**: respeta XDG; persistente entre runs.
|
|
- **Sin GeoJSON parsing en MVP**: solo markers/polylines via API. GeoJSON en issue futuro.
|
|
|
|
## Riesgos
|
|
|
|
- **Bloqueo de IP por OSM**: documentar terminos de uso (max 1 req/s recomendado, User-Agent unico).
|
|
- **Tiles a alta latitud**: documentar que la proyeccion Web Mercator distorsiona >85°.
|
|
- **Threading de descargas**: cuidado con marshalling de texturas GL (deben crearse en hilo con contexto). Patron: descargar PNG bytes en thread, crear GL texture en main thread.
|