Skip to content

pawelmajcher/SwiftyH3

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

34 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SwiftyH3 ⬑

The Swifty way to use Uber's H3 geospatial indexing system.

Documentation Swift versions Swift platforms

Quick Start

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

Installation

Swift Package Manager

Add the following line to your package's Package.swift file:

.package(url: "https://github.com/pawelmajcher/SwiftyH3.git", from: "0.4.1")

Xcode

Go to File > Add Package Dependencies... and enter https://github.com/pawelmajcher/SwiftyH3.git in the upper-right corner.

H3 API support

Indexing functions

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 πŸ“–

Index inspection functions

H3 C function Example SwiftyH3 code Docs
getResolution try H3DirectedEdge("115283473fffffff")!.resolution πŸ“–
getBaseCellNumber try H3Vertex("22528340bfffffff")!.baseCellNumber πŸ“–
getIndexDigit ⚠️ Not yet available
stringToH3 H3Cell("8a283082a677fff")! πŸ“–
h3ToString try H3Cell(599686042433355775).description πŸ“–
isValidCell cell.isValid πŸ“–
isResClassIII cell.isResClassIII πŸ“–
isPentagon cell.isPentagon πŸ“–
getIcosahedronFaces ⚠️ Not yet available
maxFaceCount This function exists for memory management and is not exposed.

Grid traversal functions

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 ⚠️ Not yet available
localIjToCell ⚠️ Not yet available

Hierarchical grid functions

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.

Region functions

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.

Directed edge functions

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 πŸ“–

Vertex functions

H3 C function Example SwiftyH3 code Docs
cellToVertex try cell.vertex(3) πŸ“–
cellToVertexes try cell.vertices πŸ“–
vertexToLatLng try vertex.latLng πŸ“–
isValidVertex vertex.isValid πŸ“–

Miscellaneous H3 functions

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.

Core Location and MapKit support

CLLocationCoordinate2D

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))

MKPolygon and MKMultiPolygon

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))
        }
    }
}

License