HeliosDB Geospatial
HeliosDB Geospatial
PostGIS-compatible geospatial data types and functions for HeliosDB v3.0.
Features
- Full OGC Geometry Support: Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection
- 30+ PostGIS Functions: Comprehensive ST_* function library
- R-tree Spatial Indexing: Fast spatial queries with R-tree data structure
- K-Nearest Neighbor Search: Efficient KNN queries with distance limits
- SRID Support: Full coordinate reference system transformations
- WKT/WKB Support: Well-Known Text and Well-Known Binary formats
- Geography Type: Spherical calculations on Earth’s surface
Quick Start
use heliosdb_geospatial::{Geometry, Point, functions::*};
// Create pointslet point1 = Point::new(0.0, 0.0, Some(4326));let point2 = Point::new(1.0, 1.0, Some(4326));
// Calculate distancelet distance = st_distance( &Geometry::Point(point1), &Geometry::Point(point2)).unwrap();
println!("Distance: {}", distance);Geometry Types
Point
let point = Point::new(-122.4194, 37.7749, Some(4326));let geom = Geometry::Point(point);LineString
use heliosdb_geospatial::{LineString, Coord};
let coords = vec![ Coord::new(0.0, 0.0), Coord::new(1.0, 1.0), Coord::new(2.0, 2.0),];let line = LineString::new(coords, Some(4326));Polygon
let exterior = LineString::new(vec![ Coord::new(0.0, 0.0), Coord::new(4.0, 0.0), Coord::new(4.0, 4.0), Coord::new(0.0, 4.0), Coord::new(0.0, 0.0),], None);
let polygon = Polygon::new(exterior, vec![], Some(4326));Spatial Functions
Measurement Functions
st_distance- Euclidean distance between geometriesst_distance_spheroid- Distance on Earth’s surface (Haversine)st_length- Length of linear geometriesst_area- Area of polygon geometriesst_perimeter- Perimeter of polygon geometries
Spatial Relationships
st_contains- Test if geometry A contains Bst_within- Test if geometry A is within Bst_intersects- Test if geometries intersectst_disjoint- Test if geometries are disjointst_touches- Test if boundaries touchst_overlaps- Test if geometries overlapst_equals- Test if geometries are equal
Geometry Processing
st_centroid- Calculate centroidst_envelope- Calculate bounding boxst_convex_hull- Calculate convex hullst_simplify- Simplify using Douglas-Peuckerst_simplify_preserve_topology- Simplify preserving topologyst_buffer- Create buffer around geometry
Accessors
st_x,st_y- Get coordinatesst_npoints- Get number of pointsst_srid- Get SRIDst_set_srid- Set SRIDst_geometry_type- Get geometry typest_is_empty- Test if emptyst_is_valid- Test if valid
Spatial Indexing
R-tree Index
use heliosdb_geospatial::rtree::SpatialIndex;
let mut index = SpatialIndex::new(Some(4326));
// Insert geometriesindex.insert(1, Geometry::Point(Point::new(0.0, 0.0, Some(4326)))).unwrap();index.insert(2, Geometry::Point(Point::new(1.0, 1.0, Some(4326)))).unwrap();
// Query bounding boxlet results = index.query_bbox(-1.0, -1.0, 2.0, 2.0);
// K-Nearest Neighbor searchlet nearest = index.knn(0.5, 0.5, 5);Bulk Loading
use heliosdb_geospatial::rtree::SpatialIndexBuilder;
let mut builder = SpatialIndexBuilder::new(Some(4326));
for i in 0..1000 { let point = Point::new(i as f64, i as f64, Some(4326)); builder.add(i, Geometry::Point(point)).unwrap();}
let index = builder.build(); // Efficient bulk loadingSpatial Join
use heliosdb_geospatial::rtree::spatial_join;
let results = spatial_join(&index1, &index2, 100.0).unwrap();
for result in results { println!("Left: {}, Right: {}, Distance: {}", result.left_id, result.right_id, result.distance);}WKT Support
use heliosdb_geospatial::wkt::{parse_wkt, to_wkt};
// Parse WKTlet geom = parse_wkt("POINT(1 2)").unwrap();
// With SRIDlet (geom, srid) = parse_wkt_with_srid("SRID=4326;POINT(1 2)").unwrap();
// Format as WKTlet wkt = to_wkt(&geom);WKB Support
use heliosdb_geospatial::wkb::{to_wkb, from_wkb, ByteOrder};
// Encode to WKBlet wkb = to_wkb(&geom, ByteOrder::LittleEndian).unwrap();
// Decode from WKBlet geom = from_wkb(&wkb).unwrap();
// With SRIDlet geom = from_wkb_with_srid(&wkb, 4326).unwrap();Coordinate Transformations
use heliosdb_geospatial::projections::{ ProjectionTransformer, transform_to_wgs84, transform_to_web_mercator,};
let transformer = ProjectionTransformer::new();
// Transform from WGS84 to Web Mercatorlet point = Point::new(-122.4194, 37.7749, Some(4326));let geom = Geometry::Point(point);
let transformed = transformer.transform(&geom, 3857).unwrap();
// Helper functionslet wgs84_geom = transform_to_wgs84(&geom).unwrap();let web_mercator_geom = transform_to_web_mercator(&geom).unwrap();Geography Type
use heliosdb_geospatial::{Geography, Point, Geometry};
// Geography uses spherical calculationslet point = Point::new(-122.4194, 37.7749, None);let geog = Geography::new(Geometry::Point(point), true);
// Always uses WGS84 (SRID 4326) for spherical calculationsassert_eq!(geog.srid(), 4326);Supported SRIDs
- 4326: WGS84 (Geographic - latitude/longitude)
- 3857: Web Mercator (Projected)
- 4269: NAD83 (North American Datum)
- 32601-32660: WGS84 UTM Northern Hemisphere
- 32701-32760: WGS84 UTM Southern Hemisphere
- 4258: ETRS89 (European)
- 27700: British National Grid
Performance
The R-tree spatial index provides efficient spatial queries:
- Point insertion: O(log n)
- Bounding box query: O(log n + k) where k is number of results
- KNN search: O(k log n)
- Bulk loading: O(n log n) with better tree structure
Examples
See the examples/ directory for complete examples:
basic_usage.rs- Basic geometry operationsspatial_index.rs- R-tree indexing and queriesprojections.rs- Coordinate transformationswkt_wkb.rs- Text and binary formats
License
MIT OR Apache-2.0