1

Swift2 で SQLite データベースからフェッチされている間にオブジェクトを注文するための単純な距離関数を作成したいと思います。私はすばらしい SQLite.swift フレームワークを使用しています。

以下を使用すると、最も近いオブジェクトを取得できます。

db.createFunction("distance") { (args) -> Binding? in
    assert(args.count == 4)
    if let lat1 = args[0] as? Double, let lon1 = args[1] as? Double, let lat2 = args[2] as? Double, let lon2 = args[3] as? Double {

        let deltaLat = lat1 - lat2
        let deltaLon = lon1 - lon2
        return deltaLat * deltaLat + deltaLon * deltaLon * 0.46512281898705
    }
    return nil
}

let queryString = "SELECT * FROM objects where lat != \"\" and lng != \"\" ORDER BY distance(lat, lng, \(lat), \(lng)) ASC LIMIT \(fetchLimit)"

let stmt = db.prepare(queryString)
for row in stmt {
    print(row)
}

しかし、クエリ文字列を使用せずにタイプ セーフな SQL 式を使用したいと考えています。このように機能させるために関数を追加するにはどうすればよいですか (ここで、緯度と経度の値はテーブル内の行の位置を表す式の値であり、centerLat、centerLon の値は計算している中心点を表します)オブジェクトの距離):

for row in db.order(distance(lat, lon, centerLat, centerLon).limit(fetchLimit) {
    print(row)
}
4

2 に答える 2

1

これを行う良い方法はまだありません (式構築ヘルパーの多くは現在、SQLite.swift の内部にあります)。機能リクエストとして問題を開くことをお勧めします。

それまでの間、これらは引用符で囲む必要のない値であるため、次の操作を実行できます。

func distance(
    lat1: Expression<Double>, lng1: Expression<Double>,
    lat2: Double, lng2: Double
) -> Expression<Double> {
    return Expression(
        literal: "distance(\(lat1.asSQL()), \(lng1.asSQL()), ?, ?)",
        lat2, lng2
    )
}
于 2015-10-14T00:47:52.393 に答える