Skip to content

Instantly share code, notes, and snippets.

@HTLife
Created December 5, 2020 13:37
Show Gist options
  • Save HTLife/32bff1dce39c484696bfc4d10193247d to your computer and use it in GitHub Desktop.
Save HTLife/32bff1dce39c484696bfc4d10193247d to your computer and use it in GitHub Desktop.
//
// GPSPoint.swift
//
// Created by Jacky Liu on 2020/11/22.
// AkoTech
import Foundation
import KDTree
// key,key_country,key_region,lat,lon,jhp_key,jp_key,us_key
public struct GPSPoint: Codable {
public static let latRange: Double = 180
public static let lonRange: Double = 360
public let normalizedLat: Float
public let normalizedLon: Float
public let key: String
public let key_country: String
public let key_region: String
public let lat: Float
public let lon: Float
init(key: String?,
key_country: String?,
key_region: String?,
lat: Float,
lon: Float) {
self.key = key ?? ""
self.key_country = key_country ?? ""
self.key_region = key_region ?? ""
self.lat = lat
self.lon = lon
self.normalizedLat = GPSPoint.normalize(lat: lat)
self.normalizedLon = GPSPoint.normalize(lon: lon)
}
init(lat: Float,
lon: Float) {
self.key = ""
self.key_country = ""
self.key_region = ""
self.lat = lat
self.lon = lon
self.normalizedLat = GPSPoint.normalize(lat: lat)
self.normalizedLon = GPSPoint.normalize(lon: lon)
}
public static func normalize(lat: Float) -> Float {
return (lat + 90)/Float(latRange)
}
public static func normalize(lon: Float) -> Float {
return (lon + 180)/Float(lonRange)
}
public static func Lat(normalizedLat: Float) -> Float {
return normalizedLat * Float(latRange) - 90
}
public static func Lon(normalizedLon: Float) -> Float {
return normalizedLon * Float(lonRange) - 180
}
public func pointMoved(lat: Float, lon: Float) -> GPSPoint {
let normalizedLat = self.normalizedLat + GPSPoint.normalize(lat: lat)
let normalizedLon = self.normalizedLon + GPSPoint.normalize(lon: lon)
return GPSPoint(lat: GPSPoint.Lat(normalizedLat: normalizedLat),
lon: GPSPoint.Lon(normalizedLon: normalizedLon))
}
}
extension GPSPoint: KDTreePoint {
public static var dimensions = 2
public func kdDimension(_ dimension: Int) -> Double {
return 2.0
}
public func squaredDistance(to otherPoint: GPSPoint) -> Double {
let x = self.lat - otherPoint.lat
let y = self.lon - otherPoint.lon
return Double(x*x + y*y)
}
}
enum MyError: Error {
case runtimeError(String)
}
func lineIterator(file: UnsafeMutablePointer<FILE>) -> AnyIterator<String>
{
return AnyIterator { () -> String? in
var line: UnsafeMutablePointer<CChar>? = nil
var linecap: Int = 0
defer { free(line) }
if getline(&line, &linecap, file) > 0, let line = line {
return String(validatingUTF8: line)
}
return nil
}
}
self.points = nil
let filePath = NSHomeDirectory() + "/Documents/kdtreebin"
do
{
let tree = try KDTree<GPSPoint>(contentsOf: URL(fileURLWithPath: filePath))
self.points = tree
}
catch
{
print("Error info: \(error)")
}
self.points = nil
let startLoading = Date()
let points: [GPSPoint] = GpsSearch.loadCSVData(from: starsPath)!
print("Time to load \(points.count) points: \(Date().timeIntervalSince(startLoading))s from \(starsPath)")
let startTreeBuilding = Date()
let tree = KDTree(values: points)
print("Time build tree: \(Date().timeIntervalSince(startTreeBuilding)),"
.appending(" complete time: \(Date().timeIntervalSince(startLoading))s"))
let filePath = NSHomeDirectory() + "/Documents/kdtreebin"
do
{
try tree.save(to: URL(fileURLWithPath: filePath) )
print("save kdtreebin to \(URL(fileURLWithPath: filePath))" )
self.points = tree
}
catch
{
print("Error info: \(error)")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment