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.