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

高德地圖之地理編碼

首先申明是地理編碼呢?地理編碼,又稱為地址匹配,是從已知的地址描述到對應的經緯度座標的轉換過程。該功能適用於根據使用者輸入的地址確認使用者具體位置的場景,常用於配送人員根據使用者輸入的具體地址找地點。既地理編碼(地址轉座標)。
這裡寫圖片描述
下面一步步來看怎麼實現的:
1、繼承 OnGeocodeSearchListener 監聽。
2、構造 GeocodeSearch 物件,並設定監聽。

geocoderSearch = new GeocodeSearch(this);
geocoderSearch.setOnGeocodeSearchListener(this);

3、通過 GeocodeQuery(java.lang.String locationName, java.lang.String city) 設定查詢引數,呼叫 GeocodeSearch 的 getFromLocationNameAsyn(GeocodeQuery geocodeQuery) 方法發起請求。

// name表示地址,第二個引數表示查詢城市,中文或者中文全拼,citycode、adcode 
GeocodeQuery query = new GeocodeQuery(name, "010"); 

geocoderSearch.getFromLocationNameAsyn(query); 

4、通過回撥介面 onGeocodeSearched 解析返回的結果。

說明:
1)可以在回撥中解析result,獲取座標資訊。
2)返回結果成功或者失敗的響應碼。1000為成功

//地理編碼結果回撥
   @Override
public void onGeocodeSearched(GeocodeResult result, int rCode) {
    dismissDialog();
if (rCode == 1000) { if (result != null && result.getGeocodeAddressList() != null && result.getGeocodeAddressList().size() > 0) { GeocodeAddress address = result.getGeocodeAddressList().get(0); aMap.animateCamera(CameraUpdateFactory.newLatLngZoom
( AMapUtil.convertToLatLng(address.getLatLonPoint()), 15)); geoMarker.setPosition(AMapUtil.convertToLatLng(address .getLatLonPoint())); addressName = "經緯度值:" + address.getLatLonPoint() + "\n位置描述:" + address.getFormatAddress(); ToastUtil.show(GeocoderActivity.this, addressName); } else { ToastUtil.show(GeocoderActivity.this, R.string.no_result); } } else { ToastUtil.showerror(this, rCode); } }

貼個具體實現類


/**
 * 地理編碼
 *  Created by dong.he on 2017-1-9
 */
public class GeocoderActivity extends Activity implements
        OnGeocodeSearchListener, OnClickListener, LocationSource,
        AMapLocationListener {
    private ProgressDialog progDialog = null;
    private GeocodeSearch geocoderSearch;
    private String addressName;
    private AMap aMap;
    private MapView mapView;
    private Marker geoMarker;
    private EditText geoInput;

    //定位
    private LocationSource.OnLocationChangedListener mListener;
    private AMapLocationClient mlocationClient;
    private AMapLocationClientOption mLocationOption;
    private Double myLat = 0.0, myLongt = 0.0;//我的當前位置的經緯度
    private String cityCode = null;
    private String currentCity = null;

    @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();
            geoMarker = aMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f)
                    .icon(BitmapDescriptorFactory
                            .defaultMarker(BitmapDescriptorFactory.HUE_BLUE)));
            setUpLocation();
        }

        geoInput = (EditText) findViewById(R.id.input_edittext);
        findViewById(R.id.btn_search).setOnClickListener(this);
        geocoderSearch = new GeocodeSearch(this);
        geocoderSearch.setOnGeocodeSearchListener(this);
        progDialog = new ProgressDialog(this);

    }

    /**
     * 方法必須重寫
     */
    @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();
    }

    /**
     * 顯示進度條對話方塊
     */
    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 getLatlon(final String name) {
        showDialog();

        GeocodeQuery query = new GeocodeQuery(name, cityCode);// 第一個引數表示地址,第二個引數表示查詢城市,中文或者中文全拼,citycode、adcode,
        geocoderSearch.getFromLocationNameAsyn(query);// 設定同步地理編碼請求
    }

    /**
     * 地理編碼查詢回撥
     */
    @Override
    public void onGeocodeSearched(GeocodeResult result, int rCode) {
        dismissDialog();
        if (rCode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getGeocodeAddressList() != null
                    && result.getGeocodeAddressList().size() > 0) {
                GeocodeAddress address = result.getGeocodeAddressList().get(0);
                aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                        AMapUtil.convertToLatLng(address.getLatLonPoint()), 15));
                geoMarker.setPosition(AMapUtil.convertToLatLng(address
                        .getLatLonPoint()));
                addressName = "經緯度值:" + address.getLatLonPoint() + "\n位置描述:"
                        + address.getFormatAddress();
                ToastUtil.show(GeocoderActivity.this, addressName);
            } else {
                ToastUtil.show(GeocoderActivity.this, R.string.no_result);
            }
        } else {
            ToastUtil.showerror(this, rCode);
        }
    }

    /**
     * 逆地理編碼回撥
     */
    @Override
    public void onRegeocodeSearched(RegeocodeResult result, int rCode) {

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            /**
             * 響應地理編碼按鈕
             */
            case R.id.btn_search:
                getLatlon(geoInput.getText().toString());
                break;
            default:
                break;
        }
    }


    /**
     * 設定一些amap的屬性
     */
    private void setUpLocation() {
        aMap.setLocationSource(this);// 設定定位監聽
        aMap.getUiSettings().setMyLocationButtonEnabled(true);// 設定預設定位按鈕是否顯示
        aMap.setMyLocationEnabled(true);// 設定為true表示顯示定位層並可觸發定位,false表示隱藏定位層並不可觸發定位,預設是false
        // 設定定位的型別為定位模式 ,可以由定位、跟隨或地圖根據面向方向旋轉幾種
        aMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
    }

    /**
     * 定位成功後回撥函式
     */
    @Override
    public void onLocationChanged(AMapLocation amapLocation) {
        if (mListener != null && amapLocation != null) {
            if (amapLocation != null
                    && amapLocation.getErrorCode() == 0) {

                //定位成功回撥資訊,設定相關訊息
                amapLocation.getLocationType();//獲取當前定位結果來源,如網路定位結果,詳見定位型別表
                myLat = amapLocation.getLatitude();//獲取緯度
                myLongt = amapLocation.getLongitude();//獲取經度
                amapLocation.getAccuracy();//獲取精度資訊
                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date date = new Date(amapLocation.getTime());
                df.format(date);//定位時間
                amapLocation.getAddress();//地址,如果option中設定isNeedAddress為false,則沒有此結果,網路定位結果中會有地址資訊,GPS定位不返回地址資訊。
                amapLocation.getCountry();//國家資訊
                amapLocation.getProvince();//省資訊
                currentCity = amapLocation.getCity();//城市資訊
                amapLocation.getDistrict();//城區資訊
                amapLocation.getStreet();//街道資訊
                amapLocation.getStreetNum();//街道門牌號資訊
                cityCode = amapLocation.getCityCode();//城市編碼
                amapLocation.getAdCode();//地區編碼
                TextView textView = (TextView) findViewById(R.id.city_detail);
                textView.setText(amapLocation.getCity() + "=" + amapLocation.getDistrict() + "==" + amapLocation.getStreetNum());
                mListener.onLocationChanged(amapLocation);// 顯示系統小藍點
            } else {
                String errText = "定位失敗," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
                Log.e("AmapErr", errText);
            }
        }
    }

    /**
     * 啟用定位
     */
    @Override
    public void activate(LocationSource.OnLocationChangedListener listener) {
        mListener = listener;
        if (mlocationClient == null) {
            mlocationClient = new AMapLocationClient(this);
            mLocationOption = new AMapLocationClientOption();
            //設定定位監聽
            mlocationClient.setLocationListener(this);
            //設定為高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //設定定位引數
            mlocationClient.setLocationOption(mLocationOption);
            // 此方法為每隔固定時間會發起一次定位請求,為了減少電量消耗或網路流量消耗,
            // 注意設定合適的定位時間的間隔(最小間隔支援為2000ms),並且在合適時間呼叫stopLocation()方法來取消定位請求
            // 在定位結束後,在合適的生命週期呼叫onDestroy()方法
            // 在單次定位情況下,定位無論成功與否,都無需呼叫stopLocation()方法移除請求,定位sdk內部會移除
            mlocationClient.startLocation();
        }
    }

    /**
     * 停止定位
     */
    @Override
    public void deactivate() {
        mListener = null;
        if (mlocationClient != null) {
            mlocationClient.stopLocation();
            mlocationClient.onDestroy();
        }
        mlocationClient = null;
    }

}

地理編碼其實就是這麼簡單。下一篇會繼續講逆地理編碼。