You are viewing v3.0.0 of the docs. The latest is v3.1.2.
Docs/Mobile SDK/API Reference

OctetRegion

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

Factories

country (ISO 3166-1)

public static func country(isoCode: String) -> OctetRegion
// e.g. OctetRegion.country(isoCode: "US")
@JvmStatic
fun country(isoCode: String): CountryRegion
// e.g. OctetRegion.country("US")

isoCode must be ISO 3166-1 alpha-2 (two uppercase letters).

subdivision (ISO 3166-2)

public static func subdivision(isoCode: String) -> OctetRegion
// e.g. OctetRegion.subdivision(isoCode: "US-CA")
@JvmStatic
fun subdivision(isoCode: String): SubdivisionRegion
// e.g. OctetRegion.subdivision("US-CA")

Country code, hyphen, 1–3 alphanumeric chars.

usState

public static func usState(_ stateCode: String) -> OctetRegion
// OctetRegion.usState("CA") == OctetRegion.subdivision(isoCode: "US-CA")
@JvmStatic
fun usState(stateCode: String): SubdivisionRegion
// OctetRegion.usState("CA") == OctetRegion.subdivision("US-CA")

Takes a standard two-letter US postal abbreviation.

city

public static func city(name: String) -> OctetRegion
// e.g. OctetRegion.city(name: "San Francisco")
@JvmStatic
fun city(name: String): CityRegion
// e.g. OctetRegion.city("San Francisco")

The SDK resolves name to an H3 polygon set internally.

disc

public static func disc(center: LatLon, radiusMeters: Meters) -> OctetRegion
// e.g. OctetRegion.disc(center: LatLon(37.422, -122.084), radiusMeters: 250)
@JvmStatic
fun disc(center: LatLon, radiusMeters: Meters): EllipseRegion
// e.g. OctetRegion.disc(LatLon(37.422, -122.084), 250.0)

A disc is stored internally as a degenerate ellipse (equal axes, heading 0). .toStr() labels it "Disc". The JSON form encodes it as an ellipse ("shape":"ellipse"). See Serialization.

ellipse

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

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

Only discs are answered in this release. A predicate on an ellipse with unequal axes returns INDETERMINATE with NOT_YET_RELEASED.

box3D

public static func box3D(
    latRange: ClosedRange<Double>,
    lonRange: ClosedRange<Double>,
    altRange: ClosedRange<Double>
) -> OctetRegion
@JvmStatic
fun box3D(
    latRange: ClosedFloatingPointRange<Double>,
    lonRange: ClosedFloatingPointRange<Double>,
    altRange: ClosedFloatingPointRange<Double>,
): BoundingBox3DRegion

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

polygonSet

public static func polygonSet(cells: [H3Cell]) -> OctetRegion
@JvmStatic
fun polygonSet(cells: List<H3Cell>): PolygonSetRegion

Non-empty cell list. Free-form lat/lon polygons are not accepted. Quantize to H3 ahead of time. See Regions for why.

earth

public static func earth(maxAltitudeMeters: Meters = 10_000) -> OctetRegion
@JvmStatic
fun earth(maxAltitudeMeters: Meters = 10_000.0): EarthRegion

isWithin(.earth(...)) always returns YES if the SDK can produce any proof at all. The SDK does not test the device's altitude against maxAltitudeMeters, so the answer is YES at any altitude.

Value types

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

public typealias Meters = Double
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

Construction helpers (Android only)

RegionSpec + getRegion

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 and are not available in this release.

buildRegion { … } DSL

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. Android additionally exposes the free functions:

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

Decoding a region: regionFromJson

New in 2.0. The inverse of toJson() / toJsonl(): it decodes the same tagged shape back into an OctetRegion, round-tripping every factory. It exists so a caller can hand a region across a language boundary (a server payload, a stored region) without re-modelling the shapes.

public func regionFromJson(_ json: String) throws -> OctetRegion
fun regionFromJson(json: String): OctetRegion

Input is treated as untrusted. Unlike the region factories (which trap on malformed input), regionFromJson always throws OctetRegion.DecodeError on malformed, missing, wrong-typed, or out-of-range input.

See also

  • Regions. Why the taxonomy looks the way it does.
  • Predicates. What consumes an OctetRegion.
  • Serialization. .toStr() / .toJson() / .toJsonl() on every region.
TermsPrivacy© 2026 Understone, Inc. d/b/a Octet