1. 程式人生 > >高德地圖之逆地理編碼

高德地圖之逆地理編碼

上一篇講述了地理編碼的使用,沒看的朋友可以看看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() 方法裡面用到執行緒同步去做請求,因為我們這裡是批量載入的。你編碼就這麼多了。