地图篇之百度地图各种自定义需求

项目中的对地图的各种需求,实现方式。

需求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,不然会报空指针

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" >

    <RelativeLayout  android:layout_width="wrap_content" android:layout_height="wrap_content" >

        <ImageView  android:id="@+id/mark_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" />

        <TextView  android:id="@+id/mark_content_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:textSize="10sp" android:textColor="@color/orange1" android:layout_marginTop="8dp" />
    </RelativeLayout>

(二)将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);

地图篇之百度地图各种自定义需求_第1张图片

需求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();
    }
}

(三) 最后别忘记了将筛选后的覆盖物添加到地图上

注意点:缩放按钮,当前位置按钮,手势缩放地图,都会造成手机屏幕包含的点发生改变,都应该针对这些情况作出处理。

地图篇之百度地图各种自定义需求_第2张图片

需求5:驾车路线搜索,自定义沿途进过的站点,添加途经点标志
解决方式:通过起点,终点,搜索路线,然后将要进过的站点设置到规划的路线上

(一)设置起点,终点,途经点,进行路线搜索:

 // 初始化搜索模块,注册事件监听
  RoutePlanSearch mSearch = RoutePlanSearch.newInstance();
  mSearch.setOnGetRoutePlanResultListener( 
        getRoutePlanResultListener);

 //设置途径点
  List<PlanNode> planNode_list = new ArrayList<PlanNode>();
  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<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(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;
    }

(四)最后在地图上添加起点,终点,途径点的覆盖物

地图篇之百度地图各种自定义需求_第3张图片

需求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;

                }
        }
}

地图篇之百度地图各种自定义需求_第4张图片

你可能感兴趣的:(地图篇之百度地图各种自定义需求)