# CLAUDE Source: https://maps.solvice.io/CLAUDE # CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview This is the documentation website for Solvice Maps API, built with Mintlify. The project contains API documentation, integration examples, and usage guides for Solvice's routing and mapping services. ## Development Commands ```bash theme={null} # Install Mintlify CLI globally (required) npm i -g mintlify # Run local development server mintlify dev # Reinstall dependencies if needed mintlify install ``` ## Project Structure The documentation is organized by API service: * `/cube/` - Cube API (matrix routing) documentation * `/table/` - Table API (distance matrix) documentation * `/route/` - Route API (directions) documentation * `/tiles/` - Map tile service documentation * `/examples/` - Integration examples for Leaflet and MapLibre GL * `/snippets/` - Reusable documentation components ## Key Files * `docs.json` - Mintlify configuration defining navigation structure, theme, and API settings * `openapi.yaml` - OpenAPI 3.0.3 specification for the Solvice Maps Routing API * MDX files - Documentation content written in Markdown with JSX support ## Architecture Notes 1. **Documentation Framework**: Uses Mintlify which renders MDX files into a modern docs site 2. **API Documentation**: Powered by OpenAPI spec with interactive playground enabled 3. **No Build Process**: Mintlify handles all compilation; no webpack/vite config needed 4. **Navigation Structure**: Two main tabs defined in docs.json - "Routing" and "Tiles" ## Working with Documentation * All documentation files use MDX format (Markdown + JSX components) * Images go in `/images/` directory * API endpoint docs are auto-generated from `openapi.yaml` * Navigation structure is controlled by the `docs.json` file * Mintlify hot-reloads changes during development ## Git Workflow * Main branch is `main` * The project uses GitHub App for automatic deployment * Always check for uncommitted changes before starting work # Api services guide Source: https://maps.solvice.io/api-services-guide # Solvice Maps: API Services Guide ## API Architecture Overview Solvice Maps provides a comprehensive suite of RESTful APIs designed for high-performance routing, distance calculations, and geospatial analysis. The API architecture is built around three core service categories, each optimized for specific use cases and performance requirements. ## Base URL and Authentication **Production API Base URL:**\ `https://routing.solvice.io` **Staging API Base URL:**\ `https://mapr-gateway-staging-181354976021.europe-west1.run.app` **Authentication:** All API requests require authentication via API key in the header: ```http theme={null} X-API-Key: your-api-key-here Content-Type: application/json ``` ## Core API Services ### 1. Route API - Turn-by-Turn Directions **Purpose:** Generate detailed turn-by-turn directions with geometry between two or more points. #### Single Route Calculation **Endpoint:** `POST /route` **Request Body:** ```json theme={null} { "coordinates": [ [4.3517, 50.8503], // Brussels (longitude, latitude) [2.3522, 48.8566] // Paris ], "profile": "car", "options": { "steps": true, "geometries": "geojson", "overview": "full", "continue_straight": true } } ``` **Response:** ```json theme={null} { "routes": [ { "geometry": { "type": "LineString", "coordinates": [[4.3517, 50.8503], ...] }, "legs": [ { "distance": 264.1, "duration": 87.9, "steps": [ { "distance": 50.3, "duration": 12.1, "geometry": { "type": "LineString", "coordinates": [[4.3517, 50.8503], ...] }, "name": "Rue de la Loi", "maneuver": { "type": "turn", "modifier": "left", "location": [4.3517, 50.8503] } } ] } ], "distance": 264100, "duration": 8790, "weight": 8790 } ], "waypoints": [ { "hint": "...", "location": [4.3517, 50.8503], "name": "Rue de la Loi" } ] } ``` #### Batch Route Processing **Endpoint:** `POST /route/batch` **Request Body:** ```json theme={null} { "requests": [ { "coordinates": [[4.3517, 50.8503], [2.3522, 48.8566]], "profile": "car" }, { "coordinates": [[2.3522, 48.8566], [3.0686, 50.6365]], "profile": "car" } ], "options": { "steps": false, "geometries": "geojson" } } ``` **Response:** ```json theme={null} { "routes": [ { "success": true, "route": { "distance": 264100, "duration": 8790, "geometry": {...} } }, { "success": true, "route": { "distance": 123400, "duration": 5420, "geometry": {...} } } ] } ``` ### 2. Table API - Distance Matrix **Purpose:** Calculate travel times and distances between multiple origins and destinations. #### Synchronous Table (Real-time) **Endpoint:** `POST /table/sync` **Use Case:** Small matrices requiring immediate response (\< 1000 coordinate pairs) **Request Body:** ```json theme={null} { "sources": [ [4.3517, 50.8503], // Brussels [2.3522, 48.8566], // Paris [3.0686, 50.6365] // Lille ], "destinations": [ [1.0952, 49.4431], // Rouen [7.7521, 48.5734], // Strasbourg [5.3698, 43.2965] // Marseille ], "profile": "car", "annotations": ["duration", "distance"] } ``` **Response:** ```json theme={null} { "durations": [ [6420, 12300, 25200], // From Brussels [4320, 9840, 22680], // From Paris [5280, 11400, 24120] // From Lille ], "distances": [ [324000, 567000, 1032000], // From Brussels (meters) [256000, 487000, 923000], // From Paris [298000, 534000, 978000] // From Lille ], "sources": [ {"hint": "...", "location": [4.3517, 50.8503]}, {"hint": "...", "location": [2.3522, 48.8566]}, {"hint": "...", "location": [3.0686, 50.6365]} ], "destinations": [ {"hint": "...", "location": [1.0952, 49.4431]}, {"hint": "...", "location": [7.7521, 48.5734]}, {"hint": "...", "location": [5.3698, 43.2965]} ] } ``` #### Asynchronous Table (Large datasets) **Endpoint:** `POST /table` **Use Case:** Large matrices requiring background processing (> 1000 coordinate pairs) **Request Body:** ```json theme={null} { "sources": [...], // Array of up to 10,000 coordinates "destinations": [...], // Array of up to 10,000 coordinates "profile": "car", "annotations": ["duration", "distance"], "engine": "osm", "fallback_speed": 50.0 } ``` **Response:** ```json theme={null} { "id": "table_123456789", "status": "IN_PROGRESS", "created_at": "2024-01-15T10:30:00Z", "estimated_completion": "2024-01-15T10:35:00Z", "progress_url": "/table/123456789/progress", "result_url": "/table/123456789/response" } ``` #### Monitor Table Progress **Endpoint:** `GET /table/{id}/progress` **Response:** ```json theme={null} { "id": "table_123456789", "status": "IN_PROGRESS", "progress": { "completed_requests": 45, "total_requests": 100, "percentage": 45.0, "estimated_completion": "2024-01-15T10:33:00Z" }, "created_at": "2024-01-15T10:30:00Z", "updated_at": "2024-01-15T10:32:15Z" } ``` #### Retrieve Table Results **Endpoint:** `GET /table/{id}/response` **Response:** Same format as synchronous table response, but potentially much larger. **For very large responses (> 10MB):** **Endpoint:** `GET /table/{id}/response/signed-url` **Response:** ```json theme={null} { "signed_url": "https://storage.googleapis.com/mapr-results/table_123456789.json?X-Goog-Algorithm=...", "expires_at": "2024-01-15T11:30:00Z", "size_bytes": 52428800, "content_type": "application/json" } ``` ### 3. Cube API - Time-Dependent Travel Matrix **Purpose:** Generate travel time matrices across multiple time periods throughout the day. #### Create Cube Request **Endpoint:** `POST /cube` **Request Body:** ```json theme={null} { "sources": [ [4.3517, 50.8503], [2.3522, 48.8566] ], "destinations": [ [1.0952, 49.4431], [7.7521, 48.5734], [5.3698, 43.2965] ], "profile": "car", "time_slices": [ {"slice": 0, "time": "06:00"}, {"slice": 1, "time": "08:00"}, {"slice": 2, "time": "10:00"}, {"slice": 3, "time": "12:00"}, {"slice": 4, "time": "14:00"}, {"slice": 5, "time": "16:00"}, {"slice": 6, "time": "18:00"}, {"slice": 7, "time": "20:00"} ], "day_type": "weekday", "generate_polynomials": true } ``` **Response:** ```json theme={null} { "id": "cube_987654321", "status": "IN_PROGRESS", "created_at": "2024-01-15T10:30:00Z", "time_slices": 8, "sources_count": 2, "destinations_count": 3, "total_tables": 8, "estimated_completion": "2024-01-15T10:45:00Z", "progress_url": "/cube/987654321/progress", "result_url": "/cube/987654321/response" } ``` #### Monitor Cube Progress **Endpoint:** `GET /cube/{id}/progress` **Response:** ```json theme={null} { "id": "cube_987654321", "status": "IN_PROGRESS", "progress": { "completed_tables": 3, "total_tables": 8, "percentage": 37.5, "current_slice": 3, "estimated_completion": "2024-01-15T10:42:00Z" }, "table_progress": [ {"slice": 0, "status": "SUCCEEDED", "duration": 45.2}, {"slice": 1, "status": "SUCCEEDED", "duration": 52.1}, {"slice": 2, "status": "SUCCEEDED", "duration": 48.7}, {"slice": 3, "status": "IN_PROGRESS", "progress": 0.6}, {"slice": 4, "status": "PENDING"}, {"slice": 5, "status": "PENDING"}, {"slice": 6, "status": "PENDING"}, {"slice": 7, "status": "PENDING"} ] } ``` #### Retrieve Cube Results **Endpoint:** `GET /cube/{id}/response` **Response:** ```json theme={null} { "id": "cube_987654321", "status": "SUCCEEDED", "sources": [...], "destinations": [...], "time_slices": [ { "slice": 0, "time": "06:00", "durations": [ [6420, 12300, 25200], [4320, 9840, 22680] ], "distances": [ [324000, 567000, 1032000], [256000, 487000, 923000] ] }, // ... additional time slices ], "polynomials": { "duration_coefficients": [ [ // Polynomial coefficients for source 0 → destination 0 [6420, 1200, -300, 50], // a₀ + a₁t + a₂t² + a₃t³ // Coefficients for source 0 → destination 1 [12300, 2400, -600, 100], // ... more destinations ], // ... more sources ] }, "created_at": "2024-01-15T10:30:00Z", "completed_at": "2024-01-15T10:43:22Z", "processing_duration": 802.3 } ``` ## Advanced Features ### 1. Request Splitting and Optimization **Automatic Request Splitting:** The API automatically splits large requests that exceed routing engine limits: * **OSRM**: 1000 coordinates per request * **TomTom**: 1000 coordinates per request * **AnyMap**: 100 coordinates per request * **Google Maps**: 1000 coordinates per request **Split Strategy:** ```json theme={null} // Original request: 2000 sources × 1500 destinations = 3M combinations { "sources": [...], // 2000 coordinates "destinations": [...] // 1500 coordinates } // Automatically split into 6 child requests: // Child 1: 1000 sources × 1000 destinations // Child 2: 1000 sources × 500 destinations // Child 3: 1000 sources × 1000 destinations // Child 4: 1000 sources × 500 destinations // etc. ``` ### 2. Content-Based Caching **Cache Key Generation:** The system generates cache keys based on request content, enabling efficient deduplication: ```json theme={null} // These requests will use the same cached result: { "sources": [[4.3517, 50.8503], [2.3522, 48.8566]], "destinations": [[1.0952, 49.4431], [7.7521, 48.5734]], "profile": "car" } { "sources": [[2.3522, 48.8566], [4.3517, 50.8503]], // Different order "destinations": [[7.7521, 48.5734], [1.0952, 49.4431]], // Different order "profile": "car" } ``` **Cache Benefits:** * Immediate response for duplicate requests (\< 10ms) * 60-80% cache hit rate for typical workloads * Significant cost reduction for repeated calculations ### 3. Multi-Engine Support **Engine Selection:** ```json theme={null} { "sources": [...], "destinations": [...], "engine": "osm", // Explicitly specify engine "fallback_engine": "tomtom", // Fallback if primary fails "profile": "car" } ``` **Available Engines:** * **`osm`**: OpenStreetMap/OSRM (free, good coverage) * **`tomtom`**: TomTom API (commercial, real-time traffic) * **`anymap`**: AnyMap service (European focus) * **`google`**: Google Maps API (premium coverage) ### 4. Time-Dependent Routing **Traffic Slice Selection:** ```json theme={null} { "sources": [...], "destinations": [...], "profile": "car", "traffic_slice": 2.5, // Decimal slice (interpolated) "day_type": "weekday" // "weekday" or "weekend" } ``` **Traffic Slice Mapping:** ``` Slice 0: 06:00 (Early morning) Slice 1: 07:00 (Morning commute start) Slice 2: 08:00 (Peak morning traffic) Slice 3: 09:00 (Late morning) Slice 4: 10:00 (Mid-morning) Slice 5: 11:00 (Pre-lunch) Slice 6: 12:00 (Lunch hour) Slice 7: 13:00 (Post-lunch) Slice 8: 14:00 (Afternoon) Slice 9: 15:00 (Pre-evening) Slice 10: 16:00 (Evening commute start) Slice 11: 17:00 (Peak evening traffic) Slice 12: 18:00 (Late evening) ``` ## Error Handling ### Standard Error Response Format ```json theme={null} { "error": { "code": "INVALID_COORDINATES", "message": "One or more coordinates are invalid or unreachable", "details": { "invalid_coordinates": [ {"index": 5, "coordinate": [0.0, 0.0], "reason": "Ocean location"} ] }, "timestamp": "2024-01-15T10:30:00Z", "request_id": "req_123456789" } } ``` ### Common Error Codes **Authentication Errors:** * `INVALID_API_KEY`: API key is missing or invalid * `RATE_LIMIT_EXCEEDED`: Request rate limit exceeded * `QUOTA_EXCEEDED`: Monthly quota exceeded **Request Errors:** * `INVALID_REQUEST`: Malformed request body * `INVALID_COORDINATES`: Invalid coordinate format or unreachable locations * `REQUEST_TOO_LARGE`: Request exceeds maximum size limits * `INVALID_PROFILE`: Unsupported transportation profile **Processing Errors:** * `ROUTING_ENGINE_ERROR`: External routing engine failure * `TIMEOUT`: Request processing timeout * `INTERNAL_ERROR`: Unexpected server error **Resource Errors:** * `RESOURCE_NOT_FOUND`: Requested table/cube ID not found * `RESOURCE_EXPIRED`: Results have expired and been deleted ### Retry Logic **Recommended Retry Strategy:** ```python theme={null} import time import random def retry_with_backoff(func, max_retries=3): for attempt in range(max_retries): try: return func() except Exception as e: if attempt == max_retries - 1: raise e if e.status_code in [429, 502, 503, 504]: # Retriable errors backoff = (2 ** attempt) + random.uniform(0, 1) time.sleep(backoff) else: raise e # Don't retry client errors ``` ## Rate Limits and Quotas ### Request Rate Limits **Standard Limits:** * **Authenticated requests**: 1000 requests/minute * **Table requests**: 100 requests/minute * **Cube requests**: 10 requests/minute **Enterprise Limits:** * **Custom rate limits**: Configurable per customer * **Burst allowance**: Handle traffic spikes * **Priority queues**: Faster processing for enterprise customers ### Usage Quotas **Monthly Quotas:** * **Route calculations**: Unlimited for standard plans * **Table requests**: Based on coordinate combinations * **Storage**: 30-day retention for results **Quota Headers:** ```http theme={null} X-RateLimit-Limit: 1000 X-RateLimit-Remaining: 987 X-RateLimit-Reset: 1642251600 X-Quota-Limit: 1000000 X-Quota-Remaining: 876543 X-Quota-Reset: 1644843600 ``` ## Performance Optimization ### Request Optimization Tips 1. **Batch Similar Requests:** ```json theme={null} // Instead of multiple single requests POST /route (request 1) POST /route (request 2) // Use batch endpoint POST /route/batch (both requests) ``` 2. **Use Appropriate Endpoints:** * Small tables (\< 100 coords): Use `/table/sync` * Large tables (> 1000 coords): Use `/table` (async) * Time analysis: Use `/cube` for multiple time periods 3. **Leverage Caching:** ```json theme={null} // Order coordinates consistently for better cache hits { "sources": [[2.3522, 48.8566], [4.3517, 50.8503]], // Sorted "destinations": [[1.0952, 49.4431], [7.7521, 48.5734]] // Sorted } ``` 4. **Choose Optimal Engines:** * **Development/Testing**: Use `osm` (free) * **Production (Europe)**: Use `anymap` for best accuracy * **Global Coverage**: Use `google` or `tomtom` * **Real-time Traffic**: Use `tomtom` or `google` ### Response Size Optimization **Large Response Handling:** * Responses > 10MB automatically use signed URLs * Use compression for data transfer * Consider pagination for very large datasets **Selective Data Retrieval:** ```json theme={null} { "annotations": ["duration"], // Only duration, not distance "geometries": "false", // Skip geometry data "steps": false // Skip turn-by-turn steps } ``` ## SDK and Integration Examples ### JavaScript/Node.js ```javascript theme={null} const SolviceMaps = require('@solvice/maps-sdk'); const client = new SolviceMaps({ apiKey: 'your-api-key', baseURL: 'https://routing.solvice.io' }); // Simple route const route = await client.route.calculate({ coordinates: [[4.3517, 50.8503], [2.3522, 48.8566]], profile: 'car', steps: true }); // Distance matrix const table = await client.table.calculate({ sources: [[4.3517, 50.8503], [2.3522, 48.8566]], destinations: [[1.0952, 49.4431], [7.7521, 48.5734]], profile: 'car' }); // Async table with polling const largeTable = await client.table.calculateAsync({ sources: largeSourceArray, destinations: largeDestinationArray, profile: 'car' }); // Wait for completion const result = await client.table.waitForCompletion(largeTable.id, { pollInterval: 5000, // 5 seconds timeout: 300000 // 5 minutes }); ``` ### Python ```python theme={null} from solvice_maps import SolviceMapsClient client = SolviceMapsClient( api_key='your-api-key', base_url='https://routing.solvice.io' ) # Simple route route = client.route.calculate( coordinates=[[4.3517, 50.8503], [2.3522, 48.8566]], profile='car', steps=True ) # Distance matrix table = client.table.calculate( sources=[[4.3517, 50.8503], [2.3522, 48.8566]], destinations=[[1.0952, 49.4431], [7.7521, 48.5734]], profile='car' ) # Async table processing large_table = client.table.calculate_async( sources=large_source_array, destinations=large_destination_array, profile='car' ) # Poll for results result = client.table.wait_for_completion( large_table.id, poll_interval=5, timeout=300 ) ``` ### cURL Examples **Simple Route:** ```bash theme={null} curl -X POST https://routing.solvice.io/route \ -H "X-API-Key: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "coordinates": [[4.3517, 50.8503], [2.3522, 48.8566]], "profile": "car", "steps": true }' ``` **Distance Matrix:** ```bash theme={null} curl -X POST https://routing.solvice.io/table/sync \ -H "X-API-Key: your-api-key" \ -H "Content-Type: application/json" \ -d '{ "sources": [[4.3517, 50.8503], [2.3522, 48.8566]], "destinations": [[1.0952, 49.4431], [7.7521, 48.5734]], "profile": "car", "annotations": ["duration", "distance"] }' ``` **Check Progress:** ```bash theme={null} curl -X GET https://routing.solvice.io/table/123456789/progress \ -H "X-API-Key: your-api-key" ``` This comprehensive API guide provides all the technical details needed to effectively integrate with and utilize the Solvice Maps routing services. # Changelog Source: https://maps.solvice.io/changelog Powering route optimization systems with blazing fast distance matrix calculations ## Changelog ## Traffic Patterns on Real-time Routing ### New `includeTrafficPatterns` parameter `TOMTOM_REAL_TIME` requests now combine live traffic with TomTom **historical traffic patterns** by default. Patterns improve duration estimates outside peak hours and cover road segments that have no live traffic data. * Applies to `POST /route` and `POST /table/sync` with `"engine": "TOMTOM_REAL_TIME"`. * **Default: enabled.** To compute against live traffic only, set `"includeTrafficPatterns": false` on the request. * Duration estimates are additionally calibrated against observed drive times. ## Real-time Traffic Routing ### New `TOMTOM_REAL_TIME` Engine A new routing engine that reflects **live traffic conditions** at the moment of the request, powered by TomTom's real-time feed. * Available on `POST /route` and `POST /table/sync`. * `departureTime` is ignored — every request uses *now* as the departure time. * Not supported on `POST /route/batch` or the async `POST /table` (real-time matrices are sync-only and not cacheable). ### Usage Set `"engine": "TOMTOM_REAL_TIME"` on the request: ```json theme={null} { "coordinates": [ [4.35171, 50.85034], [4.40269, 50.83712], [4.44216, 50.63650] ], "sources": [0, 1], "annotations": ["duration"], "engine": "TOMTOM_REAL_TIME" } ``` ### Matrix Constraints (`/table/sync`) * `sources` is required and must be contiguous starting from `0`. * The result has shape `sources × (coordinates − sources)` — sources first, destinations next; no square padding. * `annotations` must not include `"distance"`; the real-time feed does not return distances. * The `destinations` filter field is not supported. * Billing is per actual destination count. See the [Route](/route/intro) and [Matrix](/table/intro) introductions for full examples. ## New Engines, Synchronous Cube & Road Exclusions ### New Routing Engines Support for additional routing engines beyond the default OSM-based engine: * **Google** — leverage Google's routing for comparison or production use * **Anymap** — Solvice's proprietary engine with advanced traffic modeling * **Custom** — bring your own engine via a custom integration ### Synchronous `/cube/sync` Endpoint A new synchronous cube endpoint for smaller, real-time cube requests — no polling required. Ideal for on-the-fly time-dependent matrix lookups. ### Road Type Exclusions Fine-grained control over which road types to avoid: * `toll` — avoid toll roads * `motorway` — avoid motorways / highways * `ferry` — avoid ferry crossings * `tunnel` — avoid tunnels * `bridge` — avoid bridges ### `departureTime` & `interpolate` Parameters Route and table endpoints now accept `departureTime` to incorporate time-dependent traffic data, and an `interpolate` flag for smooth linear interpolation between traffic time slices. ### Richer OpenAPI Metadata The OpenAPI specification has been updated with improved endpoint descriptions, contact information, and semantic tags for better discoverability and tooling support. ## Batch Route Processing & Performance Enhancements ### 🚀 New Batch Route Endpoint Introducing the new `/route/batch` endpoint for processing multiple route requests efficiently in a single API call. This enables: * Reduced API overhead for multiple route calculations * Optimized network usage and faster processing ### ⚡ Performance Breakthroughs Major performance improvements across all routing services: * **Sub-50ms response times** for simple route calculations * **Sub-quadratic scaling** for large distance matrices - up to 3,836 table cells processed per millisecond * **Production-grade reliability** with 99.9% uptime SLA ### 🔄 Advanced Traffic Interpolation Enhanced time-dependent routing with decimal slice support: * **Granular traffic modeling** using decimal slices (e.g., 2.5, 4.7) for smooth transitions * **Linear interpolation** between time periods for more accurate travel time predictions * **Simplified architecture** reduces processing complexity while improving accuracy ### Demo page Added a demo page to showcase the new features and performance improvements. ### 📊 Performance Scaling ```mermaid theme={null} %%{init: {'theme':'base', 'themeVariables': { 'primaryColor': '#0f62fe', 'primaryTextColor': '#000000', 'primaryBorderColor': '#0f62fe', 'lineColor': '#000000', 'secondaryColor': '#0f62fe', 'tertiaryColor': '#ffffff', 'background': 'transparent', 'mainBkg': 'transparent', 'secondaryBkg': 'transparent', 'cScale0': 'transparent', 'cScale1': 'transparent', 'cScale2': 'transparent', 'xyChart': {'backgroundColor': 'transparent', 'plotColorPalette': '#0f62fe, #0f62fe, #0f62fe'}}}}%% xychart-beta title "Table Operation Performance Scaling" x-axis ["10", "100", "1000"] y-axis "Throughput (cells/ms)" 0 --> 4000 bar [17, 1060, 3836] ``` *Performance demonstrates exceptional sub-quadratic scaling: as matrix size increases 100x, throughput increases 225x* ## Introducing the `/cube` endpoint We all know about distance matrices (our `/table` endpoint), but Route Optimization systems require multiple slices throughout the day. Ideally one for every 5 minutes in the day in order to get the travel time as granular and accurately as possible. However, if you would want to solve a 1000-jobs VRP request, you would need 288 matrices of 1000x1000 elements. That would be quite cumbersome to first calculate and then secondly hold in memory during the solve. That is why we are introducing a /cube endpoint to fetch the entire 3-D matrix or what we call cube. 288 slices is too much but what if we can approximate it with a function? A polynomial that reduces the necessary slices. Read more in the [`/cube` introduction](cube/intro) ## Predictive traffic integration Thanks to our partnership with TomTom, we can now provide predictive traffic information to our routing engine. ## Publicly launching Solvice Maps Solvice Maps is now publicly available since December 2024. We believe that it is one of the most powerful and fastest routing engines available. We're launching on OpenStreetMap data initially and will soon expand to other map data providers such as TomTom. Next to the routing engine, we also provide a tile server that can integrate with any map application and framework such as Leaflet, Mapbox GL JS, OpenLayers, etc.