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

来源:互联网 发布:杭州橙速网络怎么样 编辑:程序博客网 时间:2024/06/06 05:36

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

需求1:自定义缩放按钮,自定义当前位置按钮
解决方式:隐藏地图本身自带的缩放按钮,添加自定义的缩放按钮,实现点击缩放地图功能

(一). 隐藏地图本身自带的缩放按钮:

// 隐藏logoView 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);

效果图

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

@Overridepublic 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> 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;    }

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

这里写图片描述

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

这里写图片描述

  • 有啥不懂的私聊,联系方式:675134792(QQ)
1 0