simple_lanelet2
A reimplementation of the Lanelet2 Python API with a Rust core and PyO3 bindings.
The goal is a drop-in replacement: import lanelet2 keeps working, unchanged, but
installation is a single wheel with no Boost, no GeographicLib and no C++ toolchain.
import lanelet2
from lanelet2.core import Point3d, LineString3d, Lanelet, getId
left = LineString3d(getId(), [Point3d(getId(), 0, 0, 0), Point3d(getId(), 1, 0, 0)])
right = LineString3d(getId(), [Point3d(getId(), 0, 1, 0), Point3d(getId(), 1, 1, 0)])
lanelet = Lanelet(getId(), left, right)
Status. All seven submodules are implemented. The library exposes 100% of the reference's public API — 633 names across every module and class — and upstream's own test suite passes against it unmodified, in both modes.
Bug-compatibility mode
Upstream has a number of outright defects — a __hash__ that contradicts __eq__, a
misnamed keyword argument on Origin, a routing filter that silently does nothing.
By default this library fixes them. Setting LANELET2_BUG_COMPAT restores
upstream's behaviour exactly:
LANELET2_BUG_COMPAT=1 python my_script.py # byte-for-byte upstream behaviour
python my_script.py # repaired behaviour (default)
The flag is read once at import time and is reported as lanelet2.BUG_COMPAT.
Every switched behaviour is listed in docs/DIVERGENCE.md and
enforced by the test harness.
Verification
Compatibility is not asserted, it is measured. Every case in tests/cases/ is run
three ways and the JSON-Lines output is compared:
| run | interpreter | environment |
|---|---|---|
REF |
.venv-ref |
the real lanelet2==1.2.3 from PyPI |
COMPAT |
.venv |
ours, LANELET2_BUG_COMPAT=1 |
FIXED |
.venv |
ours, default |
REF and COMPAT must agree exactly. COMPAT and FIXED must differ in exactly
the places listed in tests/compat_matrix.toml — no more, and no fewer, so neither
an accidental behaviour change nor an unwired repair can slip through.
just venvs # create both virtualenvs
just build # build and install into .venv
just diff # run the harness
just upstream-tests # upstream's own tests, unmodified, in both modes
just test-rust # the Rust unit tests
What the harness checks, beyond "it runs":
- the 594 KB example map from the Lanelet2 repository loads, and writing it back reproduces the reference's file byte for byte — every node, way, relation and tag, in the same order — and a second pass is identical again;
- every lanelet's full centerline matches, on that map and on forty procedurally generated shapes chosen to exercise the parts of the algorithm a rectangular lanelet never reaches;
- the projections agree with GeographicLib to 7e-15 m across zone edges, the Norway and Svalbard zone irregularities, both hemispheres and the antimeridian;
- the traffic-rule tables are swept exhaustively — every participant against every way subtype, both directions, both locations — rather than spot-checked;
- the routing graph's whole edge list is compared before any query is.
Autoware maps
autoware_lanelet2_extension's regulatory elements and its transverse Mercator
projector are provided under the upstream import path, in this same wheel:
import lanelet2
import autoware_lanelet2_extension_python.regulatory_elements # registers the subtypes
from autoware_lanelet2_extension_python.projection import TransverseMercatorProjector
Importing regulatory_elements is what makes road_marking, crosswalk,
detection_area and the rest resolvable, and it makes traffic_light resolve to
AutowareTrafficLight. Before that import a map carrying them is refused, exactly as
stock Lanelet2 refuses it. That is upstream's behaviour, not an accident of packaging:
registration there happens when the extension's shared library loads. Note that it is
process-wide and cannot be undone, so an unrelated module importing the extension
changes what lanelet2.io.load produces from that point on.
Coordinates come from latitude and longitude, not from local_x/local_y.
Autoware's C++ AutowareOsmParser prefers those tags, and a real Autoware map is full
of them — the Nishi-Shinjuku example carries 36,936. That parser is not reachable from
Python in the reference either, so lanelet2.io.load behaves the same in both; our
output on that map is byte-identical to the reference's. But it does mean the numbers
differ from what Autoware's own C++ tooling produces.
utility.query and utility.utilities are provided apart from their ROS-dependent
halves, which are defined but raise when called — upstream imports geometry_msgs and
rclpy at module top, so its versions cannot be imported at all without ROS. Several
of upstream's own bindings do not work; those are repaired here and reproduced under
LANELET2_BUG_COMPAT=1. See docs/DIVERGENCE.md for the list.
CI
Four jobs, arranged around the compatibility claim rather than around the test suite:
| job | what it proves | needs |
|---|---|---|
check |
it builds, lints, and the wheel installs into an empty venv and imports | nothing |
diff |
20 cases against the PyPI lanelet2==1.2.3, plus upstream's vendored tests |
a wheel |
upstream |
upstream's own tests, cloned at HEAD each run, unmodified, both modes | network |
oracle |
31 cases, including the Autoware extension and the two-reference skew check | pixi + colcon |
One case is not in that count. 1150_aw_map loads a real 10.5 MB Autoware map and
checks it writes back byte for byte; the map it was developed against is CC BY-NC
licensed, so it can neither be vendored here nor fetched by CI. Point
SIMPLE_LL2_AW_MAP at a real Autoware map to run it. 1160_aw_synthetic_map covers
the same behaviour on a map small enough to write inline, and does run in CI.
One caveat on what upstream proves. Lanelet2's own tests are substantive; the
Autoware extension's Python tests are import smoke tests, and its real suite is C++
gtest that cannot run against a Python implementation. The extension is verified by the
# ORACLE: aw diff cases instead — see tests/upstream-awext/README.md.
upstream fetching at HEAD rather than a pin is deliberate. A vendored copy proves
compatibility with whatever upstream looked like the day it was copied; fetching proves
it against upstream as it stands, and a test they change becomes a signal rather than a
silent drift. It runs on a schedule too, since upstream moves without anyone touching
this repository. Locally: just upstream-fresh.
Licence
BSD-3-Clause, matching upstream Lanelet2. See NOTICE for vendored assets.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file simple_lanelet2-1.0.0.tar.gz.
File metadata
- Download URL: simple_lanelet2-1.0.0.tar.gz
- Upload date:
- Size: 222.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f6d609ebf93b998fd19bfc807f306373fdad8794846b6f6967fd73ce5866aca
|
|
| MD5 |
b68f54ad1f6428fa78a215ca716ee947
|
|
| BLAKE2b-256 |
20c796120b9ad6841b8053e6f8cdf8d2cef21692c06609daa98586bcb02301c0
|
Provenance
The following attestation bundles were made for simple_lanelet2-1.0.0.tar.gz:
Publisher:
release.yml on hakuturu583/simple_lanelet2
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
simple_lanelet2-1.0.0.tar.gz -
Subject digest:
1f6d609ebf93b998fd19bfc807f306373fdad8794846b6f6967fd73ce5866aca - Sigstore transparency entry: 2332766679
- Sigstore integration time:
-
Permalink:
hakuturu583/simple_lanelet2@c1c9bb27b3e1063092714cfa090cc88fdd3a2e9c -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/hakuturu583
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c1c9bb27b3e1063092714cfa090cc88fdd3a2e9c -
Trigger Event:
push
-
Statement type:
File details
Details for the file simple_lanelet2-1.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: simple_lanelet2-1.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 951.2 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48225b02d846086c448e72654237342ebe0e9681a6c633a7f17556e1e0e9d3b1
|
|
| MD5 |
f424a81377dcd43517b85ddaacea0333
|
|
| BLAKE2b-256 |
29ccd30098e4ffc6940d3fbc21943839aeaafe18d69666d8d213878af55f046b
|
Provenance
The following attestation bundles were made for simple_lanelet2-1.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on hakuturu583/simple_lanelet2
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
simple_lanelet2-1.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
48225b02d846086c448e72654237342ebe0e9681a6c633a7f17556e1e0e9d3b1 - Sigstore transparency entry: 2332746528
- Sigstore integration time:
-
Permalink:
hakuturu583/simple_lanelet2@1b8dbcf7fe36cb4cb99eb31a768b7e832747a6b1 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/hakuturu583
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1b8dbcf7fe36cb4cb99eb31a768b7e832747a6b1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file simple_lanelet2-1.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: simple_lanelet2-1.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 922.8 kB
- Tags: CPython 3.9+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1b70455c2981b4da609d9678af72af0a9550c7b0d90fd608c43abc055d437b84
|
|
| MD5 |
422504ba5b151299e99c8085d0fd0c70
|
|
| BLAKE2b-256 |
b2a741cc8a4276758c9e6eb9875f8c8429b033a1a230af13e3d08b0f96aa115e
|
Provenance
The following attestation bundles were made for simple_lanelet2-1.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on hakuturu583/simple_lanelet2
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
simple_lanelet2-1.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
1b70455c2981b4da609d9678af72af0a9550c7b0d90fd608c43abc055d437b84 - Sigstore transparency entry: 2332746537
- Sigstore integration time:
-
Permalink:
hakuturu583/simple_lanelet2@1b8dbcf7fe36cb4cb99eb31a768b7e832747a6b1 -
Branch / Tag:
refs/tags/v1.0.0 - Owner: https://github.com/hakuturu583
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@1b8dbcf7fe36cb4cb99eb31a768b7e832747a6b1 -
Trigger Event:
push
-
Statement type: