2012年5月1日 星期二

找出以標記為中心一公里之內的地點

這個問題其實是在看論壇時看到的
因為自己之後要寫的東西也會用到,所以就先來查了一下
不過一查才發現這是相當複雜的問題呀 XD

(圖片取自維基百科

座標跟距離的問題有分成兩種:
1、知道兩點的座標,如何求出兩點之間的距離(以公尺或者公里為單位)
2、以某點為中心點,附近有很多座標不同的其他點,如何得知距離在 XXX 公尺/公里之內的點有哪些

1、知道兩點的座標,如何求出兩點之間的距離(以公尺或者公里為單位)

第一點在網路上討論好像比較多,主要問題在於地球是個球體
所以在緯度 0 度的地方,經度移動 1 度所走的實際距離,跟在緯度 60 度的地方移動 1 度經度所走的距離實際上是不同的。


查到的資料(Android获取经纬度、计算距离、方位角)是說可用以下公式計算:


說明轉錄如下:
(1) Lat1 Lung1 表示A點經緯度,Lat2 Lung2 表示B點經緯度;
(2) a=Lat1 – Lat2 為兩點緯度之差 b=Lung1 -Lung2 為兩點經度之差;
(3) 6378.137為地球半徑,單位為公里

當然正確度不知 XD,但由於該部落格有實作的關係,所以先記起來。

private final double EARTH_RADIUS = 6378137.0;  
private double gps2m(double lat_a, double lng_a, double lat_b, double lng_b) {
  double radLat1 = (lat_a * Math.PI / 180.0);
  double radLat2 = (lat_b * Math.PI / 180.0);
  double a = radLat1 - radLat2;
  double b = (lng_a - lng_b) * Math.PI / 180.0;
  double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
    + Math.cos(radLat1) * Math.cos(radLat2)
    * Math.pow(Math.sin(b / 2), 2)));
  s = s * EARTH_RADIUS;
  s = Math.Round(s * 10000) / 10000;
  return s;
}

2、以某點為中心點,附近有很多座標不同的其他點,如何得知距離在 XXX 公尺/公里之內的點有哪些

第二點...簡單搜尋了一下 Google,但實在沒找到什麼資料。
所以目前只有先想到間接篩選的方式。
假設資料是存放在資料庫中,有記錄所有標記點的座標,那麼鎖定某個標記點 A 為中心,要找出周圍 1 公里的其他標記點時
可以先取出 A 東西一公里的經度座標、以及 A 南北一公里的緯度座標,畫出一個以 A 為中心的方形
方形的四個角就是邊界,在資料庫中可以直接用 WHERE 條件式來篩選標記點
應該可以先篩選到只剩下少部分的標記點是落在這個方形之內的,然後再把問題轉換成第一點
對每個方形之內的標記點去計算與 A 之間的距離,如果距離大於 1 公里就忽略掉
這樣應該就能夠以比較有效率的方式取得「以某標記點為中心一公里之內的地點」了。

那麼問題就縮小成:要如何得到方形的四個角的座標?
根據 請問經緯度10度換算成距離多少公里? 這篇的回應
得到的經緯度換算公式:(單位好像是公尺吧?XD...另一個來源為 全華新版高二上,是同一個公式)

  • 緯度一度的距離:111.1367-0.5623 cos 2ψ+0.0011 cos 4ψ
  • 經度一度的距離:111.4179cosψ-0.0940cos3ψ+0.0002cos5ψ

不過正確與否不明 XD,可能還需要再查查其他的資料吧。
先簡單用回應中最下面的約略距離來討論,台灣的緯度大約是北緯 2x 度附近
以該篇回應的舉例來說就是:

緯度(度)      每度距離(km)
緯度30度 經度線上 110.85
緯度30度 緯度線上 96.49

也就是緯度 30 度的位置時,經度移動 1 度,實際移動約 110.85 公里、緯度移動 1 度,實際移動約 96.49 公里
如此大約可以得出 1 公里範圍內,經度大約是 (-1/110.85) ~ (+1/110.85) 度之間
緯度則大約是 (-1/96.49) ~ (+1/96.49) 度之間。
這樣就可以得到約略的方形四個角的座標了。

不過這樣簡略的算法一方面精準度不足,另一方面只限於台灣或者其他緯度大約在 30 度附近的地區
如果能夠確定上面找到經緯度一度的距離公式是正確的,或者能找到其他確定正確的公式
也許就能夠有更完整的轉換方法了。

參考資料:
1、經緯度轉換(提供網頁版小工具可將經緯度由 60 進位轉成 10 進位)
2、Android获取经纬度、计算距离、方位角
3、請問經緯度10度換算成距離多少公里?
4、全華新版高二上
5、lbs中从库中查询某经纬度2KM范围内的数据
6、SAE使用以及GPS 的经纬度换算成距离的代码(转载)

沒有留言: