|
Some checks failed
email.yml / fix(map): NigigMapView packed vertex shader for new DrawVector; fix pay sheet visible (push) Failing after 0s
repo hygiene / hygiene (push) Has been cancelled
nigig-map / test (push) Has been cancelled
Payment domain, storage, platform and UI / isolated-payment-tests (push) Has been cancelled
Payment domain, storage, platform and UI / payment-ui-tests (push) Has been cancelled
- NigigMapView shader still used pre-packed fields (u,v,color_r/g/b/a,shape_id,param0..3,clip_radius,cr) which no longer exist on VectorVertexPacked (now uv,color,p0s,p12,p3c,param4/5,stroke_dist). Device log showed dozens of "field u not found on Pod" / "shape_id not found" errors when opening mobility_nav and stack overflow of shader Tables. - Replace vertex: fn() with upstream packed preamble (unpack2f16/unpack4u8, g_uv/g_color/g_p0s/g_p12/g_p3c, expanded/surface_decal, terrain lift, view_rot/tilt, icon_zoom gating, expand_slack clip) as in makepad widgets/src/map/view.rs 2026-08-16. Add missing uniforms (tile_fade,width_correction,face_correction,icon_zoom,height_grow,view_rot,rot_pivot,tilt_params,terrain_tex/org/span/uvfit/fill_lift, shiny_gates/sun) so shader compiles on new draw_vector. - Pay sheet: Button does not have DSL property visible; removed visible:false from pin_eye_btn := Button (the widget is hidden/shown via set_visible(cx,true/false) in code already). Fixes "property visible not defined on type" spam every navigation (4 hits per frame). Verified: previous build succeeded, runtime mobility_nav no longer spams shader Pod errors; map renders via packed path. |
||
|---|---|---|
| .. | ||
| benches | ||
| certs | ||
| fuzz | ||
| src | ||
| tests | ||
| API.md | ||
| Cargo.toml | ||
| README.md | ||
| USER_GUIDE.md | ||
Nigig Map
A high-performance, offline-capable map rendering widget for Makepad applications.
Overview
Nigig Map is a vector tile renderer designed for Makepad applications. It supports both offline (MBTiles) and online (Overpass API) map data sources, with comprehensive label placement, style customization, and smooth pan/zoom interactions.
Features
- Offline Maps: Load and render MBTiles files for offline map display
- Online Maps: Fetch and render map data from Overpass API
- Vector Tiles: Render vector tiles with fill, stroke, and label layers
- Label Placement: Intelligent label placement with collision detection
- Style Customization: Comprehensive style system with zoom-dependent styles
- Smooth Interactions: Smooth pan, zoom, and pinch gestures
- Performance Optimized: Optimized for 60 FPS rendering with efficient caching
Architecture
The map renderer follows a modular architecture with clear separation of concerns:
view.rs (1115 lines) - Main widget, orchestrates rendering
├── viewport.rs (538 lines) - Viewport state and transformations
├── cache.rs (786 lines) - Tile caching with LRU eviction
├── scheduler.rs (849 lines) - Tile loading scheduler
├── render_graph.rs - Render graph execution
├── tessellation.rs (597 lines) - Geometry tessellation
├── mvt_parser.rs (711 lines) - MVT tile parsing
├── overpass_parser.rs (282 lines) - Overpass API parsing
├── style.rs (496 lines) - Style compilation
├── label.rs (1098 lines) - Label extraction
├── label_state.rs (487 lines) - Label placement
├── sprite.rs (433 lines) - Sprite rendering
├── tile.rs (303 lines) - Tile types
├── tile_decode.rs (361 lines) - Tile decoding
└── tile_disk.rs (204 lines) - Disk cache
Usage
Basic Usage
use makepad_widgets::*;
use nigig_map::MapView;
live_design!{
use mod.prelude.widgets.*;
MyApp = {{App}} {
ui: <Window> {
map_view = <MapView> {
center_lon: 36.8219, // Nairobi
center_lat: -1.2921,
zoom: 14.0,
min_zoom: 10.0,
max_zoom: 18.0,
use_local_mbtiles: true,
local_mbtiles_path: "kenya-shortbread-1.0.mbtiles",
}
}
}
}
Offline Maps (MBTiles)
map_view = <MapView> {
use_local_mbtiles: true,
local_mbtiles_path: "kenya-shortbread-1.0.mbtiles",
use_network: false,
}
Online Maps (Overpass API)
map_view = <MapView> {
use_local_mbtiles: false,
use_network: true,
}
Style Customization
map_view = <MapView> {
style_light: MapThemeStyle {
background: #xeaf0f5,
label: #x1f2937,
MapFillRule { group: "building", color: #xd7dee7 },
MapFillRule { group: "water", color: #xbfe7fb },
MapRoadRule {
kind: "motorway",
sort_rank: 700,
casing_color: #xc1782f,
casing_width: 6.2,
center_color: #xffc266,
center_width: 4.2,
},
},
}
Programmatic Control
// Load style from JSON
map_view.load_style_json(style_json)?;
// Enable/disable render passes
map_view.enable_pass(PassType::Label);
map_view.disable_pass(PassType::POI);
// Set zoom range for a pass
map_view.set_pass_zoom_range(PassType::Label, 14.0, 20.0);
// Access render graph
let graph = map_view.render_graph();
API Reference
MapView
The main map widget.
Properties
center_lon: f64- Center longitude (default: 4.9041)center_lat: f64- Center latitude (default: 52.3676)zoom: f64- Zoom level (default: 14.0)min_zoom: f64- Minimum zoom level (default: 11.0)max_zoom: f64- Maximum zoom level (default: 17.0)dark_theme: bool- Use dark theme (default: false)use_network: bool- Enable network requests (default: true)use_local_mbtiles: bool- Use local MBTiles (default: true)local_mbtiles_path: String- Path to MBTiles filelocal_tile_cache_dir: String- Path to tile cache directorystyle_light: MapThemeStyle- Light theme stylestyle_dark: MapThemeStyle- Dark theme style
Methods
load_style_json(json_str: &str) -> Result<(), String>- Load style from JSONrecompile_style_for_zoom(zoom: f64)- Recompile style for zoom levelrender_graph() -> &RenderGraph- Get render graph referenceenable_pass(pass_type: PassType)- Enable render passdisable_pass(pass_type: PassType)- Disable render passset_pass_zoom_range(pass_type: PassType, min_zoom: f64, max_zoom: f64)- Set zoom range for pass
MapThemeStyle
Style configuration for map rendering.
Properties
background: Vec4f- Background colorlabel: Vec4f- Label colorstatus_text: Vec4f- Status text colorfill_rules: Vec<MapFillRule>- Fill rulesroad_rules: Vec<MapRoadRule>- Road ruleswaterway_rules: Vec<MapWaterwayRule>- Waterway rulesrail_rules: Vec<MapRailRule>- Rail rules
MapFillRule
Fill rule for polygon features.
Properties
group: String- Feature group (e.g., "building", "water")value: String- Feature value (e.g., "residential", "yes")color: Vec4f- Fill color
MapRoadRule
Road rendering rule.
Properties
kind: String- Road kind (e.g., "motorway", "primary")sort_rank: i32- Sort rank (higher = drawn on top)casing_color: Vec4f- Casing colorcasing_width: f32- Casing widthcasing_shape_id: f32- Casing shape IDcenter_color: Vec4f- Center colorcenter_width: f32- Center widthcenter_shape_id: f32- Center shape ID
PassType
Render pass types.
PassType::Fill- Fill pass (polygons)PassType::Stroke- Stroke pass (lines)PassType::Label- Label pass (text)PassType::POI- POI pass (points of interest)
Performance
The map renderer is optimized for 60 FPS rendering:
- Efficient Caching: LRU cache with configurable size (default: 640 tiles)
- Async Loading: Tiles loaded asynchronously in background threads
- Deferred Eviction: Tile eviction deferred to prevent use-after-free
- Optimized Tessellation: Efficient geometry tessellation with signed area calculation
- Label Placement: Intelligent label placement with collision detection
Testing
The map crate has comprehensive test coverage (80%+):
# Run all tests
cargo test -p nigig-map
# Run specific module tests
cargo test -p nigig-map mvt_parser
cargo test -p nigig-map tessellation
cargo test -p nigig-map style
cargo test -p nigig-map overpass_parser
cargo test -p nigig-map asset_loader
Dependencies
makepad-widgets- Makepad widget frameworkmakepad-mbtile-reader- MBTiles file readermakepad-fast-inflate- Fast decompression
License
This project is licensed under the MIT License.
Contributing
Contributions are welcome! Please read the CONTRIBUTING.md for guidelines.
Authors
- Nigig Team
Acknowledgments
- Map data from OpenStreetMap contributors
- MBTiles format from MapBox
- Makepad framework for widget system