> ## Documentation Index
> Fetch the complete documentation index at: https://astral-6ef288be-claude-ascii-globe-mouse-interaction-bupya.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Geospatial Operations

> Spatial computations powered by PostGIS

<Warning>
  **Research Preview** — Under active development.
</Warning>

# 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](/concepts/policy-attestations) — signed results that can be used offchain or submitted onchain to trigger smart contract logic.

<Info>
  PostGIS uses [GEOS](https://libgeos.org/) (Geometry Engine Open Source) under the hood for geometry operations. GEOS is the C++ library that powers most professional geospatial software.
</Info>

## Available Operations

### Measurements

Operations that return **numeric** results (as [NumericPolicyAttestations](/concepts/policy-attestations#numericpolicyattestation)):

| Operation  | Description                             | Unit          | Geometry Types              | PostGIS Function |
| ---------- | --------------------------------------- | ------------- | --------------------------- | ---------------- |
| `distance` | Nearest distance between two geometries | meters        | Any                         | `ST_Distance`    |
| `area`     | Area of a polygon                       | square meters | Polygon, MultiPolygon       | `ST_Area`        |
| `length`   | Length of a line                        | meters        | LineString, MultiLineString | `ST_Length`      |

### Predicates

Operations that return **boolean** results (as [BooleanPolicyAttestations](/concepts/policy-attestations#booleanpolicyattestation)):

| Operation    | Description                                      | PostGIS Function |
| ------------ | ------------------------------------------------ | ---------------- |
| `contains`   | Is geometry B **entirely** inside geometry A?    | `ST_Contains`    |
| `within`     | Is geometry within a specified radius of target? | `ST_DWithin`     |
| `intersects` | Do geometries share any space?                   | `ST_Intersects`  |

## Operation Examples

<Note>
  **Code snippets need testing** — Verify against actual implementation before use.
</Note>

### Distance

Calculate the nearest distance between two geometries in meters. For polygons, this returns the minimum distance between their boundaries.

```typescript theme={null}
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.

```typescript theme={null}
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**.

```typescript theme={null}
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).

```typescript theme={null}
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).

```typescript theme={null}
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).

```typescript theme={null}
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**:

| Measurement          | Unit          |
| -------------------- | ------------- |
| Distance             | meters        |
| Length               | meters        |
| Area                 | square meters |
| Radius (in `within`) | meters        |

<Note>
  No unit conversion options are provided. Developers should convert client-side if needed.
</Note>

## Precision

Results are stored with centimeter precision to enable **deterministic, reproducible** computation:

| Type            | Precision | Storage              |
| --------------- | --------- | -------------------- |
| Distance/Length | 0.01m     | Scaled integer (cm)  |
| Area            | 0.0001 m² | Scaled integer (cm²) |

```
523.45 meters → stored as 52345 (centimeters)
1234.5678 m² → stored as 12345678 (cm²)
```

<Info>
  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.
</Info>

## Compute Options

All operations require these parameters:

```typescript theme={null}
interface ComputeOptions {
  chainId: number;        // Target chain for attestation signing
  schema: string;         // EAS schema UID (required)
  recipient?: string;     // Attestation recipient address
}
```

<Warning>
  **`chainId` is required.** The service needs to know which chain to sign the policy attestation for.
</Warning>

<Note>
  We only support official EAS deployments on supported chains. See the SDK overview for the chain list.
</Note>

## Future Operations

Post-MVP, we plan to add:

| Operation      | Type           | Description                        |
| -------------- | -------------- | ---------------------------------- |
| `disjoint`     | Predicate      | Do geometries not touch?           |
| `buffer`       | Transformation | Create buffer zone around geometry |
| `centroid`     | Transformation | Find center point                  |
| `union`        | Transformation | Merge geometries                   |
| `intersection` | Transformation | Overlapping 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](https://turfjs.org/)** for client-side geospatial operations. Use Turf.js for instant UX feedback, and Astral for verifiable attestations:

```typescript theme={null}
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 Case               | Tool    | Why                                    |
| ---------------------- | ------- | -------------------------------------- |
| Real-time UI feedback  | Turf.js | Instant, free, runs client-side        |
| Verifiable computation | Astral  | Signed attestation for onchain actions |

<Card title="Next: Policy Attestations" icon="file-signature" href="/concepts/policy-attestations">
  Learn about the signed outputs of geospatial operations
</Card>
