Expand description
§SQLiteGIS
PostGIS-style spatial functions for SQLite in pure Rust. Ships as a SQLite loadable extension (native and WebAssembly) and as a Diesel ORM integration. Geometries travel as EWKB BLOBs, matching the PostGIS wire format so queries port between SQLite and PostGIS without rewriting.
§SQLite extension
cargo build --release -p sqlitegis --features sqlite-extensionSELECT load_extension('./target/release/libsqlitegis');
SELECT ST_AsText(ST_Buffer(ST_Point(0, 0), 1.0));
SELECT ST_Distance(ST_GeomFromText('POINT(0 0)'), ST_GeomFromText('POINT(3 4)'));§Pure-Rust geometry
use sqlitegis::core::functions::constructors::st_point;
use sqlitegis::core::functions::measurement::st_distance;
let a = st_point(0.0, 0.0, None).unwrap();
let b = st_point(3.0, 4.0, None).unwrap();
assert!((st_distance(&a, &b).unwrap() - 5.0).abs() < 1e-10);§Diesel integration
use diesel::prelude::*;
use sqlitegis::diesel::functions::st_point;
use sqlitegis::diesel::prelude::*;
diesel::table! {
features (id) {
id -> Integer,
geom -> Nullable<sqlitegis::diesel::Geometry>,
}
}
let _query = features::table
.filter(features::geom.st_dwithin(st_point(13.4, 52.5).nullable(), 1000.0).eq(true))
.select(features::geom.st_astext());CreateSpatialIndex and DropSpatialIndex are DDL helpers without typed wrappers, called through diesel::sql_query. R-tree-backed queries run 50 to 60x faster than the non-indexed equivalents (see Benchmarks).
§Notes
Geodesic functions (ST_DistanceSphere, ST_DistanceSpheroid, ST_LengthSphere, ST_Azimuth, ST_Project, ST_DWithinSphere, ST_DWithinSpheroid) require SRID=4326 non-empty Point inputs and reject anything else. ST_GeomFromGeoJSON defaults to SRID=4326. ST_DWithin* predicates require a finite, non-negative distance.
§Benchmarks
Criterion central estimates on the included R-tree workloads:
| Scenario | Indexed | Non-indexed | Speedup |
|---|---|---|---|
intersects_window | 178 us | 9.81 ms | ~55x |
knn | 89 us | 5.66 ms | ~64x |
§Contributing
See CONTRIBUTING.md.
§License
MIT OR Apache-2.0
§Crate layout
Modules are gated behind features so consumers only pay for what they
ask for. See the [features] table in Cargo.toml for the full list;
in short:
coreis always available (pure-Rust geometry, EWKB I/O, function catalog, no SQLite or Diesel deps).sqliteaddscrate::sqlite::register_functionsfor in-process registration against a*mut sqlite3connection.sqlite-extensionfurther adds the#[no_mangle]C entry points so the cdylib build is loadable via SQLite’sload_extension.dieseladds backend-agnostic types (Geometry,Geography) plusGeometryExpressionMethods.diesel-sqlite/diesel-postgresadd the backend-specific impls.
Diesel users typically import via the prelude:
use sqlitegis::prelude::*; (re-exported from
crate::diesel::prelude).
Re-exports§
pub use core::error::Result;pub use core::error::SqliteGisError;pub use diesel::prelude;
Modules§
- core
- Pure-Rust geometry primitives, EWKB I/O, and the canonical function catalog used by the SQLite and Diesel layers to generate their surfaces. No SQLite, Diesel, or wasm dependency at this level.
- diesel
- Diesel ORM integration. Backend-agnostic types and the
GeometryExpressionMethodstrait live here. Enablediesel-sqliteordiesel-postgresto compile the backend-specific impls. - sqlite
- SQLite integration. Available under
feature = "sqlite"for in-process registration against a raw*mut sqlite3, and underfeature = "sqlite-extension"for the#[no_mangle]C entry points that make the cdylib loadable via SQLite’sload_extension.