Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 地圖篇之百度地圖各種自定義需求

地圖篇之百度地圖各種自定義需求

編輯:關於Android編程

項目中的對地圖的各種需求,實現方式。

需求1:自定義縮放按鈕,自定義當前位置按鈕
解決方式:隱藏地圖本身自帶的縮放按鈕,添加自定義的縮放按鈕,實現點擊縮放地圖功能

(一). 隱藏地圖本身自帶的縮放按鈕:

// 隱藏logo
View child = mMapView.getChildAt(1);
if (child != null&& 
(child instanceof ImageView||child instanceof ZoomControls)) {
            child.setVisibility(View.INVISIBLE);
}
mapView.showZoomControls(false); // 設置是否顯示縮放控件
mapView.showScaleControl(false);

(二).添加自定義按鈕,實現點擊縮放地圖功能。

1. 先獲取到地圖當前的縮放級別,最大,最小級別
    public float getBaiduMapZoom() {
        maxZoom = baiduMap.getMaxZoomLevel();//最大級別
        miniZoom = baiduMap.getMinZoomLevel();//最小級別
        currentZoom = baiduMap.getMapStatus().zoom;//當前級別
        return currentZoom;
    }

 2.按鈕放大地圖功能:
    // 加大地圖比例
    public void plusBaiduZoom() {
        if (getBaiduMapZoom() < maxZoom) {
             baiduMap.setMapStatus(  
             MapStatusUpdateFactory.zoomIn());
        } else {
             plus_iv.setEnabled(false);  
          //plus_iv為加大按鈕,當已經是最大級別時,設置按鈕不可點擊
        }
    }

3.按鈕縮小地圖功能:
    // 縮小地圖比例
    public void minusBaiduZoom() {
        if (getBaiduMapZoom() > miniZoom) {
           baiduMap.setMapStatus(      
           MapStatusUpdateFactory.zoomOut());
        } else {
            minus_iv.setEnabled(false);  
            //minus_iv為縮小按鈕
        }
    }
4.當手勢縮放地圖,造成地圖縮放級別改變,自定義的縮放按鈕也必須隨著改變 解決方式:OnMapStatusChangeListener中的onMapStatusChange()中監控
    public void onMapStatusChange(MapStatus status) {
        currentZoom = status.zoom;
        if (currentZoom == maxZoom) {
            plus_iv.setEnabled(false);
        } 
        else if (currentZoom == miniZoom) {
            minus_iv.setEnabled(false);
        }  
        else {
            plus_iv.setEnabled(true);
            minus_iv.setEnabled(true);
        }
      }

(三)自定義當前位置的按鈕:

// 定位中心點和縮放比例
    public void locationBaidu_locationZoom() {
        LatLng ll;
        if (latitude > 0 && longtitude > 0) {
            ll = new LatLng(latitude, longtitude);
        }else{
            return;
        }
        baiduMap.setMapStatus(  
        MapStatusUpdateFactory.newLatLngZoom(ll,13));

    }

這裡寫圖片描述

需求2:自定義覆蓋物,不單純是圖片,還需要生成有文字的marker
解決方式: BitmapDescriptorFactory.fromView(),將xml生成一個icon

(一)對應的xml: 注意點:xml最外層的應該是LinearLayout,不然會報空指針<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;">

(二)將xml生成對應的view:

 首先獲取到view:優化多次findviewbyid:
  private View view;
  //參數: 圖片資源,文字
  private View getView(int resId, StringBuffer str) {
      ViewHolder viewHolder;
      if (view == null) {
         view = View.inflate(activity,  
                R.layout.baidumarklayout, null);
         viewHolder = new ViewHolder();
         viewHolder.iv = (ImageView)  
             view.findViewById(R.id.mark_iv);
         viewHolder.tv = (TextView) 
             view.findViewById(R.id.mark_content_tv);
         view.setTag(viewHolder);
       }
       else {
            viewHolder = (ViewHolder) view.getTag();
       }
       viewHolder.iv.setImageResource(resId);
       viewHolder.tv.setText(str);
       return view;
    }

    private static class ViewHolder {
        public TextView tv;
        public ImageView iv;
    }

(三)將view生成icon:

   //將view生成icon:
   BitmapDescriptor bdOpen_iv=  
      BitmapDescriptorFactory.fromView(   
         getView(R.drawable.bdopen_iv, stringBuffer));

   //將BitmapDescriptor設置marker的icon:
   new MarkerOptions().icon(bdOpen_iv);

效果圖

需求3:覆蓋物實現縮放效果
解決方式: 在覆蓋物的點擊事件中做出處理,通過MarkerOptions.setIcon()替換圖片

public boolean onMarkerClick(Marker marker) {
        this.marker = marker;
        entity = (Gasstation) 
        marker.getExtraInfo().get(extramessage_mark);
        //替換icon
        marker.setIcon(getScalleIcon(entity)); 
        return true;
}
  //注意點:手機點back鍵,時會要恢復原本icon大小,要針對做出處理

這裡寫圖片描述

需求4:只顯示當前手機屏幕下的覆蓋物,隨著地圖改變,所顯示的覆蓋物業隨著改變
解決方式:先獲取到當前手機屏幕下的地圖上全部點,開啟工作線程進行篩選

(一)先獲取到手機屏幕下的地圖點

 private  LatLngBounds  latLngBounds;
 public LatLngBounds  getLatLngBounds(){
         if(latLngBounds==null){
           latLngBounds=baiduMap.getMapStatus().bound;
         }
         return latLngBounds;
}

(二)在工作線程中進行篩選:latLngBounds.contains(latLng)

@Override
public void run() {
    android.os.Process.setThreadPriority( 
        android.os.Process.THREAD_PRIORITY_BACKGROUND);
    task.setCurrentThread(Thread.currentThread());
    try {
        if (Thread.interrupted()) {
                return;
        }
        //先獲取到手機屏幕下的地圖點
        LatLngBounds latLngBounds= 
               gasStationFragment.getLatLngBounds();
        //清空存儲的覆蓋物的坐標
        gasStionList.clear();
      for (Gasstation gasstation : jsonBean.getReplydata()) {
        LatLng latLng = new   
              LatLng(gasstation.latitude,
                    gasstation.longitude);
           //進行篩選工作
          if (latLngBounds.contains(latLng)) {
                        gasStionList.add(gasstation);
          }
       }
       if (Thread.interrupted()) {
            return;
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        task.handleResult(0);
        task.setCurrentThread(null);
        task.setCurrentRunnable(null);
        Thread.interrupted();
    }
}

(三) 最後別忘記了將篩選後的覆蓋物添加到地圖上

注意點:縮放按鈕,當前位置按鈕,手勢縮放地圖,都會造成手機屏幕包含的點發生改變,都應該針對這些情況作出處理。

這裡寫圖片描述

需求5:駕車路線搜索,自定義沿途進過的站點,添加途經點標志
解決方式:通過起點,終點,搜索路線,然後將要進過的站點設置到規劃的路線上

(一)設置起點,終點,途經點,進行路線搜索:

 // 初始化搜索模塊,注冊事件監聽
  RoutePlanSearch mSearch = RoutePlanSearch.newInstance();
  mSearch.setOnGetRoutePlanResultListener( 
        getRoutePlanResultListener);

 //設置途徑點
  List planNode_list = new ArrayList();
  PlanNode passby = PlanNode.withLocation(latlng);//途徑點
  planNode_list.add(passby);

 // 設置起終點信息
 PlanNode stNode = PlanNode.withLocation(stLatlng);
 PlanNode enNode = PlanNode.withLocation(enLatlng);
 mSearch.drivingSearch( 
    new  DrivingRoutePlanOption()
             .from(stNode)
             .to(enNode)
             .passBy(planNode_list));

(二)搜索結果回調,將結果顯示在地圖上:

private OnGetRoutePlanResultListener    
      getRoutePlanResultListener =  
      new  OnGetRoutePlanResultListener() {
        @Override
        public void    
           onGetWalkingRouteResult(WalkingRouteResult arg0) {
        }

        @Override
        public void  
           onGetTransitRouteResult(TransitRouteResult arg0) {
        }

        @Override
        public void 
         onGetDrivingRouteResult(DrivingRouteResult result) {

            if (result == null || result.error !=  
                 SearchResult.ERRORNO.NO_ERROR) {
                 Toast.makeText( 
                    BaiduRoutePlanningActivity.this,
                    R.string.cannot_find_result,   
                    Toast.LENGTH_SHORT).show();
            }
            if (result.error ==     
             SearchResult.ERRORNO.AMBIGUOUS_ROURE_ADDR) {
         // 起終點或途經點地址有岐義,通過以下接口獲取建議查詢信息
                // result.getSuggestAddrInfo()
                return;
            }
            if (result.error ==   
                   SearchResult.ERRORNO.NO_ERROR) {
                setRoutePlanning(result);
            }

        }

        @Override
        public void    
        onGetBikingRouteResult(BikingRouteResult arg0) {
            // TODO Auto-generated method stub
        }
};

//將結果顯示在地圖上
private void setRoutePlanning(DrivingRouteResult result) {
        DrivingRouteOverlay overlay = new     
             MyCustomRouteOverlay(mBaiduMap);
        // mBaiduMap.setOnMarkerClickListener(overlay);
        overlay.setData(result.getRouteLines().get(0));
        overlay.addToMap();
        overlay.zoomToSpan();
}

private class MyCustomRouteOverlay extendsDrivingRouteOverlay {
        public MyCustomRouteOverlay(BaiduMap baiduMap) {
            super(baiduMap);
        }

        @Override
        // 自定義起點坐標
        public BitmapDescriptor getStartMarker() {
            // return bdNotOpen_iv;
            return null;
        }

        @Override
        // 自定義終點坐標
        public BitmapDescriptor getTerminalMarker() {
            // return bdNotOpen_iv;
            return null;
        }

}

(三)隱藏百度地圖上的沿途的帶有方向的覆蓋物(step node):
DrivingRouteOverlay.java中隱藏覆蓋物(/* */部分)

 public final List getOverlayOptions() {
        if (mRouteLine == null) {
            return null;
        }

       List overlayOptionses = 
              new ArrayList();
/*
           // 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 steps = mRouteLine.getAllStep();
            int stepNum = steps.size();

            List points = new ArrayList();
            ArrayList traffics = new ArrayList();
            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(11)
                    .dottedLine(isDotLine)
                    .focus(true)
                    .color(getLineColor() != 0 ? getLineColor() : Color.argb(
                            178, 0, 139, 0)).zIndex(0);//設置線條的顏色
            if (isDotLine) {
                option.customTextureList(getCustomTextureList());
            }
            overlayOptionses.add(option);
        }
        return overlayOptionses;
    }

(四)最後在地圖上添加起點,終點,途徑點的覆蓋物

這裡寫圖片描述

需求6:找到當前最近的站點
解決方式:通過工作線程,篩選最近的氣站(DistanceUtil.getDistance(locationLatLng,
latLng);)
(一):獲取到當前城市(根據城市來縮小比對數據),當前的經緯度

    public class MyLocationListenner implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation location) {
            if (location == null) {
                return;
            }
            BaseApplication.getContext().longtitude = location.getLongitude();
            BaseApplication.getContext().latitude = location.getLatitude();
            BaseApplication.getContext().address = location.getAddrStr();
            String cityMark = location.getCity();
            upDateNavigation(cityMark);
        }
    }

(二)工作線程內,篩選:

//獲取到全部站點數據,此處省略(聯網獲取,或者本地數據庫獲取)
Gasstation gasstation = null;//含有站點信息得對象
LatLng locationLatLng = new LatLng(
            BaseApplication.getContext().latitude,
            BaseApplication.getContext().longtitude);
for (int i = 0; i < navigationList.size(); ++i) {
        Gasstation gasstation2 = navigationList.get(i);//根據城市曬選出來的比對數據
        LatLng latLng = new LatLng(gasstation2.latitude,
                            gasstation2.longitude);
        double distance = DistanceUtil.getDistance(locationLatLng,
                            latLng);
        if (i == 0) {
                minDistanc = distance;
                gasstation = gasstation2;

        }  
        else {
               if (distance < minDistanc) {
                        minDistanc = distance;
                        gasstation = gasstation2;

                }
        }
}

這裡寫圖片描述

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved