關于map的具體用法請參考各自官方API(感覺有點標題黨o_O)
google和百度map都提供了范圍搜索的功能:比如搜索指定位置指定范圍內的所有kfc店鋪,它們使用的都是自己的店鋪數據,可有時候我們只需要在地圖上顯示我們自己存儲的店鋪,并把它們標注在地圖上,同樣只給定兩個參數:指定位置(某一處的經緯度lnglat)和搜索半徑(r)。
每個地圖API都提供了計算兩個坐標之間距離的方法,我們可以從庫中拿出所有的店鋪的經緯度(slnglat),然后逐一計算出lnglat到slnglat距離s,若s<r,則這個店鋪就是我們想要的可以直接返回給前端標注在地圖上。呃...這種方法當然不可行,不過當然也不是絕對的啦...^_^
前段時間寫了個例子,主要通過java實現(計算距離經緯度范圍之類的)
1. 建立模型:半徑r的范圍表示一個圓,不過一般情況下我們完全可以把它看作是一正方形...呀呀呀,還是用代碼說話吧,下面是一個pojo:
/**
* 類Bounds.java的實現描述:用戶當前位置半徑x米的經緯度范圍
*
* @author zjb 2011-3-30 下午04:56:13
*/
public class Bounds {
/**
* 當前位置正北方向x米處 緯度
*/
PRivate Double latN;
/**
* 當前位置正南方向x米處 緯度
*/
private Double latS;
/**
* 當前位置正東方向x米處 經度
*/
private Double lagE;
/**
* 當前位置正西方向x米處 經度
*/
private Double lagW;
//getters or setters
}
2. 計算所需要的經緯度范圍Bounds,表示該點(lnglat)處正東西南北距離r處的經緯度坐標,具體方法如下:
/**
* @param lat 緯度
* @param lag 經度
* @param r 半徑
* @return Boolean
*/
public static Boolean check(Company company, Double lat, Double lag, Integer r) {
double R = 6371;//地球半徑
double distance = 0.0;
double dLat = Double.valueOf(new BigDecimal(String.valueOf((company.getLat() - lat)))
.multiply(new BigDecimal(String.valueOf(Math.PI)))
.divide(new BigDecimal(String.valueOf(180)),
DEFAULT_DIV_SCALE,BigDecimal.ROUND_HALF_EVEN).toString());
double dLon = Double.valueOf(new BigDecimal(String.valueOf((company.getLag() - lag)))
.multiply(new BigDecimal(String.valueOf(Math.PI)))
.divide(new BigDecimal(String.valueOf(180)),
DEFAULT_DIV_SCALE,BigDecimal.ROUND_HALF_EVEN).toString());
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(company.getLat() * Math.PI / 180)
* Math.cos(lat * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
distance = (2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))) * R * 1000;
System.out.println(distance);
if (distance > Double.valueOf(String.valueOf(r))){
return false;
}
return true;
}
好了,拿到圓形區域內的所有店鋪了,根據其經緯度標注到地圖上吧。
//company 里面存放經緯度
SELECT * FROM company where lat >= #{latS} and lat <= #{latN} and lag >= #{lagW} and lag <= #{lagE}
//注意BigDecimal類
private static final int DEFAULT_DIV_SCALE = 6;
/**
* 1000表示1公里,111表示同經度時,緯度相差一度,距離就相差111公里
*
* @param lat 當前位置緯度
* @param lag 當前位置經度
* @param r 半徑,單位M(附近rM)
* @return Bounds
*/
public static Bounds conversion(Double lat, Double lag, Integer r) {
String l = String.valueOf(1000 * 111);
String latx = new BigDecimal(String.valueOf(r)).divide(new BigDecimal(l), DEFAULT_DIV_SCALE,
BigDecimal.ROUND_HALF_EVEN).toString();
String lagx = new BigDecimal(latx).divide(new BigDecimal(String.valueOf(Math.cos(lat))), DEFAULT_DIV_SCALE,
BigDecimal.ROUND_HALF_EVEN).toString();
Double latN = lat + Math.abs(Double.valueOf(latx));
Double latS = lat - Math.abs(Double.valueOf(latx));
Double lagE = lag + Math.abs(Double.valueOf(lagx));
Double lagW = lag - Math.abs(Double.valueOf(lagx));
Bounds bounds = new Bounds();
bounds.setLagE(lagE);
bounds.setLagW(lagW);
bounds.setLatN(latN);
bounds.setLatS(latS);
return bounds;
}
新聞熱點
疑難解答