高德地圖之逆地理編碼
阿新 • • 發佈:2019-02-01
上一篇講述了地理編碼的使用,沒看的朋友可以看看http://blog.csdn.net/hedong_77/article/details/54287292,Ok,我們繼續來看你地理編碼,首先要理解它的概念,逆地理編碼,又稱地址解析服務,是指從已知的經緯度座標到對應的地址描述(如行政區劃、街區、樓層、房間等)的轉換。常用於根據定位的座標來獲取該地點的位置詳細資訊,與定位功能是黃金搭檔。也就是座標轉地址。
逆地理編碼就很實用了,很多時候後臺都會返回經緯度,然後APP端根據經緯度來定位,最常見的,好的,不說廢話,來看看:
跟地理編碼類似,只是在不同的方法裡面做請求返回操作而已:
1、繼承 OnGeocodeSearchListener 監聽。
2、構造 GeocodeSearch 物件,並設定監聽。
geocoderSearch = new GeocodeSearch(this);
geocoderSearch.setOnGeocodeSearchListener(this);
3、通過 RegeocodeQuery(LatLonPoint point, float radius, java.lang.String latLonType) 設定查詢引數,呼叫 GeocodeSearch 的 getFromLocationAsyn(RegeocodeQuery regeocodeQuery) 方法發起請求。
// 第一個引數表示一個Latlng,第二引數表示範圍多少米,第三個引數表示是火系座標系還是GPS 原生座標系
RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200,GeocodeSearch.AMAP);
geocoderSearch.getFromLocationAsyn(query);
4、通過回撥介面 onRegeocodeSearched 解析返回的結果。
這裡跟地理編碼不一樣的地方,就是返回方法不同,地理編碼是在onGeocodeSearched裡面做相應操作。
@Override
public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
dismissDialog();
if (rCode == 1000) {
if (result != null && result.getRegeocodeAddress() != null
&& result.getRegeocodeAddress().getFormatAddress() != null) {
addressName = result.getRegeocodeAddress().getFormatAddress()
+ "附近";
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
AMapUtil.convertToLatLng(latLonPoint), 15));
regeoMarker.setPosition(AMapUtil.convertToLatLng(latLonPoint));
ToastUtil.show(ReGeocoderActivity.this, addressName);
} else {
ToastUtil.show(ReGeocoderActivity.this, R.string.no_result);
}
} else {
ToastUtil.showerror(this, rCode);
}
}
來看全部程式碼:
/**
* 逆地理編碼功能介紹
*/
public class ReGeocoderActivity extends Activity implements
OnGeocodeSearchListener, OnClickListener, OnMarkerClickListener {
private ProgressDialog progDialog = null;
private GeocodeSearch geocoderSearch;
private String addressName;
private AMap aMap;
private MapView mapView;
private LatLonPoint latLonPoint = new LatLonPoint(39.90865, 116.39751);
private Marker regeoMarker;
private ExecutorService mExecutorService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.geocoder_activity);
/*
* 設定離線地圖儲存目錄,在下載離線地圖或初始化地圖設定;
* 使用過程中可自行設定, 若自行設定了離線地圖儲存的路徑,
* 則需要在離線地圖下載和使用地圖頁面都進行路徑設定
* */
//Demo中為了其他介面可以使用下載的離線地圖,使用預設位置儲存,遮蔽了自定義設定
// MapsInitializer.sdcardDir =OffLineMapUtils.getSdCacheDir(this);
mapView = (MapView) findViewById(R.id.map);
mapView.onCreate(savedInstanceState);// 此方法必須重寫
init();
}
/**
* 初始化AMap物件
*/
private void init() {
if (aMap == null) {
aMap = mapView.getMap();
regeoMarker = aMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f)
.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
aMap.setOnMarkerClickListener(this);
}
geocoderSearch = new GeocodeSearch(this);
geocoderSearch.setOnGeocodeSearchListener(this);
progDialog = new ProgressDialog(this);
getAddresses();
}
/**
* 方法必須重寫
*/
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
/**
* 方法必須重寫
*/
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
/**
* 方法必須重寫
*/
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
/**
* 方法必須重寫
*/
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
if (mExecutorService != null) {
mExecutorService.shutdownNow();
}
}
/**
* 顯示進度條對話方塊
*/
public void showDialog() {
progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progDialog.setIndeterminate(false);
progDialog.setCancelable(true);
progDialog.setMessage("正在獲取地址");
progDialog.show();
}
/**
* 隱藏進度條對話方塊
*/
public void dismissDialog() {
if (progDialog != null) {
progDialog.dismiss();
}
}
/**
* 響應逆地理編碼
*/
public void getAddress(final LatLonPoint latLonPoint) {
showDialog();
RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200,
GeocodeSearch.AMAP);// 第一個引數表示一個Latlng,第二引數表示範圍多少米,第三個引數表示是火系座標系還是GPS原生座標系
geocoderSearch.getFromLocationAsyn(query);// 設定非同步逆地理編碼請求
}
/**
* 地理編碼查詢回撥
*/
@Override
public void onGeocodeSearched(GeocodeResult result, int rCode) {
}
/**
* 逆地理編碼回撥
*/
@Override
public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
dismissDialog();
if (rCode == AMapException.CODE_AMAP_SUCCESS) {
if (result != null && result.getRegeocodeAddress() != null
&& result.getRegeocodeAddress().getFormatAddress() != null) {
addressName = result.getRegeocodeAddress().getFormatAddress()
+ "附近";
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
AMapUtil.convertToLatLng(latLonPoint), 15));
regeoMarker.setPosition(AMapUtil.convertToLatLng(latLonPoint));
ToastUtil.show(ReGeocoderActivity.this, addressName);
} else {
ToastUtil.show(ReGeocoderActivity.this, R.string.no_result);
}
} else {
ToastUtil.showerror(this, rCode);
}
}
@Override
public void onClick(View v) {
}
/**
* 響應逆地理編碼的批量請求
*/
private void getAddresses() {
if (mExecutorService == null) {
mExecutorService = Executors.newSingleThreadExecutor();
}
List<LatLonPoint> geopointlist = readLatLonPoints();
for (final LatLonPoint point : geopointlist) {
mExecutorService.submit(new Runnable() {
@Override
public void run() {
try {
RegeocodeQuery query = new RegeocodeQuery(point, 200,
GeocodeSearch.AMAP);// 第一個引數表示一個Latlng,第二引數表示範圍多少米,第三個引數表示是火系座標系還是GPS原生座標系
RegeocodeAddress result = geocoderSearch.getFromLocation(query);// 設定同步逆地理編碼請求
if (result != null && result.getFormatAddress() != null) {
aMap.addMarker(new MarkerOptions()
.position(new LatLng(point.getLatitude(), point.getLongitude()))
.title(result.getFormatAddress()));
}
} catch (AMapException e) {
Message msg = msgHandler.obtainMessage();
msg.arg1 = e.getErrorCode();
msgHandler.sendMessage(msg);
}
}
});
}
}
private Handler msgHandler = new Handler() {
public void handleMessage(Message msg) {
ToastUtil.showerror(ReGeocoderActivity.this, msg.arg1);
}
};
private List<LatLonPoint> readLatLonPoints() {
List<LatLonPoint> points = new ArrayList<LatLonPoint>();
for (int i = 0; i < coords.length; i += 2) {
points.add(new LatLonPoint(coords[i + 1], coords[i]));
}
return points;
}
//測試的經緯度
private double[] coords = {116.339925, 39.976587,
116.328467, 39.976357,
116.345289, 39.966556,
116.321428, 39.967477,
116.358421, 39.961556,
116.366146, 39.961293,
116.359666, 39.953234,
116.373013, 39.948628,
116.355374, 39.94037,
116.41713, 39.940666,
116.433309, 39.940929,
116.461933, 39.949319,
116.473907, 39.938461,
116.478971, 39.933854,
116.491631, 39.96603,
116.489399, 39.971029,
116.495364, 39.98517,
116.530812, 39.99556,
116.5607, 39.996023,
116.525982, 40.022825,
116.568511, 40.016843,
116.584046, 40.014608,
116.422599, 40.012439,
116.44131, 40.00616,
116.39303, 40.026998,
116.384147, 40.039222,
116.388352, 39.928242};
@Override
public boolean onMarkerClick(Marker marker) {
marker.showInfoWindow();
return false;
}
}
getAddresses() 方法裡面用到執行緒同步去做請求,因為我們這裡是批量載入的。你編碼就這麼多了。