Skip to content
Document DB v12 - Improved Interceptors with Soft Delete Integration, AI protections, & Admin UI with Aspire Integration!How!?

Algorithms & Serialization

Shiny.Spatial includes standalone algorithm classes and WKB serialization that can be used independently of the database layer.

The DistanceCalculator class provides distance computation between coordinates.

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)

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)

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);

The SpatialPredicates class provides geometry-to-geometry relationship testing for any pair of geometry types.

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); // true

Tests whether one geometry fully contains another.

bool contains = SpatialPredicates.Contains(polygon, point); // true

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));

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)

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
);

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 -

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.

using Shiny.Spatial.Serialization;
var point = new Point(-104.99, 39.74);
byte[] wkb = WkbWriter.Write(point);
Geometry geometry = WkbReader.Read(wkb);
// Cast to specific type
if (geometry is Point p)
{
Console.WriteLine($"{p.X}, {p.Y}");
}

WKB roundtrip serialization is supported for all geometry types:

  • Point
  • LineString
  • Polygon (with holes)
  • MultiPoint
  • MultiLineString
  • MultiPolygon
  • GeometryCollection
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