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.boundary
Add the following line to your package's Package.swift
file:
.package(url: "https://github.com/pawelmajcher/SwiftyH3.git", from: "0.4.1")
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 |
||
stringToH3 |
H3Cell("8a283082a677fff")! |
π |
h3ToString |
try H3Cell(599686042433355775).description |
π |
isValidCell |
cell.isValid |
π |
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))
}
}
}
- SwiftyH3 (this repository) is licensed under the Apache 2.0 license.
- Ch3 (with raw bindings and additional maintenance code) is licensed under the MIT License.
- Uber's H3 library is licensed under the Apache 2.0 license.