Algorithms & Serialization
Shiny.Spatial includes standalone algorithm classes and WKB serialization that can be used independently of the database layer.
Distance Calculations
Section titled “Distance Calculations”The DistanceCalculator class provides distance computation between coordinates.
Haversine (WGS84)
Section titled “Haversine (WGS84)”Calculates the great-circle distance between two geographic coordinates on Earth. Returns distance in meters.
using Shiny.Spatial.Algorithms;
var london = new Coordinate(-0.1276, 51.5074);var paris = new Coordinate(2.3522, 48.8566);
double meters = DistanceCalculator.Haversine(london, paris);// ~343,000 meters (~343 km)Euclidean (Cartesian)
Section titled “Euclidean (Cartesian)”Calculates the straight-line distance between two points in a flat coordinate system.
var a = new Coordinate(0, 0);var b = new Coordinate(3, 4);
double distance = DistanceCalculator.Euclidean(a, b);// 5.0 (classic 3-4-5 triangle)Distance to segment
Section titled “Distance to segment”Calculates the perpendicular distance from a point to a line segment.
var point = new Coordinate(1, 1);var segStart = new Coordinate(0, 0);var segEnd = new Coordinate(2, 0);
double distance = DistanceCalculator.DistanceToSegment(point, segStart, segEnd);Spatial Predicates
Section titled “Spatial Predicates”The SpatialPredicates class provides geometry-to-geometry relationship testing for any pair of geometry types.
Intersects
Section titled “Intersects”Tests whether two geometries share any point in common.
using Shiny.Spatial.Algorithms;
var point = new Point(-104.99, 39.74);var polygon = new Polygon(new[]{ new Coordinate(-109.05, 37.0), new Coordinate(-102.05, 37.0), new Coordinate(-102.05, 41.0), new Coordinate(-109.05, 41.0), new Coordinate(-109.05, 37.0)});
bool intersects = SpatialPredicates.Intersects(point, polygon); // trueContains
Section titled “Contains”Tests whether one geometry fully contains another.
bool contains = SpatialPredicates.Contains(polygon, point); // truePoint-in-Polygon
Section titled “Point-in-Polygon”The PointInPolygon class implements the ray-casting algorithm for testing whether a coordinate falls inside a polygon, including support for holes (interior rings).
using Shiny.Spatial.Algorithms;
bool inside = PointInPolygon.Contains(polygon, new Coordinate(-104.99, 39.74));Segment Intersection
Section titled “Segment Intersection”The SegmentIntersection class tests whether two line segments cross each other.
using Shiny.Spatial.Algorithms;
bool crosses = SegmentIntersection.Intersects( new Coordinate(0, 0), new Coordinate(2, 2), // segment A new Coordinate(0, 2), new Coordinate(2, 0) // segment B);// true (segments form an X)Envelope Expansion
Section titled “Envelope Expansion”The EnvelopeExpander class expands an envelope by a distance, accounting for the coordinate system.
using Shiny.Spatial.Algorithms;
var envelope = new Envelope(-105, -104, 39, 40);
// Expand by 10km in WGS84 (accounts for Earth curvature)var expanded = EnvelopeExpander.ExpandByDistance( envelope, meters: 10_000, CoordinateSystem.Wgs84);Algorithm Performance
Section titled “Algorithm Performance”Benchmark results (Apple M2, .NET 10):
| Algorithm | Mean | Allocated |
|---|---|---|
| Haversine distance | 28.3 ns | - |
| Euclidean distance | 0.15 ns | - |
| Point-in-polygon (5 vertices) | 23.6 ns | - |
| Point-in-polygon (100 vertices) | 253 ns | - |
| Segment intersection | 2.7 ns | - |
| SpatialPredicates.Intersects (point/polygon) | 25.7 ns | 32 B |
| SpatialPredicates.Intersects (polygon/polygon) | 41.9 ns | - |
WKB Serialization
Section titled “WKB Serialization”Well-Known Binary (WKB) is a standard binary format for encoding geometries. Shiny.Spatial includes a complete WKB encoder and decoder supporting all geometry types.
Write geometry to WKB
Section titled “Write geometry to WKB”using Shiny.Spatial.Serialization;
var point = new Point(-104.99, 39.74);byte[] wkb = WkbWriter.Write(point);Read geometry from WKB
Section titled “Read geometry from WKB”Geometry geometry = WkbReader.Read(wkb);
// Cast to specific typeif (geometry is Point p){ Console.WriteLine($"{p.X}, {p.Y}");}Supported types
Section titled “Supported types”WKB roundtrip serialization is supported for all geometry types:
- Point
- LineString
- Polygon (with holes)
- MultiPoint
- MultiLineString
- MultiPolygon
- GeometryCollection
Serialization performance
Section titled “Serialization performance”| Operation | Mean | Allocated |
|---|---|---|
| Write Point | 58 ns | 432 B |
| Read Point | 50 ns | 248 B |
| Write Polygon (5 vertices) | 116 ns | 504 B |
| Read Polygon (5 vertices) | 136 ns | 672 B |
| Write Polygon (100 vertices) | 1.37 us | 5.7 KB |
| Read Polygon (100 vertices) | 2.21 us | 8.4 KB |
| Write LineString (50 coordinates) | 705 ns | 2.8 KB |
| Read LineString (50 coordinates) | 827 ns | 4.2 KB |