Skip to main content
Research Preview — Under active development.

Geospatial Operations

Astral provides verifiable spatial computations backed by PostGIS — the gold standard in geospatial databases with 20+ years of production use. All operations return Policy Attestations — signed results that can be used offchain or submitted onchain to trigger smart contract logic.
PostGIS uses GEOS (Geometry Engine Open Source) under the hood for geometry operations. GEOS is the C++ library that powers most professional geospatial software.

Available Operations

Measurements

Operations that return numeric results (as NumericPolicyAttestations):
OperationDescriptionUnitGeometry TypesPostGIS Function
distanceNearest distance between two geometriesmetersAnyST_Distance
areaArea of a polygonsquare metersPolygon, MultiPolygonST_Area
lengthLength of a linemetersLineString, MultiLineStringST_Length

Predicates

Operations that return boolean results (as BooleanPolicyAttestations):
OperationDescriptionPostGIS Function
containsIs geometry B entirely inside geometry A?ST_Contains
withinIs geometry within a specified radius of target?ST_DWithin
intersectsDo geometries share any space?ST_Intersects

Operation Examples

Code snippets need testing — Verify against actual implementation before use.

Distance

Calculate the nearest distance between two geometries in meters. For polygons, this returns the minimum distance between their boundaries.
const result = await astral.compute.distance({
  from: userLocationUID,
  to: landmarkUID,
  chainId: 84532,
  schema: SCHEMA_UID
});

console.log(result.result);  // 523.45 (meters)
console.log(result.units);   // "meters"

Contains

Check if a geometry is entirely inside a container geometry.
const result = await astral.compute.contains({
  container: sfBayAreaPolygonUID,  // Container polygon
  geometry: userLocationUID,        // Geometry to check
  chainId: 84532,
  schema: SCHEMA_UID
});

console.log(result.result);  // true or false

Within

Check if a geometry is within a specified radius of a target — essentially a radius check.
const result = await astral.compute.within({
  geometry: userLocationUID,   // Geometry to check
  target: landmarkUID,         // Target location
  radius: 500,                 // Radius in meters
  chainId: 84532,
  schema: SCHEMA_UID
});

console.log(result.result);  // true if within 500m

Intersects

Check if two geometries share any space (overlap, touch, or cross).
const result = await astral.compute.intersects({
  geometry1: polygon1UID,
  geometry2: polygon2UID,
  chainId: 84532,
  schema: SCHEMA_UID
});

console.log(result.result);  // true if they share space

Area

Calculate the area of a polygon (must be Polygon or MultiPolygon).
const result = await astral.compute.area({
  geometry: propertyBoundaryUID,
  chainId: 84532,
  schema: SCHEMA_UID
});

console.log(result.result);  // 5432.10 (square meters)
console.log(result.units);   // "square_meters"

Length

Calculate the length of a line (must be LineString or MultiLineString).
const result = await astral.compute.length({
  geometry: routeUID,
  chainId: 84532,
  schema: SCHEMA_UID
});

console.log(result.result);  // 2345.67 (meters)
console.log(result.units);   // "meters"

Units

All measurements use metric units only:
MeasurementUnit
Distancemeters
Lengthmeters
Areasquare meters
Radius (in within)meters
No unit conversion options are provided. Developers should convert client-side if needed.

Precision

Results are stored with centimeter precision to enable deterministic, reproducible computation:
TypePrecisionStorage
Distance/Length0.01mScaled integer (cm)
Area0.0001 m²Scaled integer (cm²)
523.45 meters → stored as 52345 (centimeters)
1234.5678 m² → stored as 12345678 (cm²)
We’re actively testing the reliability of deterministic geospatial computation with this precision approach. This is an area of ongoing research in the beta implementation.

Compute Options

All operations require these parameters:
interface ComputeOptions {
  chainId: number;        // Target chain for attestation signing
  schema: string;         // EAS schema UID (required)
  recipient?: string;     // Attestation recipient address
}
chainId is required. The service needs to know which chain to sign the policy attestation for.
We only support official EAS deployments on supported chains. See the SDK overview for the chain list.

Future Operations

Post-MVP, we plan to add:
OperationTypeDescription
disjointPredicateDo geometries not touch?
bufferTransformationCreate buffer zone around geometry
centroidTransformationFind center point
unionTransformationMerge geometries
intersectionTransformationOverlapping area
We’re also exploring nested/composable operations — combining multiple predicates in a single attestation, such as “is inside region A AND within 500m of landmark B”.

Client-Side Operations with Turf.js

We recommend Turf.js for client-side geospatial operations. Use Turf.js for instant UX feedback, and Astral for verifiable attestations:
import * as turf from '@turf/turf';

// Client-side: instant UX feedback (unverified, but instant)
const localDistance = turf.distance(point1, point2);
showUI(`${localDistance}km away`);

// Verifiable: signed attestation for onchain use
const attestedResult = await astral.compute.distance({
  from: uid1,
  to: uid2,
  chainId: 84532,
  schema: SCHEMA_UID
});
await astral.eas.submitDelegated(attestedResult.delegatedAttestation);
Use CaseToolWhy
Real-time UI feedbackTurf.jsInstant, free, runs client-side
Verifiable computationAstralSigned attestation for onchain actions

Next: Policy Attestations

Learn about the signed outputs of geospatial operations