diff --git a/Sources/Geohash/GeohashIterator.swift b/Sources/Geohash/GeohashIterator.swift new file mode 100644 index 0000000..a84a06e --- /dev/null +++ b/Sources/Geohash/GeohashIterator.swift @@ -0,0 +1,39 @@ +// +// GeohashIterator.swift +// Geohash +// +// Created by michael groble on 1/12/17. +// +// + +public class GeohashIterator : IteratorProtocol, Sequence { + + let bounds: BoundingBox + var latBaseline: GeohashBits + var current: GeohashBits? + + public init(bounds: BoundingBox, bitPrecision: UInt8) throws { + self.bounds = bounds + self.latBaseline = try GeohashBits(location: bounds.min, bitPrecision: bitPrecision) + self.current = self.latBaseline + } + + public func next() -> GeohashBits? { + defer { advanceCurrent() } + return current + } + + private func advanceCurrent() { + // advance eastward until we are out of the bounds then advance northward + if var bits = self.current { + bits = bits.neighbor(.east) + if bounds.intersects(bits.boundingBox()) { + self.current = bits + } + else { + self.latBaseline = latBaseline.neighbor(.north) + self.current = bounds.intersects(latBaseline.boundingBox()) ? latBaseline : nil + } + } + } +} diff --git a/Tests/GeohashTests/GeohashIteratorTests.swift b/Tests/GeohashTests/GeohashIteratorTests.swift new file mode 100644 index 0000000..5939da4 --- /dev/null +++ b/Tests/GeohashTests/GeohashIteratorTests.swift @@ -0,0 +1,40 @@ +// +// GeohashIteratorTests.swift +// Geohash +// +// Created by michael groble on 1/12/17. +// +// + +import XCTest +@testable import Geohash + +class GeohashIteratorTests: XCTestCase { + + var bounds: BoundingBox! + + override func setUp() { + super.setUp() + + self.bounds = try! BoundingBox( + min: Location(longitude: 0.09991, latitude: 51.49996), + max: Location(longitude: 0.10059, latitude: 51.50028) + ) + } + + + func testIterateLevel8() throws { + let subject = try GeohashIterator(bounds: bounds, bitPrecision: 20) + XCTAssertEqual(subject.next()!.hash(), "u10hfr2c") + XCTAssertEqual(subject.next()!.hash(), "u10hfr31") + XCTAssertEqual(subject.next()!.hash(), "u10hfr2f") + XCTAssertEqual(subject.next()!.hash(), "u10hfr34") + XCTAssertNil(subject.next()) + } +} + +extension GeohashIteratorTests { + static var allTests = [ + ("testIterateLevel8", testIterateLevel8), + ] +} diff --git a/Tests/LinuxMain.swift b/Tests/LinuxMain.swift index c8eff9c..0770625 100644 --- a/Tests/LinuxMain.swift +++ b/Tests/LinuxMain.swift @@ -4,5 +4,6 @@ import XCTest XCTMain([ testCase(BoundingBoxTests.allTests), testCase(GeohashBitsTests.allTests), + testCase(GeohashIteratorTests.allTests), testCase(LocationTests.allTests), ])