import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# `OctetRegion`

The shape a predicate is evaluated against. Constructed via static factory methods that validate inputs eagerly. Invalid regions trap at construction.

## Factories

### `country`. Verified via MCC.

<Tabs groupId="platform">
  <TabItem value="swift" label="Swift (iOS)">

```swift
public static func country(isoCode: String) -> OctetRegion
// e.g. OctetRegion.country(isoCode: "US")
```

  </TabItem>
  <TabItem value="kotlin" label="Kotlin (Android)">

```kotlin
@JvmStatic
fun country(isoCode: String): CountryRegion
// e.g. OctetRegion.country("US")
```

  </TabItem>
</Tabs>

`isoCode` must be ISO 3166-1 alpha-2 (two uppercase letters). Verified via mobile country code from the serving cell tower and network operator. Usually works indoors and without GPS.

### `subdivision`. ISO 3166-2.

<Tabs groupId="platform">
  <TabItem value="swift" label="Swift (iOS)">

```swift
public static func subdivision(isoCode: String) -> OctetRegion
// e.g. OctetRegion.subdivision(isoCode: "US-CA")
```

  </TabItem>
  <TabItem value="kotlin" label="Kotlin (Android)">

```kotlin
@JvmStatic
fun subdivision(isoCode: String): SubdivisionRegion
// e.g. OctetRegion.subdivision("US-CA")
```

  </TabItem>
</Tabs>

Country code, hyphen, 1-3 alphanumeric chars. Verified at proof time by reverse-geocoding the trusted fix's admin area.

### `usState`. Sugar for `subdivision`.

<Tabs groupId="platform">
  <TabItem value="swift" label="Swift (iOS)">

```swift
public static func usState(_ stateCode: String) -> OctetRegion
// OctetRegion.usState("CA") == OctetRegion.subdivision(isoCode: "US-CA")
```

  </TabItem>
  <TabItem value="kotlin" label="Kotlin (Android)">

```kotlin
@JvmStatic
fun usState(stateCode: String): SubdivisionRegion
// OctetRegion.usState("CA") == OctetRegion.subdivision("US-CA")
```

  </TabItem>
</Tabs>

Takes a standard two-letter US postal abbreviation.

### `city`. Name-resolved.

<Tabs groupId="platform">
  <TabItem value="swift" label="Swift (iOS)">

```swift
public static func city(name: String) -> OctetRegion
// e.g. OctetRegion.city(name: "San Francisco")
```

  </TabItem>
  <TabItem value="kotlin" label="Kotlin (Android)">

```kotlin
@JvmStatic
fun city(name: String): CityRegion
// e.g. OctetRegion.city("San Francisco")
```

  </TabItem>
</Tabs>

The SDK resolves `name` to an H3 polygon set internally (bundled atlas for top-N cities, server lookup beyond that).

### `disc`. Analytic circle.

<Tabs groupId="platform">
  <TabItem value="swift" label="Swift (iOS)">

```swift
public static func disc(center: LatLon, radiusMeters: Meters) -> OctetRegion
// e.g. OctetRegion.disc(center: LatLon(37.422, -122.084), radiusMeters: 250)
```

  </TabItem>
  <TabItem value="kotlin" label="Kotlin (Android)">

```kotlin
@JvmStatic
fun disc(center: LatLon, radiusMeters: Meters): EllipseRegion
// e.g. OctetRegion.disc(LatLon(37.422, -122.084), 250.0)
```

  </TabItem>
</Tabs>

A disc is stored internally as a degenerate ellipse (equal axes, heading 0). The serializer renders this special case as `disc(lat,lon,r)` for readability.

### `ellipse`. Oriented 2D ground ellipse.

<Tabs groupId="platform">
  <TabItem value="swift" label="Swift (iOS)">

```swift
public static func ellipse(
    center: LatLon,
    semiMajorM: Meters,
    semiMinorM: Meters,
    headingDeg: Double      // [0, 360), clockwise from north
) -> OctetRegion
```

  </TabItem>
  <TabItem value="kotlin" label="Kotlin (Android)">

```kotlin
@JvmStatic
fun ellipse(
    center: LatLon,
    semiMajorM: Meters,
    semiMinorM: Meters,
    headingDeg: Double,     // [0, 360), clockwise from north
): EllipseRegion
```

  </TabItem>
</Tabs>

Pre-validated: `semiMinorM > 0`, `semiMajorM >= semiMinorM`, `headingDeg in [0, 360)`.

### `box3D`. Bounding box.

<Tabs groupId="platform">
  <TabItem value="swift" label="Swift (iOS)">

```swift
public static func box3D(
    latRange: ClosedRange<Double>,
    lonRange: ClosedRange<Double>,
    altRange: ClosedRange<Double>
) -> OctetRegion
```

  </TabItem>
  <TabItem value="kotlin" label="Kotlin (Android)">

```kotlin
@JvmStatic
fun box3D(
    latRange: ClosedFloatingPointRange<Double>,
    lonRange: ClosedFloatingPointRange<Double>,
    altRange: ClosedFloatingPointRange<Double>,
): BoundingBox3DRegion
```

  </TabItem>
</Tabs>

Latitude validated to `[-90, 90]`, longitude to `[-180, 180]`, altitude finite.

### `polygonSet`. Union of H3 cells.

<Tabs groupId="platform">
  <TabItem value="swift" label="Swift (iOS)">

```swift
public static func polygonSet(cells: [H3Cell]) -> OctetRegion
```

  </TabItem>
  <TabItem value="kotlin" label="Kotlin (Android)">

```kotlin
@JvmStatic
fun polygonSet(cells: List<H3Cell>): PolygonSetRegion
```

  </TabItem>
</Tabs>

Non-empty cell list. Free-form lat/lon polygons are not accepted. Quantize to H3 ahead of time. See [Regions](/docs/concepts/regions/) for why.

### `earth`. Defensive fallback.

<Tabs groupId="platform">
  <TabItem value="swift" label="Swift (iOS)">

```swift
public static func earth(maxAltitudeMeters: Meters = 10_000) -> OctetRegion
```

  </TabItem>
  <TabItem value="kotlin" label="Kotlin (Android)">

```kotlin
@JvmStatic
fun earth(maxAltitudeMeters: Meters = 10_000.0): EarthRegion
```

  </TabItem>
</Tabs>

`isWithin(.earth(...))` always returns `YES` if the SDK can produce any proof at all.

## Value types

<Tabs groupId="platform">
  <TabItem value="swift" label="Swift (iOS)">

```swift
public struct LatLon: Sendable, Hashable {
    public let latitude: Double   // [-90, 90]
    public let longitude: Double  // [-180, 180]
}

public typealias Meters = Double
```

  </TabItem>
  <TabItem value="kotlin" label="Kotlin (Android)">

```kotlin
data class LatLon(val latitude: Double, val longitude: Double) {
    // validated [-90,90] and [-180,180] at construction
}

typealias Meters = Double

@JvmInline
value class H3Cell(val cellId: ULong)  // 64-bit H3 cell index
```

  </TabItem>
</Tabs>

## Construction helpers (Android only at v1)

### `RegionSpec` + `getRegion`

```kotlin
sealed class RegionSpec {
    data class Country(val isoCode: String)        : RegionSpec()
    data class Subdivision(val isoCode: String)    : RegionSpec()
    data class City(val name: String)              : RegionSpec()
    data class NamedZone(val id: String)           : RegionSpec()
}

suspend fun getRegion(spec: RegionSpec): OctetRegion
```

`country` and `subdivision` are local and return immediately. `city` and `namedZone` are declared but currently throw `OctetFutureFlag`. Atlas and server lookup are not yet wired.

### `buildRegion { ... }` DSL

```kotlin
val r = buildRegion {
    disc(center = LatLon(37.422, -122.084), radiusMeters = 250.0)
}
```

Sugar over the static factories. Synchronous. Same validation rules.

## Inspecting a region

Available on all platforms via the uniform `.toStr()` / `.toJson()` / `.toJsonl()` methods. See [Serialization](/docs/api-reference/serialization/). Android additionally exposes the free functions:

```kotlin
fun whatisRegion(r: OctetRegion): String   // human, NOT stable
fun regionToStr(r: OctetRegion): String    // machine, STABLE wire form
```

## See also

- [Regions](/docs/concepts/regions/). Why the taxonomy looks the way it does.
- [Predicates](/docs/api-reference/predicates/). What consumes an `OctetRegion`.
- [Serialization](/docs/api-reference/serialization/). `.toStr()` / `.toJson()` / `.toJsonl()` on every region.
