# `Feature`

A shape with your own data attached, in GeoJSON's form, as a map library takes one.

Use it to send one shape and its properties to a map. To send a whole layer, use [`FeatureCollection`](/docs/types/type-feature-collection.md). Inside your app, store your own records with a [`Point`](/docs/types/type-point.md) or [`Polygon`](/docs/types/type-polygon.md) field.

## Shape

| Field | Type | Required? |
|---|---|---|
| `geometry` | `G` | Yes |
| `properties` | `P` | Yes |

## Example

```jadpo
type StopInfo = Object {
    name: Text
}

var stop: Feature<Point, StopInfo> = Feature {
    geometry: Point { latitude: 51.5072 longitude: -0.1276 altitude: none }
    properties: StopInfo { name: "Charing Cross" }
}
assert stop.properties.name == "Charing Cross"
```

## Good to know

- Name both types when you use it, the geometry and the properties: `Feature<Point, StopInfo>`. The geometry can be one of the six shapes or [`Geometry`](/docs/types/type-geometry.md).
- It has no `id`, so an incoming feature with one is refused.
- `==` tells you whether two are the same. `<` and `list.sort_by` don't take it, so sort by one of its parts instead.

## In JSON

A GeoJSON object of its geometry and properties, in a request, a response or `json.write`:

```json
{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.1276,51.5072]},"properties":{"name":"Site A"}}
```

## Details

<details>
<summary>Text form, storage, how it is shown, and operations</summary>

`Feature` is in the group Geospatial, and has been in Jadpo since 0.1.0.

### Text form

It has no single text form, so `text.from` and `text.parse` don't take it.

### How it is stored

It is stored in one column named for the field, of type `jsonb`. `{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.1276,51.5072]},"properties":{"name":"Site A"}}` is stored as `'{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.1276,51.5072]},"properties":{"name":"Site A"}}'::jsonb`.

### How it is shown to people

`text.format(value, locale:)` shows it to people in their locale.

With `locale: Locale.en_gb`:

| Value | Shown |
|---|---|
| `{"type":"Feature","geometry":{"type":"Point","coordinates":[-0.1276,51.5072]},"properties":{"name":"Site A"}}` | `""` |

### Operations

It also takes `text.format`, `json.read`, `json.write` and `==`. [How every standard type behaves](/docs/every-standard-type-meets-one-contract.md) says how they work.

</details>
