92 lines
5.7 KiB
Swift
Raw Normal View History

import XCTest
class QuadKeyTests: XCTestCase {
func testQuadKeys() {
// Iterate over a good sampling of latitudes and longitudes at given zoom levels to verify our quad key calculations
var p: QuadKeyPrecision = 1
while p <= 32 { // iterate precisions
var lat: QuadKeyDegrees = -90
while lat <= 90 { // iterate latitudes
var lon: QuadKeyDegrees = -180
while lon <= 180 { // iterate longitudes
let latPart = QuadKeyPart(latitude: lat, precision: p) // calculate the latitude part (the y coordinate of the quad key)
let lonPart = QuadKeyPart(longitude: lon, precision: p) // calculate the longitude part (the x coordinate of the quad key)
let quadKey = QuadKey(latitudePart: latPart, longitudePart: lonPart, precision: p) // calculate the QuadKey given the two parts
let altQuadKey = QuadKey(latitude: lat, longitude: lon, precision: p) // calculate the quad key directly from lat and lon
XCTAssertEqual(quadKey, altQuadKey, "QuadKeys should match no matter how they were calculated")
let fullPrecisionLatPart = QuadKeyPart(latitude: lat)
let fullPrecisionLonPart = QuadKeyPart(longitude: lon)
let fullPrecisionQuadKey = QuadKey(latitude: lat, longitude: lon) // Calculate the full precision quad key
let adjustedQuadKey = fullPrecisionQuadKey.adjusted(downBy: 32 - p) // Adjust the quad key to the given zoom level (lose precision)
XCTAssertEqual(quadKey, adjustedQuadKey, "QuadKeys should match no matter how they were calculated\n\(adjustedQuadKey.bitmaskString)\n\(quadKey.bitmaskString)\n\(fullPrecisionQuadKey.bitmaskString)\n\n\(fullPrecisionLatPart.bitmaskString)\n\(latPart.bitmaskString)\n\n\(fullPrecisionLonPart.bitmaskString)\n\(lonPart.bitmaskString)")
let bounds = QuadKeyBounds(quadKey: adjustedQuadKey, precision: p)
XCTAssertGreaterThanOrEqual(fullPrecisionQuadKey, bounds.min)
XCTAssertLessThanOrEqual(fullPrecisionQuadKey, bounds.max)
let signedInteger = Int64(quadKey: fullPrecisionQuadKey)
let signedMax = Int64(quadKey: bounds.max)
let signedMin = Int64(quadKey: bounds.min)
XCTAssertGreaterThanOrEqual(signedInteger, signedMin)
XCTAssertLessThanOrEqual(signedInteger, signedMax)
XCTAssertEqual(QuadKey(int64: signedInteger), fullPrecisionQuadKey)
let coord = QuadKeyCoordinate(quadKey: quadKey, precision: p)
XCTAssertEqual(coord.latitudePart, latPart, "latPart: \(latPart) != \(coord.latitudePart)")
XCTAssertEqual(coord.longitudePart, lonPart, "lonPart: \(lonPart) != \(coord.longitudePart)")
let calculatedLat = QuadKeyDegrees(latitudePart: coord.latitudePart, precision: p)
let calculatedLon = QuadKeyDegrees(longitudePart: coord.longitudePart, precision: p)
XCTAssertEqual(calculatedLat, lat, accuracy: p.deltaLatitude, "latitude is wrong at precision \(p)")
XCTAssertEqual(calculatedLon, lon, accuracy: p.deltaLongitude, "longitude is wrong at precision \(p)")
if p == 32 {
let fullPrecision = QuadKeyPrecision(32)
let fullPrecisionCoord = QuadKeyCoordinate(quadKey: fullPrecisionQuadKey)
let fullPrecisionCalculatedLat = QuadKeyDegrees(latitudePart: fullPrecisionCoord.latitudePart)
let fullPrecisionCalculatedLon = QuadKeyDegrees(longitudePart: fullPrecisionCoord.longitudePart)
XCTAssertEqual(fullPrecisionCalculatedLat, lat, accuracy: fullPrecision.deltaLatitude, "full precision latitude is wrong")
XCTAssertEqual(fullPrecisionCalculatedLon, lon, accuracy: fullPrecision.deltaLongitude, "full precision longitude is wrong")
}
lon += 5.25
}
lat += 5.25
}
p += (p == 1 ? 3 : 4)
}
}
func testInvalidQuadKeys() {
var invalidKey = QuadKey(latitude: Double.nan, longitude: Double.nan)
XCTAssertEqual(invalidKey.latitude, -90)
XCTAssertEqual(invalidKey.longitude, -180)
invalidKey = QuadKey(latitude: Double.signalingNaN, longitude: Double.signalingNaN)
XCTAssertEqual(invalidKey.latitude, -90)
XCTAssertEqual(invalidKey.longitude, -180)
invalidKey = QuadKey(latitude: Double.infinity, longitude: Double.infinity)
XCTAssertEqual(invalidKey.latitude, -90)
XCTAssertEqual(invalidKey.longitude, -180)
invalidKey = QuadKey(latitude: 90.00001, longitude: 180.00001)
XCTAssertEqual(invalidKey.longitude, 180)
XCTAssertEqual(invalidKey.latitude, 90)
invalidKey = QuadKey(latitude: -90.01, longitude: -180.01)
XCTAssertEqual(invalidKey.longitude, -180)
XCTAssertEqual(invalidKey.latitude, -90)
var validKey = QuadKey(latitude: 90, longitude: 180)
XCTAssertEqual(validKey.longitude, 180)
XCTAssertEqual(validKey.latitude, 90)
validKey = QuadKey(latitude: -90, longitude: -180)
XCTAssertEqual(validKey.longitude, -180)
XCTAssertEqual(validKey.latitude, -90)
validKey = QuadKey(latitude: -0.0, longitude: -0.0)
XCTAssertEqual(validKey.longitude, 0, accuracy: 0.00001)
XCTAssertEqual(validKey.latitude, 0, accuracy: 0.00001)
}
}