Replimap SDK & API¶
Developer Documentation and Usage Guide¶
Main Sections¶
- 1. Introduction
- 2. Replimap SDK Capabilities Overview
- 3. Architecture and Usage Model
- 4. Installation and Integration
- 5. SDK Overview and Module Organization
- 6. Core SDK Concepts
- 7. Core SDK APIs
- 8. Geometry and Spatial APIs
- 9. Road and Lane APIs
- 10. Junction APIs
- 11. Objects, Signals, and Controllers APIs
- 12. Rail Network APIs
- 13. Validation APIs (XODR Validator)
- 14. HERE2ODR APIs
- 15. XODR Explorer APIs
- 16. Utilities and Mathematical Helper APIs
- 17. Asynchronous Operations
- 18. Error Handling and Diagnostics
- 19. Performance and Best Practices
- 20. Examples and Typical Workflows
- 21. Automation and Procedural Operations APIs
- 22. Versioning, Compatibility, and Support
- 23. Sample Maps APIs
1. Introduction¶
Replimap is a professional-grade HD map authoring, processing, and analysis platform designed to work with ASAM OpenDRIVE (XODR) maps. It provides comprehensive capabilities for creating, editing, validating, converting, and analyzing road networks at lane-level precision, supporting modern automotive, simulation, and mapping workflows.
The Replimap SDK exposes these capabilities as a native, in-process software development kit, while the Replimap API defines the stable, public interface through which applications interact with the underlying engine. Together, the SDK and API enable developers to integrate Replimap’s backend functionality directly into their own software stacks, without reliance on any specific user interface or rendering technology.
The SDK is designed to be:
- Deterministic and robust
- Suitable for interactive and headless usage
- Safe for integration into long-running applications
- Independent of UI frameworks and visualization layers
All rendering, editor tooling, and user interaction logic are intentionally kept outside the SDK and are expected to be implemented by the integrating application.
Purpose of This Document¶
This document serves as a combined SDK and API reference, providing both conceptual guidance and detailed technical documentation. It is intended to help developers understand:
- The overall scope and capabilities of Replimap
- How the SDK and API are structured and organized
- Which modules are available and how they relate to each other
- How to use the API to create, modify, validate, convert, and analyze OpenDRIVE maps
- How to work with long-running and asynchronous operations
- Best practices for safe, efficient, and predictable usage
This document is designed to be suitable for both day-to-day development and long-term integration planning.
Intended Audience¶
This documentation is intended for software engineers, SDK integrators, and technical users who wish to embed Replimap functionality into their own applications or pipelines. Readers are expected to have familiarity with:
- General software development concepts
- Backend or SDK-based integration
- Automotive mapping or simulation domains (recommended but not mandatory)
Prior knowledge of Replimap’s internal implementation is not required.
Scope and Non-Goals¶
The Replimap SDK and API focus exclusively on backend functionality, including data modeling, geometry processing, validation, and conversion. They do not include:
- User interface components
- Rendering or visualization systems
- Editor widgets, tools, or interaction logic
- Platform-specific UI frameworks
By keeping these concerns separate, the SDK ensures maximum flexibility, performance, and long-term maintainability across different client applications and environments.
2. Replimap SDK Capabilities Overview¶
Replimap provides a comprehensive set of backend capabilities for working with ASAM OpenDRIVE (XODR) maps across their entire lifecycle — from creation and editing, to validation, conversion, and deep inspection. The SDK and API are designed to support both interactive authoring tools and headless, automated workflows with the same level of precision and determinism.
At a high level, Replimap can be described as a lane-level road network engine with strong guarantees around structural correctness, geometric consistency, and repeatable results.
2.1 OpenDRIVE Map Authoring and Editing¶
The SDK exposes full programmatic control over OpenDRIVE map content, enabling applications to:
- Create and manage complete road networks
- Define and modify road plan-view geometry
- Model elevation, superelevation, and lateral profiles
- Create, edit, and organize lane sections and lanes
- Control lane widths, borders, offsets, and heights
- Define road connectivity and lane-level topology
- Create and manage junctions and their internal connections
All editing operations are designed to be deterministic and explicitly controlled through the API, making them suitable for both manual authoring tools and automated generation pipelines.
2.2 Lane-Level Topology and Connectivity¶
Replimap operates on a detailed lane-based topology model, allowing precise control and inspection of:
- Lane predecessor and successor relationships
- Cross-road lane connectivity
- Junction lane linking
- Road and lane ordering and normalization
- Connectivity graphs representing the navigable structure of the map
These capabilities enable advanced use cases such as routing analysis, consistency checks, and simulation-ready map preparation.
2.3 Roadside Objects, Signals, and Controllers¶
The SDK supports the creation and management of OpenDRIVE objects and traffic elements, including:
- Roadside objects such as guardrails, barriers, poles, trees, buildings, and obstacles
- Parametric and repeated objects
- Signals with detailed positioning and orientation
- Signal dependencies and validity ranges
- Traffic signal controllers and phase definitions
All objects and signals can be positioned relative to roads or lanes, with full access to their attributes and relationships.
2.4 Geometry, Coordinate Systems, and Spatial Queries¶
Replimap provides extensive geometric and spatial utilities, including:
- Support for multiple coordinate systems and geo-referencing
- Conversion between road-relative (s, t) and Cartesian (x, y, z) coordinates
- Sampling of road and lane geometry at arbitrary resolutions
- Projection of points onto road reference lines
- Queries for heading, curvature, elevation, and super-elevation
- Spatial filtering and bounding-box queries
These features enable precise geometric analysis and integration with external geospatial data sources.
2.5 Import, Export, and Data Conversion¶
The SDK supports robust data exchange workflows, including:
- Importing and exporting OpenDRIVE files
- Version-aware OpenDRIVE serialization
- Partial and subset-based export
- Batch import and export workflows
- Deterministic serialization suitable for automated pipelines
In addition to OpenDRIVE I/O, Replimap includes dedicated conversion capabilities through the HERE2ODR module (described later in this document).
2.6 HERE2ODR Conversion¶
The HERE2ODR module enables the creation of OpenDRIVE maps from HERE data sources. Supported workflows include:
- Conversion of HERE tiles within a bounding box or GeoJSON polygon
- Conversion based on explicit HERE tile identifiers
- Processing of encoded HERE HD map data
- Route-based conversion using HERE Routing APIs
- Path-matching conversion, where only roads corresponding to a given path are converted
These workflows allow users to generate OpenDRIVE maps that are immediately ready for editing, validation, or simulation.
2.7 Validation and Quality Assurance¶
Replimap includes a dedicated XODR validation module that supports:
- Structural validation against ASAM OpenDRIVE rules
- Custom and extended validation rules
- Full-map and partial-map validation
- Detailed validation reports with severity levels
- Location-aware error reporting
Validation can be used interactively during editing or as part of automated quality assurance pipelines.
2.8 XODR Exploration and Analysis¶
The XODR Explorer module allows deep inspection and analysis of OpenDRIVE maps, providing:
- Access to full road, lane, and junction graphs
- Queries over connectivity and relationships
- Attribute-based and geometry-based filtering
- Graph traversal and reachability analysis
- Controlled modification of inspected map elements
This module is particularly useful for debugging, auditing, and advanced analysis tasks.
2.9 Headless and Automated Workflows¶
All Replimap capabilities are available without any dependency on a user interface. The SDK is suitable for:
- Command-line tools
- Batch processing pipelines
- CI/CD validation workflows
- Automated map generation and conversion
Long-running operations are exposed through asynchronous APIs to ensure non-blocking integration.
Summary¶
Together, these capabilities position Replimap as a full-featured OpenDRIVE backend engine, capable of supporting a wide range of authoring, conversion, validation, and analysis use cases. The following sections of this document describe how these capabilities are exposed through the SDK and API, and how they can be used effectively in client applications.
3. Architecture and Usage Model¶
This section describes how the Replimap SDK and API are designed to be used within client applications. It focuses on practical usage expectations rather than internal implementation details.
3.1 In-Process SDK Model¶
Replimap is delivered as a native, in-process SDK. The SDK is linked directly into the host application and executes within the same process space. This design enables:
- High-performance access to complex map data structures
- Efficient manipulation of large road and lane graphs
- Low-latency interactive editing workflows
- Simple integration into desktop and backend applications
The SDK exposes a well-defined public API that serves as the only supported interaction point with the underlying engine. All access to map data and processing functionality must occur through this API.
3.2 Session-Based Usage¶
All operations in the Replimap SDK are performed within the context of an explicit session.
A session represents: - A single working context - One or more loaded or created maps - The lifetime boundary for allocated resources
Typical usage follows this pattern: 1. Create a session 2. Load or create a map 3. Perform editing, querying, validation, or conversion operations 4. Save or export results 5. Close the session
Sessions provide isolation, predictable resource management, and clear ownership of map state.
3.3 Deterministic and Controlled Execution¶
The SDK is designed to be deterministic. Given the same inputs and execution order, the API produces the same outputs and results.
Key characteristics include: - No hidden background modifications - No implicit state changes - Explicit control over all mutating operations - Predictable serialization and validation results
This behavior is critical for reproducible workflows, automated pipelines, and long-running integrations.
3.4 Command and Query Separation¶
The Replimap API follows a clear separation between commands and queries:
-
Commands modify map state
Examples include creating roads, editing geometry, adding lanes, or modifying connectivity. -
Queries retrieve information without modifying state
Examples include geometry sampling, connectivity inspection, attribute access, and spatial queries.
This separation improves: - API clarity - Predictability of side effects - Reasoning about performance - Safe integration into complex applications
Commands and queries are grouped consistently across SDK modules.
3.5 Error Handling Model¶
The SDK uses an explicit, structured error handling model.
Key principles: - Public API methods do not expose raw exceptions - All recoverable failures are reported through structured result objects - Errors include clear codes, messages, and context - Callers are expected to handle errors explicitly
This approach improves stability in long-running applications and avoids unexpected termination due to unhandled failures.
3.6 Threading and Concurrency Expectations¶
Unless explicitly stated otherwise: - SDK API calls are expected to be invoked from a controlled execution context - Concurrent access to the same session or map must be managed by the caller - Queries are designed to be side-effect free - Commands must not be executed concurrently on the same mutable map state
Long-running or blocking operations are exposed through asynchronous APIs, described later in this document.
3.7 Asynchronous Operations Overview¶
Certain operations, such as validation and data conversion, may require significant processing time or external I/O. These operations are exposed as asynchronous jobs.
Asynchronous APIs are designed to: - Avoid blocking the calling thread - Provide progress reporting - Support cancellation - Return structured results upon completion
The detailed usage of asynchronous APIs is covered in a dedicated section later in this document.
Summary¶
The Replimap SDK and API are designed around a clear, predictable usage model: an in-process, session-based engine with deterministic behavior, explicit error handling, and a strong separation between state-modifying commands and read-only queries. This model enables reliable integration into both interactive tools and automated processing pipelines.
4. Installation and Integration¶
This section describes how to install and integrate the Replimap SDK and API into a .NET-based application. The SDK is implemented in C# and is designed to be consumed directly by .NET projects as a native, in-process library.
4.1 Supported Platforms¶
The Replimap SDK supports the following environments:
- .NET 6.0 or later (recommended)
- .NET Framework (version as specified per release)
- Windows desktop applications
- Backend and headless .NET services
- Unity-based applications (when targeting a compatible .NET runtime)
Platform-specific requirements, if any, are documented in the release notes for each SDK version.
4.2 SDK Package Contents¶
The SDK is distributed as a set of managed assemblies and related resources, typically including:
- Core SDK assemblies (
Replimap.*.dll) - Optional module assemblies (e.g., HERE2ODR, Validator, Explorer)
- Supporting configuration files
- License and version metadata
Each assembly exposes a clearly defined public API and is versioned consistently across the SDK.
4.3 Installation Methods¶
Option 1: Direct DLL Reference (Recommended for Controlled Environments)¶
This approach is suitable for desktop applications, internal tools, and environments with strict dependency control.
Steps:
1. Copy the provided SDK .dll files into a directory within your project or solution.
2. In your .NET project, add references to the required assemblies.
3. Ensure all dependent assemblies are available at runtime.
This method provides full control over SDK versions and is well-suited for long-term integrations.
Option 2: NuGet Package (If Provided)¶
If the SDK is distributed via a NuGet package:
- Add the package source (if private).
- Install the required Replimap packages via NuGet.
- Restore dependencies as part of your build process.
NuGet-based distribution simplifies updates and dependency management but may be optional depending on deployment requirements.
4.4 Referencing the SDK in a .NET Project¶
After adding the SDK assemblies to your project, reference the primary namespaces exposed by the SDK.
Typical usage begins by importing the core namespaces:
using Replimap.Core;
using Replimap.Geometry;
using Replimap.Roads;
using Replimap.Validation;
using Replimap.Here2Odr;
using Replimap.Explorer;
Note: Only the modules required for a given application need to be referenced.
4.5 Initializing the SDK¶
Integration typically begins by creating a session that represents the working context for all subsequent operations.
A minimal initialization flow is as follows:
var session = ReplimapSession.Create();
var map = session.CreateMap();
// or
var map = session.LoadMap("example.xodr");
The session manages the lifetime of maps and internal resources. Applications are expected to explicitly close or dispose of sessions when they are no longer needed.
4.6 API Access Model¶
The Replimap SDK exposes all functionality through session-scoped module APIs.
APIs are not static, nor are they created independently. Instead, a session acts as the single access point to all SDK modules.
A session:
- Owns all API instances
- Defines their lifetime
- Ensures deterministic and isolated execution
All API surfaces are exposed as properties of the session and are valid only while the session is active.
API Acquisition Pattern¶
The following pattern is used consistently across the SDK and is assumed by all examples in this document:
var session = ReplimapSession.Create();
// Core editing APIs
var roadApi = session.Roads;
var geometryApi = session.Geometry;
var junctionApi = session.Junctions;
// Objects and traffic elements
var objectApi = session.Objects;
var signalApi = session.Signals;
var controllerApi = session.Controllers;
// Utilities and analysis
var utilitiesApi = session.Utilities;
var validatorApi = session.Validator;
var explorerApi = session.Explorer;
// Conversion
var here2odrApi = session.Here2Odr;
Notes¶
- All APIs are session-scoped.
- APIs must not be used after the session is disposed.
- Handles returned by APIs are valid only within the owning session.
This model avoids global state, enables deterministic behavior, and supports both interactive and headless workflows.
Active Map Selection¶
For convenience, SDK APIs that do not take a MapHandle operate on the session’s active map.
For multi-map workflows, most map-mutating commands also provide overloads that accept a MapHandle (for example, CreateRoad(MapHandle, ...)). These overloads let you target a specific map without changing the session’s active map.
Important Usage Guidance
When developing applications that use multiple maps, involve modular architectures, perform background processing, or use long-lived sessions, it is strongly recommended to use API variants that explicitly accept a
MapHandle.Relying on the session’s active map is intended primarily for simple scripts, code examples, or interactive tools. In production systems or complex/multi-map workflows, avoid depending on the active map to ensure clear and predictable map targeting.
Active map rules:
- CreateMap() and LoadMap(...) set the newly created/loaded map as active.
- You can switch the active map explicitly using SetActiveMap(...).
- Use GetActiveMap() to inspect the current active map.
Example: switching the active map
var session = ReplimapSession.Create();
var mapA = session.CreateMap().Value;
var mapB = session.LoadMap("city.xodr").Value;
// LoadMap makes mapB active; switch back to mapA
session.SetActiveMap(mapA);
var road = session.Roads.CreateRoad("R_Main", RoadRule.RightHandTraffic).Value;
❌ Anti-pattern: Relying on the session’s active map across multiple classes or modules, as changes to the active map are global to the session and can lead to unintended edits.
4.7 Quick Start | Hello World Example¶
This section provides a minimal, complete example that demonstrates how to:
- Create a session
- Create a map
- Create a road
- Add basic geometry
- Save the map to an OpenDRIVE file
This example assumes the SDK is already installed (see Section 4.3).
Step 1: Create a New Console Application¶
Create a new C# console application and add the required SDK references.
Step 2: Complete Example¶
// Program.cs
using System;
using Replimap.Core;
using Replimap.Roads;
using Replimap.Geometry;
namespace ReplimapHelloWorld
{
class Program
{
static void Main(string[] args)
{
// Create a session
using var session = ReplimapSession.Create();
// Access required APIs
var roadApi = session.Roads;
var geometryApi = session.Geometry;
// Create a new map
var mapResult = session.CreateMap();
if (!mapResult.IsSuccess)
{
Console.WriteLine($"Failed to create map: {mapResult.Error}");
return;
}
var map = mapResult.Value;
// Create a road
var roadResult = roadApi.CreateRoad(
map,
"R1",
RoadRule.RightHandTraffic
);
// Note: Passing MapHandle explicitly is the recommended pattern
if (!roadResult.IsSuccess)
{
Console.WriteLine($"Failed to create road: {roadResult.Error}");
return;
}
var road = roadResult.Value;
// Add a simple line geometry to the road
var geometryResult = geometryApi.AddLineGeometry(
road,
length: 100.0
);
if (!geometryResult.IsSuccess)
{
Console.WriteLine($"Failed to add geometry: {geometryResult.Error}");
return;
}
// Save the map
var saveResult = session.SaveMap(map, "hello_world.xodr");
if (!saveResult.IsSuccess)
{
Console.WriteLine($"Failed to save map: {saveResult.Error}");
return;
}
Console.WriteLine("Hello World map created successfully!");
}
}
}
Expected Result¶
A file named hello_world.xodr is created in the application directory.
The map contains:
- One road
- A single straight geometry segment
No errors are produced if the SDK is correctly installed and configured.
Notes¶
- All APIs are accessed via the session (see Section 4.6).
- Error handling uses the
Result<T>pattern consistently across the SDK. - This example represents the smallest valid OpenDRIVE map that can be authored using Replimap.
4.8 Error Handling Example¶
All Replimap SDK APIs return structured Result or Result<T> objects.
Applications are expected to explicitly inspect results and handle failures in a controlled manner.
The following example demonstrates how to access detailed error information when an operation fails.
Example: Handling and Inspecting Errors
var roadResult = roadApi.CreateRoad(map, "R1", RoadRule.RightHandTraffic);
if (!roadResult.IsSuccess)
{
var error = roadResult.Error;
Console.WriteLine("Operation failed");
Console.WriteLine($"Error Code : {error.ErrorCode}");
Console.WriteLine($"Category : {error.Category}");
Console.WriteLine($"Severity : {error.Severity}");
Console.WriteLine($"Message : {error.Message}");
// Optional contextual information
if (error.Context != null)
Console.WriteLine($"Context : {error.Context}");
return;
}
Handling Specific Error Codes
Applications may handle specific error conditions explicitly by inspecting the error code.
if (!roadResult.IsSuccess)
{
switch (roadResult.Error.ErrorCode)
{
case ErrorCode.DuplicateRoadId:
Console.WriteLine("A road with this ID already exists.");
break;
case ErrorCode.InvalidRoadRule:
Console.WriteLine("The specified road rule is not valid.");
break;
default:
Console.WriteLine($"Unhandled error: {roadResult.Error.Message}");
break;
}
}
Notes - Public APIs do not throw raw exceptions under normal operation. - All recoverable failures are reported via structured error objects. - Error codes are stable and documented in Section 17.12 – Common Error Codes Reference. - This pattern applies uniformly to synchronous and asynchronous APIs.
4.9 Managing External Credentials¶
Certain modules, such as HERE2ODR, require external credentials (e.g., HERE API keys).
Credential handling is designed to be explicit and controlled by the integrating application. Typical patterns include:
- Passing credentials via configuration objects
- Loading credentials from environment variables
- Using secure storage mechanisms provided by the host system
Important: Credentials are never embedded directly into the SDK and are not persisted unless explicitly configured by the application.
4.10 Build and Deployment Considerations¶
When deploying an application that uses the Replimap SDK:
- Ensure all required SDK assemblies are included in the output directory
- Verify that the target .NET runtime version matches the SDK requirements
- Include any native or data dependencies referenced by optional modules
- Validate licensing and credential availability in the target environment
For headless or batch applications, no additional UI or rendering dependencies are required.
4.11 Version Compatibility¶
Each SDK release is versioned and designed to be consumed as a coherent set of assemblies. Mixing assemblies from different SDK versions is not supported.
Compatibility guarantees, deprecation policies, and upgrade guidance are described in the Versioning, Compatibility, and Support section of this document.
5. SDK Overview and Module Organization¶
The Replimap SDK is organized into a set of clearly defined modules, each responsible for a specific aspect of OpenDRIVE map authoring, processing, conversion, or analysis. This modular structure allows applications to integrate only the functionality they require, while maintaining a consistent and predictable API surface across the SDK.
At a high level, the SDK is composed of a core layer that manages sessions and maps, along with a collection of functional modules that operate on map data through well-defined APIs.
5.1 Core Module¶
The Core module provides the foundational building blocks required to work with the SDK. All other modules depend on this layer.
Responsibilities include: - Session creation and lifecycle management - Map creation, loading, and saving - Map metadata access and modification - Global configuration and execution context - Common result and error types used across the SDK
The Core module is always required and serves as the primary entry point into the SDK.
5.2 Geometry and Spatial Module¶
The Geometry module provides APIs for defining, modifying, and querying geometric data associated with roads and lanes.
Key responsibilities: - Road plan-view geometry (lines, arcs, spirals, parametric curves) - Elevation profiles - Superelevation and lateral shapes - Coordinate system conversions - Sampling and projection utilities - Spatial and distance-based queries
This module underpins most authoring and analysis workflows and is used extensively by higher-level modules.
5.3 Roads and Lanes Module¶
The Roads and Lanes module exposes APIs for creating and managing the structural elements of an OpenDRIVE map.
Responsibilities include: - Road creation, deletion, and modification - Lane section management - Lane creation, removal, and reindexing - Lane widths, borders, offsets, and heights - Road and lane connectivity - Topology consistency utilities
This module represents the core OpenDRIVE data model and is central to most SDK usage scenarios.
5.4 Junctions Module¶
The Junctions module focuses on modeling complex connectivity between roads.
Responsibilities include: - Junction creation and deletion - Road-to-junction associations - Lane-to-lane connections within junctions - Contact point management - Junction consistency and integrity checks - Automatic junction generation and repair utilities
This module is typically used in conjunction with the Roads and Lanes module when building connected road networks.
5.5 Objects, Signals, and Controllers Module¶
This module provides APIs for managing roadside and traffic-related elements defined in OpenDRIVE.
Responsibilities include: - Roadside objects (e.g., guardrails, barriers, poles, trees, buildings) - Parametric and repeated objects - Traffic signals and signal dependencies - Signal controllers and phase definitions - Object and signal placement relative to roads and lanes
These APIs allow detailed modeling of the environment and traffic infrastructure associated with a road network.
5.6 Validation Module (XODR Validator)¶
The Validation module exposes APIs for validating OpenDRIVE maps against structural and semantic rules.
Responsibilities include: - Validation against ASAM OpenDRIVE specifications - Execution of custom validation rules - Full-map and partial-map validation - Generation of structured validation reports - Severity classification and error localization
Validation can be invoked interactively during authoring or as part of automated quality assurance workflows.
5.7 HERE2ODR Conversion Module¶
The HERE2ODR module provides APIs for converting HERE map data into OpenDRIVE format.
Responsibilities include: - Downloading HERE tiles using bounding boxes or GeoJSON polygons - Tile-based conversion using explicit tile identifiers - Processing encoded HERE HD map data - Route-based conversion using HERE Routing APIs - Path-matching conversion for selective road extraction - Conversion configuration and credential handling
This module is typically used for map generation and data ingestion workflows.
5.8 XODR Explorer Module¶
The XODR Explorer module provides advanced inspection and analysis capabilities for OpenDRIVE maps.
Responsibilities include: - Loading and parsing OpenDRIVE data - Exploring road, lane, and junction graphs - Connectivity and relationship queries - Attribute-based and geometry-based filtering - Controlled modification of inspected map elements
This module is particularly useful for debugging, auditing, and analytical applications.
5.9 Utilities and Shared Components¶
In addition to the primary modules, the SDK includes shared utility components that support common tasks, such as:
- Progress reporting
- Asynchronous job management
- Diagnostics and logging
- Batch operation helpers
These components are used internally by multiple modules and may also be exposed where appropriate.
Summary¶
The modular organization of the Replimap SDK allows developers to reason about functionality at a high level while providing fine-grained control over specific aspects of OpenDRIVE map processing. Subsequent sections of this document describe each module’s API in detail, along with usage patterns and examples.
6. Core SDK Concepts¶
This section introduces the key concepts required to use the Replimap SDK and API correctly and efficiently. These concepts apply consistently across all modules.
6.1 Sessions¶
A session represents the primary execution context for all SDK operations. Every interaction with the Replimap SDK occurs within a session.
Key characteristics: - A session owns all loaded and created maps - A session defines the lifetime of allocated resources - Sessions provide isolation between independent workflows
Note: A session may own multiple maps simultaneously.
Applications are encouraged to passMapHandleexplicitly to APIs when working with more than one map.
Typical usage: 1. Create a session 2. Perform operations on one or more maps 3. Close or dispose the session when finished
Applications should explicitly manage session lifetimes to ensure predictable resource usage.
6.2 Maps¶
A map represents an in-memory OpenDRIVE data model. Maps can be created from scratch or loaded from existing XODR files.
Maps are: - Fully mutable through command APIs - Queryable through read-only APIs - Owned by a session - Explicitly saved or exported by the caller
The SDK does not perform implicit saving or background modification of map data.
6.3 Handles and Object References¶
The SDK uses handles or lightweight references to identify and operate on map elements such as roads, lanes, junctions, objects, and signals.
Key principles: - Handles uniquely identify elements within a map - Handles remain valid as long as the referenced element exists - Direct access to internal data structures is not exposed
This approach ensures API stability and prevents accidental corruption of internal state.
6.4 Command-Based Operations¶
Commands are API methods that modify map state.
Examples include: - Creating or deleting roads - Editing geometry or lane attributes - Modifying connectivity - Adding or removing objects or signals
Commands are: - Explicit - Deterministic - Executed in the order invoked - Expected to be error-checked by the caller
Applications should group related commands when performing complex edits to improve clarity and performance.
6.5 Query-Based Operations¶
Queries are API methods that retrieve information without modifying map state.
Examples include: - Geometry sampling - Connectivity inspection - Attribute queries - Spatial and graph-based searches
Queries are: - Side-effect free - Safe to call repeatedly - Suitable for inspection, analysis, and visualization logic
6.6 Result-Based API Pattern¶
All public API methods return structured result objects rather than throwing raw exceptions.
A result typically contains: - A success or failure indicator - A return value (for successful operations) - An error object (for failed operations)
This pattern ensures: - Predictable error handling - Safe integration into long-running applications - Clear separation between control flow and error reporting
Callers are expected to check results explicitly and handle failures appropriately.
6.7 Error Categories and Recoverability¶
Errors reported by the SDK are categorized to help applications determine appropriate responses.
Common categories include: - Invalid input or configuration - Structural or consistency violations - Unsupported operations - External dependency failures - Internal execution errors
Most errors are recoverable, allowing applications to continue operating after handling the failure. Fatal conditions are explicitly documented where applicable.
6.8 Deterministic Behavior Guarantees¶
The SDK is designed to be deterministic.
This means: - Identical inputs produce identical outputs - Operations do not rely on hidden state or randomness - Serialization and validation results are repeatable
Determinism is essential for testing, automation, and large-scale production workflows.
Summary¶
Understanding these core concepts—sessions, maps, handles, command and query separation, and result-based error handling—is essential for effective use of the Replimap SDK and API. The following sections build on these concepts to describe the individual modules and their APIs in detail.
7. Core SDK APIs¶
This section introduces the core APIs that form the entry point to the Replimap SDK. These APIs are required for initializing the SDK, managing sessions, loading and saving maps, and accessing global map-level information. All other modules build upon these core APIs.
7.1 Session APIs¶
Sessions represent the primary execution context for all SDK operations. A session must be created before any map or processing API can be used.
CreateSession¶
Creates a new SDK session.
Description
Initializes a new execution context and allocates internal resources required by the SDK.
Typical Usage
var session = ReplimapSession.Create();
Notes¶
- A session is required for all subsequent operations.
- Multiple sessions may exist simultaneously, but must be managed explicitly by the application.
CloseSession / Dispose¶
Releases all resources associated with a session.
Description
Terminates the session and invalidates all maps and handles owned by it.
Typical Usage
session.Dispose();
Notes - Applications should always close sessions explicitly. - Using a disposed session results in an error response.
7.2 Map Creation and Loading APIs¶
Maps represent in-memory OpenDRIVE data models that can be created from scratch or loaded from existing files.
CreateMap¶
Creates a new empty map within the session.
Signature
Result<MapHandle> CreateMap();
Example
var result = session.CreateMap();
if (!result.IsSuccess)
{
HandleError(result.Error);
}
var map = result.Value;
LoadMap¶
Loads an OpenDRIVE map from a file.
Signature
Result<MapHandle> LoadMap(string filePath);
Example
var mapResult = session.LoadMap("example.xodr");
if (!mapResult.IsSuccess)
{
HandleError(mapResult.Error);
}
var map = mapResult.Value;
Notes - The SDK does not modify the source file during loading. - Structural validation is not automatically performed unless explicitly requested.
LoadMapFromString / LoadMapFromStream¶
Loads an OpenDRIVE map from a string or stream.
Use Cases - Integration with network-based data sources - In-memory processing pipelines - Testing and automation workflows
7.3 Map Saving and Export APIs¶
Saving and exporting maps is an explicit operation controlled by the application.
SaveMap¶
Saves a map to an OpenDRIVE file.
Signature
Result SaveMap(MapHandle map, string filePath);
Example
var saveResult = session.SaveMap(map, "output.xodr");
if (!saveResult.IsSuccess)
{
HandleError(saveResult.Error);
}
ExportMap¶
Exports a map to an OpenDRIVE file with configurable export options, enabling the map to be transformed to suit a particular OpenDRIVE version, downstream toolchain, or consumer.
Export operations may adapt and filter map content to satisfy target constraints while ensuring structural correctness is preserved.
ExportMap is typically used for: - Simulator and toolchain integration - Batch processing, automation pipelines - Producing reduced or specialized map variants
Signature
Result ExportMap(
MapHandle map,
string filePath,
ExportOptions options
);
ExportOptions control export behavior, such as: - Target OpenDRIVE version (e.g., 1.6) - Toolchain/consumer profile - Feature inclusion/exclusion (objects, signals, controllers, etc.) - Formatting and serialization preferences
Public Types¶
struct ExportOptions
{
// Target OpenDRIVE version for export
OpenDriveVersion TargetOpenDriveVersion;
// Optional toolchain / consumer hint
ExportToolchain TargetToolchain;
// Feature inclusion flags
bool IncludeRoads; // default: true
bool IncludeLanes; // default: true
bool IncludeJunctions; // default: true
bool IncludeObjects; // default: true
bool IncludeSignals; // default: true
bool IncludeControllers; // default: true
// Serialization / formatting options
ExportFormatting Formatting;
// Predefined default configuration
static ExportOptions Default;
}
enum OpenDriveVersion
{
V1_6
// Future versions added here
}
enum ExportToolchain
{
Generic,
Simulator,
Validator,
Custom
}
struct ExportFormatting
{
bool DeterministicOutput;
int NumericPrecision;
}
Usage Examples
Example 1: Export using default options
var exportResult = session.ExportMap(
map,
"export_default.xodr",
ExportOptions.Default
);
if (!exportResult.IsSuccess)
{
HandleError(exportResult.Error);
}
Example 2: Export targeting OpenDRIVE 1.6
var options = new ExportOptions
{
TargetOpenDriveVersion = OpenDriveVersion.V1_6
};
session.ExportMap(
map,
"export_odr16.xodr",
options
);
Example 3: Export without objects and signals
var options = new ExportOptions
{
TargetOpenDriveVersion = OpenDriveVersion.V1_6,
IncludeObjects = false,
IncludeSignals = false,
IncludeControllers = false
};
session.ExportMap(
map,
"export_geometry_only.xodr",
options
);
Notes - Export does not modify the in-memory map. - Unsupported options for a target version or toolchain result in an explicit error. - Additional OpenDRIVE versions and export filters may be added in future SDK releases.
7.4 Map Metadata APIs¶
Metadata APIs provide access to high-level information about a map.
GetMapMetadata¶
Retrieves metadata associated with a map.
Examples of Metadata - OpenDRIVE version - Geo-reference information - Map bounds - User-defined attributes
Example
var metadataResult = session.GetMapMetadata(map);
if (metadataResult.IsSuccess)
{
var metadata = metadataResult.Value;
}
UpdateMapMetadata¶
Updates map-level metadata fields.
Notes - Metadata updates do not modify geometric or topological content. - Changes are reflected in exported OpenDRIVE files.
7.5 Map Lifecycle Utilities¶
These APIs assist with managing map state during editing workflows.
CloneMap¶
Creates a deep copy of a map.
Use Cases - Branching workflows - Undo/redo systems - Scenario experimentation
ClearMap¶
Removes all content from a map while preserving the map instance.
SetActiveMap¶
Sets the active map for the session. All map-modifying APIs that do not take a MapHandle operate on this map.
Signature
Result SetActiveMap(MapHandle map);
Example
var mapA = session.CreateMap().Value;
var mapB = session.LoadMap("city.xodr").Value;
// Switch active map to mapA before editing
session.SetActiveMap(mapA);
GetActiveMap¶
Returns the current active map for the session.
Signature
Result<MapHandle> GetActiveMap();
Example
var activeMap = session.GetActiveMap().Value;
7.6 Error Handling in Core APIs¶
All core APIs return structured result objects.
General Pattern
var result = SomeApiCall();
if (!result.IsSuccess)
{
Log(result.Error);
return;
}
Common Error Scenarios - Invalid input parameters - File I/O failures - Unsupported OpenDRIVE versions - Session or map lifecycle violations
Errors are reported explicitly and do not cause application termination.
Summary¶
The Core SDK APIs provide the foundation for all interactions with the Replimap SDK. By creating and managing sessions, loading and saving maps, and accessing map-level metadata, applications establish the context in which all authoring, validation, conversion, and analysis workflows operate.
Subsequent sections describe the APIs exposed by individual functional modules in greater detail.
8. Geometry and Spatial APIs¶
The Geometry and Spatial APIs provide low-level control over the geometric foundations of an OpenDRIVE map. These APIs are used to define, modify, and query road reference lines, elevation profiles, superelevation, lateral shapes, and spatial relationships.
All geometry APIs operate on existing map elements and follow the command/query separation model described earlier.
8.1 Overview¶
This module is responsible for:
- Road plan-view geometry
- Elevation and vertical alignment
- Superelevation and lateral deformation
- Coordinate transformations
- Geometry sampling and spatial queries
These APIs are foundational and are heavily used by higher-level modules such as Roads, Lanes, Junctions, Objects, and Validation.
8.2 Public Types¶
enum GeometryType
{
Line,
Arc,
Spiral,
Poly3,
ParamPoly3
}
struct GeometryHandle { }
struct ElevationHandle { }
struct SuperelevationHandle { }
struct LateralShapeHandle { }
struct SRange
{
double SStart;
double SEnd;
}
struct Vector2
{
double X; // X-coordinate in map space
double Y; // Y-coordinate in map space
}
struct XYCoordinate
{
double X; // X-coordinate in map space
double Y; // Y-coordinate in map space
}
struct PointAndHeading
{
Vector2 Point; // Position on the road reference line
double Heading; // Tangent direction at this point (radians)
}
struct RoadProjection
{
double S; // Longitudinal position along the road reference line
double T; // Lateral offset from the reference line
Vector2 ProjectedPoint; // Closest point on the road reference line
double Distance; // Euclidean distance from the original point
}
struct LaneProjection
{
double S; // Longitudinal position along the lane
double T; // Lateral offset relative to the lane center or border
Vector2 ProjectedPoint; // Closest point within the lane
double Distance; // Euclidean distance from the original point
bool IsInsideLane; // True if the projected point lies within lane boundaries
}
struct BoundingBox
{
Vector2 Min; // Lower-left corner of the bounding box
Vector2 Max; // Upper-right corner of the bounding box
}
8.3 PlanView Geometry APIs¶
Commands¶
AddGeometrySegment
Adds a geometry segment to a road’s plan view.
Signature
Result<GeometryHandle> AddGeometrySegment(
RoadHandle road,
GeometryType type,
GeometryParameters parameters
);
Example
var result = geometryApi.AddGeometrySegment(
road,
GeometryType.Line,
new LineGeometryParameters { Length = 50.0 }
);
if (!result.IsSuccess)
{
Log(result.Error);
}
InsertGeometrySegment
Inserts a geometry segment at a specific s position.
Result<GeometryHandle> InsertGeometrySegment(
RoadHandle road,
double sPosition,
GeometryType type,
GeometryParameters parameters
);
UpdateGeometrySegment
Updates parameters of an existing geometry segment.
Result UpdateGeometrySegment(
GeometryHandle geometry,
GeometryParameters newParameters
);
RemoveGeometrySegment
Removes a geometry segment.
Result RemoveGeometrySegment(GeometryHandle geometry);
TrimGeometry
Trims road geometry to a specified range.
Result TrimGeometry(
RoadHandle road,
SRange range
);
SplitRoadGeometry
Splits a road into two roads at a specified longitudinal position.
Result<(RoadHandle FirstRoad, RoadHandle SecondRoad)> SplitRoadGeometry(
RoadHandle road,
double sSplit
);
Queries¶
GetGeometrySegments
Result<IReadOnlyList<GeometryHandle>> GetGeometrySegments(
RoadHandle road
);
GetGeometryAtS
Returns the geometry segment active at s.
Result<GeometryHandle> GetGeometryAtS(
RoadHandle road,
double s
);
GetRoadLength
Result<double> GetRoadLength(RoadHandle road);
SamplePlanView
Samples plan-view geometry at s.
Result<PlanViewSample> SamplePlanView(
RoadHandle road,
double s
);
GetPoint
Returns the Cartesian position on the road reference line at a given s.
Result<Vector2> GetPoint(
RoadHandle road,
double s
);
sis measured along the road reference line- The returned point is in the map’s Cartesian coordinate system
GetHeading
Returns the heading (orientation) of the road reference line at a given s.
Result<double> GetHeading(
RoadHandle road,
double s
);
- Heading is returned in radians
- Measured relative to the map’s coordinate frame
GetPointAndHeading
Returns both position and heading at a given s.
Result<PointAndHeading> GetPointAndHeading(
RoadHandle road,
double s
);
- This is a convenience API equivalent to calling
GetPointandGetHeadingat the sames.
GetPointsOnLength
Samples multiple points along the road reference line over a given length.
Result<IReadOnlyList<Vector2>> GetPointsOnLength(
RoadHandle road,
double sStart,
double length,
double step
);
- Sampling begins at
sStart - Points are generated at intervals of
step
Useful for: - Visualization - Trajectory generation - Collision checks - Geometry inspection
8.4 Elevation Profile APIs¶
Commands¶
AddElevationSegment
Result<ElevationHandle> AddElevationSegment(
RoadHandle road,
double sStart,
ElevationPolynomial polynomial
);
UpdateElevationSegment
Result UpdateElevationSegment(
ElevationHandle elevation,
ElevationPolynomial polynomial
);
RemoveElevationSegment
Result RemoveElevationSegment(ElevationHandle elevation);
Queries¶
GetElevationAtS
Result<double> GetElevationAtS(
RoadHandle road,
double s
);
GetSlopeAtS
Result<double> GetSlopeAtS(
RoadHandle road,
double s
);
8.5 Superelevation APIs¶
Commands¶
AddSuperelevationSegment
Result<SuperelevationHandle> AddSuperelevationSegment(
RoadHandle road,
double sStart,
SuperelevationPolynomial polynomial
);
RemoveSuperelevationSegment
Result RemoveSuperelevationSegment(
SuperelevationHandle superelevation
);
Queries¶
GetSuperelevationAtS
Result<double> GetSuperelevationAtS(
RoadHandle road,
double s
);
8.6 Lateral Shape APIs¶
Commands¶
AddLateralShape
Result<LateralShapeHandle> AddLateralShape(
RoadHandle road,
double sStart,
LateralShapePolynomial polynomial
);
RemoveShape
Removes a previously defined lateral elevation shape from the road.
Result RemoveShape(
RoadHandle road,
double sOffset
);
Queries¶
EvaluateLateralShape
Result<double> EvaluateLateralShape(
RoadHandle road,
double s,
double t
);
8.7 Coordinate Transformation APIs¶
Queries¶
ConvertXYToST
Result<STCoordinate> ConvertXYToST(
RoadHandle road,
double x,
double y
);
ConvertSTToXY
Result<XYCoordinate> ConvertSTToXY(
RoadHandle road,
double s,
double t
);
ConvertToGeographic
Result<GeoCoordinate> ConvertToGeographic(
double x,
double y,
double z
);
8.8 Spatial Queries and Sampling¶
Queries¶
FindNearestRoad
Result<RoadHandle> FindNearestRoad(
double x,
double y
);
FindNearestLane
Result<LaneHandle> FindNearestLane(
double x,
double y
);
GetMapBoundingBox
Result<BoundingBox> GetMapBoundingBox();
DistanceToRoad
Computes the shortest distance from a point to a road reference line.
Result<double> DistanceToRoad(
RoadHandle road,
Vector2 point
);
DistanceToLane
Computes the shortest distance from a point to a lane surface.
Result<double> DistanceToLane(
LaneHandle lane,
Vector2 point
);
- Used for lane assignment and validation
ProjectPointToRoad
Projects a point onto the road reference line.
Result<RoadProjection> ProjectPointToRoad(
RoadHandle road,
Vector2 point
);
s
- Lateral offset t
- Projected Cartesian point
ProjectPointToLane
Projects a point onto a lane surface.
Result<LaneProjection> ProjectPointToLane(
LaneHandle lane,
Vector2 point
);
FindRoadIntersections
Finds all geometric intersections between two roads.
Result<IReadOnlyList<Vector2>> FindRoadIntersections(
RoadHandle roadA,
RoadHandle roadB
);
RoadsIntersect
Checks whether two roads geometrically intersect.
Result<bool> RoadsIntersect(
RoadHandle roadA,
RoadHandle roadB
);
GetRoadBoundingBox
Returns the axis-aligned bounding box of a road.
Result<BoundingBox> GetRoadBoundingBox(
RoadHandle road
);
CalculateAngleBetweenRoads
Computes the angle between two roads at their closest intersection or approach.
Result<double> CalculateAngleBetweenRoads(
RoadHandle roadA,
RoadHandle roadB
);
Notes
- All methods are pure and deterministic
- No geometry or topology is modified
- Errors are returned if:
- Handles are invalid
- Geometry is undefined
- Roads do not intersect where required
8.9 Geometry Validation Utilities¶
Commands¶
ValidateGeometryContinuity
Result ValidateGeometryContinuity(
RoadHandle road
);
Queries¶
GetGeometryDiscontinuities
Result<IReadOnlyList<double>> GetGeometryDiscontinuities(
RoadHandle road
);
8.10 Usage Example¶
var road = roadApi.CreateRoad(map, "R1").Value;
geometryApi.AddGeometrySegment(
road,
GeometryType.Line,
new LineGeometryParameters { Length = 100.0 }
);
geometryApi.AddElevationSegment(
road,
0.0,
new ElevationPolynomial { A = 0, B = 0, C = 0, D = 0 }
);
var elevation = geometryApi.GetElevationAtS(road, 50.0);
Summary¶
The Geometry and Spatial APIs provide full control over the geometric definition and evaluation of OpenDRIVE maps. These APIs are fundamental to all authoring, conversion, validation, and analysis workflows supported by the Replimap SDK.
9. Road and Lane APIs¶
The Road and Lane APIs provide full control over the structural and topological elements of an OpenDRIVE map. These APIs are responsible for creating and modifying roads, lane sections, lanes, lane attributes, and lane-level connectivity.
Roads are created as topological entities. Geometry and spatial properties are defined separately using Geometry APIs. This separation allows geometry to be modified, replaced, or analyzed without altering road identity or connectivity.
Together with the Geometry APIs, this module forms the core of OpenDRIVE authoring and editing workflows.
9.1 Overview¶
This module enables applications to:
- Create and manage roads
- Define lane sections along roads
- Add, remove, and modify lanes
- Control lane widths, borders, offsets, and heights
- Define predecessor and successor relationships
- Build and inspect lane-level topology
All operations follow deterministic, command-based execution with explicit error handling.
9.2 Public Types¶
Handle Types¶
struct RoadHandle { }
struct LaneSectionHandle { }
struct LaneHandle { }
Road Structure and Topology¶
enum RoadRule
{
RightHandTraffic,
LeftHandTraffic
}
enum LaneSide
{
Left,
Center,
Right
}
enum LaneType
{
Driving,
Shoulder,
Sidewalk,
Border,
Median,
Parking,
Restricted,
None
}
Lane Border Geometry¶
struct BorderPolynomial
{
double a; // constant term
double b; // linear term
double c; // quadratic term
double d; // cubic term
}
struct LaneBorder
{
double sOffset;
BorderPolynomial polynomial;
}
// Semantics: The lateral position of the lane border at a given s is computed as:
// t(s) = a + b·Δs + c·Δs² + d·Δs³
// where Δs = s - sOffset
Lane Markings¶
enum LaneMarkingType
{
Solid,
Broken,
SolidSolid,
BrokenBroken,
SolidBroken,
BrokenSolid,
Curb,
None
}
enum LaneMarkingColor
{
White,
Yellow,
Red,
Blue,
Green,
Other
}
enum LaneMarkingMaterial
{
Standard,
Reflective,
BottsDots,
Grass,
Curb
}
enum LaneMarkingSide
{
Left,
Right,
Center
}
// Lane Marking Definition
struct LaneMarking
{
double SOffset; // Start position along lane/road
LaneMarkingSide Side; // Left / Right / Center
LaneMarkingType Type;
LaneMarkingColor Color;
LaneMarkingMaterial Material;
double Width; // In meters
}
Road Type Segmentation¶
enum RoadType
{
Unknown,
Urban,
Rural,
Motorway,
Highway,
Expressway,
Residential,
Service,
Ramp,
SlipRoad,
Roundabout,
Connector
}
// Road Type Segment Definition
struct RoadTypeSegment
{
double SStart; // Start position along the road reference line
RoadType Type; // Road functional classification
}
Speed Properties¶
enum SpeedUnit
{
MetersPerSecond,
KilometersPerHour,
MilesPerHour
}
// Speed Value Definition
struct SpeedValue
{
double Value; // Numeric speed value
SpeedUnit Unit; // Unit of the speed value
}
// Speed Segment Definition
struct SpeedSegment
{
double SStart; // Start position along the road or lane
SpeedValue Speed; // Speed value with unit
}
Lane Material¶
enum LaneMaterialType
{
Unknown,
Asphalt,
Concrete,
Cobblestone,
Gravel,
Dirt,
Grass,
Sand,
Snow,
Ice,
PavedShoulder,
UnpavedShoulder
}
// Lane Material Segment Definition
struct LaneMaterialSegment
{
double SStart; // Start position along the road or lane
LaneMaterialType Material; // Surface material type
}
Tram Usage¶
enum TramUsageType
{
None, // Lane does not support tram traffic
Shared, // Tram shares lane with road vehicles
Exclusive // Tram-only lane
}
struct TramLaneSegment
{
double SStart; // Start position along the lane
TramUsageType Usage; // Tram usage mode
}
9.3 Road APIs¶
Commands¶
CreateRoad
Creates a new road and adds it to the map.
Result<RoadHandle> CreateRoad(
string roadId,
RoadRule rule
);
Result<RoadHandle> CreateRoad(
MapHandle map,
string roadId,
RoadRule rule
);
- DuplicateRoadId
- InvalidRoadRule
Example
// Target a specific map without changing the active map -- Recommended!
var roadInMapB = roadApi.CreateRoad(mapB, "R2", RoadRule.RightHandTraffic).Value;
// or use the currently active map:
var roadResult = roadApi.CreateRoad("R1", RoadRule.RightHandTraffic);
var road = roadResult.Value;
DeleteRoad
Result DeleteRoad(RoadHandle road);
RenameRoad
Result RenameRoad(
RoadHandle road,
string newRoadId
);
ReverseRoadDirection
Reverses the reference line direction and updates dependent data.
Result ReverseRoadDirection(RoadHandle road);
SplitRoad
Splits a road at a given s position.
Result<IReadOnlyList<RoadHandle>> SplitRoad(
RoadHandle road,
double sSplit
);
MergeRoads
Merges two compatible roads into one.
Result<RoadHandle> MergeRoads(
RoadHandle first,
RoadHandle second
);
Queries¶
GetRoadById
Result<RoadHandle> GetRoadById(string roadId);
GetAllRoads
Result<IReadOnlyList<RoadHandle>> GetAllRoads();
GetRoadRule
Result<RoadRule> GetRoadRule(RoadHandle road);
9.4 Road Type APIs¶
Road Type APIs provide control over the functional classification of roads.
Road types describe the intended usage and driving context of a road segment and are used by downstream consumers such as simulators, validators, and export pipelines.
Road Types: - Are defined at the road level - May vary along the road using s-based segments - Do not affect geometry or topology - May influence defaults, validation rules, and export behavior
Commands¶
AddRoadTypeSegment
Adds a road type segment starting at segment.SStart.
Result AddRoadTypeSegment(
RoadHandle road,
RoadTypeSegment segment
);
// Adds a road type segment starting at segment.SStart
// Multiple segments may exist on the same road
UpdateRoadTypeSegment
Updates an existing road type segment identified by SStart.
Result UpdateRoadTypeSegment(
RoadHandle road,
RoadTypeSegment segment
);
// Updates an existing road type segment identified by SStart
RemoveRoadTypeSegment
Removes the road type segment that starts at sStart.
Result RemoveRoadTypeSegment(
RoadHandle road,
double sStart
);
// Removes the road type segment that starts at sStart
ClearRoadTypeSegments
Removes all road type segments from the road.
Result ClearRoadTypeSegments(
RoadHandle road
);
// Removes all road type segments from the road
Queries¶
GetRoadTypeSegments
Returns all road type segments defined on the road, ordered by SStart.
Result<IReadOnlyList<RoadTypeSegment>> GetRoadTypeSegments(
RoadHandle road
);
// Returns all road type segments defined on the road
// Segments are ordered by SStart
GetRoadTypeAtS
Returns the road type active at longitudinal position s.
If no segment exists, RoadType.Unknown is returned.
Result<RoadType> GetRoadTypeAtS(
RoadHandle road,
double s
);
// Returns the road type active at longitudinal position s
// If no segment exists, RoadType.Unknown is returned
Error Handling¶
Road Type APIs return structured errors in the following cases: - Invalid road handle - Invalid s-position (negative or outside road length) - Overlapping or duplicate road type segments - Attempting to update or remove a non-existent segment
All errors are reported using the standard Result / Result<T> pattern and do not modify road geometry or connectivity.
9.5 Lane Section APIs¶
Commands¶
AddLaneSection
Adds a lane section starting at s.
Result<LaneSectionHandle> AddLaneSection(
RoadHandle road,
double sStart
);
RemoveLaneSection
Result RemoveLaneSection(
LaneSectionHandle laneSection
);
SplitLaneSection
Result<IReadOnlyList<LaneSectionHandle>> SplitLaneSection(
LaneSectionHandle laneSection,
double sSplit
);
Queries¶
GetLaneSections
Result<IReadOnlyList<LaneSectionHandle>> GetLaneSections(
RoadHandle road
);
GetLaneSectionAtS
Result<LaneSectionHandle> GetLaneSectionAtS(
RoadHandle road,
double s
);
9.6 Lane APIs¶
Commands¶
AddLane
Adds a lane to a lane section.
Result<LaneHandle> AddLane(
LaneSectionHandle laneSection,
LaneSide side,
int laneId,
LaneType type
);
RemoveLane
Result RemoveLane(LaneHandle lane);
Note: Only outer-most lanes may be removed. Attempting to remove a center lane or an inner lane results in an error. [LaneNotRemovable]
ChangeLaneType
Result ChangeLaneType(
LaneHandle lane,
LaneType newType
);
ChangeLaneId
Result ChangeLaneId(
LaneHandle lane,
int newLaneId
);
ReverseLaneDirection
Result ReverseLaneDirection(LaneHandle lane);
Queries¶
GetLanes
Result<IReadOnlyList<LaneHandle>> GetLanes(
LaneSectionHandle laneSection
);
GetLaneType
Result<LaneType> GetLaneType(LaneHandle lane);
ContainsLane
Checks whether a lane with the specified identifier exists in a lane section.
bool ContainsLane(
LaneSectionHandle laneSection,
int laneId
);
true if the lane exists
- Does not modify map state
GetLaneCount
Returns the number of lanes in a lane section.
int GetLaneCount(
LaneSectionHandle laneSection
);
AddBorder
Adds or updates a lateral border definition for a lane.
Result AddBorder(
LaneHandle lane,
LaneBorder border
);
This API is typically used to: - Define lane widths - Modify lane boundaries independently of road geometry
RemoveBorder
Removes an existing border definition from a lane.
Result RemoveBorder(
LaneHandle lane
);
GetBorder
Retrieves the border definition associated with a lane.
Result<LaneBorder> GetBorder(
LaneHandle lane
);
9.7 Lane Width APIs¶
Commands¶
AddLaneWidthSegment
Result AddLaneWidthSegment(
LaneHandle lane,
double sOffset,
WidthPolynomial polynomial
);
UpdateLaneWidthSegment
Result UpdateLaneWidthSegment(
LaneHandle lane,
int segmentIndex,
WidthPolynomial polynomial
);
RemoveLaneWidthSegment
Result RemoveLaneWidthSegment(
LaneHandle lane,
int segmentIndex
);
Queries¶
GetLaneWidthAtS
Result<double> GetLaneWidthAtS(
LaneHandle lane,
double s
);
9.8 Lane Offset and Height APIs¶
Commands¶
AddLaneOffsetSegment
Result AddLaneOffsetSegment(
RoadHandle road,
double sStart,
OffsetPolynomial polynomial
);
AddLaneHeightSegment
Result AddLaneHeightSegment(
LaneHandle lane,
double sStart,
HeightPolynomial polynomial
);
Queries¶
GetLaneOffsetAtS
Result<double> GetLaneOffsetAtS(
RoadHandle road,
double s
);
GetLaneHeightAtS
Result<double> GetLaneHeightAtS(
LaneHandle lane,
double s
);
9.9 Lane Connectivity APIs¶
Commands¶
SetLanePredecessor
Result SetLanePredecessor(
LaneHandle lane,
LaneHandle predecessor
);
SetLaneSuccessor
Result SetLaneSuccessor(
LaneHandle lane,
LaneHandle successor
);
RemoveLaneLinks
Result RemoveLaneLinks(LaneHandle lane);
Queries¶
GetLanePredecessor
Result<LaneHandle> GetLanePredecessor(LaneHandle lane);
GetLaneSuccessor
Result<LaneHandle> GetLaneSuccessor(LaneHandle lane);
GetLaneConnectivityGraph
Result<LaneConnectivityGraph> GetLaneConnectivityGraph();
9.10 Lane Marking APIs¶
Lane marking APIs provide programmatic control over lane boundary markings and road-wide default markings. Lane markings define the visual and semantic separation between lanes and are essential for simulation, validation, and downstream consumer compatibility.
Lane markings may be defined at two levels:
- Lane-level markings – Explicit markings applied directly to a specific lane
- Road-level default markings – Fallback markings applied when a lane does not define its own marking
Lane-level markings always take precedence over road-level defaults.
All lane marking operations are deterministic and do not modify road geometry.
Lane-Level Lane Markings¶
Lane-level lane markings define markings on the left, right, or center boundaries of a specific lane. These markings are scoped to the owning lane and override any road-level default markings.
Commands
AddLaneMarking¶
Result AddLaneMarking(
LaneHandle lane,
LaneMarking marking
);
// Adds a lane marking definition to the specified lane
// The marking is applied starting at marking.SOffset
// Overrides any road-level default marking for the same side
UpdateLaneMarking¶
Result UpdateLaneMarking(
LaneHandle lane,
LaneMarking updatedMarking
);
// Updates an existing lane marking on the lane
// The marking is identified by side and sOffset
RemoveLaneMarking¶
Result RemoveLaneMarking(
LaneHandle lane,
double sOffset,
LaneMarkingSide side
);
// Removes the lane marking defined at the given sOffset and side
Queries
GetLaneMarkings¶
Result<IReadOnlyList<LaneMarking>> GetLaneMarkings(
LaneHandle lane
);
// Returns all lane markings explicitly defined on the lane
GetLaneMarkingAtS¶
Result<LaneMarking> GetLaneMarkingAtS(
LaneHandle lane,
double s,
LaneMarkingSide side
);
// Returns the lane marking active at position s for the given side
// Only considers lane-level markings
Road-Level Default Lane Markings¶
Road-level default lane markings define fallback markings that apply to all lanes of a road when a lane does not explicitly define its own marking.
These markings are typically used to:
- Define consistent markings across an entire road
- Reduce duplication when multiple lanes share the same marking behavior
- Establish defaults that may be selectively overridden per lane
Commands
Result SetRoadDefaultLaneMarking(
RoadHandle road,
LaneMarking marking
);
// Sets or replaces a default lane marking for the road
// Applies to all lanes unless overridden at lane level
Result RemoveRoadDefaultLaneMarking(
RoadHandle road,
LaneMarkingSide side
);
// Removes the road-level default marking for the specified side
Queries
Result<IReadOnlyList<LaneMarking>> GetRoadDefaultLaneMarkings(
RoadHandle road
);
// Returns all default lane markings defined for the road
Effective Lane Marking Resolution¶
To simplify inspection and downstream usage, the SDK provides a resolved query that applies precedence rules automatically.
Lane-level markings take priority over road-level defaults.
Query
Result<LaneMarking> GetEffectiveLaneMarkingAtS(
LaneHandle lane,
double s,
LaneMarkingSide side
);
// Returns the effective lane marking at position s
// Resolution order:
// 1. Lane-level marking
// 2. Road-level default marking
9.11 Speed Limit APIs¶
Speed Limit APIs provide control over road-level and lane-level speed limits. Speed limits define the maximum allowed speed for vehicles and are used by simulators, routing systems, validation workflows, and export pipelines.
Speed limits: - May be defined at both road and lane level - May vary along the road or lane using s-based segments - Are semantic attributes and do not affect geometry or topology - Support multiple units without implicit conversion - Lane-level speed limits always take precedence over road-level speed limits.
Road-Level Speed Limits¶
Road-level speed limits define default speed limits for all lanes of a road unless explicitly overridden by lane-level definitions.
Commands
AddRoadSpeedSegment¶
Result AddRoadSpeedSegment(
RoadHandle road,
SpeedSegment segment
);
// Adds a road-level speed limit starting at segment.SStart
UpdateRoadSpeedSegment¶
Result UpdateRoadSpeedSegment(
RoadHandle road,
SpeedSegment segment
);
// Updates an existing road-level speed segment identified by SStart
RemoveRoadSpeedSegment¶
Result RemoveRoadSpeedSegment(
RoadHandle road,
double sStart
);
// Removes the road-level speed segment that starts at sStart
ClearRoadSpeedSegments¶
Result ClearRoadSpeedSegments(
RoadHandle road
);
// Removes all road-level speed segments from the road
Queries
GetRoadSpeedSegments¶
Result<IReadOnlyList<SpeedSegment>> GetRoadSpeedSegments(
RoadHandle road
);
// Returns all road-level speed segments ordered by SStart
GetRoadSpeedAtS¶
Result<SpeedValue> GetRoadSpeedAtS(
RoadHandle road,
double s
);
// Returns the road-level speed limit active at position s
Lane-Level Speed Limits¶
Lane-level speed limits define speed restrictions specific to a lane and override any road-level speed limits.
Commands
AddLaneSpeedSegment¶
Result AddLaneSpeedSegment(
LaneHandle lane,
SpeedSegment segment
);
// Adds a lane-level speed limit starting at segment.SStart
UpdateLaneSpeedSegment¶
Result UpdateLaneSpeedSegment(
LaneHandle lane,
SpeedSegment segment
);
// Updates an existing lane-level speed segment identified by SStart
RemoveLaneSpeedSegment¶
Result RemoveLaneSpeedSegment(
LaneHandle lane,
double sStart
);
// Removes the lane-level speed segment that starts at sStart
ClearLaneSpeedSegments¶
Result ClearLaneSpeedSegments(
LaneHandle lane
);
// Removes all lane-level speed segments from the lane
Queries
GetLaneSpeedSegments¶
Result<IReadOnlyList<SpeedSegment>> GetLaneSpeedSegments(
LaneHandle lane
);
// Returns all lane-level speed segments ordered by SStart
GetLaneSpeedAtS¶
Result<SpeedValue> GetLaneSpeedAtS(
LaneHandle lane,
double s
);
// Returns the lane-level speed limit active at position s
Effective Speed Resolution¶
For convenience and downstream usage, the SDK provides a resolved query that applies precedence rules automatically.
Lane-level speed limits override road-level speed limits.
Query
GetEffectiveSpeedAtS¶
Result<SpeedValue> GetEffectiveSpeedAtS(
LaneHandle lane,
double s
);
// Resolution order:
// 1. Lane-level speed limit
// 2. Road-level speed limit
9.12 Lane Material APIs¶
Lane Material APIs define the surface material of roads and lanes. Lane materials describe the physical surface over which vehicles travel and are primarily intended for use by simulators, physics engines, validation workflows, and export pipelines.
Lane materials: - Are semantic attributes, not geometric - May be defined at both lane and road level - May vary along s using segment-based definitions - Do not affect lane topology or geometry - Lane-level material definitions always take precedence over road-level defaults.
Road-Level Default Lane Materials¶
Road-level lane materials define default surface materials that apply to all lanes of a road unless explicitly overridden at lane level.
Commands¶
-
AddRoadMaterialSegment
Result AddRoadMaterialSegment( RoadHandle road, LaneMaterialSegment segment ); // Adds a road-level material segment starting at segment.SStart -
UpdateRoadMaterialSegment
Result UpdateRoadMaterialSegment( RoadHandle road, LaneMaterialSegment segment ); // Updates an existing road-level material segment identified by SStart -
RemoveRoadMaterialSegment
Result RemoveRoadMaterialSegment( RoadHandle road, double sStart ); // Removes the road-level material segment that starts at sStart -
ClearRoadMaterialSegments
Result ClearRoadMaterialSegments( RoadHandle road ); // Removes all road-level material segments from the road
Queries¶
-
GetRoadMaterialSegments
Result<IReadOnlyList<LaneMaterialSegment>> GetRoadMaterialSegments( RoadHandle road ); // Returns all road-level material segments ordered by SStart -
GetRoadMaterialAtS
Result<LaneMaterialType> GetRoadMaterialAtS( RoadHandle road, double s ); // Returns the road-level material active at position s
Lane-Level Materials¶
Lane-level materials define surface materials specific to a lane and override any road-level default materials.
Commands¶
-
AddLaneMaterialSegment
Result AddLaneMaterialSegment( LaneHandle lane, LaneMaterialSegment segment ); // Adds a lane-level material segment starting at segment.SStart -
UpdateLaneMaterialSegment
Result UpdateLaneMaterialSegment( LaneHandle lane, LaneMaterialSegment segment ); // Updates an existing lane-level material segment identified by SStart -
RemoveLaneMaterialSegment
Result RemoveLaneMaterialSegment( LaneHandle lane, double sStart ); // Removes the lane-level material segment that starts at sStart -
ClearLaneMaterialSegments
Result ClearLaneMaterialSegments( LaneHandle lane ); // Removes all lane-level material segments from the lane
Queries¶
-
GetLaneMaterialSegments
Result<IReadOnlyList<LaneMaterialSegment>> GetLaneMaterialSegments( LaneHandle lane ); // Returns all lane-level material segments ordered by SStart -
GetLaneMaterialAtS
Result<LaneMaterialType> GetLaneMaterialAtS( LaneHandle lane, double s ); // Returns the lane-level material active at position s
Effective Lane Material Resolution¶
For convenience and downstream consumers, the SDK provides a resolved query that applies precedence rules automatically.
Lane-level material definitions override road-level defaults.
Query¶
- GetEffectiveLaneMaterialAtS
Result<LaneMaterialType> GetEffectiveLaneMaterialAtS( LaneHandle lane, double s ); // Resolution order: // 1. Lane-level material // 2. Road-level default material // 3. LaneMaterialType.Unknown if none exists
9.13 Tram Lane APIs¶
Tram Lane APIs define tram usage capabilities on lanes. Trams are modeled as a lane-dependent semantic feature, allowing lanes to support tram traffic either exclusively or in combination with regular road traffic.
Tram support: - Is defined at lane level - May vary along the lane using s-based segments - Does not introduce geometry or rail objects by itself - Is intended to be consumed by export, validation, and simulation pipelines - Tram lane definitions do not affect road or lane geometry and do not imply the presence of physical rails unless explicitly added through other APIs.
Commands¶
AddTramLaneSegment¶
Result AddTramLaneSegment(
LaneHandle lane,
TramLaneSegment segment
);
// Enables tram usage on the lane starting at segment.SStart
// Tram usage may be exclusive or shared depending on segment.Usage
// Multiple segments may exist on the same lane
UpdateTramLaneSegment¶
Result UpdateTramLaneSegment(
LaneHandle lane,
TramLaneSegment segment
);
// Updates the tram usage segment identified by segment.SStart
// The updated segment replaces the existing definition at that position
RemoveTramLaneSegment¶
Result RemoveTramLaneSegment(
LaneHandle lane,
double sStart
);
// Removes the tram usage segment that starts at sStart
ClearTramLaneSegments¶
Result ClearTramLaneSegments(
LaneHandle lane
);
// Clears all tram usage segments defined on the lane
// After this call, the lane does not support tram traffic
Queries¶
GetTramLaneSegments¶
Result<IReadOnlyList<TramLaneSegment>> GetTramLaneSegments(
LaneHandle lane
);
// Returns all tram usage segments ordered by SStart
GetTramUsageAtS¶
Result<TramUsageType> GetTramUsageAtS(
LaneHandle lane,
double s
);
// Returns the tram usage mode active at position s
// If no segment applies, TramUsageType.None is returned
Error handling¶
Tram Lane APIs return structured errors in the following cases: - Invalid lane handle - Invalid or negative s positions - Overlapping or duplicate tram usage segments - Attempting to update or remove a non-existent segment
All errors are reported using the standard Result / Result
9.14 Road Structures APIs (Bridges and Tunnels)¶
Road Structure APIs provide explicit support for modeling bridges and tunnels as road-level semantic structures. These structures describe how a road segment interacts with its surrounding environment and infrastructure but do not define geometric shape or elevation by themselves.
Road structures:
- Are defined at road level
- Are segment-based along s
- Do not modify plan-view or elevation geometry
- Are used by export, validation, and simulation pipelines
A road segment may be classified as either a bridge, a tunnel, or neither. Bridge and tunnel segments must not overlap.
Design Principles¶
Road structure definitions follow these principles:
- Structures are semantic annotations, not geometry
- Geometry (height, slope, clearance) is handled separately
- Structures are explicit and deterministic
- Structure segments are non-overlapping and ordered
- Only one structure type may be active at a given s position
These principles align directly with ASAM OpenDRIVE <bridge> and <tunnel> elements.
Bridge APIs¶
Bridge APIs define road segments that are structurally elevated above the surrounding terrain or other infrastructure.
Commands
AddBridgeSegment
Result AddBridgeSegment(
RoadHandle road,
BridgeSegment segment
);
// Adds a bridge structure segment starting at segment.SStart
// Bridge segments are road-level and segment-based
UpdateBridgeSegment
Result UpdateBridgeSegment(
RoadHandle road,
BridgeSegment segment
);
// Updates an existing bridge segment identified by segment.SStart
RemoveBridgeSegment
Result RemoveBridgeSegment(
RoadHandle road,
double sStart
);
// Removes the bridge segment that starts at sStart
ClearBridgeSegments
Result ClearBridgeSegments(
RoadHandle road
);
// Removes all bridge segments from the road
Queries
GetBridgeSegments
Result<IReadOnlyList<BridgeSegment>> GetBridgeSegments(
RoadHandle road
);
// Returns all bridge segments ordered by SStart
IsBridgeAtS
Result<bool> IsBridgeAtS(
RoadHandle road,
double s
);
// Returns true if the road is classified as a bridge at position s
Tunnel APIs¶
Tunnel APIs define road segments that are structurally enclosed within terrain or constructed infrastructure.
Commands
AddTunnelSegment
Result AddTunnelSegment(
RoadHandle road,
TunnelSegment segment
);
// Adds a tunnel structure segment starting at segment.SStart
// Tunnel segments are road-level and segment-based
UpdateTunnelSegment
Result UpdateTunnelSegment(
RoadHandle road,
TunnelSegment segment
);
// Updates an existing tunnel segment identified by segment.SStart
RemoveTunnelSegment
Result RemoveTunnelSegment(
RoadHandle road,
double sStart
);
// Removes the tunnel segment that starts at sStart
ClearTunnelSegments
Result ClearTunnelSegments(
RoadHandle road
);
// Removes all tunnel segments from the road
Queries
GetTunnelSegments
Result<IReadOnlyList<TunnelSegment>> GetTunnelSegments(
RoadHandle road
);
// Returns all tunnel segments ordered by SStart
IsTunnelAtS
Result<bool> IsTunnelAtS(
RoadHandle road,
double s
);
// Returns true if the road is classified as a tunnel at position s
Effective Road Structure Queries¶
For convenience and inspection, the SDK provides resolved queries that determine the active road structure at a given position.
Queries
GetRoadStructureAtS
Result<RoadStructureType> GetRoadStructureAtS(
RoadHandle road,
double s
);
// Returns the active road structure at position s
// Possible results: None, Bridge, Tunnel
Error Handling¶
Road Structure APIs return structured errors in the following cases:
- Invalid road handle
- Invalid or negative s positions
- Overlapping bridge or tunnel segments
- Attempting to overlap bridge and tunnel segments
- Attempting to update or remove a non-existent segment
All errors are reported using the standard Result / Result
Usage Example¶
// Add a bridge segment
roadApi.AddBridgeSegment(
road,
new BridgeSegment
{
SStart = 100.0,
Length = 50.0
}
);
// Add a tunnel segment
roadApi.AddTunnelSegment(
road,
new TunnelSegment
{
SStart = 300.0,
Length = 120.0
}
);
9.15 Usage Example¶
var road = roadApi.CreateRoad(map, "R_Main", RoadRule.RightHandTraffic).Value;
var section = roadApi.AddLaneSection(road, 0.0).Value;
var lane = roadApi.AddLane(
section,
LaneSide.Right,
-1,
LaneType.Driving
).Value;
roadApi.AddLaneWidthSegment(
lane,
0.0,
new WidthPolynomial { A = 3.5 }
);
Usage Example — GetLaneConnectivityGraph¶
This example demonstrates how to use the lane connectivity graph to inspect inter-lane topology across several roads.
Scenario
We create: - 3 roads - 1 lane per road - Explicit successor/predecessor connectivity
Then, we retrieve and inspect the lane connectivity graph.
Step 1: Create roads and lanes
var roadA = roadApi.CreateRoad(map, "R_A", RoadRule.RightHandTraffic).Value;
var roadB = roadApi.CreateRoad(map, "R_B", RoadRule.RightHandTraffic).Value;
var roadC = roadApi.CreateRoad(map, "R_C", RoadRule.RightHandTraffic).Value;
var secA = roadApi.AddLaneSection(roadA, 0.0).Value;
var secB = roadApi.AddLaneSection(roadB, 0.0).Value;
var secC = roadApi.AddLaneSection(roadC, 0.0).Value;
var laneA = roadApi.AddLane(secA, LaneSide.Right, -1, LaneType.Driving).Value;
var laneB = roadApi.AddLane(secB, LaneSide.Right, -1, LaneType.Driving).Value;
var laneC = roadApi.AddLane(secC, LaneSide.Right, -1, LaneType.Driving).Value;
Step 2: Define lane connectivity
roadApi.SetLaneSuccessor(laneA, laneB);
roadApi.SetLaneSuccessor(laneB, laneC);
// This represents: laneA → laneB → laneC
Step 3: Retrieve the lane connectivity graph
var graphResult = roadApi.GetLaneConnectivityGraph();
if (!graphResult.IsSuccess)
{
HandleError(graphResult.Error);
}
var graph = graphResult.Value;
Step 4: Inspect the graph (adjacency-style)
foreach (var node in graph.Lanes)
{
var lane = node.Lane;
Console.WriteLine($"Lane: {lane}");
foreach (var successor in node.Successors)
{
Console.WriteLine($" -> Successor: {successor}");
}
foreach (var predecessor in node.Predecessors)
{
Console.WriteLine($" <- Predecessor: {predecessor}");
}
}
Conceptual graph structure (simplified) - Lane A: Successors: [Lane B], Predecessors: [] - Lane B: Successors: [Lane C], Predecessors: [Lane A] - Lane C: Successors: [], Predecessors: [Lane B]
What this graph is useful for - Routing and reachability analysis - Detecting broken or missing lane links - Validation and debugging - Visualization and tooling - Simulation preparation
Summary¶
The Road and Lane APIs provide full control over the structural and topological components of an OpenDRIVE map. These APIs are central to Replimap’s authoring capabilities and are used by most higher-level workflows, including junction creation, validation, and simulation preparation.
10. Junction APIs¶
The Junction APIs provide functionality for modeling complex connectivity between roads in an OpenDRIVE map. Junctions define how multiple roads intersect and how lanes connect across those intersections.
This module builds on the Road, Lane, and Geometry APIs and is essential for creating navigable and simulation-ready road networks.
10.1 Overview¶
The Junction APIs allow applications to:
- Create and delete junctions
- Associate roads with junctions
- Define lane-to-lane connections within junctions
- Manage contact points and priorities
- Automatically generate or repair junction structures
- Inspect junction topology and connectivity
All junction operations are explicit and deterministic.
10.2 Public Types¶
struct JunctionHandle { }
struct JunctionConnectionHandle { }
enum ContactPoint
{
Start,
End
}
enum JunctionType
{
Default,
Priority,
Roundabout,
Direct
}
10.3 Junction Management APIs¶
Commands¶
CreateJunction
Creates a new junction.
Result<JunctionHandle> CreateJunction(
string junctionId,
JunctionType type
);
Result<JunctionHandle> CreateJunction(
MapHandle map,
string junctionId,
JunctionType type
);
Example
var junction = junctionApi
.CreateJunction("J1", JunctionType.Default)
.Value;
// Target a specific map without changing the active map
var junctionInMapB = junctionApi
.CreateJunction(mapB, "J2", JunctionType.Default)
.Value;
DeleteJunction
Result DeleteJunction(JunctionHandle junction);
RenameJunction
Result RenameJunction(
JunctionHandle junction,
string newJunctionId
);
SetJunctionType
Result SetJunctionType(
JunctionHandle junction,
JunctionType type
);
Queries¶
GetJunctionById
Result<JunctionHandle> GetJunctionById(string junctionId);
GetAllJunctions
Result<IReadOnlyList<JunctionHandle>> GetAllJunctions();
GetJunctionType
Result<JunctionType> GetJunctionType(JunctionHandle junction);
10.4 Junction Connection APIs¶
Junction connections define how a road connects to a junction and how traffic flows through it.
Commands¶
AddRoadToJunction
Associates a road with a junction.
Result<JunctionConnectionHandle> AddRoadToJunction(
JunctionHandle junction,
RoadHandle road,
ContactPoint contactPoint
);
RemoveRoadFromJunction
Result RemoveRoadFromJunction(
JunctionHandle junction,
RoadHandle road
);
SetConnectionPriority
Result SetConnectionPriority(
JunctionConnectionHandle connection,
int priority
);
Queries¶
GetJunctionConnections
Result<IReadOnlyList<JunctionConnectionHandle>> GetJunctionConnections(
JunctionHandle junction
);
GetConnectedRoads
Result<IReadOnlyList<RoadHandle>> GetConnectedRoads(
JunctionHandle junction
);
10.5 Lane-to-Lane Linking APIs¶
Lane-to-lane links define the navigable paths through a junction.
Commands¶
AddLaneLink
Result AddLaneLink(
JunctionHandle junction,
LaneHandle fromLane,
LaneHandle toLane
);
RemoveLaneLink
Result RemoveLaneLink(
JunctionHandle junction,
LaneHandle fromLane,
LaneHandle toLane
);
ClearLaneLinks
Result ClearLaneLinks(JunctionHandle junction);
Queries¶
GetLaneLinks
Result<IReadOnlyList<LaneLink>> GetLaneLinks(
JunctionHandle junction
);
GetSuccessorLanesThroughJunction
Result<IReadOnlyList<LaneHandle>> GetSuccessorLanesThroughJunction(
LaneHandle lane
);
10.6 Automatic Junction Utilities¶
Commands¶
AutoGenerateJunctionConnections
Automatically generates junction connections based on road and lane topology.
Result AutoGenerateJunctionConnections(
JunctionHandle junction
);
RebuildJunction
Recomputes all internal junction connectivity.
Result RebuildJunction(JunctionHandle junction);
RepairJunctionConnectivity
Attempts to fix invalid or incomplete lane links.
Result RepairJunctionConnectivity(
JunctionHandle junction
);
10.7 Junction Validation Queries¶
Queries¶
ValidateJunction
Result<JunctionValidationReport> ValidateJunction(
JunctionHandle junction
);
GetJunctionConnectivityGraph
Result<JunctionConnectivityGraph> GetJunctionConnectivityGraph(
JunctionHandle junction
);
10.8 Junction Transformation APIs¶
Junction Transformation APIs provide high-level, procedural operations for modifying junction geometry and topology in a controlled and deterministic manner. These operations encapsulate complex, multi-step algorithms that operate across multiple roads, lanes, and geometry elements associated with a junction.
Junction transformations are intended to:
- Improve geometric quality and continuity
- Normalize junction structure
- Prepare junctions for simulation, validation, or export
These APIs operate at junction scope and must not be confused with low-level geometry editing commands.
Design Principles¶
Junction transformation operations follow these principles:
- Operate on an entire junction as a single unit
- May modify geometry, elevation, lane widths, and connectivity as required
- Are deterministic given the same inputs and options
- Expose intent through explicit, named operations
- Do not expose internal algorithmic steps
All transformations are executed explicitly via command APIs.
Junction Smoothing¶
Junction smoothing improves geometric continuity by reducing sharp curvature, heading discontinuities, and abrupt transitions between incoming and outgoing roads.
Commands
SmoothJunction
Result SmoothJunction(
JunctionHandle junction,
JunctionSmoothingOptions options
);
// Smooths geometric transitions within the junction
// Adjusts plan-view geometry to reduce curvature and heading discontinuities
// May modify connected road geometry within junction influence area
JunctionSmoothingOptions
struct JunctionSmoothingOptions
{
double InfluenceRadius; // Distance from junction center affected by smoothing
double MaxCurvature; // Maximum allowed curvature after smoothing
bool PreserveLaneCount; // Ensures lane counts are preserved
}
Junction Flattening¶
Junction flattening removes vertical variation within a junction to produce a level intersection area.
This operation is commonly used to:
- Remove elevation noise
- Simplify junctions for simulators
- Ensure consistent vertical alignment
Commands
FlattenJunction
Result FlattenJunction(
JunctionHandle junction,
JunctionFlatteningOptions options
);
// Removes elevation, superelevation, and lane height variation within the junction
// Produces a vertically flat junction area
JunctionFlatteningOptions
struct JunctionFlatteningOptions
{
double Elevation; // Target elevation for the junction
bool PreserveApproachSlopes; // Preserves elevation slopes outside the junction
}
Junction Equalization¶
Junction equalization normalizes lane and geometry attributes across junction connections to improve consistency and symmetry.
This operation may adjust:
- Lane widths
- Lane offsets
- Geometry lengths
- Connection alignment
Commands
EqualizeJunction
Result EqualizeJunction(
JunctionHandle junction,
JunctionEqualizationOptions options
);
// Normalizes lane and geometry properties across junction connections
// Ensures consistent widths and alignment where possible
JunctionEqualizationOptions
struct JunctionEqualizationOptions
{
bool EqualizeLaneWidths; // Normalizes lane widths across connections
bool EqualizeOffsets; // Normalizes lateral offsets
bool EqualizeGeometryLengths; // Normalizes connection geometry lengths
}
Queries¶
Junction Transformation APIs are command-only operations.
No query APIs are provided, as transformations directly modify junction state.
Inspection of results should be performed using existing:
- Geometry APIs
- Lane APIs
- Junction inspection queries
Error Handling¶
Junction transformation APIs return structured errors in the following cases:
- Invalid junction handle
- Junction is not editable
- Junction geometry is incomplete or inconsistent
- Transformation constraints cannot be satisfied with the provided options
All errors are reported using the standard Result pattern. No partial transformations are applied if an operation fails.
Usage Example¶
// Smooth and flatten a junction
junctionApi.SmoothJunction(
junction,
new JunctionSmoothingOptions
{
InfluenceRadius = 30.0,
MaxCurvature = 0.02,
PreserveLaneCount = true
}
);
junctionApi.FlattenJunction(
junction,
new JunctionFlatteningOptions
{
Elevation = 0.0,
PreserveApproachSlopes = true
}
);
10.9 Usage Example¶
var junction = junctionApi
.CreateJunction("J_Main", JunctionType.Default)
.Value;
junctionApi.AddRoadToJunction(
junction,
roadA,
ContactPoint.End
);
junctionApi.AddRoadToJunction(
junction,
roadB,
ContactPoint.Start
);
junctionApi.AutoGenerateJunctionConnections(junction);
Usage Example — GetJunctionConnectivityGraph¶
This example demonstrates how to use the junction connectivity graph to inspect lane-level connections through a junction.
Scenario
We model a simple 4-way intersection: - Two roads crossing: - North–South road - East–West road - One driving lane per road - Straight-through movements only
We then inspect the junction connectivity graph to understand how lanes are connected through the junction.
Step 1: Create roads and lanes
var roadNS = roadApi.CreateRoad(map, "R_NS", RoadRule.RightHandTraffic).Value;
var roadEW = roadApi.CreateRoad(map, "R_EW", RoadRule.RightHandTraffic).Value;
var secNS = roadApi.AddLaneSection(roadNS, 0.0).Value;
var secEW = roadApi.AddLaneSection(roadEW, 0.0).Value;
var laneNS = roadApi.AddLane(secNS, LaneSide.Right, -1, LaneType.Driving).Value;
var laneEW = roadApi.AddLane(secEW, LaneSide.Right, -1, LaneType.Driving).Value;
Step 2: Create a junction
var junction = junctionApi
.CreateJunction("J_Main", JunctionType.Default)
.Value;
Step 3: Attach roads to the junction
junctionApi.AddRoadToJunction(
junction,
roadNS,
ContactPoint.End
);
junctionApi.AddRoadToJunction(
junction,
roadEW,
ContactPoint.Start
);
Step 4: Define lane-to-lane connectivity
junctionApi.AddLaneLink(
junction,
laneNS,
laneEW
);
junctionApi.AddLaneLink(
junction,
laneEW,
laneNS
);
This encodes: - NS → EW (straight movement) - EW → NS (straight movement)
Step 5: Retrieve the junction connectivity graph
var graphResult = junctionApi.GetJunctionConnectivityGraph(junction);
if (!graphResult.IsSuccess)
{
HandleError(graphResult.Error);
}
var graph = graphResult.Value;
Step 6: Inspect the graph
foreach (var entry in graph.Connections)
{
Console.WriteLine(
$"From lane {entry.FromLane} → To lane {entry.ToLane}"
);
}
Conceptual example output:
Lane R_NS:-1 → Lane R_EW:-1
Lane R_EW:-1 → Lane R_NS:-1
What this graph represents: - Directed connectivity inside the junction - All legal lane-to-lane movements - Independent of linear predecessor/successor links
Summary¶
The Junction APIs provide explicit and fine-grained control over how roads and lanes intersect and connect. These APIs are critical for building realistic and navigable OpenDRIVE maps and are commonly used alongside Road, Lane, and Validation APIs.
11. Objects, Signals, and Controllers APIs¶
The Objects, Signals, and Controllers APIs provide functionality for modeling roadside infrastructure and traffic control elements in an OpenDRIVE map. These APIs allow applications to add, modify, query, and manage static and dynamic elements associated with roads and lanes.
This module is essential for enriching road networks with real-world context and traffic behavior information.
11.1 Overview¶
This module enables applications to:
- Create and manage OpenDRIVE objects
- Define parametric and repeated objects
- Model roadside infrastructure such as guardrails, barriers, trees, buildings, and obstacles
- Create and manage traffic signals
- Define signal dependencies and validity ranges
- Create and configure traffic signal controllers and phases
All objects and signals are positioned relative to roads or lanes using OpenDRIVE’s coordinate conventions.
11.2 Public Types¶
struct ObjectHandle { }
struct SignalHandle { }
struct ControllerHandle { }
enum ObjectType
{
GuardRail,
Barrier,
Pole,
Tree,
Building,
Obstacle,
Tunnel,
Bridge,
Custom
}
enum SignalType
{
Static,
Dynamic
}
enum Orientation
{
Positive,
Negative,
Both
}
enum AttachmentAlignment
{
None,
AlignWithRoad,
AlignWithLane,
FaceTraffic,
FaceOppositeTraffic
}
// Defines how the object orientation is aligned relative to the host
enum AttachmentUpdateMode
{
Static,
ResnapOnGeometry,
AlwaysFollowHost
}
// Defines how the object reacts to host geometry changes
struct AttachmentReference
{
double SOffset;
double LateralOffset;
double HeightOffset;
}
// Defines the object anchor point in host-relative coordinates
struct ObjectAttachmentOptions
{
AttachmentReference Reference;
AttachmentAlignment Alignment;
AttachmentUpdateMode UpdateMode;
}
// Defines attachment behavior, alignment, and update policy
enum ObjectAttachmentHostType
{
None,
Road,
Lane
}
// Identifies the type of host entity the object is attached to
struct ObjectAttachmentInfo
{
ObjectAttachmentHostType HostType;
RoadHandle Road;
LaneHandle Lane;
ObjectAttachmentOptions Options;
}
// Describes the attachment relationship of an object
// Only one of Road or Lane is valid based on HostType
11.3 Object APIs¶
Commands¶
AddObject
Adds a new object to a road.
Result<ObjectHandle> AddObject(
RoadHandle road,
ObjectType type,
double s,
double t
);
Errors - InvalidRoadHandle - InvalidObjectType - InvalidPosition
RemoveObject
Result RemoveObject(ObjectHandle obj);
UpdateObjectPosition
Result UpdateObjectPosition(
ObjectHandle obj,
double s,
double t,
double z
);
SetObjectOrientation
Result SetObjectOrientation(
ObjectHandle obj,
double heading,
double pitch,
double roll
);
SetObjectRepeat
Defines repetition rules for an object.
Result SetObjectRepeat(
ObjectHandle obj,
double sStart,
double sEnd,
double distance
);
SetObjectOutline
Result SetObjectOutline(
ObjectHandle obj,
ObjectOutline outline
);
Queries¶
GetObjectById
Result<ObjectHandle> GetObjectById(string objectId);
GetObjectsOnRoad
Result<IReadOnlyList<ObjectHandle>> GetObjectsOnRoad(
RoadHandle road
);
GetObjectPosition
Result<ObjectPosition> GetObjectPosition(
ObjectHandle obj
);
11.4 Signal APIs¶
Commands¶
AddSignal
Adds a traffic signal to a road.
Result<SignalHandle> AddSignal(
RoadHandle road,
double s,
double t,
SignalType type
);
RemoveSignal
Result RemoveSignal(SignalHandle signal);
SetSignalOrientation
Result SetSignalOrientation(
SignalHandle signal,
Orientation orientation
);
SetSignalValidity
Result SetSignalValidity(
SignalHandle signal,
double sStart,
double sEnd
);
AddSignalDependency
Result AddSignalDependency(
SignalHandle signal,
SignalHandle dependentSignal
);
Queries¶
GetSignalsOnRoad
Result<IReadOnlyList<SignalHandle>> GetSignalsOnRoad(
RoadHandle road
);
GetSignalPosition
Result<SignalPosition> GetSignalPosition(
SignalHandle signal
);
GetSignalDependencies
Result<IReadOnlyList<SignalHandle>> GetSignalDependencies(
SignalHandle signal
);
11.5 Controller APIs¶
Commands¶
CreateController
Creates a new traffic signal controller.
Result<ControllerHandle> CreateController(
string controllerId
);
Result<ControllerHandle> CreateController(
MapHandle map,
string controllerId
);
DeleteController
Result DeleteController(ControllerHandle controller);
AssignSignalToController
Result AssignSignalToController(
ControllerHandle controller,
SignalHandle signal
);
AddControllerPhase
Adds a phase definition to a controller.
Result AddControllerPhase(
ControllerHandle controller,
ControllerPhase phase
);
Queries¶
GetControllerById
Result<ControllerHandle> GetControllerById(
string controllerId
);
GetControllerSignals
Result<IReadOnlyList<SignalHandle>> GetControllerSignals(
ControllerHandle controller
);
GetControllerPhases
Result<IReadOnlyList<ControllerPhase>> GetControllerPhases(
ControllerHandle controller
);
11.6 Object and Signal Catalog APIs¶
The Object and Signal Catalog APIs expose a read-only catalog of predefined objects and signals bundled with the SDK. These catalog entries represent standard, reusable assets such as road markings, traffic signs, barriers, poles, and other commonly used roadside elements.
The catalog is intended to:
- Improve discoverability of available objects and signals
- Enable consistent reuse of standard assets
- Simplify creation of road markings and traffic elements
- Avoid hardcoding object definitions in client applications
Catalog entries are immutable and versioned with the SDK.
Design Principles¶
The catalog APIs follow these principles:
- Catalog entries are read-only
- Each entry has a stable, unique identifier
- Entries expose metadata only, not rendering logic
- Catalog content is independent of any UI framework
- Object and signal instances are created separately using existing APIs
Object Catalog Queries¶
GetObjectCatalog
Returns all available object catalog entries.
Result<IReadOnlyList<ObjectCatalogItem>> GetObjectCatalog();
// Returns all predefined object catalog items
// Includes road markings, barriers, poles, and other standard objects
GetObjectCatalogItem
Returns a specific object catalog entry.
Result<ObjectCatalogItem> GetObjectCatalogItem(
string catalogId
);
// Returns metadata for the specified object catalog identifier
GetObjectCatalogByCategory
Returns object catalog entries filtered by category.
Result<IReadOnlyList<ObjectCatalogItem>> GetObjectCatalogByCategory(
ObjectCatalogCategory category
);
// Returns all object catalog items belonging to the given category
Signal Catalog Queries¶
GetSignalCatalog
Returns all available signal catalog entries.
Result<IReadOnlyList<SignalCatalogItem>> GetSignalCatalog();
// Returns all predefined signal catalog items
GetSignalCatalogItem
Returns a specific signal catalog entry.
Result<SignalCatalogItem> GetSignalCatalogItem(
string catalogId
);
// Returns metadata for the specified signal catalog identifier
Creating Objects and Signals from the Catalog¶
Catalog entries may be instantiated as regular objects or signals using the existing creation APIs.
CreateObjectFromCatalog
Result<ObjectHandle> CreateObjectFromCatalog(
MapHandle map,
string catalogId,
ObjectPlacement placement
);
// Creates an object instance from a catalog entry
// Placement defines road or lane attachment and offsets
CreateSignalFromCatalog
Result<SignalHandle> CreateSignalFromCatalog(
MapHandle map,
string catalogId,
SignalPlacement placement
);
// Creates a signal instance from a catalog entry
11.7 Object and Signal Preview APIs¶
The Object and Signal Preview APIs provide lightweight preview descriptors for catalog entries. These previews are intended to support UI visualization, inspection, and placement workflows without introducing rendering or graphics dependencies into the SDK.
Previews describe shape and spatial characteristics, not visual appearance.
Design Principles¶
Preview APIs follow these principles:
- No rendering or drawing logic
- No images or textures required
- Geometry-only descriptors
- Deterministic and lightweight
- Optional for client usage
Object Preview Queries¶
GetObjectPreview
Returns a preview descriptor for an object catalog entry.
Result<ObjectPreview> GetObjectPreview(
string catalogId
);
// Returns a geometric preview of the object
// Includes footprint, bounding box, and orientation hints
Signal Preview Queries¶
GetSignalPreview
Returns a preview descriptor for a signal catalog entry.
Result<SignalPreview> GetSignalPreview(
string catalogId
);
// Returns a geometric preview of the signal
// Intended for placement and inspection workflows
Preview Descriptor Semantics¶
Preview descriptors may include:
- Axis-aligned bounding boxes
- 2D footprints
- Reference orientation and pivot point
- Nominal dimensions
Preview data:
- Is independent of scale and styling
- Must not be interpreted as final visual appearance
- Is suitable for editor previews and snapping logic
11.8 Object Attachment and Snapping APIs¶
Object Attachment and Snapping APIs define semantic attachment relationships between objects (including signals, road marks, poles, and other roadside assets) and host entities such as roads and lanes.
Attachment relationships ensure that objects remain correctly positioned and oriented relative to their host when geometry or topology changes occur. These APIs are backend-safe and UI-agnostic.
Commands¶
AttachObjectToRoad
Result AttachObjectToRoad(
ObjectHandle object,
RoadHandle road,
ObjectAttachmentOptions options
);
// Attaches an object to a road using host-relative placement rules
// The object position is stored relative to the road reference line
// Attachment behavior is controlled by the provided options
AttachObjectToLane
Result AttachObjectToLane(
ObjectHandle object,
LaneHandle lane,
ObjectAttachmentOptions options
);
// Attaches an object to a lane using lane-relative placement rules
// Overrides any existing attachment
DetachObject
Result DetachObject(
ObjectHandle object
);
// Removes any existing attachment from the object
// The object remains at its current world position
ResnapObject
Result ResnapObject(
ObjectHandle object
);
// Recomputes the object placement based on its attachment definition
// Does not modify attachment options
UpdateObjectAttachment
Result UpdateObjectAttachment(
ObjectHandle object,
ObjectAttachmentOptions options
);
// Updates the attachment options of an already attached object
// Does not change the attachment host
Queries¶
GetObjectAttachment
Result<ObjectAttachmentInfo> GetObjectAttachment(
ObjectHandle object
);
// Returns attachment information for the object
// Includes host reference and attachment options
IsObjectAttached
Result<bool> IsObjectAttached(
ObjectHandle object
);
// Returns true if the object has an active attachment
GetAttachedObjectsForRoad
Result<IReadOnlyList<ObjectHandle>> GetAttachedObjectsForRoad(
RoadHandle road
);
// Returns all objects currently attached to the specified road
GetAttachedObjectsForLane
Result<IReadOnlyList<ObjectHandle>> GetAttachedObjectsForLane(
LaneHandle lane
);
// Returns all objects currently attached to the specified lane
Summary¶
The Object Attachment and Snapping APIs provide a robust and explicit mechanism for defining host-relative object behavior. By separating attachment semantics from placement and geometry, the SDK enables stable snap-and-adjust workflows, automation, and editor tooling without introducing UI dependencies.
11.9 Usage Example¶
var obj = objectApi.AddObject(
road,
ObjectType.GuardRail,
s: 10.0,
t: -2.0
).Value;
var signal = signalApi.AddSignal(
road,
s: 25.0,
t: -1.5,
SignalType.Dynamic
).Value;
var controller = controllerApi.CreateController("C1").Value;
controllerApi.AssignSignalToController(controller, signal);
// Target a specific map without changing the active map
var controllerInMapB = controllerApi.CreateController(mapB, "C2").Value;
Summary¶
The Objects, Signals, and Controllers APIs enable detailed modeling of roadside infrastructure and traffic control systems. These APIs are commonly used to enrich road networks for simulation, validation, and visualization workflows, and they integrate closely with the Road, Lane, and Junction APIs.
12. Rail Network APIs¶
The Rail Network APIs provide support for modeling railroad infrastructure as an independent transportation network. Railroads are not represented as roads or lanes and do not share road-based topology, geometry, or traffic rules.
Rail networks are modeled as a separate graph with their own tracks, connectivity, and interaction points with the road network.
12.1 Design Principles¶
Rail networks follow these core principles:
- Railroads are not lanes
- Railroads do not use road reference lines
- Rail topology is independent from road topology
- Road–rail interaction occurs only through explicit crossings
- Rail APIs do not modify road or lane geometry
12.2 Public Data Types¶
Rail Track Direction
enum RailDirection
{
Bidirectional,
ForwardOnly,
ReverseOnly
}
Rail Track Type
enum RailTrackType
{
MainLine,
BranchLine,
Yard,
Siding,
Depot,
Industrial
}
Rail Track Definition
struct RailTrackDefinition
{
string Id;
RailTrackType Type;
RailDirection Direction;
}
Rail Track Segment
struct RailTrackSegment
{
double Length;
}
Road–Rail Crossing Type
enum RoadRailCrossingType
{
LevelCrossing,
Bridge,
Tunnel
}
Road–Rail Crossing Definition
struct RoadRailCrossingDefinition
{
RoadRailCrossingType Type;
double RoadS;
}
12.3 Rail Track APIs¶
Rail tracks represent linear infrastructure elements forming the nodes of the rail network.
Commands¶
AddRailTrack
Result<RailTrackHandle> AddRailTrack(
RailTrackDefinition definition
);
// Creates a new rail track in the rail network
// Track identifiers must be unique within the session
RemoveRailTrack
Result RemoveRailTrack(
RailTrackHandle track
);
// Removes the rail track and all associated rail connections
Queries¶
GetRailTracks
Result<IReadOnlyList<RailTrackHandle>> GetRailTracks();
// Returns all rail tracks defined in the current session
GetRailTrackDefinition
Result<RailTrackDefinition> GetRailTrackDefinition(
RailTrackHandle track
);
// Returns metadata associated with the specified rail track
12.4 Rail Connectivity APIs¶
Rail connectivity defines how rail tracks are linked together to form a navigable rail network.
Commands¶
ConnectRailTracks
Result ConnectRailTracks(
RailTrackHandle from,
RailTrackHandle to
);
// Creates a directional connection between two rail tracks
// Direction constraints are enforced based on track definitions
DisconnectRailTracks
Result DisconnectRailTracks(
RailTrackHandle from,
RailTrackHandle to
);
// Removes an existing rail connection
Queries¶
GetRailConnectivityGraph
Result<RailNetworkGraph> GetRailConnectivityGraph();
// Returns the rail network connectivity graph
12.5 Road–Rail Crossing APIs¶
Road–rail crossings define explicit interaction points between road and rail networks.
Crossings do not merge road and rail topology and are represented as standalone interaction entities.
Commands¶
AddRoadRailCrossing
Result<RoadRailCrossingHandle> AddRoadRailCrossing(
RoadHandle road,
RailTrackHandle track,
RoadRailCrossingDefinition definition
);
// Creates a road–rail crossing at the specified road position
// Does not modify road or rail topology
RemoveRoadRailCrossing
Result RemoveRoadRailCrossing(
RoadRailCrossingHandle crossing
);
// Removes the specified road–rail crossing
Queries¶
GetRoadRailCrossings
Result<IReadOnlyList<RoadRailCrossingHandle>> GetRoadRailCrossings();
// Returns all defined road–rail crossings
12.6 Rail and Road Interaction Queries¶
Queries¶
GetRailTracksAtRoad
Result<IReadOnlyList<RailTrackHandle>> GetRailTracksAtRoad(
RoadHandle road
);
// Returns rail tracks that intersect the specified road
GetRoadsCrossedByRail
Result<IReadOnlyList<RoadHandle>> GetRoadsCrossedByRail(
RailTrackHandle track
);
// Returns all roads intersected by the specified rail track
12.7 Error Handling¶
Rail Network APIs return structured errors in the following cases:
- Duplicate rail track identifiers
- Invalid rail track or crossing handles
- Invalid road handles
- Incompatible or invalid rail connections
- Attempting to remove non-existent tracks or crossings
All errors are reported using the standard Result / Result
12.8 Usage Example¶
// Create a rail track
var track = railApi.AddRailTrack(new RailTrackDefinition
{
Id = "Rail_01",
Type = RailTrackType.MainLine,
Direction = RailDirection.Bidirectional
}).Value;
// Connect tracks
railApi.ConnectRailTracks(trackA, trackB);
// Add a road–rail crossing
railApi.AddRoadRailCrossing(
road,
track,
new RoadRailCrossingDefinition
{
Type = RoadRailCrossingType.LevelCrossing,
RoadS = 120.0
}
);
Summary¶
The Rail Network APIs model railroad infrastructure as a first-class, independent domain within the SDK. By keeping rail topology separate from road and lane semantics, the SDK preserves architectural clarity while enabling accurate multimodal and road–rail interaction workflows.
13. Validation APIs (XODR Validator)¶
The Validation APIs provide comprehensive mechanisms for verifying the structural correctness, semantic consistency, and specification compliance of OpenDRIVE (XODR) maps. These APIs support both fine-grained validation checks and full black-box validation workflows, making them suitable for interactive editing, automated QA pipelines, and large-scale batch processing.
The validation system combines:
- ASAM OpenDRIVE rule validation
- Custom and extended rules
- Structural and topological analysis
- Geometry and attribute consistency checks
Validation can be executed synchronously for fast checks or asynchronously for long-running, full-map analysis.
13.1 Overview of Validation Capabilities¶
The XODR Validator can be used to:
- Validate a full OpenDRIVE map against ASAM specifications
- Validate subsets of a map (roads, lanes, junctions)
- Perform deep structural analysis without modifying the map
- Detect geometry, topology, and connectivity issues
- Identify violations with precise location context
- Generate structured, machine-readable validation reports
- Run validation in blocking or non-blocking (async) mode
The validator operates independently of any UI and is safe to use in headless environments.
13.2 Validation Scope and Categories¶
Validation checks are grouped into logical categories:
- Structural Validation
- Road and lane hierarchy correctness
- Presence of required OpenDRIVE elements
- Valid ID references and cross-links
-
Duplicate or missing identifiers
-
Geometry Validation
- Plan-view continuity
- Overlapping or disconnected geometry
- Invalid curvature or polynomial definitions
-
Degenerate or zero-length segments
-
Elevation and Profile Validation
- Elevation continuity
- Superelevation correctness
- Lateral shape consistency
-
Physically implausible slopes or banking
-
Lane and Topology Validation
- Lane section ordering
- Lane ID consistency
- Lane width and border continuity
- Lane predecessor/successor correctness
-
Missing or invalid lane links
-
Junction Validation
- Road–junction associations
- Lane-to-lane connectivity through junctions
- Contact point correctness
-
Priority and rule consistency
-
Object and Signal Validation
- Object placement validity
- Signal orientation and range checks
- Signal dependency cycles
-
Controller–signal consistency
-
Semantic and Rule-Based Validation
- ASAM OpenDRIVE rule compliance
- Country- or project-specific custom rules
- Unsupported or deprecated attribute usage
13.3 Validation Reports¶
All validation operations produce a Validation Report, which is a structured result containing:
- Validation status (Passed / Failed / Warnings)
- List of detected issues
- Severity classification:
- Info
- Warning
- Error
- Fatal
- Rule or check identifier
- Affected element (road, lane, junction, object, signal)
- Location context (road ID, lane ID, s range)
- Human-readable description
- Optional auto-fix suggestions (when available)
Validation reports are deterministic and suitable for automated comparison and auditing.
13.4 Synchronous Validation APIs¶
Synchronous validation APIs are intended for:
- Interactive editing
- Small or medium-sized maps
- Quick correctness checks
- Immediate feedback scenarios
These calls block until validation completes.
ValidateMap
Validates the entire map synchronously.
Result<ValidationReport> ValidateMap(
MapHandle map
);
ValidateRoad
Result<ValidationReport> ValidateRoad(
RoadHandle road
);
ValidateLaneSection
Result<ValidationReport> ValidateLaneSection(
LaneSectionHandle laneSection
);
ValidateJunction
Result<ValidationReport> ValidateJunction(
JunctionHandle junction
);
ValidateObjectsAndSignals
Result<ValidationReport> ValidateObjectsAndSignals(
MapHandle map
);
When to Use Synchronous Validation
Use synchronous validation when:
- The expected execution time is short
- Validation is triggered by a user action
- Immediate results are required
- Blocking the calling thread is acceptable
13.5 Asynchronous Validation APIs¶
Asynchronous validation APIs are designed for:
- Large or complex maps
- Full black-box validation
- Batch and CI/CD pipelines
- Background processing without blocking the main thread
Asynchronous APIs return a JobHandle that represents the running validation task.
ValidateMapAsync (Black-Box Validation)
Performs a full, deep validation of the map in the background.
JobHandle<ValidationReport> ValidateMapAsync(
MapHandle map,
ValidationOptions options
);
- Performs all structural, geometric, and semantic checks
- Does not modify the map
- Can run for extended durations
- Is safe for headless execution
ValidateXodrFileAsync
Validates an XODR file without loading it into an editable map.
JobHandle<ValidationReport> ValidateXodrFileAsync(
string xodrFilePath,
ValidationOptions options
);
- External file validation
- Regression testing
- CI pipelines
- Third-party data verification
13.6 JobHandle and Async Workflow¶
All asynchronous validation methods return a JobHandle<T>.
A job handle provides full control over the lifecycle of the validation task.
Job Status
JobStatus GetStatus();
Possible statuses:
- Pending
- Running
- Completed
- Failed
- Cancelled
Progress Reporting
double GetProgress();
Completion and Result Retrieval
bool IsCompleted();
Result<ValidationReport> GetResult();
GetResult() is only valid once the job has completed.
Awaiting Completion (Async/Await)
var report = await validator
.ValidateMapAsync(map, options)
.AwaitCompletionAsync();
Cancellation
Result Cancel();
13.7 Validation Options and Configuration¶
Validation behavior can be customized using ValidationOptions, including:
- Enable or disable specific rule groups
- Set severity thresholds
- Enable strict or relaxed modes
- Include or exclude custom rules
- Control performance vs thoroughness trade-offs
These options allow the same API to be used for both interactive validation and strict automated QA.
13.8 Recommended Validation Workflows¶
Interactive Editing - Use synchronous validation on affected elements - Validate incrementally (road, lane section, junction) - Surface warnings without blocking user flow
Batch Processing / CI - Use asynchronous black-box validation - Validate full maps or files - Store and compare validation reports - Fail pipelines on error or fatal severity
Client Integration - Expose progress and status via job handles - Allow cancellation - Log full reports for traceability
Summary¶
The Validation APIs provide a robust, flexible, and scalable foundation for ensuring OpenDRIVE map correctness. By supporting both synchronous and asynchronous workflows, fine-grained checks and full black-box analysis, the Replimap SDK enables validation to be integrated seamlessly into interactive tools, automated pipelines, and enterprise QA systems.
14. HERE2ODR APIs¶
The HERE2ODR APIs provide functionality for converting HERE HD map data into ASAM OpenDRIVE (XODR) format. This module supports multiple data ingestion and conversion workflows and is designed for asynchronous execution, as operations may involve network access, large data downloads, and intensive processing.
All HERE2ODR operations are deterministic and suitable for interactive tools, headless batch pipelines, and CI/CD environments.
14.1 Overview¶
The HERE2ODR module enables applications to:
- Download HERE HD map data and tiles
- Convert HERE data into OpenDRIVE maps
- Perform selective conversion based on area, route, or path
- Process offline or pre-encoded HERE HDLM data
- Generate XODR outputs suitable for editing, validation, or simulation
All conversion workflows are exposed as non-blocking asynchronous jobs.
14.2 Credential Groups and Configuration¶
HERE2ODR requires credentials for two distinct HERE services. These credentials are logically separated and must be provided explicitly by the integrating application.
14.2.1 HERE Maps API Credentials (HD Map Data Access)¶
These credentials are required for:
- Downloading HERE tiles
- Accessing HERE HD map data
- Processing HERE HDLM content
Credential Set
{
"HERE_USER_ID": "...",
"HERE_CLIENT_ID": "...",
"HERE_ACCESS_KEY_ID": "...",
"HERE_ACCESS_KEY_SECRET": "..."
}
These credentials are collectively referred to as HERE Maps API credentials.
14.2.2 HERE Routing API Credentials¶
These credentials are required for:
- Route-based map generation
- Path discovery using HERE Routing APIs
Credential Set
{
"HERE_ROUTING_API_KEY": "..."
}
This credential is referred to as the HERE Routing API credential.
14.2.3 Configuring Credentials¶
Credentials must be configured before invoking any HERE2ODR conversion API.
Result ConfigureHereCredentials(
HereMapsCredentials mapsCredentials,
HereRoutingCredentials routingCredentials
);
Credential configuration is:
- Explicit
- Application-controlled
- Not persisted by default
- Required once per session
Credentials may be sourced from:
- Secure configuration files
- Environment variables
- Secret management systems
- Runtime injection
14.3 Asynchronous Execution Model¶
All HERE2ODR conversion methods are asynchronous and return a JobHandle<XodrResult>.
Each job:
- Executes independently
- Reports progress
- Supports cancellation
- Produces structured results or structured errors
Blocking (synchronous) conversion APIs are intentionally not provided.
14.4 Conversion by Geographic Area¶
ConvertByBoundingBoxAsync¶
Downloads and converts all HERE tiles intersecting a geographic bounding box.
JobHandle<XodrResult> ConvertByBoundingBoxAsync(
GeoBoundingBox boundingBox,
Here2OdrOptions options
);
ConvertByPolygonAsync¶
Downloads and converts all HERE tiles intersecting a GeoJSON polygon.
JobHandle<XodrResult> ConvertByPolygonAsync(
GeoJsonPolygon polygon,
Here2OdrOptions options
);
Required Credentials: HERE Maps API credentials
14.5 Conversion by HERE Tile Identifiers¶
ConvertByTileIdsAsync¶
Downloads and converts HERE tiles using explicit tile identifiers.
JobHandle<XodrResult> ConvertByTileIdsAsync(
IReadOnlyList<string> tileIds,
Here2OdrOptions options
);
Required Credentials: HERE Maps API credentials
14.6 Conversion from Offline or Encoded HDLM Data¶
ConvertFromEncodedHdlmAsync¶
Processes pre-encoded HERE HDLM data without performing network downloads.
JobHandle<XodrResult> ConvertFromEncodedHdlmAsync(
IReadOnlyList<EncodedHdlmData> hdlmData,
Here2OdrOptions options
);
Required Credentials: None (offline workflow)
14.7 Route-Based Conversion Using HERE Routing API¶
This workflow generates a route using HERE Routing APIs and converts only the roads required to represent that route.
ConvertByRouteAsync¶
JobHandle<XodrResult> ConvertByRouteAsync(
GeoCoordinate start,
GeoCoordinate end,
RoutingOptions routingOptions,
Here2OdrOptions options
);
Required Credentials: HERE Maps API credentials, HERE Routing API credentials
14.8 Path-Matching Conversion (Selective Road Extraction)¶
This workflow converts only the roads that match a given path.
ConvertByPathAsync¶
JobHandle<XodrResult> ConvertByPathAsync(
PathDefinition path,
PathMatchingOptions matchingOptions,
Here2OdrOptions options
);
Supported Path Inputs:
- HERE Routing API response
- LineString coordinate sequences
- GPS trajectory-derived paths
Required Credentials: HERE Maps API credentials; HERE Routing API credentials (if route generation is involved)
14.9 JobHandle Usage for HERE2ODR¶
All HERE2ODR jobs expose a common job interface.
Checking Job Status¶
JobStatus GetStatus();
Progress Reporting¶
double GetProgress();
Awaiting Completion¶
var result = await here2odrApi
.ConvertByPolygonAsync(polygon, options)
.AwaitCompletionAsync();
Retrieving Results¶
Result<XodrResult> GetResult();
Cancelling a Conversion¶
Result Cancel();
14.10 Error Handling and Failure Modes¶
HERE2ODR operations may fail due to:
- Missing or invalid credentials
- Network connectivity issues
- Routing API failures
- Missing or unsupported HERE data
- Conversion rule violations
All failures are reported through structured error responses.
14.11 Determinism and Reproducibility¶
HERE2ODR guarantees:
- Deterministic output for identical inputs
- Stable tile selection
- Repeatable geometry generation
- Consistent OpenDRIVE serialization
This makes the module suitable for automated pipelines and regression testing.
Summary¶
The HERE2ODR APIs provide a flexible and robust solution for converting HERE HD map data into OpenDRIVE format. By separating credential responsibilities, enforcing asynchronous execution, and supporting multiple input modes, the module integrates cleanly into both interactive tools and enterprise-scale automation workflows.
15. XODR Explorer APIs¶
The XODR Explorer APIs provide deep inspection, analysis, querying, and controlled modification capabilities for OpenDRIVE (XODR) maps. This module is designed for analysis-heavy workflows, debugging, auditing, validation support, and advanced tooling where users need to understand and reason about the internal structure and relationships of a map.
The Explorer can operate on:
- In-memory maps
- Loaded XODR files
- Results produced by HERE2ODR or other conversion pipelines
All Explorer APIs are query-first by design, with optional controlled mutation where explicitly allowed.
15.1 Overview¶
The XODR Explorer enables applications to:
- Traverse road, lane, and junction graphs
- Query structural and geometric properties
- Perform attribute-based and geometry-based filtering
- Analyze connectivity and reachability
- Compute statistics and summaries
- Inspect relationships between entities
- Perform controlled modifications and re-serialization
This module is especially useful for:
- Debugging complex maps
- Automated map analysis
- QA and auditing pipelines
- Advanced visualization and reporting tools
15.2 Public Types¶
struct ExplorerContext { }
struct RoadInfo { }
struct LaneInfo { }
struct JunctionInfo { }
struct ConnectivityGraph { }
struct BoundingBox { }
enum ComparisonOperator
{
LessThan,
GreaterThan,
Equal,
NotEqual,
LessOrEqual,
GreaterOrEqual
}
15.3 Explorer Context APIs¶
The Explorer operates within an explicit context.
CreateExplorerContext
Result<ExplorerContext> CreateExplorerContext(
MapHandle map
);
DisposeExplorerContext
Result DisposeExplorerContext(
ExplorerContext context
);
15.4 High-Level Map Queries¶
GetMapSummary
Returns a high-level summary of the map.
Result<MapSummary> GetMapSummary(
ExplorerContext context
);
Summary includes: - Number of roads - Number of lane sections - Number of lanes - Number of junctions - Number of objects - Number of signals - Total road length - Map bounding box
GetMapBoundingBox
Result<BoundingBox> GetMapBoundingBox(
ExplorerContext context
);
GetAllRoads
Result<IReadOnlyList<RoadHandle>> GetAllRoads(
ExplorerContext context
);
15.5 Road-Level Queries and Filters¶
GetRoadInfo
Result<RoadInfo> GetRoadInfo(
ExplorerContext context,
RoadHandle road
);
FilterRoadsByLength
Result<IReadOnlyList<RoadHandle>> FilterRoadsByLength(
ExplorerContext context,
ComparisonOperator op,
double length
);
FilterRoadsByLaneCount
Result<IReadOnlyList<RoadHandle>> FilterRoadsByLaneCount(
ExplorerContext context,
ComparisonOperator op,
int laneCount
);
FilterRoadsByBoundingBox
Result<IReadOnlyList<RoadHandle>> FilterRoadsByBoundingBox(
ExplorerContext context,
BoundingBox box
);
FilterRoadsByLaneWidth
Returns roads having at least one lane matching width criteria.
Result<IReadOnlyList<RoadHandle>> FilterRoadsByLaneWidth(
ExplorerContext context,
ComparisonOperator op,
double widthMeters
);
Example: - Roads having lanes smaller than 5m - Roads having lanes wider than 3.75m
15.6 Lane-Level Queries and Filters¶
GetLaneInfo
Result<LaneInfo> GetLaneInfo(
ExplorerContext context,
LaneHandle lane
);
FilterLanesByType
Result<IReadOnlyList<LaneHandle>> FilterLanesByType(
ExplorerContext context,
LaneType type
);
FilterLanesByWidth
Result<IReadOnlyList<LaneHandle>> FilterLanesByWidth(
ExplorerContext context,
ComparisonOperator op,
double widthMeters
);
FilterLanesByHeight
Result<IReadOnlyList<LaneHandle>> FilterLanesByHeight(
ExplorerContext context,
ComparisonOperator op,
double heightMeters
);
FindDisconnectedLanes
Result<IReadOnlyList<LaneHandle>> FindDisconnectedLanes(
ExplorerContext context
);
15.7 Junction and Connectivity Analysis¶
GetJunctionInfo
Result<JunctionInfo> GetJunctionInfo(
ExplorerContext context,
JunctionHandle junction
);
GetRoadConnectivityGraph
Result<ConnectivityGraph> GetRoadConnectivityGraph(
ExplorerContext context
);
GetLaneConnectivityGraph
Result<ConnectivityGraph> GetLaneConnectivityGraph(
ExplorerContext context
);
FindUnreachableRoads
Result<IReadOnlyList<RoadHandle>> FindUnreachableRoads(
ExplorerContext context
);
FindDeadEndLanes
Result<IReadOnlyList<LaneHandle>> FindDeadEndLanes(
ExplorerContext context
);
TraceLanePath
Traces reachable lanes from a starting lane.
Result<IReadOnlyList<LaneHandle>> TraceLanePath(
ExplorerContext context,
LaneHandle startLane,
int maxDepth
);
15.8 Object and Signal Analysis¶
CountObjectsByType
Result<int> CountObjectsByType(
ExplorerContext context,
ObjectType type
);
GetObjectsInBoundingBox
Result<IReadOnlyList<ObjectHandle>> GetObjectsInBoundingBox(
ExplorerContext context,
BoundingBox box
);
GetSignalsByController
Result<IReadOnlyList<SignalHandle>> GetSignalsByController(
ExplorerContext context,
ControllerHandle controller
);
FindSignalsWithoutController
Result<IReadOnlyList<SignalHandle>> FindSignalsWithoutController(
ExplorerContext context
);
15.9 Statistical and Analytical Queries¶
ComputeLaneWidthStatistics
Result<LaneWidthStatistics> ComputeLaneWidthStatistics(
ExplorerContext context
);
ComputeRoadLengthStatistics
Result<RoadLengthStatistics> ComputeRoadLengthStatistics(
ExplorerContext context
);
CountEntities
Result<EntityCounts> CountEntities(
ExplorerContext context
);
15.10 Controlled Modification APIs¶
Explorer supports controlled, explicit modifications for analysis-driven workflows.
EnableModificationMode
Result EnableModificationMode(
ExplorerContext context
);
RemoveDisconnectedElements
Result RemoveDisconnectedElements(
ExplorerContext context
);
NormalizeLaneOrdering
Result NormalizeLaneOrdering(
ExplorerContext context
);
CommitExplorerChanges
Result CommitExplorerChanges(
ExplorerContext context
);
15.11 Re-Serialization and Export¶
ExportExplorerView
Exports the current explorer state to XODR.
Result ExportExplorerView(
ExplorerContext context,
string outputPath
);
15.12 Usage Example¶
var ctx = explorerApi.CreateExplorerContext(map).Value;
var narrowRoads = explorerApi.FilterRoadsByLaneWidth(
ctx,
ComparisonOperator.LessThan,
5.0
);
var stats = explorerApi.ComputeLaneWidthStatistics(ctx);
var deadEnds = explorerApi.FindDeadEndLanes(ctx);
Summary¶
The XODR Explorer APIs transform OpenDRIVE maps from static data files into fully navigable, queryable, and analyzable structures. By supporting rich filtering, connectivity analysis, statistics, and controlled modification, the Explorer enables advanced tooling, auditing, and insight-driven workflows that go far beyond basic map editing.
16. Utilities and Mathematical Helper APIs¶
The Utilities APIs provide a collection of mathematical, geometric, and normalization utilities that support OpenDRIVE (XODR) authoring, analysis, and correction workflows. These utilities are designed to be reusable across multiple modules and expose functionality that is commonly required when working with road geometry, lanes, and profiles.
This module does not introduce new domain entities (roads, lanes, junctions), but instead operates on existing data to compute, normalize, fit, or reorder information in a deterministic and reproducible manner.
16.1 Overview¶
The Utilities module enables applications to:
- Sort lanes correctly from left to right using mathematical rules
- Normalize lane ordering and lane IDs
- Fit curves and polynomials to sampled geometry
- Compute and refit Poly3 and ParamPoly3 representations
- Perform curvature, heading, and derivative calculations
- Smooth noisy geometry or profiles
- Generate derived geometric representations
- Support cleanup and normalization workflows for imported or converted XODR data
These APIs are especially useful after:
- Data conversion (e.g., HERE2ODR)
- Importing externally generated XODR files
- Manual or automated map editing
And before:
- Validation or simulation export
16.2 Lane Sorting and Normalization Utilities¶
Correct lane ordering is critical for OpenDRIVE compliance and downstream simulation usage.
SortLanesLeftToRight
Sorts lanes within a lane section from left to right using geometric evaluation.
Result SortLanesLeftToRight(
LaneSectionHandle laneSection
);
Behavior
- Evaluates lane centerlines at a representative s
- Computes lateral offsets relative to the reference line
- Orders lanes using signed t coordinates
- Preserves lane types and attributes
Use Cases
- Fixing incorrectly ordered lanes
- Normalizing imported or generated data
- Preparing maps for validation or export
NormalizeLaneIds
Reassigns lane IDs based on sorted order and OpenDRIVE conventions.
Result NormalizeLaneIds(
LaneSectionHandle laneSection
);
Behavior
- Ensures left lanes have positive IDs
- Right lanes have negative IDs
- Center lane is 0
- Preserves connectivity where possible
NormalizeAllLaneSections
Result NormalizeAllLaneSections(
RoadHandle road
);
16.3 Curve Fitting Utilities¶
These utilities provide mathematical fitting tools to derive OpenDRIVE-compatible geometry from sampled or noisy data.
FitLineToSamples
Result<LineGeometryParameters> FitLineToSamples(
IReadOnlyList<XYCoordinate> samples
);
FitArcToSamples
Fits a circular arc to sampled points.
Result<ArcGeometryParameters> FitArcToSamples(
IReadOnlyList<XYCoordinate> samples
);
FitSpiralToSamples
Fits a clothoid (spiral) to sampled geometry.
Result<SpiralGeometryParameters> FitSpiralToSamples(
IReadOnlyList<XYCoordinate> samples
);
16.4 Poly3 and ParamPoly3 Utilities¶
Poly3 and ParamPoly3 curves are commonly used to represent road geometry and profiles in OpenDRIVE.
FitPoly3
Fits a cubic polynomial to sampled data.
Result<Poly3Parameters> FitPoly3(
IReadOnlyList<double> sSamples,
IReadOnlyList<double> values
);
Use Cases
- Elevation profile fitting
- Lane width fitting
- Superelevation fitting
- Lateral shape fitting
FitParamPoly3
Fits a parametric cubic curve to sampled XY geometry.
Result<ParamPoly3Parameters> FitParamPoly3(
IReadOnlyList<XYCoordinate> samples
);
RefitGeometryAsPoly3
Result RefitGeometryAsPoly3(
GeometryHandle geometry,
int sampleCount
);
16.5 Derivative and Curvature Calculations¶
These utilities expose low-level mathematical evaluations commonly required in analysis and validation.
ComputeHeading
Result<double> ComputeHeading(
IReadOnlyList<XYCoordinate> samples,
int index
);
ComputeCurvature
Result<double> ComputeCurvature(
IReadOnlyList<XYCoordinate> samples,
int index
);
ComputeCurvatureProfile
Result<IReadOnlyList<double>> ComputeCurvatureProfile(
IReadOnlyList<XYCoordinate> samples
);
16.6 Geometry Smoothing and Cleanup¶
These utilities help clean noisy or overly complex data.
SmoothPolyline
Result<IReadOnlyList<XYCoordinate>> SmoothPolyline(
IReadOnlyList<XYCoordinate> samples,
SmoothingOptions options
);
SimplifyPolyline
Reduces point count while preserving shape.
Result<IReadOnlyList<XYCoordinate>> SimplifyPolyline(
IReadOnlyList<XYCoordinate> samples,
double tolerance
);
RemoveShortGeometrySegments
Result RemoveShortGeometrySegments(
RoadHandle road,
double minLength
);
16.7 Sampling and Resampling Utilities¶
ResampleGeometry
Result<IReadOnlyList<XYCoordinate>> ResampleGeometry(
GeometryHandle geometry,
double stepSize
);
ResampleLaneCenterline
Result<IReadOnlyList<XYCoordinate>> ResampleLaneCenterline(
LaneHandle lane,
double stepSize
);
16.8 Consistency and Normalization Utilities¶
NormalizeRoadDirection
Result NormalizeRoadDirection(
RoadHandle road
);
NormalizeJunctionLaneLinks
Result NormalizeJunctionLaneLinks(
JunctionHandle junction
);
CleanupUnusedElements
Result CleanupUnusedElements(
MapHandle map
);
Removes:
- Unreferenced lanes
- Empty lane sections
- Orphaned objects
- Unused controllers
16.9 Usage Example¶
utilitiesApi.SortLanesLeftToRight(laneSection);
utilitiesApi.NormalizeLaneIds(laneSection);
var poly3 = utilitiesApi.FitPoly3(sSamples, elevationSamples).Value;
utilitiesApi.RemoveShortGeometrySegments(road, minLength: 1.0);
Summary¶
The Utilities APIs provide the mathematical backbone required for reliable OpenDRIVE authoring and processing. By exposing lane sorting, curve fitting, polynomial evaluation, smoothing, and normalization utilities, the Replimap SDK enables applications to build clean, compliant, and simulation-ready maps from a wide variety of data sources.
17. Asynchronous Operations¶
The Replimap SDK provides a unified and consistent asynchronous execution model for operations that may require significant processing time, external I/O, or large data traversal. This includes workflows such as validation, data conversion, deep analysis, and batch processing.
This section describes the asynchronous programming model, lifecycle of asynchronous jobs, and recommended usage patterns.
17.1 When to Use Asynchronous APIs¶
Asynchronous APIs are used when an operation:
- May take a noticeable amount of time to complete
- Performs network I/O (e.g., HERE data download)
- Processes large or complex maps
- Performs full-map analysis or validation
- Should not block the calling thread
Typical asynchronous modules include:
- HERE2ODR
- XODR Validator (full-map validation)
- XODR Explorer (deep analysis)
- Utility batch operations
17.2 JobHandle Concept¶
All asynchronous operations return a JobHandle<T>, which represents a running or scheduled background task.
A job handle:
- Is created immediately
- Executes independently
- Represents exactly one operation
- Produces a typed result upon completion
The job handle is the primary interface for monitoring, controlling, and retrieving results from asynchronous operations.
17.3 Job Lifecycle and States¶
Each job progresses through a well-defined lifecycle.
Job States:
- Pending – Job created but not yet started
- Running – Job currently executing
- Completed – Job finished successfully
- Failed – Job terminated due to an error
- Cancelled – Job was explicitly cancelled
State transitions are deterministic and monotonic.
17.4 Querying Job Status¶
GetStatus
JobStatus GetStatus();
17.5 Progress Reporting¶
GetProgress
double GetProgress();
Progress reporting is designed for UI feedback and monitoring dashboards.
17.6 Retrieving Results¶
Results are available once the job reaches the Completed state.
GetResult
Result<T> GetResult();
GetResult():
- Is valid only after completion
- Returns the operation result or an error
- Does not block
17.7 Awaiting Completion (Async/Await Integration)¶
For applications using modern .NET async workflows, job handles provide awaitable completion helpers.
AwaitCompletionAsync
var result = await job.AwaitCompletionAsync();
- Does not block threads
- Integrates with async / await
- Throws no raw exceptions
- Returns structured results
This is the recommended approach for most applications.
17.8 Cancellation¶
Jobs can be cancelled explicitly.
Cancel
Result Cancel();
- Is cooperative
- Stops further processing where possible
- May not interrupt non-interruptible operations
- Results in the Cancelled state
Cancelled jobs do not produce partial results.
17.9 Error Handling in Asynchronous Operations¶
If a job fails:
- The job state becomes Failed
- The error is available via
GetResult() - No exceptions are thrown implicitly
Errors include:
- Execution failures
- External service failures
- Invalid input or configuration
- Resource limitations
Applications must explicitly inspect job results.
17.10 Threading and Concurrency Considerations¶
- Asynchronous jobs run on SDK-managed execution contexts
- Jobs do not block the calling thread
- Concurrent jobs may execute in parallel
- Access to shared map state must be coordinated by the caller
- Modifying a map while an asynchronous job is operating on it is not supported unless explicitly documented
17.11 Recommended Usage Patterns¶
Interactive Applications
- Use async APIs for long-running operations
- Display progress to users
- Allow cancellation
- Avoid blocking UI threads
Batch and Automation
- Schedule multiple jobs
- Poll or await completion
- Log structured results
- Fail pipelines on error states
CI/CD Pipelines
- Use black-box async validation
- Store validation reports
- Compare results across builds
17.12 Anti-Patterns to Avoid¶
- Blocking on async jobs using busy-wait loops
- Ignoring job results
- Assuming completion without checking status
- Modifying shared map state during execution
Summary¶
The Replimap SDK’s asynchronous execution model provides a robust, predictable, and scalable foundation for handling long-running operations. By exposing a consistent JobHandle abstraction with progress reporting, cancellation, and structured results, the SDK enables safe integration into interactive tools, backend services, and automated pipelines alike.
18. Error Handling and Diagnostics¶
The Replimap SDK is designed with a robust, explicit, and predictable error handling model. All public APIs follow a result-based pattern, ensuring that failures are reported in a structured and recoverable manner without causing unexpected crashes or unhandled exceptions.
This section explains how errors are represented, categorized, reported, and diagnosed across the SDK.
18.1 Design Principles¶
The error handling system follows these core principles:
- No implicit crashes: Public APIs do not throw raw exceptions under normal operation
- Explicit error reporting: All failures are returned as structured results
- Recoverability by default: Most errors allow applications to continue execution
- Deterministic behavior: Identical failures produce identical error outputs
- Actionable diagnostics: Errors include context to aid debugging and resolution
18.2 Result-Based API Pattern¶
All SDK APIs return a Result or Result<T> type.
Result
A result contains:
- Success or failure state
- A return value (on success)
- An error object (on failure)
Applications are expected to explicitly check results.
var result = roadApi.CreateRoad(map, "R1", RoadRule.RightHandTraffic);
if (!result.IsSuccess)
{
Log(result.Error);
return;
}
18.3 Public Error Types¶
This section defines the public error-related types used throughout the Replimap SDK.
All error information returned by SDK APIs conforms to this model.
Error¶
Represents a structured description of a failed operation.
struct Error
{
ErrorCode ErrorCode;
ErrorCategory Category;
ErrorSeverity Severity;
string Message;
// Optional diagnostic information
string Context;
string Location;
object Details;
}
Description
- Returned via Result.Error when an operation fails
- Never thrown as an exception under normal operation
- Designed to be machine-readable and human-readable
ErrorCode¶
Identifies the specific failure condition.
enum ErrorCode
{
// Defined error codes are documented in Section 17.12
}
Notes - Error codes are stable across SDK versions - Used for programmatic branching and recovery - A complete list is provided in Section 17.12 – Common Error Codes Reference
ErrorCategory¶
Classifies the error by subsystem or responsibility.
enum ErrorCategory
{
Validation,
Geometry,
Topology,
IO,
Conversion,
Internal
}
Usage - High-level grouping - Useful for logging, filtering, and diagnostics - Not intended for fine-grained control flow
ErrorSeverity¶
Indicates the seriousness of the error.
enum ErrorSeverity
{
Info,
Warning,
Error,
Critical
}
Semantics - Info – Informational, no action required - Warning – Non-fatal issue, operation may still succeed - Error – Operation failed - Critical – Unrecoverable failure, session may be invalid
Result and Result<T> (Reference)¶
All SDK APIs return either Result or Result<T>:
struct Result
{
bool IsSuccess;
Error Error;
}
struct Result<T>
{
bool IsSuccess;
T Value;
Error Error;
}
Rules
- Value is valid only when IsSuccess == true
- Error is non-null only when IsSuccess == false
- Applications must always check IsSuccess
Notes - Errors are explicit, never implicit - APIs do not rely on exceptions for control flow - This model applies consistently across: - Core APIs - Geometry APIs - Conversion APIs - Asynchronous operations
18.4 Error Object Structure¶
An error object contains structured diagnostic information.
Typical fields include:
- ErrorCode – Stable, machine-readable identifier
- Category – Broad error classification
- Message – Human-readable description
- Severity – Informational, warning, error, fatal
- Context – Related entity identifiers (road ID, lane ID, junction ID, etc.)
- Location – Optional spatial or s-range information
- Details – Optional extended diagnostic data
This structure allows both humans and automated systems to interpret errors reliably.
18.5 Error Categories¶
Errors are grouped into well-defined categories to guide handling strategies.
Input and Configuration Errors¶
- Invalid parameters
- Missing required values
- Invalid credential configuration
- Unsupported options
Structural Errors¶
- Broken OpenDRIVE structure
- Missing references
- Invalid connectivity
- Duplicate identifiers
Geometry Errors¶
- Discontinuous geometry
- Invalid curvature or polynomial coefficients
- Degenerate or zero-length segments
Topology Errors¶
- Lane predecessor/successor mismatches
- Invalid junction connectivity
- Unreachable roads or lanes
External Dependency Errors¶
- HERE API authentication failures
- Network errors
- Routing API failures
- Missing external data
Execution Errors¶
- Resource exhaustion
- Operation cancellation
- Internal processing failures
18.6 Severity Levels¶
Each error includes a severity level that indicates its impact.
- Info – Informational messages, no action required
- Warning – Non-critical issues that may affect quality
- Error – Operation failed, but application may continue
- Fatal – Unrecoverable error, operation cannot proceed
Severity levels are especially important in validation and analysis workflows.
18.7 Recoverable vs Fatal Errors¶
Most SDK errors are recoverable, allowing applications to:
- Adjust inputs
- Retry operations
- Skip problematic elements
- Continue processing unaffected data
Fatal errors are rare and explicitly documented. They typically indicate:
- Corrupted internal state
- Unsupported runtime environment
- Incompatible SDK usage
18.8 Error Handling in Asynchronous Operations¶
Asynchronous jobs report errors through their job results.
- Failed jobs transition to the
Failedstate - Errors are retrieved via
GetResult() - No exceptions are thrown implicitly
if (job.GetStatus() == JobStatus.Failed)
{
var error = job.GetResult().Error;
Log(error);
}
Cancelled jobs report a distinct cancellation state.
18.9 Diagnostics and Logging¶
The SDK provides hooks for diagnostics and logging to support debugging and production monitoring.
Typical diagnostic features include:
- Structured log events
- Operation lifecycle logging
- External service call tracing
- Validation and conversion summaries
Logging integration is designed to work with:
- Application-level logging frameworks
- File-based logging
- Centralized monitoring systems
18.10 Debugging and Inspection Support¶
To assist debugging and analysis, the SDK exposes:
- Detailed validation reports
- Explorer-based inspection APIs
- Connectivity and graph visualization data
- Map and entity summaries
- Deterministic reproduction of errors
These tools allow developers to investigate issues without modifying or corrupting map data.
18.11 Recommended Error Handling Practices¶
Interactive Applications
- Display warnings without blocking workflows
- Block operations only on fatal or critical errors
- Provide actionable feedback to users
Automation and CI Pipelines
- Treat errors as failures
- Persist error reports
- Fail builds on critical validation issues
Long-Running Services
- Log structured errors
- Retry transient failures
- Monitor error frequency and trends
18.12 Anti-Patterns to Avoid¶
- Ignoring result checks
- Relying on exceptions for control flow
- Swallowing errors without logging
- Assuming success without validation
- Retrying unrecoverable errors indefinitely
18.13 Common Error Codes Reference¶
This section lists commonly returned error codes across the SDK.
Each error code is stable and may be returned by multiple APIs.
DuplicateRoadId¶
A road with the specified identifier already exists in the map.
InvalidRoadRule¶
The specified road rule is invalid, unsupported, or incompatible with the current map configuration.
InvalidRoadHandle¶
The provided road handle is invalid, expired, or does not belong to the current map.
InvalidGeometryParameters¶
One or more geometry parameters are invalid, undefined, or mathematically inconsistent.
GeometryContinuityViolation¶
The provided geometry breaks continuity with adjacent geometry segments.
InvalidObjectType¶
The specified object type is unsupported or not valid in the given context.
InvalidPosition¶
The specified spatial position (s, t, z) is outside valid bounds or inconsistent with the road geometry.
DuplicateJunctionId¶
A junction with the specified identifier already exists in the map.
InvalidJunctionType¶
The specified junction type is invalid or not supported by the SDK.
LaneNotRemovable¶
Only the outer-most lane can be removed from any given road. Attempting to delete a center or inner lane is not permitted and results in this error.
InvalidLaneMarkingDefinition¶
The lane marking definition is invalid or incomplete.
LaneMarkingOverlap¶
The lane marking overlaps with an existing marking on the same side.
LaneMarkingNotFound¶
The specified lane marking does not exist.
InvalidLaneMarkingSide¶
The specified lane marking side is not valid in this context.
NoEffectiveLaneMarking¶
No lane-level or road-level lane marking exists at the specified position.
RoadDefaultLaneMarkingNotFound¶
The specified road-level default lane marking does not exist.
UnsupportedLaneMarkingForLaneType¶
The lane marking type is not supported for the given lane type.
InvalidLaneMarkingForLaneSide¶
The lane marking is not valid for the specified lane side.
Notes
- Error codes may appear in multiple modules.
- Additional error codes may be introduced in future SDK versions.
- Detailed handling guidance is provided in the surrounding sections of this chapter.
Summary¶
The Replimap SDK’s error handling and diagnostics system provides a clear, consistent, and robust framework for detecting, reporting, and resolving issues. By enforcing explicit result-based APIs, structured error reporting, and strong diagnostic support, the SDK enables safe integration into interactive tools, automated pipelines, and enterprise-scale systems.
19. Performance and Best Practices¶
This section provides guidance on using the Replimap SDK efficiently and safely in performance-sensitive environments. The recommendations apply to interactive desktop tools, headless batch pipelines, CI systems, and long-running backend services.
The SDK is designed to scale to large and complex OpenDRIVE maps, but optimal performance depends on how the APIs are used.
19.1 General Performance Principles¶
The following principles apply across all modules:
- Prefer explicit control over implicit behavior
- Minimize repeated full-map traversals
- Use queries for inspection, commands for modification
- Batch related operations where possible
- Avoid unnecessary geometry recalculation
- Use asynchronous APIs for long-running tasks
19.2 Session and Map Management¶
Best Practices
- Reuse a session for related workflows
- Avoid creating excessive short-lived sessions
- Dispose sessions explicitly when finished
- Keep map lifetimes well-defined
Avoid
- Creating a new session for every small operation
- Holding sessions open indefinitely without purpose
- Mixing unrelated workflows in the same session without isolation
19.3 Command Batching and Edit Strategy¶
Many SDK operations trigger internal consistency updates.
Recommended Patterns
- Group related commands together
- Perform bulk edits before validation
- Apply normalization and cleanup at logical checkpoints
- Prefer single-pass modifications over repeated micro-edits
Example
- Create roads and lanes first
- Then assign widths, offsets, and connectivity
- Then normalize and validate
19.4 Geometry Performance Considerations¶
Geometry operations can be computationally expensive.
Recommendations
- Avoid excessive geometry sampling at very fine resolutions
- Cache sampled results when used repeatedly
- Use resampling utilities with appropriate step sizes
- Avoid frequent refitting of curves unless necessary
Curve Fitting
- Use curve fitting utilities after data ingestion, not during every edit
- Prefer Poly3/ParamPoly3 fitting only when required by the target workflow
19.5 Lane and Topology Operations¶
Lane and connectivity updates may affect large portions of the map.
Best Practices
- Modify lane topology before attaching objects or signals
- Normalize lane ordering after bulk changes
- Validate connectivity incrementally, not after every edit
Avoid
- Rebuilding connectivity graphs repeatedly
- Modifying lane IDs after connectivity is finalized
19.6 Validation Performance¶
Validation can range from lightweight to computationally intensive.
Recommendations
- Use partial validation during interactive editing
- Use full-map validation only when required
- Prefer asynchronous validation for large maps
- Store validation reports instead of re-running identical checks
CI / Automation
- Use black-box validation for reproducibility
- Fail fast on fatal or critical errors
19.7 HERE2ODR Performance Guidelines¶
HERE2ODR workflows involve external services and large datasets.
Best Practices
- Limit geographic scope where possible
- Use tile-based or route-based conversion for targeted maps
- Cache HERE tiles when allowed
- Avoid repeated conversions of identical inputs
Async Usage
- Always use async conversion APIs
- Monitor progress instead of blocking
- Support cancellation for user-triggered workflows
19.8 Explorer and Analysis Performance¶
Explorer queries may traverse large graphs.
Recommendations
- Use filters to narrow search scope
- Avoid repeated full-map queries in loops
- Compute statistics once and reuse results
- Use bounding boxes to limit spatial queries
19.9 Memory Management¶
Large maps can consume significant memory.
Best Practices
- Dispose maps and sessions explicitly
- Avoid keeping multiple full-map copies in memory
- Use cloning selectively
- Prefer black-box analysis for external XODR files
19.10 Asynchronous Concurrency Guidelines¶
- Limit the number of concurrent jobs
- Avoid running multiple heavy jobs on the same map
- Coordinate access to shared map state
- Use job completion callbacks or await patterns
19.11 Common Anti-Patterns¶
Avoid the following patterns:
- Running validation after every single edit
- Blocking on async jobs using busy-wait loops
- Ignoring result objects and error states
- Recomputing geometry unnecessarily
- Mixing analysis and modification in the same workflow
- Treating the SDK as a UI-driven system
19.12 Recommended Workflow Patterns¶
Interactive Editing
- Fine-grained edits
- Partial validation
- Deferred normalization
- Responsive async operations
Batch Processing
- Deterministic inputs
- Async conversion and validation
- Structured logging
- Repeatable outputs
Enterprise Integration
- Centralized error handling
- Performance monitoring
- Version-controlled outputs
- Clear lifecycle management
Summary¶
By following these performance and best-practice guidelines, applications can integrate the Replimap SDK efficiently and reliably across a wide range of use cases. Proper session management, thoughtful command batching, careful use of geometry operations, and disciplined asynchronous workflows ensure scalability, stability, and predictable behavior in production environments.
20. Examples and Typical Workflows¶
This section presents complete, real-world workflows demonstrating how the Replimap SDK can be used to create, convert, analyze, validate, and export OpenDRIVE (XODR) maps. The examples are written in C# and reflect recommended usage patterns for interactive tools, batch processing, and automated pipelines.
20.1 Creating a Map from Scratch¶
This workflow demonstrates how to create a new OpenDRIVE map programmatically.
using var session = ReplimapSession.Create();
var mapResult = session.CreateMap();
if (!mapResult.IsSuccess)
throw new Exception(mapResult.Error.Message);
var map = mapResult.Value;
20.2 Creating Roads and Defining Geometry¶
var road = roadApi.CreateRoad(
roadId: "R_Main",
rule: RoadRule.RightHandTraffic
).Value;
// Add plan-view geometry
geometryApi.AddGeometrySegment(
road,
GeometryType.Line,
new LineGeometryParameters { Length = 100.0 }
);
geometryApi.AddGeometrySegment(
road,
GeometryType.Arc,
new ArcGeometryParameters
{
Length = 50.0,
Curvature = 0.01
}
);
20.3 Adding Elevation, Superelevation, and Lateral Shape¶
geometryApi.AddElevationSegment(
road,
sStart: 0.0,
new ElevationPolynomial
{
A = 0.0,
B = 0.02,
C = 0.0,
D = 0.0
}
);
geometryApi.AddSuperelevationSegment(
road,
sStart: 0.0,
new SuperelevationPolynomial
{
A = 0.0,
B = 0.001,
C = 0.0,
D = 0.0
}
);
20.4 Creating Lane Sections and Lanes¶
var laneSection = roadApi.AddLaneSection(
road,
sStart: 0.0
).Value;
// Right driving lane
var rightLane = roadApi.AddLane(
laneSection,
LaneSide.Right,
laneId: -1,
LaneType.Driving
).Value;
// Left driving lane
var leftLane = roadApi.AddLane(
laneSection,
LaneSide.Left,
laneId: 1,
LaneType.Driving
).Value;
// Set lane widths
roadApi.AddLaneWidthSegment(
rightLane,
sOffset: 0.0,
new WidthPolynomial { A = 3.5 }
);
roadApi.AddLaneWidthSegment(
leftLane,
sOffset: 0.0,
new WidthPolynomial { A = 3.5 }
);
20.5 Sorting and Normalizing Lanes (Utilities)¶
utilitiesApi.SortLanesLeftToRight(laneSection);
utilitiesApi.NormalizeLaneIds(laneSection);
20.6 Creating a Junction Between Roads¶
var roadB = roadApi.CreateRoad(
"R_Cross",
RoadRule.RightHandTraffic
).Value;
// Add minimal geometry for second road
geometryApi.AddGeometrySegment(
roadB,
GeometryType.Line,
new LineGeometryParameters { Length = 60.0 }
);
var junction = junctionApi.CreateJunction(
"J_Intersection",
JunctionType.Default
).Value;
junctionApi.AddRoadToJunction(
junction,
road,
ContactPoint.End
);
junctionApi.AddRoadToJunction(
junction,
roadB,
ContactPoint.Start
);
// Auto-generate lane-to-lane connectivity
junctionApi.AutoGenerateJunctionConnections(junction);
20.7 Adding Roadside Objects and Signals¶
// Add a guardrail
var guardrail = objectApi.AddObject(
road,
ObjectType.GuardRail,
s: 5.0,
t: -2.5
).Value;
// Repeat guardrail every 5 meters
objectApi.SetObjectRepeat(
guardrail,
sStart: 5.0,
sEnd: 95.0,
distance: 5.0
);
// Add traffic signal
var signal = signalApi.AddSignal(
road,
s: 40.0,
t: -1.5,
SignalType.Dynamic
).Value;
// Create controller
var controller = controllerApi.CreateController("CTRL_1").Value;
controllerApi.AssignSignalToController(controller, signal);
20.8 Using Mathematical Utilities (Curve Fitting)¶
var samples = geometryApi.ResampleGeometry(
geometryHandle,
stepSize: 1.0
).Value;
// Fit Poly3 to elevation samples
var poly3 = utilitiesApi.FitPoly3(
sSamples,
elevationSamples
).Value;
20.9 HERE2ODR Conversion — Bounding Box¶
here2odrApi.ConfigureHereCredentials(
mapsCredentials,
routingCredentials
);
var job = here2odrApi.ConvertByBoundingBoxAsync(
new GeoBoundingBox
{
MinLat = 52.51,
MinLon = 13.38,
MaxLat = 52.53,
MaxLon = 13.42
},
new Here2OdrOptions()
);
// Await completion
var conversionResult = await job.AwaitCompletionAsync();
var convertedMap = conversionResult.Value.Map;
20.10 HERE2ODR Conversion — Route-Based¶
var routeJob = here2odrApi.ConvertByRouteAsync(
start: new GeoCoordinate(52.5200, 13.4050),
end: new GeoCoordinate(52.5150, 13.4550),
routingOptions: new RoutingOptions(),
options: new Here2OdrOptions()
);
while (!routeJob.IsCompleted())
{
Console.WriteLine($"Progress: {routeJob.GetProgress():P}");
await Task.Delay(500);
}
var routeMap = routeJob.GetResult().Value.Map;
20.11 Deep Analysis Using XODR Explorer¶
var ctx = explorerApi.CreateExplorerContext(map).Value;
// Find narrow roads
var narrowRoads = explorerApi.FilterRoadsByLaneWidth(
ctx,
ComparisonOperator.LessThan,
3.0
);
// Find disconnected lanes
var deadEnds = explorerApi.FindDeadEndLanes(ctx);
// Compute statistics
var stats = explorerApi.ComputeLaneWidthStatistics(ctx);
20.12 Validation Workflow (Sync + Async)¶
Quick Synchronous Validation
var report = validatorApi.ValidateMap(map).Value;
foreach (var issue in report.Issues)
{
Console.WriteLine($"{issue.Severity}: {issue.Message}");
}
Full Black-Box Asynchronous Validation
var validationJob = validatorApi.ValidateXodrFileAsync(
"input.xodr",
new ValidationOptions { StrictMode = true }
);
var validationResult = await validationJob.AwaitCompletionAsync();
20.13 Cleanup, Normalization, and Final Validation¶
utilitiesApi.NormalizeAllLaneSections(road);
utilitiesApi.CleanupUnusedElements(map);
var finalReport = validatorApi.ValidateMap(map).Value;
20.14 Saving and Exporting the Map¶
session.SaveMap(
map,
"final_output.xodr"
);
20.15 Typical End-to-End Pipeline (Summary)¶
- Create or load map
- Add roads, geometry, lanes
- Normalize and sort lanes
- Add junctions, objects, signals
- Apply math utilities and cleanup
- Validate (partial → full)
- Export OpenDRIVE
Summary¶
These workflows demonstrate how the Replimap SDK can be used to build complete OpenDRIVE pipelines—from raw HERE data ingestion to detailed map authoring, analysis, validation, and export. The SDK’s modular design allows these workflows to be composed, automated, and scaled across interactive tools and enterprise environments.
21. Automation and Procedural Operations APIs¶
Automation and Procedural Operations APIs provide high-level, rule-driven batch operations that act on a map as a whole. These APIs encapsulate multi-step workflows that may modify roads, lanes, junctions, objects, and signals based on user-defined rules and parameters.
Automation APIs are intended to:
- Reduce repetitive manual editing
- Apply consistent rules across large maps
- Enable batch processing and headless workflows
- Serve as building blocks for editor “tools” and presets
Automation operations are explicit, deterministic, and parameterized. They do not introduce hidden behavior and do not replace low-level editing APIs.
21.1 Design Principles¶
Automation APIs follow these principles:
- Operate at map scope
- Express intent, not implementation details
- Encapsulate multi-entity modifications
- Are deterministic given the same inputs and options
- Use explicit options structures
- May internally invoke multiple SDK modules
- Are safe for both interactive and headless usage
Automation APIs are modeled as commands. Inspection of results is performed using existing query APIs.
21.2 Execution Model¶
Automation operations:
- Execute synchronously in the current SDK version
- Return a single
Result - Apply changes atomically (no partial application on failure)
The execution model is designed to allow future extension to:
- Asynchronous execution using JobHandle
- Dry-run or preview modes
- Profile-based or preset-driven execution
21.3 Lane-Based Automations¶
Lane-based automations apply rule-driven transformations to lanes that satisfy specific criteria.
Sidewalk Height Automation
Applies a uniform or rule-based height profile to all sidewalk lanes in the map.
Typical use cases include: - Normalizing sidewalk elevation - Preparing maps for pedestrian simulation - Enforcing design or export constraints
Commands
Result ApplySidewalkHeightAutomation(
MapHandle map,
SidewalkHeightAutomationOptions options
);
// Applies lane height definitions to all sidewalk lanes
// Only lanes classified as sidewalks are affected
struct SidewalkHeightAutomationOptions
{
double Height;
bool OverrideExistingHeights;
}
21.4 Junction-Based Automations¶
Junction-based automations operate on junctions and their connected roads and lanes.
Stop Line Generation
Automatically adds stop line objects to qualifying junction approaches using catalog-based object definitions.
This automation: - Uses the Object Catalog - Applies placement rules relative to junction geometry - Avoids duplicating existing stop lines unless explicitly requested
Commands
Result AddStopLinesToJunctions(
MapHandle map,
StopLineAutomationOptions options
);
// Adds stop line objects to all qualifying junction approaches
// Existing stop lines are preserved unless overridden
struct StopLineAutomationOptions
{
double OffsetFromJunction;
bool OverrideExisting;
string StopLineCatalogId;
}
21.5 Roadside Automations¶
Roadside automations populate roadside areas with objects based on geometric, semantic, and spacing rules.
Roadside Vegetation Population
Populates roadside vegetation such as trees or shrubs along eligible roads.
This automation: - Uses road geometry and lane layout - Places objects at regular intervals - Can optionally respect green-space constraints
Commands
Result PopulateRoadsideVegetation(
MapHandle map,
VegetationAutomationOptions options
);
// Populates roadside vegetation objects along eligible roads
// Objects are placed using spacing and offset rules
struct VegetationAutomationOptions
{
string TreeCatalogId;
double Spacing;
double LateralOffset;
bool RestrictToGreenSpaces;
bool AvoidJunctions;
}
21.6 Example Use Cases¶
Normalize Sidewalk Heights
automationApi.ApplySidewalkHeightAutomation(
map,
new SidewalkHeightAutomationOptions
{
Height = 0.15,
OverrideExistingHeights = true
}
);
Prepare an urban map for pedestrian simulation by enforcing consistent sidewalk elevation.
Add Stop Lines to All Junctions
automationApi.AddStopLinesToJunctions(
map,
new StopLineAutomationOptions
{
OffsetFromJunction = 2.0,
OverrideExisting = false,
StopLineCatalogId = "roadmark.stop_line.standard"
}
);
Rapidly make a converted map compliant with basic traffic control expectations.
Populate Roadside Trees
automationApi.PopulateRoadsideVegetation(
map,
new VegetationAutomationOptions
{
TreeCatalogId = "vegetation.tree.deciduous",
Spacing = 10.0,
LateralOffset = 3.5,
RestrictToGreenSpaces = true,
AvoidJunctions = true
}
);
Enhance semantic richness and visual realism for simulation or visualization workflows.
21.7 Error Handling¶
Automation APIs return structured errors in the following cases:
- Invalid map handle
- Invalid automation options
- Missing required catalog entries
- Conflicting or unsatisfiable rules
- Map state not suitable for the requested automation
If an automation fails, no partial changes are applied.
21.8 Extensibility¶
The Automation APIs are designed for future extension, including:
- Asynchronous execution
- Dry-run and preview support
- Profile-based automations (city, highway, country rules)
- User-defined or plugin-based automations
Summary
Automation and Procedural Operations APIs provide a powerful, scalable mechanism for applying rule-based transformations to maps. By keeping these operations separate from core editing APIs, the SDK enables advanced workflows while preserving clarity, determinism, and long-term maintainability.
22. Versioning, Compatibility, and Support¶
This section describes how the Replimap SDK and API are versioned, how compatibility is managed across releases, and how clients can expect long-term support and maintenance.
The goal is to ensure predictability, stability, and trust for integrations built on top of the SDK.
22.1 Versioning Strategy¶
The Replimap SDK follows semantic versioning:
MAJOR.MINOR.PATCH
- MAJOR – Breaking changes to the public API or data contracts
- MINOR – Backward-compatible feature additions
- PATCH – Bug fixes, performance improvements, and internal corrections
Version numbers apply to the SDK as a whole, and all shipped modules share the same version.
22.2 API Stability Guarantees¶
The SDK provides the following stability guarantees:
- Public APIs documented in this guide are considered stable
- Breaking changes occur only in major releases
- Experimental or preview APIs are explicitly marked
- Internal APIs are not part of the compatibility contract
Clients are encouraged to depend only on documented public APIs.
22.3 Backward Compatibility¶
Backward compatibility is maintained within a major version:
- Existing method signatures remain valid
- Behavior remains consistent unless explicitly documented
- New optional parameters may be introduced with safe defaults
- Validation and conversion behavior changes are documented in release notes
Where backward compatibility cannot be maintained, the change is deferred to a major release.
22.4 Deprecation Policy¶
APIs are deprecated in a controlled and transparent manner.
Deprecation process:
- API is marked as deprecated in documentation
- Alternative API is provided where applicable
- Deprecated API remains available for at least one major version
- Removal occurs only in a future major release
This policy ensures clients have sufficient time to migrate.
22.5 OpenDRIVE Compatibility¶
The SDK supports multiple versions of ASAM OpenDRIVE.
- Import and export behavior is version-aware
- Unsupported or deprecated OpenDRIVE features are reported explicitly
- Version-specific validation rules are applied where relevant
- Conversion workflows preserve semantic correctness across versions
Supported OpenDRIVE versions are documented per SDK release.
22.6 External Dependency Compatibility¶
For modules that rely on external services or formats:
HERE APIs
- Compatibility is maintained with supported HERE API versions
- Credential and endpoint changes are documented
- Breaking changes in HERE services may require SDK updates
Runtime and Platform
- Supported .NET runtimes are specified per release
- Platform-specific limitations are documented
- Unity compatibility is documented separately where applicable
22.7 Upgrade Guidelines¶
When upgrading the SDK:
- Review release notes for breaking changes
- Update SDK assemblies as a complete set
- Rebuild and run existing validation workflows
- Address any deprecated API usage
- Re-run automated tests and validation pipelines
Upgrading within a minor or patch version typically requires no code changes.
22.8 Support and Maintenance¶
Support options depend on the engagement agreement and may include:
- Issue tracking and bug reports
- Documentation clarifications
- API usage guidance
- Performance and integration assistance
- Validation rule extensions
Support requests should include:
- SDK version
- Reproduction steps
- Input data (where possible)
- Validation or error reports
22.9 Reporting Issues¶
When reporting issues, provide:
- Clear description of the problem
- Relevant API calls or workflows
- Logs or validation reports
- OpenDRIVE input or output files (if applicable)
This helps ensure timely and accurate resolution.
22.10 Long-Term Vision¶
The Replimap SDK is designed as a long-lived backend platform for OpenDRIVE authoring, conversion, validation, and analysis.
Future roadmap goals include:
- Expanded conversion pipelines
- Additional validation rule sets
- Enhanced analysis and exploration capabilities
- Continued performance improvements
- Strong backward compatibility guarantees
Client feedback plays a key role in shaping future development.
23. Sample Maps APIs¶
Sample Maps APIs provide access to a curated set of read-only example XODR maps bundled with the Replimap SDK. These sample maps are intended for learning, testing, prototyping, and validation workflows.
Sample maps:
- Are shipped with the SDK installation
- Are accessed using stable sample identifiers
- Are read-only templates
- Can be loaded or cloned into editable sessions
- Do not expose file paths or filesystem details
23.1 Design Principles¶
Sample Maps APIs follow these principles:
- Sample content is bundled and versioned with the SDK
- Access is identifier-based, not path-based
- Sample maps are immutable
- Loaded or cloned maps behave like regular editable maps
- APIs are UI-agnostic and safe for headless usage
23.2 Sample Map Discovery¶
Queries
GetSampleMaps
Result<IReadOnlyList<SampleMapInfo>> GetSampleMaps();
GetSampleMapInfo
Result<SampleMapInfo> GetSampleMapInfo(
string sampleId
);
23.3 Loading and Cloning Sample Maps¶
Sample maps can be either loaded or cloned into a session.
- Loading creates a map instance directly from the sample
- Cloning creates a new editable copy of the sample map
Commands
LoadSampleMap
Result<MapHandle> LoadSampleMap(
string sampleId
);
- The returned map behaves like a regular editable map
CloneSampleMap
Result<MapHandle> CloneSampleMap(
string sampleId
);
- Modifications do not affect the original sample
23.4 Sample Map Metadata¶
Each sample map exposes descriptive metadata to help users select appropriate examples.
SampleMapInfo
struct SampleMapInfo
{
string Id;
string Name;
string Description;
IReadOnlyList<string> CoveredFeatures;
string IntendedUse;
}
// Describes a bundled sample map
// CoveredFeatures may include roads, junctions, signals, tram lanes, rail crossings, automation demos, etc.
23.5 Typical Sample Maps¶
The SDK may include example maps such as:
- Simple two-road intersection
- Urban four-way junction with signals
- Tram shared-lane scenario
- Road–rail crossing example
- Automation demonstration map
The exact set of samples may evolve between SDK versions.
23.6 Usage Examples¶
List available sample maps
var samples = sampleApi.GetSampleMaps().Value;
// Enumerates all bundled sample maps
Load a sample map for experimentation
var map = sampleApi.LoadSampleMap(
"urban.4way.basic"
).Value;
// Loads a basic urban junction sample into the session
Clone a sample map for editing
var map = sampleApi.CloneSampleMap(
"tram.shared.lane"
).Value;
// Creates a new editable map based on a tram-related sample
23.7 Error Handling¶
Sample Maps APIs return structured errors in the following cases:
- Invalid or unknown sample identifier
- Sample content unavailable or incompatible with the current SDK version
- Session state does not allow loading a new map
All errors follow the standard Result / Result
Final Summary¶
This document has described the Replimap SDK and API in detail—from high-level concepts and architecture to concrete APIs, workflows, and best practices. By providing a stable, modular, and deterministic backend, the Replimap SDK enables clients to build powerful OpenDRIVE-based tools and pipelines with confidence.