天地圖之定位信息詳解

原文首發於微信公衆號:jzman-blog,歡迎關注交流!

最近的項目涉及到百度地圖的使用,項目組通知使用天地圖替代百度地圖,一個緣由是天地圖是國家測繪地理信息局建設的,企業可使用其公衆版本進行開發以提供相關的地圖信息服務,較其餘地圖具備權威性,固然天地圖提供的服務是否較其餘地圖更具備權威性和實時性,這個做爲普通開發者是不能肯定的,另外一個緣由是減小運用成本,我以爲是否真能達到這樣的目標真不必定,畢竟商業地圖輸出能力仍是較免費版本更強。仍是先來開始天地圖 Android SDK 的學習之路吧,先從一下幾個方面來學習:java

  1. 引入天地圖 SDK
  2. 地圖顯示
  3. 個人位置
  4. 定位圖標的修改
  5. 獲取位置信息
  6. 顯示效果

引入天地圖 SDK

首先下載天地圖地圖 SDK,而後添加相應的 Jar 包和 so 文件到 libs 文件夾中,在 module 的 build.gradle 文件中指定 so 文件的目錄爲 libs 目錄,具體以下:android

sourceSets {
    main {
        //指定so文件的查找目錄是libs目錄
        jniLibs.srcDir 'libs'
    }
}

按照官網指定的權限配置,使用過程當中發現少了權限,下面是完整權限列表,具體以下:微信

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

若是項目 targetSdkVersion 是 23 以上記得動態申請相關危險權限,此時,天地圖地圖 SDK 就引入到項目中了。ide

地圖顯示

首先在佈局中引入 MapView,佈局代碼以下:佈局

<com.tianditu.android.maps.MapView
    android:id="@+id/mapView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

此時,地圖就能夠正常顯示了,不須要額外的配置,固然能夠初始化地圖相關的一些參數,經常使用配置以下:學習

private void initMapView() {
    //啓用內置的縮放組件
    mapView.setBuiltInZoomControls(true);
    //獲得MapView的控制權,能夠用它控制和驅動平移和縮放
    mMapController = mapView.getController();
    //用給定的經緯度構造一個GeoPoint,單位是微度 (度 * 1E6)
    GeoPoint point = new GeoPoint((int) (39.915 * 1E6), (int) (116.404 * 1E6));
    //設置地圖中心點
    mMapController.setCenter(point);
    //設置地圖縮放級別
    mMapController.setZoom(12);
}

天地圖 Android SDK 的引入及地圖顯示相對百度地圖、高德地圖仍是比較方便的。gradle

個人位置

開發中經常須要定位當前位置,而且要從以前的位置動畫移動到當前位置,獲取個人位置的關鍵類是 MyLocationOverlay ,經過該類能夠輕鬆獲取個人位置,因爲該類是 Overlay 的子類,在啓用個人位置後要將該類的實例添加到 MapView 中,個人位置纔會正確顯示,至於移動到當前位置使用到 MapController 這個類,從MapView 中獲取到地圖控制器就能夠移動到個人位置了,代碼參考以下:動畫

//建立MyLocationOverlay
myLocationOverlay = new MyLocationOverlay(this, mapView);
//啓用指南針位置更新
myLocationOverlay.enableCompass();
//啓用個人位置
myLocationOverlay.enableMyLocation();
mapView.addOverlay(myLocationOverlay);
//得到當前位置
mPoint = myLocationOverlay.getMyLocation();
//動畫移動到當前位置
mMapController.animateTo(mPoint);

個人位置定位成功,那麼如何修改默認的定位圖標呢,下面告訴你如何修改默認的定位圖標。ui

定位圖標修改

天地圖默認定位圖標是一個藍色的小圓點圖標,不少時候都會遇到修改定位圖標以及偏差半徑的修改,後者主要會顯示一個帶陰影的圓圈,以此來表示當前定位的偏差範圍,關於定位主要涉及到的類是 MyLocationOverlay,這個類是一個位置覆蓋類,主要負責繪製、獲取個人位置以及指南針的顯示等,那麼如何修改這個默認的定位圖標呢,下面是一點思路:this

  1. 在項目路徑中找到默認定位圖標;
  2. 在關鍵類中找到設置該默認圖標的位置;
  3. 繼承關鍵類,重寫相關代碼,替換原有的定位圖標爲新的定位圖標;
  4. 使用新的類替換 MyLocationOverlay 類。

這種修改方式基本適用於相似的修改默認圖標的場景,關鍵一點是找到相關類及相關位置而後作一下替換工做就 OK 了,固然這裏對應的就是繼承 MyLocationOverlay,重寫 drawMyLocation 方法,而後替換相應圖標,關鍵代碼以下:

@Override
protected void drawMyLocation(GL10 gl, MapView mapView, Location lastFix, GeoPoint myLocation, long when) {
    //得到屏幕座標
    Point point = new Point();
    mapView.getProjection().toPixels(myLocation,point);
    //默認精度
    float accuracy = getAccuracy();
    //指定精度
    float accuracy = 500;
    //得到實際偏差距離
    float distance = mapView.getProjection().metersToEquatorPixels(accuracy);
    AndroidJni.OpenglFillRound(point.x, point.y, (int)distance, 0, 360, 137, 170, 213, 77);
    //建立Drawable
    UtilTextureDrawable drawable = new UtilTextureDrawable(mContext, R.drawable.ic_location, BOUND_TYPE_CENTER);
    drawable.DrawTexture(gl,point,0.0F);
}

此時,使用自定義的 MLocationOverlay 替換 MyLocationOverlay 啓用個人位置,定位圖標已經被更改了,這裏默認定位圖標修改的另外一種思路是獲取到當前位置後,使用 Marker 設置標註來實現本身定義的定位圖標,實踐發現是沒有問題的,可是這樣偏差範圍就不可以輕鬆實現了,綜上,仍是上一種思路比較好,一勞永逸的解決自定義圖標的修改。

獲取位置信息

這裏獲取具體的位置信息,須要設置逆地理編碼回調結果的監聽獲取詳細地址信息,設置座標位置,開始搜索地址,先實現逆地理編碼結果監聽器,代碼以下:

/**
 * 逆地理編碼回調結果監聽
 */
class OnGeoResultListener implements TGeoDecode.OnGeoResultListener {

    @Override
    public void onGeoDecodeResult(TGeoAddress tGeoAddress, int errorCode) {

        if (TErrorCode.OK == errorCode) {
            // 查詢點相關信息
            String str = "最近的 poi 名稱:" + tGeoAddress.getPoiName() + "\n";
            str += "查詢點 Poi 點的方位:" + tGeoAddress.getPoiDirection() + "\n";
            str += "查詢點 Poi 點的距離:" + tGeoAddress.getPoiDistance() + "\n";
            str += "查詢點行政區名稱:" + tGeoAddress.getCity() + "\n";
            str += "查詢點地理描述全稱:" + tGeoAddress.getFullName() + "\n";
            str += "查詢點的地址:" + tGeoAddress.getAddress() + "\n";
            str += "查詢點的方位:" + tGeoAddress.getAddrDirection() + "\n";
            str += "查詢點的距離:" + tGeoAddress.getAddrDistance() + "\n";
            str += "查詢點道路名稱:" + tGeoAddress.getRoadName() + "\n";
            str += "查詢點與最近道路的距離:" + tGeoAddress.getRoadDistance();
            tvAddress.setText(tGeoAddress.getFullName());
            System.out.println(str);
        } else {
            System.out.println("查詢出錯:" + errorCode);
        }
    }
}

而後,設置對逆地理編碼結果的監聽,代碼參考以下:

//逆地理編碼類,根據輸入的點座標,返回相應的地理信息
TGeoDecode tGeoDecode = new TGeoDecode(new OnGeoResultListener());
tGeoDecode.search(mPoint);

若是前面都沒有問題,那麼具體的位置信息確定沒有問題,只是沒有提供獲取當前城市名稱的方法,getCity() 返回的是行政區名稱而不是當前城市名稱,這必定對於只想定位當前城市的需求就不友好了,關於天地圖的初次接觸就到此爲止了。

顯示效果

注意兩次修改前和修改後的圖標以及偏差範圍的顯示,下面是顯示效果,具體以下:

clipboard.png

實際上地圖的使用大同小異,經過以上內容基本需求已經可以完成,固然地圖開發中還有一塊內容是地圖標註,這一步內容陸續推送出來,能夠添加個人微信 jamanu 互相交流學習。

圖片描述

相關文章
相關標籤/搜索