The Swifty way to use Uber's H3 geospatial indexing system.
import SwiftyH3
// Find the containing cell for a given location
let latlng = H3LatLng(latitudeDegs: 37.7955, longitudeDegs: -122.3937)
let cell = try! latlng.cell(at: .res10)
print(cell) // 8a283082a677fff
// Retrieve the center of the cell (as H3LatLng or CLLocationCoordinate2D)
let coordinate: CLLocationCoordinate2D = try! cell.center.coordinates
// Find the bounds of this cell
let bounds: [H3LatLng] = try! cell.boundaryAdd the following line to your package's Package.swift file:
.package(url: "https://github.com/pawelmajcher/SwiftyH3.git", "0.5.0"..<"0.6.0")Go to File > Add Package Dependencies... and enter https://github.com/pawelmajcher/SwiftyH3.git in the upper-right corner.
| H3 C function | Example SwiftyH3 code | Docs |
|---|---|---|
latLngToCell |
try H3LatLng(latitudeDegs: 37.7955, longitudeDegs: -122.3937).cell(at: .res8) |
π |
cellToLatLng |
try H3Cell("8a283082a677fff")!.center |
π |
cellToBoundary |
try H3Cell("8a283082a677fff")!.boundary |
π |
| H3 C function | Example SwiftyH3 code | Docs |
|---|---|---|
getResolution |
try H3DirectedEdge("115283473fffffff")!.resolution |
π |
getBaseCellNumber |
try H3Vertex("22528340bfffffff")!.baseCellNumber |
π |
getIndexDigit |
try H3Vertex("22528340bfffffff")!.digit(for: .res2) |
π |
constructCell |
try H3Cell(base: 20, [0, 6, 0, 4, 0, 5]) |
π |
stringToH3 |
H3Cell("8a283082a677fff")! |
π |
h3ToString |
try H3Cell(599686042433355775).description |
π |
isValidCell |
cell.isValid |
π |
isValidIndex |
cell.isSomeH3Index |
π |
isResClassIII |
cell.isResClassIII |
π |
isPentagon |
cell.isPentagon |
π |
getIcosahedronFaces |
||
maxFaceCount |
This function exists for memory management and is not exposed. |
| H3 C function | Example SwiftyH3 code | Docs |
|---|---|---|
gridDistance |
try originCell.gridDistance(to: destinationCell) |
π |
gridRing |
try cell.gridRing(distance: 1) |
π |
gridRingUnsafe |
Not exposed. Use gridRing. |
|
maxGridRingSize |
This function exists for memory management and is not exposed. | |
gridDisk |
try cell.gridDisk(distance: 2) |
π |
maxGridDiskSize |
This function exists for memory management and is not exposed. | |
gridDiskDistances |
Not exposed. Use try 1...3.map { cell.gridRing(distance: $0) }. |
|
gridDiskUnsafe |
Not exposed. Use gridDisk. |
|
gridDiskDistancesUnsafe |
Not exposed. Use try 1...3.map { cell.gridRing(distance: $0) }. |
|
gridDiskDistancesSafe |
Not exposed. Use try 1...3.map { cell.gridRing(distance: $0) }. |
|
gridDisksUnsafe |
Not exposed. Use try cells.flatMap { cell in 1...3.flatMap { cell.gridRing(distance: $0) } }. |
|
gridPathCells |
try cell1.path(to: ...) |
π |
gridPathCellsSize |
This function exists for memory management and is not exposed. | |
cellToLocalIj |
||
localIjToCell |
| H3 C function | Example SwiftyH3 code | Docs |
|---|---|---|
cellToParent |
try cell.parent(at: .res1) |
π |
cellToChildren |
try cell.children(at: .res12) |
π |
cellToChildrenSize |
try cell.children(at: .res12).count |
π |
cellToCenterChild |
try cell.children(at: .res12).center |
π |
cellToChildPos |
try parentCell.children(at: .res12).index(of: childCell) |
π |
childPosToCell |
try cell.children(at: .res12)[23] |
π |
compactCells |
try [cell1, ..., cell50].compacted |
π |
uncompactCells |
try [cell1, cell2, cell3].uncompacted(at: .res8) |
π |
uncompactCellsSize |
This function exists for memory management and is not exposed. |
| H3 C function | Example SwiftyH3 code | Docs |
|---|---|---|
polygonToCells |
try H3Polygon([...]).cells(at: .res7) |
π |
maxPolygonToCellsSize |
This function exists for memory management and is not exposed. | |
polygonToCellsExperimental |
try H3Polygon([...]).cellsExperimental(at: .res7, containmentType: .overlapping) |
π |
maxPolygonToCellsSizeExperimental |
This function exists for memory management and is not exposed. | |
cellsToLinkedMultiPolygon |
try [cell1, cell2, cell3].multiPolygon |
π |
destroyLinkedMultiPolygon |
This function exists for memory management and is not exposed. |
| H3 C function | Example SwiftyH3 code | Docs |
|---|---|---|
areNeighborCells |
try cell1.isNeighbor(of: cell2) |
π |
cellsToDirectedEdge |
try originCell.directedEdge(to: destinationCell) |
π |
isValidDirectedEdge |
directedEdge.isValid |
π |
getDirectedEdgeOrigin |
try directedEdge.origin |
π |
getDirectedEdgeDestination |
try directedEdge.destination |
π |
directedEdgeToCells |
Not exposed. Use try (directedEdge.origin, directedEdge.destination). |
|
originToDirectedEdges |
try originCell.directedEdges |
π |
directedEdgeToBoundary |
try directedEdge.boundary |
π |
| H3 C function | Example SwiftyH3 code | Docs |
|---|---|---|
cellToVertex |
try cell.vertex(3) |
π |
cellToVertexes |
try cell.vertices |
π |
vertexToLatLng |
try vertex.latLng |
π |
isValidVertex |
vertex.isValid |
π |
| H3 C function | Example SwiftyH3 code | Docs |
|---|---|---|
degsToRads |
Not exposed. Use Measurement<UnitAngle>(value: 23, unit: .degrees).converted(to: .radians).value. |
|
radsToDegs |
Not exposed. Use Measurement<UnitAngle>(value: 1.2, unit: .radians).converted(to: .degrees).value. |
|
getHexagonAreaAvgKm2 |
H3Cell.Resolution.res8.averageHexagonArea.converted(to: .squareKilometers).value |
|
getHexagonAreaAvgM2 |
H3Cell.Resolution.res8.averageHexagonArea.value |
π |
cellAreaRads2 |
try cell.areaRads2 |
π |
cellAreaKm2 |
try cell.area.converted(to: .squareKilometers).value |
|
cellAreaM2 |
try cell.area.converted(to: .squareMeters).value |
π |
getHexagonEdgeLengthAvgKm |
H3Cell.Resolution.res8.averageHexagonEdgeLength.converted(to: .kilometers).value |
|
getHexagonEdgeLengthAvgM |
H3Cell.Resolution.res8.averageHexagonEdgeLength.value |
π |
edgeLengthKm |
try directedEdge.length.converted(to: .kilometers).value |
|
edgeLengthM |
try directedEdge.length.value |
π |
edgeLengthRads |
try directedEdge.lengthRads.value |
π |
getNumCells |
H3Cell.Resolution.res3.numberOfCells |
π |
getRes0Cells |
H3Cell.res0Cells |
π |
res0CellCount |
This function exists for memory management and is not exposed. | |
getPentagons |
H3Cell.Resolution.res3.pentagons |
π |
pentagonCount |
This function exists for memory management and is not exposed. | |
greatCircleDistanceKm |
h3LatLng1.distance(to: h3LatLng2).converted(to: .kilometers).value |
|
greatCircleDistanceM |
h3LatLng1.distance(to: h3LatLng2).value |
π |
greatCircleDistanceRads |
h3LatLng1.distanceRads(to: h3LatLng2).value |
π |
describeH3Error |
do {...} catch { print(error.errorDescription) } |
π |
Note
The Measurement<UnitType> types and LocalizedError protocol, including related
methods and properties, are part of Foundation. Include import Foundation to use them.
You can convert an H3LatLng value to CLLocationCoordinate2D and vice versa using initializers or computed properties.
// H3LatLng β‘οΈ CLLocationCoordinate2D
let coordinateFromProperty: CLLocationCoordinate2D = H3LatLng(latitudeDegs: 37.7955, longitudeDegs: -122.3937).coordinates
let coordinateFromInitializer = CLLocationCoordinate2D(H3LatLng(latitudeDegs: 37.7955, longitudeDegs: -122.3937))
// CLLocationCoordinate2D β‘οΈ H3LatLng
let h3LatLngFromProperty: H3LatLng = CLLocationCoordinate2D(latitude: 37.7955, longitude: -122.3937).h3LatLng
let h3LatLngFromInitializer = H3LatLng(CLLocationCoordinate2D(latitude: 37.7955, longitude: -122.3937))You can create an MKPolygon with an initializer taking [H3LatLng] or H3Polygon values. Analogically, you can initialize MKMultiPolygon with [H3Polygon] array.
// H3 with MapKit for SwiftUI example
import SwiftUI
import MapKit
import SwiftyH3
struct H3CellMapExampleView: View {
let cellBoundary = try! H3LatLng(latitudeDegs: 37.7955, longitudeDegs: -122.3937).cell(at: .res4).boundary
var body: some View {
Map {
MapPolygon(MKPolygon(cellBoundary))
}
}
}H3Cell, H3Polygon, and H3DirectedEdge conform to the MapContent protocol which means that you can use them as map content when using MapKit for SwiftUI.
// H3 with MapKit for SwiftUI example
import SwiftUI
import MapKit
import SwiftyH3
struct H3CellMapExampleView: View {
var body: some View {
Map {
H3Cell("87283082affffff")
H3DirectedEdge("115283473fffffff").stroke(.blue, lineWidth: 2)
try? ["8528342ffffffff", "85283093fffffff"].map { H3Cell($0)! }.multiPolygon[0]
}
}
}- SwiftyH3 (this repository) is licensed under the Apache 2.0 license.
- Uber's H3 library is licensed under the Apache 2.0 license.