Skip to content

Instantly share code, notes, and snippets.

@piemonte
Created January 22, 2023 18:14
Show Gist options
  • Save piemonte/607afd1f22989a1d5fd2431d37da6661 to your computer and use it in GitHub Desktop.
Save piemonte/607afd1f22989a1d5fd2431d37da6661 to your computer and use it in GitHub Desktop.
//
// CLLocation+H3.swift
//
// The MIT License (MIT)
//
// Copyright (c) 2020-present patrick piemonte (http://patrickpiemonte.com/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import Foundation
import CoreLocation
import H3kit
/// CLLocation additions for Swift wrapper https://github.com/ehmjaysee/H3kit and C interface https://github.com/long1eu/h3-ios
extension CLLocation {
public static func h3_resolution(for areaInMeters: Double) -> Int32 {
var resolution: Int32 = 0
while resolution <= 15 {
let hexAreaInMeters = hexAreaM2(resolution)
if areaInMeters > hexAreaInMeters {
break
} else {
resolution += 1
}
}
return resolution
}
public func h3_cellIndex( resolution: Int32 ) -> UInt64 {
let lat = degsToRads(coordinate.latitude)
let lon = degsToRads(coordinate.longitude)
var location = GeoCoord(lat: lat, lon: lon)
let index = geoToH3(&location, resolution)
return index
}
public func h3_neighbors( resolution: Int32, ringLevel: Int32 ) -> [H3Index] {
let index = h3_cellIndex(resolution: resolution)
let count = Int(maxKringSize(ringLevel))
var neighbors = Array(repeating: H3Index(), count: count)
kRing(index, ringLevel, &neighbors)
return neighbors
}
}
@piemonte
Copy link
Author

usage:

var area: Double = 0
if let areaInMeters = areaInMeters {
        area = areaInMeters
} else {
        area = Double.pi * pow(Double(radiusInMeters), 2.0)
}

let resolution: Int32 = CLLocation.h3_resolution(for: area)
let centerIndex = location.h3_cellIndex(resolution: resolution)
let neighborIndexes = location.h3_neighbors(resolution: resolution, ringLevel: 1)

var h3Indexes = [String(centerIndex, radix: 16, uppercase: true)]
h3Indexes.append(contentsOf: neighborIndexes.map { String($0, radix: 16, uppercase: true) })

// perform query

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment