Geospatial Types
Chronicle has built-in support for geospatial types from Cratis.Fundamentals: Point, LineString, and Polygon. You can use them directly in events, read models, reducers, and projections without any extra setup.
Geospatial Types
Section titled “Geospatial Types”The three geospatial types are records defined in the Cratis.Geospatial namespace:
using Cratis.Geospatial;
public static class GeospatialTypeExamples{ public static Point CreatePoint() => new(10.456, 42.123);
public static LineString CreatePath() => new([ new Point(10.456, 42.123), new Point(11.789, 43.456) ]);
public static Polygon CreateBoundary() => new( Shell: new LinearRing([ new Point(0, 0), new Point(10, 0), new Point(10, 10), new Point(0, 10), new Point(0, 0) ]), Holes: []);}- Point represents a single geographic location in longitude-then-latitude order (GeoJSON standard).
- LineString represents a connected series of points forming a line or path.
- Polygon represents an enclosed area with a shell (outer boundary) and optional holes (inner boundaries).
- LinearRing is an array of points that form a closed loop (used by Polygon).
Using Geospatial Types in Events and Read Models
Section titled “Using Geospatial Types in Events and Read Models”Import the namespace and use the geospatial types as any other property type:
using Cratis.Chronicle.Events;using Cratis.Geospatial;
[EventType]public record GeospatialAssetLocationUpdated(Point Location);
[EventType]public record GeospatialRouteCreated(LineString Path);
[EventType]public record GeospatialZoneEstablished(Polygon Boundaries);
public record GeospatialAssetReadModel(Guid Id, Point Location);public record GeospatialRouteReadModel(Guid Id, LineString Path);public record GeospatialZoneReadModel(Guid Id, Polygon Boundaries);Projections and reducers handle geospatial types like any other value type. AutoMap picks them up automatically:
using Cratis.Chronicle.Events;using Cratis.Chronicle.Projections;using Cratis.Geospatial;
[EventType]public record GeospatialProjAssetLocationUpdated(Point Location);
public record GeospatialProjAssetReadModel(Guid Id, Point Location);
public class GeospatialProjAssetProjection : IProjectionFor<GeospatialProjAssetReadModel>{ // AutoMap picks up the Point-typed property automatically — no manual mapping needed public void Define(IProjectionBuilderFor<GeospatialProjAssetReadModel> builder) => builder .From<GeospatialProjAssetLocationUpdated>();}JSON Schema
Section titled “JSON Schema”When Chronicle generates the JSON schema, geospatial types are annotated with their GeoJSON-compatible formats:
Point: Generates as an object with longitude and latitude properties, marked with "format": "point"
{ "type": "object", "format": "point", "properties": { "longitude": { "type": "number" }, "latitude": { "type": "number" } }}LineString: Generates as an array of point objects, marked with "format": "linestring"
{ "type": "array", "format": "linestring", "items": { "type": "object", "properties": { "longitude": { "type": "number" }, "latitude": { "type": "number" } } }}Polygon: Generates as an object with shell and holes, marked with "format": "polygon"
{ "type": "object", "format": "polygon", "properties": { "shell": { "type": "array", "items": { "type": "object", "properties": { "longitude": { "type": "number" }, "latitude": { "type": "number" } } } }, "holes": { "type": "array", "items": { "type": "array", "items": { "type": "object", "properties": { "longitude": { "type": "number" }, "latitude": { "type": "number" } } } } } }}This lets consumers inspect the schema and know the field contains geographic data, and the format annotations make it possible for tools like the Workbench to recognize and properly display geographic values.
Storage
Section titled “Storage”MongoDB Sink
Section titled “MongoDB Sink”Chronicle stores geospatial values in BSON format:
Point: Flat document with longitude and latitude
{ "longitude": 10.456, "latitude": 42.123 }LineString: Array of points
[ { "longitude": 10.456, "latitude": 42.123 }, { "longitude": 11.789, "latitude": 43.456 }]Polygon: Document with shell (outer ring) and holes (inner rings)
{ "shell": [ { "longitude": 0, "latitude": 0 }, { "longitude": 10, "latitude": 0 }, { "longitude": 10, "latitude": 10 }, { "longitude": 0, "latitude": 10 }, { "longitude": 0, "latitude": 0 } ], "holes": []}BSON serializers are registered automatically — no configuration required.
SQL Sink
Section titled “SQL Sink”Geospatial types generate as JSON objects in the schema, so the SQL sink stores them as JSON columns. No migration or configuration changes are required.
Workbench Display
Section titled “Workbench Display”The Chronicle Workbench recognizes geospatial format markers in event schemas and renders them as human-readable strings rather than expanding nested structures:
Point: lat: 42.123, long: 10.456LineString: [lat: 42.123, long: 10.456], [lat: 43.456, long: 11.789]Polygon: shell with 5 points, 0 holes