1. 程式人生 > >百度地圖marker標記即行車路線規劃和marker點選氣泡事件

百度地圖marker標記即行車路線規劃和marker點選氣泡事件

上一篇,之前的定位什麼的就不在說了,我們可以做個簡單的demo,點選地圖任意位置新增標記marker,並且根據,我們定位的位置為起點stNode,和marker標記即我們點選的位置即enNode,進行自動路線規劃,橙色程式碼位置為新增marker如果你只需要marker標記那麼即新增這些程式碼即可。

import android.content.Context;
import android.widget.Toast;

import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapPoi;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.RouteLine;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.route.BikingRouteResult;
import com.baidu.mapapi.search.route.DrivingRoutePlanOption;
import com.baidu.mapapi.search.route.DrivingRouteResult;
import com.baidu.mapapi.search.route.OnGetRoutePlanResultListener;
import com.baidu.mapapi.search.route.PlanNode;
import com.baidu.mapapi.search.route.RoutePlanSearch;
import com.baidu.mapapi.search.route.TransitRouteResult;
import com.baidu.mapapi.search.route.WalkingRouteResult;
import com.sanshi.demo.R;

/**
 * Created by PC_F on 2017/4/7.
 * 地圖單擊事件監聽介面
 */

public class BaiduMapClickListener implements BaiduMap.OnMapClickListener, OnGetRoutePlanResultListener {

    private Context context;
    public BaiduMap mBaiduMap;
    private BitmapDescriptor bitmapDefault;
    private double mCurrentLantitude, mCurrentLongitude;

    //全域性變數
    private double myLongitude;     //經度
    private double myLatitude;  //緯度
    private RouteLine route = null;
    private OverlayManager routeOverlay = null;
    //搜尋相關
    RoutePlanSearch mSearch = null;// 搜尋模組,也可去掉地圖模組獨立使用

    public BaiduMapClickListener(Context context, BaiduMap mBaiduMap, double mCurrentLantitude, double mCurrentLongitude) {
        this.context = context;
        this.mBaiduMap = mBaiduMap;
        this.mCurrentLongitude = mCurrentLongitude;
        this.mCurrentLantitude = mCurrentLantitude;
        bitmapDefault = BitmapDescriptorFactory
                .fromResource(R.drawable.red_car);
//        初始化搜尋模組,註冊事件監聽
        mSearch = RoutePlanSearch.newInstance();
        mSearch.setOnGetRoutePlanResultListener(this);
    }

    /**
     * 地圖單擊事件回撥函式
     *
     * @param point 點選的地理座標
     */
    public void onMapClick(LatLng point) {
        mBaiduMap.clear();
        // 構建MarkerOption,用於在地圖上新增Marker
        MarkerOptions options = new MarkerOptions().position(point)
                .icon(bitmapDefault);
        myLatitude = point.latitude;
        myLongitude = point.longitude;
        // 在地圖上新增Marker,並顯示
        mBaiduMap.addOverlay(options);
mBaiduMap.setOnMarkerClickListener(new BaiduMarkerClickListener(context, mBaiduMap, mCurrentLantitude, mCurrentLongitude)); SearchButtonProcess(); } /** * 地圖內 Poi 單擊事件回撥函式 * * @param poi 點選的 poi 資訊 */ public boolean onMapPoiClick(MapPoi poi) { return false; } /** * 發起路線規劃搜尋示例 */ public void SearchButtonProcess() { //重置瀏覽節點的路線資料 route = null; mBaiduMap.clear(); PlanNode stNode = PlanNode.withLocation(new LatLng(mCurrentLantitude, mCurrentLongitude)); //TODO 伺服器資料介面 //PlanNode enNode = PlanNode.withLocation(new LatLng(shopLatitude,shopLongitude)); //如果使用伺服器傳遞資料將shop的經緯度替換 //PlanNode enNode = PlanNode.withCityNameAndPlaceName("無錫", editEn.getText().toString()); // PlanNode enNode = PlanNode.withCityNameAndPlaceName("無錫", "無錫火車站"); PlanNode enNode = PlanNode.withLocation(new LatLng(myLatitude, myLongitude)); // 實際使用中請對起點終點城市進行正確的設定 mSearch.drivingSearch((new DrivingRoutePlanOption()) .from(stNode) .to(enNode)); } @Override public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) { } @Override public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) { } @Override public void onGetDrivingRouteResult(DrivingRouteResult result) { if (result == null || result.error != SearchResult.ERRORNO.NO_ERROR) { Toast.makeText(context, "抱歉,未找到結果", Toast.LENGTH_SHORT).show(); } if (result.error == SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) { //起終點或途經點地址有岐義,通過以下介面獲取建議查詢資訊 //result.getSuggestAddrInfo() return; } if (result.error == SearchResult.ERRORNO.NO_ERROR) { route = result.getRouteLines().get(0); DrivingRouteOverlay overlay = new DrivingRouteOverlay(mBaiduMap); routeOverlay = overlay; mBaiduMap.setOnMarkerClickListener(overlay); overlay.setData(result.getRouteLines().get(0)); overlay.addToMap(); overlay.zoomToSpan(); } } @Override public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) { } }

但是這樣寫還是不夠,需要加上百度地圖DrivingRouteOverlay,才能正常進行路線規劃,如果是騎車不行的話有不同的類可以供你進行選擇,這是百度api提供給我們的我們可以一點不動複製貼上過來就可以了

package com.sanshi.demo.tools;

import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;

import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.Polyline;
import com.baidu.mapapi.map.PolylineOptions;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.route.DrivingRouteLine;
import com.baidu.mapapi.search.route.DrivingRouteLine.DrivingStep;

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

/**
 * 用於顯示一條駕車路線的overlay,自3.4.0版本起可例項化多個新增在地圖中顯示,當資料中包含路況資料時,則預設使用路況紋理分段繪製
 */
public class DrivingRouteOverlay extends OverlayManager {

    private DrivingRouteLine mRouteLine = null;
    boolean focus = false;
    /**
     * 建構函式
     * 
     * @param baiduMap
     *            該DrivingRouteOvelray引用的 BaiduMap
     */
    public DrivingRouteOverlay(BaiduMap baiduMap) {
        super(baiduMap);
    }

    @Override
    public final List<OverlayOptions> getOverlayOptions() {
        if (mRouteLine == null) {
            return null;
        }

        List<OverlayOptions> overlayOptionses = new ArrayList<OverlayOptions>();
        // step node
        if (mRouteLine.getAllStep() != null
                && mRouteLine.getAllStep().size() > 0) {

            for (DrivingRouteLine.DrivingStep step : mRouteLine.getAllStep()) {
                Bundle b = new Bundle();
                b.putInt("index", mRouteLine.getAllStep().indexOf(step));
                if (step.getEntrance() != null) {
                    overlayOptionses.add((new MarkerOptions())
                            .position(step.getEntrance().getLocation())
                            .anchor(0.5f, 0.5f)
                            .zIndex(10)
                            .rotate((360 - step.getDirection()))
                            .extraInfo(b)
                            .icon(BitmapDescriptorFactory
                                    .fromAssetWithDpi("Icon_line_node.png")));
                }
                // 最後路段繪製出口點
                if (mRouteLine.getAllStep().indexOf(step) == (mRouteLine
                        .getAllStep().size() - 1) && step.getExit() != null) {
                    overlayOptionses.add((new MarkerOptions())
                            .position(step.getExit().getLocation())
                            .anchor(0.5f, 0.5f)
                            .zIndex(10)
                            .icon(BitmapDescriptorFactory
                                    .fromAssetWithDpi("Icon_line_node.png")));

                }
            }
        }

        if (mRouteLine.getStarting() != null) {
            overlayOptionses.add((new MarkerOptions())
                    .position(mRouteLine.getStarting().getLocation())
                    .icon(getStartMarker() != null ? getStartMarker() :
                            BitmapDescriptorFactory
                                    .fromAssetWithDpi("Icon_start.png")).zIndex(10));
        }
        if (mRouteLine.getTerminal() != null) {
            overlayOptionses
                    .add((new MarkerOptions())
                            .position(mRouteLine.getTerminal().getLocation())
                            .icon(getTerminalMarker() != null ? getTerminalMarker() :
                                    BitmapDescriptorFactory
                                            .fromAssetWithDpi("Icon_end.png"))
                            .zIndex(10));
        }
        // poly line
        if (mRouteLine.getAllStep() != null
                && mRouteLine.getAllStep().size() > 0) {

            List<DrivingStep> steps = mRouteLine.getAllStep();
            int stepNum = steps.size();


            List<LatLng> points = new ArrayList<LatLng>();
            ArrayList<Integer> traffics = new ArrayList<Integer>();
            int totalTraffic = 0;
            for (int i = 0; i < stepNum ; i++) {
                if (i == stepNum - 1) {
                    points.addAll(steps.get(i).getWayPoints());
                } else {
                    points.addAll(steps.get(i).getWayPoints().subList(0, steps.get(i).getWayPoints().size() - 1));
                }

                totalTraffic += steps.get(i).getWayPoints().size() - 1;
                if (steps.get(i).getTrafficList() != null && steps.get(i).getTrafficList().length > 0) {
                    for (int j = 0;j < steps.get(i).getTrafficList().length;j++) {
                        traffics.add(steps.get(i).getTrafficList()[j]);
                    }
                }
            }

//            Bundle indexList = new Bundle();
//            if (traffics.size() > 0) {
//                int raffic[] = new int[traffics.size()];
//                int index = 0;
//                for (Integer tempTraff : traffics) {
//                    raffic[index] = tempTraff.intValue();
//                    index++;
//                }
//                indexList.putIntArray("indexs", raffic);
//            }
            boolean isDotLine = false;

            if (traffics != null && traffics.size() > 0) {
                isDotLine = true;
            }
            PolylineOptions option = new PolylineOptions().points(points).textureIndex(traffics)
                    .width(7).dottedLine(isDotLine).focus(true)
                    .color(getLineColor() != 0 ? getLineColor() : Color.argb(178, 0, 78, 255)).zIndex(0);
            if (isDotLine) {
                option.customTextureList(getCustomTextureList());
            }
            overlayOptionses.add(option);
        }
        return overlayOptionses;
    }

    /**
     * 設定路線資料
     *
     * @param routeLine
     *            路線資料
     */
    public void setData(DrivingRouteLine routeLine) {
        this.mRouteLine = routeLine;
    }

    /**
     * 設定路線資料
     * 
     *            路線資料
     */
    public BitmapDescriptor getStartMarker() {
        return null;
    }

    /**
     * 覆寫此方法以改變預設起點圖示
     * 
     * @return 起點圖示
     */
    public int getLineColor() {
        return 0;
    }
    /**
     * 覆寫此方法以改變預設繪製顏色
     * @return 線顏色
     */
    public List<BitmapDescriptor> getCustomTextureList() {
        ArrayList<BitmapDescriptor> list = new ArrayList<BitmapDescriptor>();
        list.add(BitmapDescriptorFactory.fromAsset("Icon_road_blue_arrow.png"));
        list.add(BitmapDescriptorFactory.fromAsset("Icon_road_green_arrow.png"));
        list.add(BitmapDescriptorFactory.fromAsset("Icon_road_yellow_arrow.png"));
        list.add(BitmapDescriptorFactory.fromAsset("Icon_road_red_arrow.png"));
        list.add(BitmapDescriptorFactory.fromAsset("Icon_road_nofocus.png"));
        return list;
    }
    /**
     * 覆寫此方法以改變預設終點圖示
     * 
     * @return 終點圖示
     */
    public BitmapDescriptor getTerminalMarker() {
        return null;
    }

    /**
     * 覆寫此方法以改變預設點選處理
     * 
     * @param i
     *            線路節點的 index
     * @return 是否處理了該點選事件
     */
    public boolean onRouteNodeClick(int i) {
        if (mRouteLine.getAllStep() != null
                && mRouteLine.getAllStep().get(i) != null) {
            Log.i("baidumapsdk", "DrivingRouteOverlay onRouteNodeClick");
        }
        return false;
    }

    @Override
    public final boolean onMarkerClick(Marker marker) {
        for (Overlay mMarker : mOverlayList) {
            if (mMarker instanceof Marker && mMarker.equals(marker)) {
                if (marker.getExtraInfo() != null) {
                    onRouteNodeClick(marker.getExtraInfo().getInt("index"));
                }
            }
        }
        return true;
    }

    @Override
    public boolean onPolylineClick(Polyline polyline) {
        boolean flag = false;
        for (Overlay mPolyline : mOverlayList) {
            if (mPolyline instanceof Polyline && mPolyline.equals(polyline)) {
                // 選中
                flag = true;
                break;
            }
        }
        setFocus(flag);
        return true;
    }

    public void setFocus(boolean flag) {
        focus = flag;
        for (Overlay mPolyline : mOverlayList) {
            if (mPolyline instanceof Polyline) {
                // 選中
                ((Polyline) mPolyline).setFocus(flag);

                break;
            }
        }

    }
}

如果需要對marker新增點選彈出氣泡的話需要mBaiduMap.setOnMarkerClickListener()點選事件
package com.sanshi.demo.tools;

import android.content.Context;
import android.widget.Button;

import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.InfoWindow;
import com.baidu.mapapi.map.Marker;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.RouteLine;
import com.baidu.mapapi.search.route.RoutePlanSearch;
import com.sanshi.demo.R;

/**
 * Created by PC_F on 2017/4/7.
 * marker點選事件處理
 */

public class BaiduMarkerClickListener implements BaiduMap.OnMarkerClickListener{

    private Context context;
    private InfoWindow mInfoWindow;
    public BaiduMap mBaiduMap;
    private Button button;
    //全域性變數
    private double myLongitude;     //經度
    private double myLatitude;  //緯度
    private RouteLine route = null;
    private OverlayManager routeOverlay = null;
    //搜尋相關
    RoutePlanSearch mSearch = null;// 搜尋模組,也可去掉地圖模組獨立使用

    private double mCurrentLantitude, mCurrentLongitude;

    public BaiduMarkerClickListener(Context context, BaiduMap mBaiduMap, double mCurrentLantitude, double mCurrentLongitude) {
        this.context = context;
        this.mBaiduMap = mBaiduMap;
        this.mCurrentLongitude = mCurrentLongitude;
        this.mCurrentLantitude = mCurrentLantitude;
    }

    @Override
    public boolean onMarkerClick(final Marker marker) {
        final LatLng latLng = marker.getPosition();
        int index = marker.getZIndex();
        button = new Button(context
                .getApplicationContext());
        button.setBackgroundResource(R.drawable.qipao);
        button.setTextColor(context.getResources().getColor(R.color.colorPrimary));
        button.setTextSize(12);
//        button.setPadding(16, 16, 16, 36);
        button.setText("火警點");
        // 定義用於顯示該InfoWindow的座標點
        // 建立InfoWindow的點選事件監聽者
//        InfoWindow.OnInfoWindowClickListener listener = new InfoWindow.OnInfoWindowClickListener() {
//            public void onInfoWindowClick() {
//                SearchButtonProcess();
//            }
//        };
        mInfoWindow = new InfoWindow(BitmapDescriptorFactory
                .fromView(button), marker.getPosition(), -70, null);
        mBaiduMap.showInfoWindow(mInfoWindow);
        return true;
    }

}

如果還要對氣泡新增點選事件的話,那麼是以下程式碼 //InfoWindow.OnInfoWindowClickListener listener = new InfoWindow.OnInfoWindowClickListener() //{ // public void onInfoWindowClick() { // SearchButtonProcess(); // } // }; 並且把 mInfoWindow = new InfoWindow(BitmapDescriptorFactory .fromView(button), marker.getPosition(), -70, null);中的null改成listener我們建立監聽方法,請特別注意我們如果需要對marker新增點選事件的話,不是button.setOnClickListener();對於氣泡,最好使用.9圖,至於點9圖的製作請自行百度。