Skip to main content

Regions

In one sentence

An OctetRegion is the area you ask about (country, city, disc, polygon, bounding box), and its shape determines how the SDK proves containment.

Why the taxonomy looks the way it does

Different region shapes are verified by different evidence. A country is best proven via the device's mobile country code; the SIM and the serving cell tower both name a country. A disc needs a real GPS fix and can fall back to inertial signals. A city resolves to a polygon set under the hood. Letting callers supply a free-form lat/lon polygon would force the SDK to triangulate and re-quantize every query, which interacts badly with the H3-based proof machinery. Polygons are therefore accepted only as H3 cell sets.

The shapes

FactoryVerified viaTypical use
earth(maxAltitudeMeters)Always YES.Sanity check / fallback.
country(isoCode)Fused MCC from serving cell, network operator, SIM home country."Is the user in the US?" Works indoors, often without GPS.
subdivision(isoCode)Reverse-geocoded admin area on a trusted fix; multi-signal estimator as fallback.ISO 3166-2 codes: US-CA, FR-75, JP-13.
usState(stateCode)Same as subdivision.Sugar for subdivision("US-XX").
city(name)SDK resolves the name to an H3 polygon set; proof is verified against that polygon."Is the user in San Francisco?"
disc(center, radiusMeters)H3-rasterized inside the proof; analytic on the caller side."Is the device within 250 m of a saved anchor point?"
ellipse(center, semiMajorM, semiMinorM, headingDeg)2D ground ellipse. Disc is a special case.GNSS uncertainty ellipses, oriented zones.
box3D(latRange, lonRange, altRange)3D bounding box.Volumetric containment, building floors.
polygonSet(cells)Union of H3 cells.Custom geofences pre-quantized to H3.

All factories validate eagerly. Invalid lat/lon, malformed ISO codes, non-positive radii, ellipse axes out of order: all trap at construction. An invalid region never reaches a predicate call.

Why polygons are H3-only

If you have a free-form polygon (a delivery zone, an event venue, a building footprint), you (or your tooling) quantize it to H3 cells ahead of time and pass the cell list. The SDK then uses those cells directly in the proof's Merkle membership circuit. No on-the-fly triangulation. No precision drift. No caller-supplied geometry slipping into the proof.

The H3 cell ID encodes its own resolution. The SDK picks the coarsest resolution per query that still satisfies the predicate's accuracy needs. Fine cells when you ask about a city block, coarse cells when you ask about a city.

Construction helpers (Android only)

On Android, two additional surfaces let you build regions dynamically:

  • getRegion(RegionSpec.country("US")). Symbolic lookup, useful when the region name comes from configuration or a server response. The city / namedZone variants currently throw OctetFutureFlag (atlas + server lookup is not yet wired).
  • buildRegion { disc(center = LatLon(37.42, -122.08), radiusMeters = 250.0) }. DSL sugar over the static factories, ergonomic for assembling regions from runtime data.

iOS exposes the static factories only at v1. Platform parity for the DSL and RegionSpec is on the roadmap.

Inspecting a region

Two helpers turn a region into a string:

  • whatisRegion(r). Short, human-readable. For log lines and debug overlays. Not stable across SDK versions.
  • regionToStr(r). Canonical, machine-readable, stable wire form. Suitable for log diffs, idempotency keys, eventual regionFromStr round-trip.

Both are surfaced uniformly on every API object via .toStr(), .toJson(), and .toJsonl(). See Serialization.

Where to go next