集成高德地图记录

高德地图集成开发

前言

集成地图前,进行了一个小的调研。感觉百度在地图开发上应该是和google这种级别的,所以首先选择了百度sdk进行集成。花了一天的功夫,大概实现了需求。快下班的时候还有些时间,就顺便看了下高德,从新建project到demo实现出来,只用了半小时左右。真是没有对比就没有伤害。可能是功能上大同小异,但是我想说的是:无论是开发文档,还是测试Demo。都不是一个级别的产品。尤其让我意外的是高德的Demo连warn都很少,可以说基本没有。真是教科书般的文档与Demo。想到了集成其他SDK时候的痛苦,都没有集成高德SDK这样的顺畅。顺便看了下腾讯地图,从文档上来说:高德,腾讯,百度。技术上不做过多评价大同小异,都能实现。

集成

第一次集成建议:直接看文档
http://lbs.amap.com/api/android-sdk/guide/create-project/android-studio-create-project#gradle_sdk

注意事项

  • sha1的值一定要取对,我的测试Demo用的本机的debug.keystore,开发Demo用的另一个debug.keystore。这个导致我浪费不少时间。
  • 平台支持,建议选前面两个。
  • 自定义marker, markerOption.icon(BitmapDescriptorFactory.fromView(mView));可以选任何资源

简单获取sha1

文档上获取sha1的方式有点麻烦,可以在Android studio 中更简单的获取

集成高德地图记录_第1张图片

一定注意自己配置的debug.keystore,文件是不是正确的。

集成流程

  1. gardle添加

    //这里说明一下根据需求添加,高德分为4个部分,定位,地图,搜索,导航。这四个部分都有相应的so和jar。地图还分为(3D、2D)。我们项目需要下面的两个,所以就写了这俩。
    //3D地图so及jar
    compile 'com.amap.api:3dmap:latest.integration'
    //搜索功能
    compile 'com.amap.api:search:latest.integration'
    
  2. 清单文件配置

    请求权限配置
    
        略(自己根据官网和项目进行增删)
    
    
    高德key
     
    
  3. 布局文件引用

    这里有两种主要的实现方式
    这六个组件实现的功能都是一样的
    区别主要是:TextureView解决了,黑边问题,如果你的容器是fragment,建议你用TextureView如果是Activity则无所谓。
    每个里面包含的三个组件的区别是:第一个生命周期需要自己管理,后面两种都是fragment生命周期帮你管理了。Support区别是支持更早的版本。
    GLSurfaceView:
        MapView、MapFragment、SupportMapFragment
    
    TextureView:
        TextureMapView、TextureMapFragment、TextureSupportMapFragment 
    
  4. 代码实现

    下面是部分常用方法,具体需求具体实现
    
    /**
     * 获取 AMap 对象
     */
    private void setUpMapIfNeeded() {
        if (aMap == null) {
            aMap = ((TextureSupportMapFragment) getActivity().getSupportFragmentManager()
                    .findFragmentById(R.id.map)).getMap();
        }
    }
    private void initMyLocation() {
        MyLocationStyle myLocationStyle;
        myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) ;//定位一次,且将视角移动到地图中心点。
        myLocationStyle.showMyLocation(true);//设置是否显示定位小蓝点,用于满足只想使用定位,不想使用定位小蓝点的场景,设置false以后图面上不再有定位蓝点的概念,但是会持续回调位置信息。
        //myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。
        aMap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
        aMap.getUiSettings().setMyLocationButtonEnabled(true);//设置默认定位按钮是否显示,非必需设置。
        aMap.getUiSettings().setZoomControlsEnabled(false);
        aMap.getUiSettings().setRotateGesturesEnabled(false);
        aMap.getUiSettings().setTiltGesturesEnabled(false);
        aMap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。
        aMap.moveCamera(CameraUpdateFactory.zoomTo(12));//地图显示级别
    
    }
    
  5. 注意添加混淆

    3D 地图 V5.0.0之前:
    -keep   class com.amap.api.maps.**{*;} 
    -keep   class com.autonavi.amap.mapcore.*{*;} 
    -keep   class com.amap.api.trace.**{*;}
    
    3D 地图 V5.0.0之后:
    -keep   class com.amap.api.maps.**{*;} 
    -keep   class com.autonavi.**{*;} 
    -keep   class com.amap.api.trace.**{*;}
    
    定位
    -keep class com.amap.api.location.**{*;}
    -keep class com.amap.api.fence.**{*;}
    -keep class com.autonavi.aps.amapapi.model.**{*;}
    
    搜索
    -keep   class com.amap.api.services.**{*;}
    
    2D地图
    -keep class com.amap.api.maps2d.**{*;}
    -keep class com.amap.api.mapcore2d.**{*;}
    
    导航
    -keep class com.amap.api.navi.**{*;}
    -keep class com.autonavi.**{*;}
    

项目需求实现

需求

要求显示用户所在位置,位置上的marker是从网络加载的图像。

用户发布活动显示的marker,也是要求显示发布者头像。

调研发现难点

  • 从网络加载图像显示
  • 显示头像样式要求,需要自定义ImageView(用布局也可以实现)

代码实现

从网络加载图片显示到marker上

建议用Glide获取到bitmap的时候在aMap.addMarker()

     Glide.with(TopMapFragment.this)
                .load(mMyList.get(i).getHead_image())
                .asBitmap().into(new SimpleTarget() {
            @Override
            public void onResourceReady(Bitmap resource, GlideAnimation glideAnimation) {
                imageView.setImageBitmap(resource);
                markerOption.icon(BitmapDescriptorFactory.fromView(imageView));
                Marker marker = aMap.addMarker(markerOption);
            }
        });

头像显示样式

方式一:直接解析布局(代码:略)用BitmapDescriptorFactory.fromView()显示

方式二:自定义View(代码:待完善)效果如下
集成高德地图记录_第2张图片

查找路线开发总结

需求是实现一套自己的路线规划,不知道为啥不用地图自带的。

参照美团app路线规划功能实现

难点倒是没有,东西比较多,好多东西又是高德写好的,只需要参照Demo就行了。需要理解那些东西,才能更好的重新组装。

查询代码实现

支持四种类型的查询bus、walk、drive、ride
下面的没有ride

集成高德地图记录_第3张图片
第一步:实现查询结果监听

mRouteSearch = new RouteSearch(this);
mRouteSearch.setRouteSearchListener(this);

第二步:实现查询

RouteSearch.BusRouteQuery query = new RouteSearch.BusRouteQuery(fromAndTo, RouteSearch.BUS_DEFAULT,
            mCurrentCityName, 0);

RouteSearch.DriveRouteQuery query1 = new RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DrivingDefault, null,
            null, "");
RouteSearch.WalkRouteQuery query2 = new RouteSearch.WalkRouteQuery(fromAndTo, RouteSearch.WALK_DEFAULT);

mRouteSearch.calculateBusRouteAsyn(query);
mRouteSearch.calculateDriveRouteAsyn(query1);
mRouteSearch.calculateWalkRouteAsyn(query2);

第三步:处理查询结果

@Override
public void onBusRouteSearched(BusRouteResult result, int errorCode) {
    if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
        if (result != null && result.getPaths() != null) {
            if (result.getPaths().size() > 0) {
                mBusRouteResult = result;
                mRouteBusFragment.setUpdateData(mBusRouteResult);
            } else if (result != null && result.getPaths() == null) {
                Log.e(TAG, "onBusRouteSearched: 出错");
            }
        } else {
        }
    } else {
    }
}

@Override
public void onDriveRouteSearched(DriveRouteResult result, int errorCode) {
    if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
        if (result != null && result.getPaths() != null) {
            if (result.getPaths().size() > 0) {
                mDriveRouteResult = result;
                mRouteCarFragment.setRouteData(mDriveRouteResult);
            } else if (result != null && result.getPaths() == null) {
            }

        } else {
        }
    } else {
    }
}

@Override
public void onWalkRouteSearched(WalkRouteResult result, int errorCode) {
    if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
        if (result != null && result.getPaths() != null) {
            if (result.getPaths().size() > 0) {
                mWalkRouteResult = result;
                mRouteWalkFragment.setRouteData(mWalkRouteResult);

            } else if (result != null && result.getPaths() == null) {
            }
        } else {
        }
    } else {
    }
}

@Override
public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {
    Log.e(TAG, "onRideRouteSearched: " + rideRouteResult);
}

显示代码实现

这里公交地铁的实现官方给的demo代码有点问题,一些参数需要自己判断,比如stepList.get(i).getBusLines()。这个参数永远不会是null,
官方却判断它是否为空,它没有数据的时候也返回一个集合,只不过size为0。stepList.get(i).getRailway()确总是为null。无论有没有地铁。
不知道他们是把它当成火车还是地铁。

集成高德地图记录_第4张图片

公交(地铁)路线

private void setBusMap() {
    BusRouteOverlay busRouteOverlay = new BusRouteOverlay(
            this, aMap, mBusPath,
            mRouteResult.getStartPos(),
            mRouteResult.getTargetPos());
    busRouteOverlay.removeFromMap();
    busRouteOverlay.addToMap();
    busRouteOverlay.zoomToSpan();
    aMap.moveCamera(CameraUpdateFactory.zoomTo(12));
    List stepList = mBusPath.getSteps();
    Boolean isFirst=true;
    for (int i = 0; i < stepList.size(); i++) {
        if (stepList.get(i).getWalk()!=null && stepList.get(i).getWalk().getDistance() > 0
            &&stepList.get(i).getBusLines().size()>0
                ) {
            if (isFirst){
                isFirst=false;
                mList.add("步行"+ stepList.get(i).getWalk().getDistance()+"米,到达起点。乘坐"
                        +stepList.get(i).getBusLines().get(0).getBusLineName()+"共"+
                        stepList.get(i).getBusLines().get(0).getPassStationNum()+"站" );
            }else {
                mList.add("步行"+ stepList.get(i).getWalk().getDistance()+"米。换乘"
                        +stepList.get(i).getBusLines().get(0).getBusLineName()+"共"+
                        stepList.get(i).getBusLines().get(0).getPassStationNum()+"站" );
            }


        }

        if (stepList.get(i).getWalk()!=null&&stepList.get(i).getWalk().getDistance()>0
                &&stepList.get(i).getBusLines().size()==0 &&stepList.get(i).getRailway()==null
                ){
            mList.add(
                    "步行"+ stepList.get(i).getWalk().getDistance()+"米,到达目的地。");
        }
    }
    mStepAdapter.notifyDataSetChanged();
}

步行结果

private void setWalkMap() {
    WalkPath walkPath = (( WalkRouteResult)mRouteResult).getPaths()
            .get(0);
    WalkRouteOverlay walkRouteOverlay = new WalkRouteOverlay(
            this, aMap, walkPath,
            mRouteResult.getStartPos(),
            mRouteResult.getTargetPos());
    walkRouteOverlay.removeFromMap();
    walkRouteOverlay.addToMap();
    walkRouteOverlay.zoomToSpan();
    aMap.moveCamera(CameraUpdateFactory.zoomTo(12));
    for (int i = 0; i <  walkPath.getSteps().size(); i++) {
        mList.add( walkPath.getSteps().get(i).getInstruction());
    }
    mStepAdapter.notifyDataSetChanged();
}

开车结果

private void setCarMap() {
    DrivePath drivePath = ((DriveRouteResult)mRouteResult).getPaths()
            .get(0);
    DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(
            this, aMap, drivePath,
            mRouteResult.getStartPos(),
            mRouteResult.getTargetPos(), null);
    drivingRouteOverlay.setNodeIconVisibility(true);//设置节点marker是否显示
    drivingRouteOverlay.setIsColorfulline(true);//是否用颜色展示交通拥堵情况,默认true
    drivingRouteOverlay.removeFromMap();
    drivingRouteOverlay.addToMap();
    drivingRouteOverlay.zoomToSpan();
    aMap.moveCamera(CameraUpdateFactory.zoomTo(12));
    for (int i = 0; i <  drivePath.getSteps().size(); i++) {
        mList.add( drivePath.getSteps().get(i).getInstruction());
    }
    mStepAdapter.notifyDataSetChanged();
}

你可能感兴趣的:(android开发)