7

初期位置を指定して、最も近い緯度と経度の座標で並べ替えるには、SQLite SQL 文を取得する必要があります。

これは、sqlite データベース内の私のテーブルの例文です。

SELECT id, name, lat, lng FROM items

EXAMPLE RESULT: 1, Museu, 41375310.0, 2175970.0

SQLite とそのテーブルでこれを達成する必要があります。これは、変更できない既存の SQlite データベース用であるため、別の手法を使用できません。

Android と SQlite でこれを達成する方法はありますか? 多くのstackoverflowの投稿をチェックしましたが、それを達成する方法が見つかりませんでした

ありがとう

4

5 に答える 5

22
SELECT * AS distance FROM items ORDER BY ABS(location_lat - lat) + ABS(location_lng - lng) ASC

これは、MySQL では距離に基づいてアイテムを大まかにソートする必要があり、SQLite でも機能するはずです。
より正確に並べ替える必要がある場合は、ピタゴラスの定理 (a^2 + b^2 = c^2) を使用して正確な距離を取得できます。

于 2012-10-01T12:02:34.167 に答える
14

クリスが提案した解決策:

SELECT * AS distance FROM items FROM ORDER BY ((location_lat-lat)*(location_lat-lat)) + ((location_lng - lng)*(location_lng - lng)) ASC

赤道に近いときは正しいです。他の緯度で正しく機能するために、私は次のことを提案します。

SELECT * AS distance FROM items FROM ORDER BY ((location_lat-lat)*(location_lat-lat)) + ((location_lng - lng)*(location_lng - lng)* cos_lat_2 ) ASC

事前計算する必要がある場所:

cos_lat_2 = cos(location_lat * PI / 180) ^ 2

問題:

赤道内で経度 (東または西) で 1 度移動すると、40,000 km の円周上で移動し、40.000 / 360 の距離を表します。緯度 (北または南) で 1 度移動すると、両方の極を横切る円でこれを行います。これには、40.000 / 360 の距離も含まれます (地球が球体であることを考慮して)。

しかし、緯度 50 度のイングランド南部にいて、経度 (東または西) で 1 度移動すると、赤道よりも円周が小さい 50 度線上で移動します。距離は perimeter_parallel_50 / 360 です。この周長の計算は簡単です: perimeter_parallel_50 = cos (50) * 2 * PI * EARHT_RADIUS = 0.64 * 40,000 km。この距離の減少は、南または北に 1 度移動しても見られません。私たちが移動する円周は、まだ 40,000 Km あります。

解決:

location_lat は事前にわかっている値であるため、cos(location_lat) の値を事前に計算して、経度と緯度の変位が等しくなるようにスケーリング係数として使用できます。さらに、2 倍する必要がないように事前に 2 乗します。

ノート:

これはまだ概算であり、長い距離を移動する場合、特に極の近くや 180 度子午線を横切る場合は、間違った結果が得られます。

于 2016-09-02T17:54:17.833 に答える
4

緯度 1 度が約 111111 メートルで、経度 1 度が 111111*cos(latitude) メートルであることがわかっている場合、特定の正方形内のすべての場所を簡単に取得できます。

SELECT * FROM items WHERE latitude BETWEEN %f AND %f AND longitude BETWEEN %f AND %f

このクエリは、数百万行であっても非常に高速です。ただし、緯度と経度のインデックスを作成することを忘れないでください。

CREATE INDEX position ON items (latitude, longitude)

これを Objective-C で使用して、現在の場所から 3 km 以内にあるすべての関心のある場所を取得します。

double latDist = 1.0 / 111111.0 * 3.0;
double lonDist = 1.0 / ABS(111111.0*cos(location.coordinate.latitude)) * 3.0;

FMResultSet *results = [database executeQueryWithFormat:@"SELECT * FROM items WHERE latitude BETWEEN %f AND %f AND longitude BETWEEN %f AND %f", location.coordinate.latitude - latDist, location.coordinate.latitude + latDist, location.coordinate.longitude - lonDist, location.coordinate.longitude + lonDist];

正確な距離を計算し、結果を並べ替えることができるようになりました...

于 2014-02-25T19:36:11.833 に答える
3

レコードをロードできる場合。それらを場所に変換してから、distanceTo関数を使用することをお勧めしますが...

プレーンな SQL を使用して 2 点間の距離を概算できます。ここでは、さまざまなアプローチが明確に説明されています。単純な計算を使用すると、比較しているポイントが離れているほど、値がますます不正確になる可能性があります

これらのことを自分で計算していて、場所がどこにでもある場合、国際日付変更線の周りの場所を比較している場合、値の折り返しに注意する必要があるかもしれません.

于 2012-10-01T12:08:10.833 に答える