Skip to content

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 points
let point1 = Point::new(0.0, 0.0, Some(4326));
let point2 = Point::new(1.0, 1.0, Some(4326));
// Calculate distance
let 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 geometries
  • st_distance_spheroid - Distance on Earth’s surface (Haversine)
  • st_length - Length of linear geometries
  • st_area - Area of polygon geometries
  • st_perimeter - Perimeter of polygon geometries

Spatial Relationships

  • st_contains - Test if geometry A contains B
  • st_within - Test if geometry A is within B
  • st_intersects - Test if geometries intersect
  • st_disjoint - Test if geometries are disjoint
  • st_touches - Test if boundaries touch
  • st_overlaps - Test if geometries overlap
  • st_equals - Test if geometries are equal

Geometry Processing

  • st_centroid - Calculate centroid
  • st_envelope - Calculate bounding box
  • st_convex_hull - Calculate convex hull
  • st_simplify - Simplify using Douglas-Peucker
  • st_simplify_preserve_topology - Simplify preserving topology
  • st_buffer - Create buffer around geometry

Accessors

  • st_x, st_y - Get coordinates
  • st_npoints - Get number of points
  • st_srid - Get SRID
  • st_set_srid - Set SRID
  • st_geometry_type - Get geometry type
  • st_is_empty - Test if empty
  • st_is_valid - Test if valid

Spatial Indexing

R-tree Index

use heliosdb_geospatial::rtree::SpatialIndex;
let mut index = SpatialIndex::new(Some(4326));
// Insert geometries
index.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 box
let results = index.query_bbox(-1.0, -1.0, 2.0, 2.0);
// K-Nearest Neighbor search
let 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 loading

Spatial 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 WKT
let geom = parse_wkt("POINT(1 2)").unwrap();
// With SRID
let (geom, srid) = parse_wkt_with_srid("SRID=4326;POINT(1 2)").unwrap();
// Format as WKT
let wkt = to_wkt(&geom);

WKB Support

use heliosdb_geospatial::wkb::{to_wkb, from_wkb, ByteOrder};
// Encode to WKB
let wkb = to_wkb(&geom, ByteOrder::LittleEndian).unwrap();
// Decode from WKB
let geom = from_wkb(&wkb).unwrap();
// With SRID
let 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 Mercator
let point = Point::new(-122.4194, 37.7749, Some(4326));
let geom = Geometry::Point(point);
let transformed = transformer.transform(&geom, 3857).unwrap();
// Helper functions
let 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 calculations
let point = Point::new(-122.4194, 37.7749, None);
let geog = Geography::new(Geometry::Point(point), true);
// Always uses WGS84 (SRID 4326) for spherical calculations
assert_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 operations
  • spatial_index.rs - R-tree indexing and queries
  • projections.rs - Coordinate transformations
  • wkt_wkb.rs - Text and binary formats

License

MIT OR Apache-2.0