vectory is the Rust port of vectkit, a GeoJSON vector library for robotics
workflows. It reads and writes GeoJSON feature collections, normalizes geometry
into a local ENU frame, and provides a higher-level Vector API for field
boundaries and typed vector elements.
The crate uses:
concordfor WGS84 and ENU conversionsdatapodfor shared geometry and spatial data typesserde_jsonfor GeoJSON parsing and serialization
The current implementation covers the core vectkit library behavior:
Feature,FeatureCollection,Geometry, andCrs- GeoJSON parsing and writing
- WGS to ENU normalization on ingest
- WGS and ENU output
- the higher-level
Vectorabstraction - a C ABI
- optional Python bindings
The crate is self-contained. It does not depend on a local ../vectkit
checkout to build, test, or run.
Add the crate to Cargo.toml:
[dependencies]
vectory = { path = "../vectory" }Python bindings are optional:
[dependencies]
vectory = { path = "../vectory", features = ["python"] }vectory re-exports the main public types from the crate root:
CrsGeometryFeatureFeatureCollectionVectorElementHeadingGeoPoint3Segment3Path3Polygon3
Geometry storage is based on datapod types. Parsed geometries are stored
internally in local ENU-style coordinates regardless of input CRS.
Read and write a feature collection:
use vectory::{Crs, read, write};
let collection = read("field.geojson")?;
write(&collection, "field_out.geojson", Crs::Wgs)?;
# Ok::<(), vectory::Error>(())Read from an in-memory JSON string:
use vectory::read_json_str;
let json = r#"{
"type": "FeatureCollection",
"properties": {
"crs": "ENU",
"datum": [5.0, 52.0, 0.0],
"heading": 0.0
},
"features": []
}"#;
let collection = read_json_str(json)?;
# Ok::<(), vectory::Error>(())Serialize a collection to a JSON string:
use concord::Geo;
use vectory::{FeatureCollection, Heading, Crs, to_json_string};
let collection = FeatureCollection::new(Geo::new(52.0, 5.0, 0.0), Heading::default());
let json = to_json_string(&collection, Crs::Wgs)?;
# let _ = json;
# Ok::<(), vectory::Error>(())Vector is the higher-level field-oriented abstraction. It stores:
- one field boundary polygon
- field properties
- a list of typed elements
- datum, heading, and CRS metadata
- global properties
Example:
use std::collections::HashMap;
use concord::Geo;
use datapod::{Point, Polygon, Vector as PodVector};
use vectory::{Crs, Heading, Vector};
let field = Polygon {
vertices: PodVector::from(vec![
Point::new(0.0, 0.0, 0.0),
Point::new(10.0, 0.0, 0.0),
Point::new(10.0, 10.0, 0.0),
Point::new(0.0, 10.0, 0.0),
]),
};
let mut vector = Vector::new(field, Geo::new(52.0, 5.0, 0.0), Heading::default(), Crs::Enu);
vector.set_field_property("name", "demo");
vector.add_point(Point::new(1.0, 2.0, 0.0), "marker", HashMap::new());
vector.to_file("vector.geojson", Crs::Wgs)?;
let loaded = Vector::from_file("vector.geojson")?;
assert_eq!(loaded.points().len(), 1);
# Ok::<(), vectory::Error>(())Important behavior inherited from vectkit:
- top-level GeoJSON must include
properties - required top-level properties are:
crsdatumheading
- accepted CRS strings include
EPSG:4326,WGS84,WGS,ENU, andECEF LineStringwith 2 points becomesSegment- longer
LineStringbecomesPath Polygonuses the outer ringMultiPoint,MultiLineString,MultiPolygon, andGeometryCollectionare flattened into multiple features- unknown geometry types are skipped gracefully
- WGS input is converted to ENU internally
The crate exposes a C ABI and installs the public header:
- header: include/vectory.h
- implementation: src/ffi.rs
The ABI covers:
- feature collection create/free/read/write/JSON conversion
- collection metadata and global properties
- vector create/free/read/write
- field boundary access
- element insertion and inspection
- last-error retrieval
A small C example is included in examples/c_abi/demo.c.
Python bindings are implemented with pyo3 behind the python feature.
Relevant files:
- module implementation: src/python/mod.rs
- packaging config: pyproject.toml
- example scripts:
Build-time check:
cargo check --features pythonRust examples:
cargo run --example maincargo run --example read_writecargo run --example vector_workflowcargo run --example json_roundtripcargo run --example crs_conversion_examplecargo run --example rerun_vis_from_wgscargo run --example rerun_vis_from_enu
C ABI example:
make c-demoRun the normal Rust test suite:
cargo testOr through the project Makefile:
make testPython binding compilation check:
make test-pythonThe Python feature currently compiles cleanly, but full cargo test --features python
can still depend on having the appropriate Python development libraries available
on the machine.
- src/lib.rs: crate exports
- src/types.rs: core data model
- src/io/parse.rs: GeoJSON parser
- src/io/write.rs: GeoJSON writer
- src/vector.rs: field-oriented API
- src/ffi.rs: C ABI
- src/python/mod.rs: Python bindings
vectory is implemented as the Rust port of vectkit for the core library
surface. The crate includes Rust tests, fixture-based integration tests, C ABI
smoke tests, examples, and optional Python bindings.