1. 程式人生 > >安卓開發使用百度地圖sdk實現定位,新增marker,城市切換等功能

安卓開發使用百度地圖sdk實現定位,新增marker,城市切換等功能

許久不寫部落格,慢慢的變的有些懶惰。keep coding,keep learining。

關於學習使用百度地圖sdk,我六點要說。。。。。。哈哈哈哈,玩笑歸玩笑,說正經的,百度地圖sdk的幫助文件寫的不是很好,很多地方不完善,有偷懶的嫌疑,建議學習時配合類參考,有歧義不清楚的地方多翻翻類參考就行了。

下面,我主要講一下我這次給大家提供的一些功能的實現,有些功能在百度的時候,並沒有找到合適的解決方案,但有些啟發。由於是準備在自己的專案中使用百度地圖sdk,所以程式碼寫在了一個測試工程內,有些亂,但是註釋還算詳盡。

1、關於如何配置百度地圖sdk等著就不說了,csdn上一搜一大堆。

2、新增marker,路線規劃,給marker設定點選事件,這些常規功能,官方的幫助文件都有提及,也有demo,不細說。

3、如何在移動的時候,將marker展現在螢幕中心。解決方案:重寫地圖移動時的一個介面,在動作時up時,獲取螢幕中心的point,再將point轉換成經緯度。將上一次的marker移除掉,通過經緯度重新設定marker。

4、如何實現城市切換。這個問題也困擾了我一下,百度沒有提供現成的介面,網上也沒找到有人維護全國各個市的經緯度的資料介面。百度這個問題,有位朋友提供了三個解決方案,受到啟發後我得到了如下解決方案。通過sdk提供的行政區搜尋,最低能找到地級市這一級政府行政中心的經緯度。然後通過mapstatus,將這一位置設定為螢幕中心,這樣就能實現城市切換。然後移動螢幕,marker又會出現在螢幕中心,這樣三和四就能有機地結合在一起。

下面,上程式碼!!!有點亂,請見諒。

xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.xuxuxiao.lbstest.MainActivity"
    android:orientation="vertical">
<Button
    android:id="@+id/button"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="搜尋"/>
    <com.baidu.mapapi.map.MapView
        android:id="@+id/bmapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clickable="true" />

</LinearLayout>
mainactivity:
package com.example.xuxuxiao.lbstest;

import android.graphics.Point;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.location.Poi;
import com.baidu.mapapi.SDKInitializer;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.district.DistrictResult;
import com.baidu.mapapi.search.district.DistrictSearch;
import com.baidu.mapapi.search.district.DistrictSearchOption;
import com.baidu.mapapi.search.district.OnGetDistricSearchResultListener;
import com.baidu.mapapi.search.geocode.GeoCodeOption;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class MainActivity extends AppCompatActivity {
    private MapView mMapView;

    private boolean isFirstLocation = true;

    public LocationClient mLocationClient = null;
    public BDLocationListener myListener = new MyLocationListener();
    private BaiduMap mBaiduMap;

    private double lat;
    private double lon;
    private Point mpoint;
    private static LatLng mlatlng;
    private Marker mMarker;
    private GeoCoder mSearch;
    private  String sheng;
    private  String city;
    private DistrictSearch mdistrictsearch;

    private List<OverlayOptions>listOverlay;
    private Button button;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //在使用SDK各元件之前初始化context資訊,傳入ApplicationContext
        //注意該方法要再setContentView方法之前實現
        //使用百度地圖的任何功能都需要先初始化這段程式碼  最好放在全域性中進行初始化
        //百度地圖+定位+marker比較簡單 我就不放到全域性去了
        SDKInitializer.initialize(getApplicationContext());
        setContentView(R.layout.activity_main);
        button=(Button)findViewById(R.id.button);
        //獲取地圖控制元件引用
        mMapView = (MapView) findViewById(R.id.bmapView);
        //獲取BaiduMap物件
        mBaiduMap = mMapView.getMap();
        mSearch=GeoCoder.newInstance();
        mdistrictsearch=DistrictSearch.newInstance();
        mdistrictsearch.setOnDistrictSearchListener(new mydirtrictsearch());
        mSearch.setOnGetGeoCodeResultListener(new myGocCoderListener());


        //宣告LocationClient類
        mLocationClient = new LocationClient(getApplicationContext());
        //註冊監聽函式
        listOverlay=new ArrayList<>();
        mLocationClient.registerLocationListener(myListener);
        mBaiduMap.setOnMapTouchListener(new myTouchMapListener());
        //配置定位引數
        initLocation();
        initList();
        //開始定位
        mLocationClient.start();
        mBaiduMap.addOverlays(listOverlay);
        //mSearch.geocode(new GeoCodeOption().address("市政府").city("北京"));
       mBaiduMap.setOnMarkerClickListener(new mymarkatclicklistener());
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mdistrictsearch.searchDistrict(new DistrictSearchOption().cityName("徐州").districtName("沛縣"));
            }
        });

    }


    /**
     * 新增marker
     */
    private void setMarker() {
        Log.v("pcw","setMarker : lat : "+ lat+" lon : " + lon);
        //定義Maker座標點
        LatLng point = new LatLng(lat, lon);
        //構建Marker圖示
        BitmapDescriptor bitmap = BitmapDescriptorFactory
                .fromResource(R.mipmap.ic_launcher);
        //構建MarkerOption,用於在地圖上新增Marker
        OverlayOptions option = new MarkerOptions()
                .position(point)
                .icon(bitmap);
        //在地圖上新增Marker,並顯示
        mMarker=(Marker) mBaiduMap.addOverlay(option);
    }

    /**
     * 設定中心點
     */
    private void setUserMapCenter() {
        Log.v("pcw","setUserMapCenter : lat : "+ lat+" lon : " + lon);
        LatLng cenpt = new LatLng(lat,lon);
        //定義地圖狀態
        MapStatus mMapStatus = new MapStatus.Builder()
                .target(cenpt)
                .zoom(18)
                .build();
        //定義MapStatusUpdate物件,以便描述地圖狀態將要發生的變化
        MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
        //改變地圖狀態
        mBaiduMap.setMapStatus(mMapStatusUpdate);

    }
    private void setCenter(LatLng l) {
        Log.v("pcw","setUserMapCenter : lat : "+ lat+" lon : " + lon);
        LatLng cenpt = l;
        //定義地圖狀態
        MapStatus mMapStatus = new MapStatus.Builder()
                .target(cenpt)
                .zoom(18)
                .build();
        //定義MapStatusUpdate物件,以便描述地圖狀態將要發生的變化
        MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
        //改變地圖狀態
        mBaiduMap.setMapStatus(mMapStatusUpdate);

    }
    private void setMoveMapCenter(LatLng lng){
        Log.d("Moving","this is center after move");
        //構建Marker圖示
        BitmapDescriptor bitmap = BitmapDescriptorFactory
                .fromResource(R.mipmap.ic_launcher);
        //構建MarkerOption,用於在地圖上新增Marker
        OverlayOptions option = new MarkerOptions()
                .position(lng)
                .icon(bitmap);
        //在地圖上新增Marker,並顯示
        mMarker=(Marker) mBaiduMap.addOverlay(option);
    }
    private void initList(){

        for (int i=0;i<10;i++){
            LatLng l=new LatLng(34.19881-i,117.305888-i/10);
            OverlayOptions option1 =  new MarkerOptions()
                    .position(l)
                    .icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_launcher));
            listOverlay.add(option1);

        }
    }

    /**
     * 配置定位引數
     */
    private void initLocation(){
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy
        );//可選,預設高精度,設定定位模式,高精度,低功耗,僅裝置
        option.setCoorType("bd09ll");//可選,預設gcj02,設定返回的定位結果座標系
        int span=1000;
        //option.setScanSpan(span);//可選,預設0,即僅定位一次,設定發起定位請求的間隔需要大於等於1000ms才是有效的
        option.setIsNeedAddress(true);//可選,設定是否需要地址資訊,預設不需要
        option.setOpenGps(true);//可選,預設false,設定是否使用gps
        option.setLocationNotify(true);//可選,預設false,設定是否當gps有效時按照1S1次頻率輸出GPS結果
        option.setIsNeedLocationDescribe(true);//可選,預設false,設定是否需要位置語義化結果,可以在BDLocation.getLocationDescribe裡得到,結果類似於“在北京天安門附近”
        option.setIsNeedLocationPoiList(true);//可選,預設false,設定是否需要POI結果,可以在BDLocation.getPoiList裡得到
        option.setIgnoreKillProcess(false);//可選,預設true,定位SDK內部是一個SERVICE,並放到了獨立程序,設定是否在stop的時候殺死這個程序,預設不殺死
        option.SetIgnoreCacheException(false);//可選,預設false,設定是否收集CRASH資訊,預設收集
        option.setEnableSimulateGps(false);//可選,預設false,設定是否需要過濾gps模擬結果,預設需要
        mLocationClient.setLocOption(option);
    }

    /**
     * 實現定位監聽 位置一旦有所改變就會呼叫這個方法
     * 可以在這個方法裡面獲取到定位之後獲取到的一系列資料
     */
    public class MyLocationListener implements BDLocationListener {

        @Override
        public void onReceiveLocation(BDLocation location) {
            //Receive Location
            StringBuffer sb = new StringBuffer(256);
            sb.append("time : ");
            sb.append(location.getTime());
            sb.append("\nerror code : ");
            sb.append(location.getLocType());
            sb.append("\nlatitude : ");
            sb.append(location.getLatitude());
            sb.append("\nlontitude : ");
            sb.append(location.getLongitude());
            sb.append("\nradius : ");
            sb.append(location.getRadius());

            if (location.getLocType() == BDLocation.TypeGpsLocation) {// GPS定位結果
                sb.append("\nspeed : ");
                sb.append(location.getSpeed());// 單位:公里每小時
                sb.append("\nsatellite : ");
                sb.append(location.getSatelliteNumber());
                sb.append("\nheight : ");
                sb.append(location.getAltitude());// 單位:米
                sb.append("\ndirection : ");
                sb.append(location.getDirection());// 單位度
                sb.append("\naddr : ");
                sb.append(location.getAddrStr());
                sb.append("\ndescribe : ");
                sb.append("gps定位成功");

            } else if (location.getLocType() == BDLocation.TypeNetWorkLocation) {// 網路定位結果
                sb.append("\naddr : ");
                sb.append(location.getAddrStr());
                //運營商資訊
                sb.append("\noperationers : ");
                sb.append(location.getOperators());
                sb.append("\ndescribe : ");
                sb.append("網路定位成功");
            } else if (location.getLocType() == BDLocation.TypeOffLineLocation) {// 離線定位結果
                sb.append("\ndescribe : ");
                sb.append("離線定位成功,離線定位結果也是有效的");
            } else if (location.getLocType() == BDLocation.TypeServerError) {
                sb.append("\ndescribe : ");
                sb.append("服務端網路定位失敗,可以反饋IMEI號和大體定位時間到[email protected],會有人追查原因");
            } else if (location.getLocType() == BDLocation.TypeNetWorkException) {
                sb.append("\ndescribe : ");
                sb.append("網路不同導致定位失敗,請檢查網路是否通暢");
            } else if (location.getLocType() == BDLocation.TypeCriteriaException) {
                sb.append("\ndescribe : ");
                sb.append("無法獲取有效定位依據導致定位失敗,一般是由於手機的原因,處於飛航模式下一般會造成這種結果,可以試著重啟手機");
            }
            sb.append("\nlocationdescribe : ");
            sb.append(location.getLocationDescribe());// 位置語義化資訊
            List<Poi> list = location.getPoiList();// POI資料
            if (list != null) {
                sb.append("\npoilist size = : ");
                sb.append(list.size());
                for (Poi p : list) {
                    sb.append("\npoi= : ");
                    sb.append(p.getId() + " " + p.getName() + " " + p.getRank());
                }
            }
            lat = location.getLatitude();
            lon = location.getLongitude();
            mlatlng=new LatLng(lat,lon);

            //這個判斷是為了防止每次定位都重新設定中心點和marker
            if(isFirstLocation){
                isFirstLocation = false;
                setMarker();
                setUserMapCenter();
            }
            Log.v("pcw","lat : " + lat+" lon : " + lon);
            Log.i("BaiduLocationApiDem", sb.toString());
        }
    }
    public class myTouchMapListener implements BaiduMap.OnMapTouchListener{
        @Override
        public void onTouch(MotionEvent motionEvent) {
            switch (motionEvent.getAction()){
                case MotionEvent.ACTION_DOWN:
                    Log.d("move","action down");
                    break;
                case MotionEvent.ACTION_MOVE:
                    Log.d("move","action move");
                    break;
                case MotionEvent.ACTION_UP:
                    mpoint=mBaiduMap.getMapStatus().targetScreen;
                    mlatlng=mBaiduMap.getProjection().fromScreenLocation(mpoint);
                    mMarker.remove();
                    setMoveMapCenter(mlatlng);
                    mSearch.reverseGeoCode(new ReverseGeoCodeOption()
                            .location(mlatlng));
                    break;


            }
        }
    }
    public class myGocCoderListener implements OnGetGeoCoderResultListener{
        @Override
        public void onGetGeoCodeResult(GeoCodeResult result) {
            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
                //沒有檢索到結果
                Log.d("geocode","no change result");
            }
            //獲取地理編碼結果
            mlatlng=result.getLocation();
            setMoveMapCenter(mlatlng);


        }

        @Override
        public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
            if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) {
                //沒有找到檢索結果
                Log.d("geocode","no result");
                return ;
            }
            //獲取反向地理編碼結果
            StringBuilder resultAddress=new StringBuilder();
            resultAddress.append(result.getAddress());
            Log.d("geocode",resultAddress.toString());

        }
    }
    public class mydirtrictsearch implements OnGetDistricSearchResultListener{

        @Override
        public void onGetDistrictResult(DistrictResult result) {
             if (result==null||result.error!=SearchResult.ERRORNO.NO_ERROR){
                 Log.d("districtresout","no resout");
                 return;
             }
             mlatlng=result.getCenterPt();
            Log.d("districtresout",mlatlng.toString());
            setCenter(mlatlng);
        }
    }
    public class mymarkatclicklistener implements BaiduMap.OnMarkerClickListener{
        @Override
        public boolean onMarkerClick(Marker marker) {
            Log.d("marketClick","this is market click");
            return true;
        }
    }


    /**
     * 必須要實現
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity執行onDestroy時執行mMapView.onDestroy(),實現地圖生命週期管理
        mMapView.onDestroy();
    }

    /**
     * 必須要實現
     */
    @Override
    protected void onResume() {
        super.onResume();
        //在activity執行onResume時執行mMapView. onResume (),實現地圖生命週期管理
        mMapView.onResume();
    }

    /**
     * 必須要實現
     */
    @Override
    protected void onPause() {
        super.onPause();
        //在activity執行onPause時執行mMapView. onPause (),實現地圖生命週期管理
        mMapView.onPause();
    }

}


百度地圖還有更多更豐富的用法,但是,我建議看看高德地圖。雖然沒學習過高德地圖sdk的用法,但是,百度地圖的幫助文件實在讓人看的生氣。對了,建議大家在使用百度地圖sdk時,多打打log,這樣出問題了才能準確迅速地找到問題所在

相關推薦

開發使用地圖sdk實現定位新增marker城市切換功能

許久不寫部落格,慢慢的變的有些懶惰。keep coding,keep learining。 關於學習使用百度地圖sdk,我六點要說。。。。。。哈哈哈哈,玩笑歸玩笑,說正經的,百度地圖sdk的幫助文件寫的不是很好,很多地方不完善,有偷懶的嫌疑,建議學習時配合類參考,有歧義不清

iOS·採用第三方(地圖SDK)實現定位功能開發

 陳滿iOS  關注 2017.05.01 01:06* 字數 2212 閱讀 6818評論 7喜歡 133 1.申請金鑰 首先,申請一個baidu賬號,接著進入新建金鑰入口申請成為baidu地圖開發者,填寫相關開發者資訊和簡訊驗證碼。接

Android使用地圖SDK實現定位與方向感測器匹配

public class MylocationListener implements BDLocationListener { //定位請求回撥介面 private boolean isFirstIn=true; //定位請求回撥函式,這裡面會得到定位資

ionic開發——地圖InfoWindow資訊視窗上新增按鈕無法觸發點選事件問題解決辦法

ionic開發中,在使用百度地圖的時候,有時我們需要在點選地圖上標註的海量點彈出一個infowindow的資訊視窗,自定義資訊視窗的內容後,我們想要可以在資訊視窗上面點選的時候,發現點選沒有效果。 我

Android 地圖開發(一)如何呼叫地圖介面和在專案中顯示地圖以及實現定位

二、下載百度地圖API庫 然後新增到專案中即可。   三、在專案清單AndroidMainifest.xml配置百度地圖API key和新增相關許可權                         四、在專案呼叫百度地圖專案功能,這篇文章就首先講講顯示地圖和定位的功能 首先

地圖SDK申請之獲取釋出版開發版SHA1

百度地圖SDK在實際開發中也算是最常用的SDK之一,但是不少新手開發者對申請金鑰時,填寫SHA1有不少疑問,在此解答 進入百度地圖SDK申請金鑰會看到這樣的場景 這裡不得不說幾件事 在安卓開發中,打包生成APK時,我們通常有兩種方式 重點: 也就是所謂的debug版

呼叫地圖定位自己的位置然後分享自己的位置資訊生成連結短串。

</pre><pre name="code" class="java">         前些天公司讓做一個這樣的功能描述如下 呼叫百度地圖的定位功能,然後通過簡訊將自己的位置

整合地圖API實現定位

一.百度地圖API獲取定位 AndroidManifest.xml必須配置: 定位服務 <service        &nbs

地圖SDK整合定位,衛星地圖

其中兩種整合方式基本相同 1.百度地圖第三方SDK的開放平臺建立應用 2.下載官方的SDK 3.複製到專案的libs目錄下 4.但這樣工程並不會自動載入libs下的so檔案,需配置so檔案的路徑為該libs路徑,關聯所有地圖SDK的so檔案 App下的groud.build的

mui使用地圖sdk定位方法

一、使用前配置:參考http://ask.dcloud.net.cn/article/29        注意事項:     (1)HBuilder預設打包使用的簽名為"BA:AD:09:3A:82:82:9F:

js呼叫地圖api實現定位

<?php /** * Created by PhpStorm. * User: onlythen * Date: 5/26/15 * Time: 3:23 PM */ session_start(); require_once("config.php"); $link_id=mys

使用地圖api實現定位及選擇位置功能

之前使用過一些第三方的地圖api,最後還是覺得百度的比較好用,剛好最近做一個專案,需要用到地圖的功能,也比較簡單,就是獲取當前位置,然後可以自己手動在地圖上選擇位置,把經緯度丟給服務端。我用的就是百度地圖 下面就開始做了,註冊開發者賬號、申請key、下載SDK什麼的,就

android使用地圖SDK獲取定位資訊

本文使用Android Studio開發。 獲取定位資訊相對簡單,我們只需要如下幾步: 第三步,建立Android Studio工程(略過不說),配置環境: 將解壓後的檔案放入libs資料夾下,並在src/main下建立一個叫做jniLibs的資料

地圖api實現定位功能

package com.demo.an.android.location; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickLis

基於地圖SDK和Elasticsearch GEO查詢的地理圍欄分析系統(3)-前端實現

方便 復制 類型 復制代碼 自動跳轉 rar 窗口 stack delete 轉載自:http://www.cnblogs.com/Auyuer/p/8086975.html MoonLight可視化訂單需求區域分析系統實現功能:   在現實生活中,計算機和互聯網迅速發展,

android studio使用SDK開發地圖應用中遇到的問題彙總

1、com.baidu.mapapi.map.MapView (Open Class, Show Exception, Clear Cache) The following classes could not be instantiated:    

地圖SDK-----地圖線上建議查詢結合AutoCompleteTextView實現搜尋下拉列表。

實現效果圖 如下 這是百度地圖 POISearch的效果,                     這是自己寫的效果 首先實現這個功能主要用到了兩個部分 第一個部分 AutoCompleteTextView     具體使用參考 http://blog.csdn.ne

地圖sdk使用

maps ase 一體化 class lib sdk map 申請 系統 1.android開發百度地圖定位,我怎麽老是定到幾內亞灣 權限問題,首先安卓6.0之後的Android的系統需要動態申請權限。 然後百度地圖的sdk的不同功能,申請的權限不同,每個功能都需要看官方文

地圖sdk sha1秘鑰獲取有種想吐的趕腳

src andro files inf com admin oid file http 擼代碼坐的腰算背疼還只是弄一個不是項目裏邊需要的升級版本的so 日 需要sha1 指紋秘鑰,還有項目包, 才能用百度地圖sdk 這個找sha1 獲取廢了20分鐘, 顯示全盤找keyt

iOS開發 - 解決地圖模擬器無法定位問題

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!