集成高德地图记录

来源:互联网 发布:股票利润怎么算法 编辑:程序博客网 时间:2024/06/05 09:02

高德地图集成开发

前言

集成地图前,进行了一个小的调研。感觉百度在地图开发上应该是和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 中更简单的获取

这里写图片描述

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

集成流程

  1. gardle添加

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

    请求权限配置    略(自己根据官网和项目进行增删)高德key <meta-data    android:name="com.amap.api.v2.apikey"    android:value="key"/>
  3. 布局文件引用

    这里有两种主要的实现方式这六个组件实现的功能都是一样的区别主要是:TextureView解决了,黑边问题,如果你的容器是fragment,建议你用TextureView如果是Activity则无所谓。每个里面包含的三个组件的区别是:第一个生命周期需要自己管理,后面两种都是fragment生命周期帮你管理了。Support区别是支持更早的版本。GLSurfaceView:    MapView、MapFragment、SupportMapFragmentTextureView:    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<Bitmap>() {            @Override            public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {                imageView.setImageBitmap(resource);                markerOption.icon(BitmapDescriptorFactory.fromView(imageView));                Marker marker = aMap.addMarker(markerOption);            }        });

头像显示样式

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

方式二:自定义View(代码:待完善)效果如下
这里写图片描述

查找路线开发总结

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

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

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

查询代码实现

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

这里写图片描述
第一步:实现查询结果监听

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);

第三步:处理查询结果

@Overridepublic 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 {    }}@Overridepublic 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 {    }}@Overridepublic 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 {    }}@Overridepublic void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {    Log.e(TAG, "onRideRouteSearched: " + rideRouteResult);}

显示代码实现

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

这里写图片描述

公交(地铁)路线

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<BusStep> 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();}
原创粉丝点击