> For the complete documentation index, see [llms.txt](https://codifi-fdm.gitbook.io/codifi-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://codifi-fdm.gitbook.io/codifi-docs/cross-platform-features/ripple/spatial-formulas.md).

# Spatial Formulas

Ripple includes a full suite of geospatial operations powered by GPS coordinates. These work with the location data attached to Records in Codifi — points, lines, and polygons captured in the field or digitized in the office.

{% hint style="info" %}
**Spatial formulas need GPS data.** Distance, area, and coordinate formulas only return values when the Record has location data attached. Fields will show empty until GPS points are captured.
{% endhint %}

***

## Distance & Position

| Operation             | Measures                                      | Returns            | Typical use                                  |
| --------------------- | --------------------------------------------- | ------------------ | -------------------------------------------- |
| `haversineDistance`   | Straight-line distance between two GPS points | Meters             | How far apart are two features?              |
| `pointToLineDistance` | Shortest distance from a point to a line      | Meters             | How far is this find from the transect?      |
| `nearestPointOnLine`  | Closest spot on a line to a given point       | Lat/Lon + distance | Snap an artifact location to the survey path |
| `bearing`             | Compass direction from one point to another   | Degrees (0–360)    | Direction from site to nearest water source  |
| `midpoint`            | Center point between two locations            | Lat/Lon            | Center of a two-point baseline               |

## Line Measurements

| Operation          | Measures                                      | Returns | Typical use                         |
| ------------------ | --------------------------------------------- | ------- | ----------------------------------- |
| `lineLength`       | Total length of a line geometry               | Meters  | How long is this transect or trail? |
| `totalTrackLength` | Sum of point-to-point distances along a track | Meters  | Total distance walked during survey |

## Area & Boundary

| Operation                   | Measures                                       | Returns         | Typical use                                   |
| --------------------------- | ---------------------------------------------- | --------------- | --------------------------------------------- |
| `polygonArea`               | Area enclosed by a polygon                     | Square meters   | Site boundary area, excavation extent         |
| `polygonPerimeter`          | Distance around a polygon                      | Meters          | Fencing estimate, site boundary length        |
| `pointInPolygon`            | Whether a point is inside a polygon            | True / False    | Is this artifact within the site boundary?    |
| `centroid`                  | Geometric center of all locations              | Lat/Lon         | Representative point for a site               |
| `boundingBox`               | Smallest rectangle enclosing all points        | Min/Max Lat/Lon | Map extent for a Record                       |
| `polygonAreaUtmPlanar`      | Area, projected into UTM before measuring      | Square meters   | Acreage that has to agree with ArcGIS         |
| `polygonPerimeterUtmPlanar` | Perimeter, projected into UTM before measuring | Meters          | Boundary length that has to agree with ArcGIS |

### Which Area Operator Should I Use?

Both are correct. They answer slightly different questions, and the difference matters when somebody else is going to check your number.

|                       | `polygonArea`                                  | `polygonAreaUtmPlanar`                                         |
| --------------------- | ---------------------------------------------- | -------------------------------------------------------------- |
| **How it measures**   | On the curved surface of the earth (spherical) | Projects into the local UTM zone first, then measures flat     |
| **Agrees with**       | Turf.js and most web mapping tools             | ArcGIS, QGIS, and the acreage attribute on a UTM feature class |
| **Reach for it when** | You want a good general-purpose area           | The number goes to a SHPO, an agency, or into a contract       |

New in v3.3, the UTM planar operators are also what the mobile app's own measurement readout uses, so a formula and the Summary sheet on an iPad now report the same figure for the same polygon.

{% hint style="warning" %}
**Converting to acres: use the US survey acre.** Divide square meters by **4046.8726098**, not by the international acre 4046.8564224. The US survey acre is what ArcGIS uses for the acreage attribute on a UTM feature class, and the apps display it too. On a large polygon the two constants diverge by enough to be queried: on 88,000 acres the difference is roughly a third of an acre.
{% endhint %}

## Coordinate Information

| Accessor                    | Description                                 | Returns                                                     |
| --------------------------- | ------------------------------------------- | ----------------------------------------------------------- |
| `utm`                       | UTM conversion of a location point          | Object with `zone`, `easting`, `northing`, plus zone letter |
| `locationIsValid`           | Check if GPS coordinates are in valid range | True / False                                                |
| `locationCount`             | Number of GPS points on a Record            | Count                                                       |
| `latitude` (on a location)  | Latitude of a location point                | Decimal degrees                                             |
| `longitude` (on a location) | Longitude of a location point               | Decimal degrees                                             |

{% hint style="warning" %}
**`latitude` and `longitude` are properties on a location object, not standalone operators.** Read them via dot navigation on a location, e.g. the **first** location of a Record. Same goes for `easting`, `northing`, and `zone` — call `utm` first to get the UTM object, then read its parts.
{% endhint %}

***

## Example: How Far Is This Find from the Survey Transect?

On an Artifact / Isolate Record (point), calculate its perpendicular distance from the parent Transect (line).

**Setup:**

* Parent: Transect Record with a **line** geometry (walked path)
* Child: Artifact Record with a **point** geometry (find location)

**Formula for&#x20;*****Distance from Transect (m)*****:**

```
round( pointToLineDistance(this point, parent's line), 1 )
```

**Result:** `23.7` (meters from the transect line)

**Use case:** Flag any artifacts found more than 50 m from the transect for QC review. Combine with a [visibility formula](/codifi-docs/cross-platform-features/ripple/visibility-formulas.md) to show a warning field when distance > 50.

***

## Example: Automatic Site Area in Acres

Calculate the area of a site boundary polygon and convert to acres.

**Setup:** Site Record with a **polygon** geometry (site boundary).

**Formula for&#x20;*****Site Area (acres)*****:**

```
round( polygonArea() / 4046.86, 2 )
```

(4,046.86 m² = 1 acre)

**Result:** `2.34` acres — updates automatically whenever the polygon is edited.

***

## Example: UTM Coordinates Displayed on a Record

Show the UTM Easting and Northing for a point Record.

```
UTM Easting  = utm.easting
UTM Northing = utm.northing
UTM Zone     = utm.zone
```

**Result:** `Easting: 327,456 Northing: 3,945,123 Zone: 13S`

***

## Tips for Spatial Formulas

* **All spatial calculations use the WGS84 coordinate system** and return metric units (meters, square meters). To convert: 1 acre = 4,046.86 m², 1 mile = 1,609.34 m, 1 hectare = 10,000 m².
* **Area and perimeter only work on polygons.** Calling `polygonArea()` on a Record with a point or line geometry returns nothing.
* **Read latitude/longitude from a specific location, not from the Record directly.** Records can have multiple location points (lines, polygons, repeated captures); the first location is usually what you want for "where is this?" use cases.
* **Distance to parent works on lines and polygons.** `pointToLineDistance` accepts the parent's geometry whether it's a line or the boundary of a polygon.

***

## See Also

* [GPS Widgets](/codifi-docs/mobile-app/mapping-locations/gps-and-live-data/live-data-bar-and-widgets.md) — live, on-screen versions of these calculations during fieldwork
* [GPS Technical Reference](/codifi-docs/mobile-app/mapping-locations/gps-and-live-data/gps-technical-reference.md) — accuracy thresholds, datum conversions, and external GPS handling
* [Operations Reference](/codifi-docs/cross-platform-features/ripple/reference.md#spatial--geospatial) — every spatial operator with arguments and return types
