|
| 1 | +--- |
| 2 | +title: "solverforge-maps 1.0: Routing Infrastructure for VRP Solvers" |
| 3 | +date: 2026-01-24 |
| 4 | +draft: false |
| 5 | +tags: [rust, release, maps, vrp] |
| 6 | +description: > |
| 7 | + solverforge-maps 1.0 provides zero-erasure road network and routing infrastructure for VRP solvers, with OSM data, R-tree indexing, and 3-tier caching. |
| 8 | +--- |
| 9 | + |
| 10 | +{{< alert title="Sidecar Release" color="info" >}} |
| 11 | +solverforge-maps is a standalone utility library that provides routing infrastructure for vehicle routing problems. It complements the main [SolverForge](/blog/releases/solverforge-0-5-0/) constraint solver but can be used independently with any VRP implementation. |
| 12 | +{{< /alert >}} |
| 13 | + |
| 14 | +We're releasing **solverforge-maps 1.0**, our Rust library for road network routing in vehicle routing problems. This library handles the map-related infrastructure that VRP solvers need: fetching road networks, computing travel time matrices, and generating route geometries. |
| 15 | + |
| 16 | +## What It Does |
| 17 | + |
| 18 | +solverforge-maps provides a simple workflow for VRP applications: |
| 19 | + |
| 20 | +```rust |
| 21 | +use solverforge_maps::{BoundingBox, Coord, RoadNetwork}; |
| 22 | + |
| 23 | +let locations = vec![ |
| 24 | + Coord::new(39.95, -75.16), |
| 25 | + Coord::new(39.96, -75.17), |
| 26 | + Coord::new(39.94, -75.15), |
| 27 | +]; |
| 28 | + |
| 29 | +let bbox = BoundingBox::from_coords(&locations).expand_for_routing(&locations); |
| 30 | +let network = RoadNetwork::load_or_fetch(&bbox, &Default::default(), None).await?; |
| 31 | +let matrix = network.compute_matrix(&locations, None).await; |
| 32 | +``` |
| 33 | + |
| 34 | +That's it. Load a road network for your delivery locations, compute the travel time matrix, feed it to your solver. |
| 35 | + |
| 36 | +## Key Features |
| 37 | + |
| 38 | +**Zero-Erasure Architecture**: Following the [SolverForge design philosophy](/blog/releases/solverforge-0-5-0/#zero-erasure-architecture), solverforge-maps uses no `Arc`, no `Box<dyn>`, and no trait objects in hot paths. The `NetworkRef` type provides zero-cost access to cached networks via `Deref`. |
| 39 | + |
| 40 | +**R-Tree Spatial Indexing**: Coordinate snapping to the road network runs in O(log n) via R-tree, making it practical to route thousands of delivery points. |
| 41 | + |
| 42 | +**3-Tier Caching**: Network data flows through in-memory cache, file cache, and Overpass API. Repeated requests for the same region are instant. Cache statistics are exposed for monitoring: |
| 43 | + |
| 44 | +```rust |
| 45 | +let stats = RoadNetwork::cache_stats().await; |
| 46 | +println!("Hits: {}, Misses: {}", stats.hits, stats.misses); |
| 47 | +``` |
| 48 | + |
| 49 | +**Dynamic Speed Profiles**: Travel times respect OSM `maxspeed` tags when available, falling back to sensible defaults by road type (motorway: 100 km/h, residential: 30 km/h, etc.). |
| 50 | + |
| 51 | +**Route Geometries**: Full road-following geometries for visualization, with Douglas-Peucker simplification and Google Polyline encoding for efficient transmission to frontends. |
| 52 | + |
| 53 | +**Graph Connectivity Analysis**: Debug routing failures with strongly connected component analysis: |
| 54 | + |
| 55 | +```rust |
| 56 | +let components = network.strongly_connected_components(); |
| 57 | +let largest_fraction = network.largest_component_fraction(); |
| 58 | +``` |
| 59 | + |
| 60 | +**Input Validation**: `Coord` and `BoundingBox` validate on construction with typed errors. No silent NaN propagation or out-of-range coordinates. |
| 61 | + |
| 62 | +## API Surface |
| 63 | + |
| 64 | +The public API consists of: |
| 65 | + |
| 66 | +| Type | Purpose | |
| 67 | +|------|---------| |
| 68 | +| `Coord` | Validated geographic coordinate | |
| 69 | +| `BoundingBox` | Validated rectangular region | |
| 70 | +| `RoadNetwork` | Core routing graph | |
| 71 | +| `NetworkRef` | Zero-cost cached network reference | |
| 72 | +| `TravelTimeMatrix` | N x N travel times with statistics | |
| 73 | +| `RouteResult` | Single route with geometry | |
| 74 | +| `RoutingProgress` | Progress updates for long operations | |
| 75 | + |
| 76 | +Error handling is explicit via `RoutingError` variants that distinguish snap failures, unreachable pairs, network errors, and invalid input. |
| 77 | + |
| 78 | +## Installation |
| 79 | + |
| 80 | +```toml |
| 81 | +[dependencies] |
| 82 | +solverforge-maps = "1.0" |
| 83 | +tokio = { version = "1", features = ["full"] } |
| 84 | +``` |
| 85 | + |
| 86 | +## Production Use |
| 87 | + |
| 88 | +We run solverforge-maps in production for the [Vehicle Routing Quickstart](https://github.com/solverforge/solverforge-quickstarts). It handles routing for real delivery optimization scenarios and has proven reliable for our use cases. |
| 89 | + |
| 90 | +The 1.0 version represents API stability. We don't anticipate breaking changes to the public interface. |
| 91 | + |
| 92 | +## Source |
| 93 | + |
| 94 | +- [GitHub Repository](https://github.com/solverforge/solverforge-maps) |
| 95 | +- [API Documentation](https://docs.rs/solverforge-maps) |
0 commit comments