高德地图定位及导航开发流程

时间:2024-03-21 09:10:58
关于高德地图导航定位及导航

最进简单研究了一下关于高德地图的使用,,简单实现了定位搜素,以及驾车的路径规划,一下将介绍我的实现过程:


先展示一下实现的简单效果:

高德地图定位及导航开发流程

首先需要进行配置,配置详情如下:

1、打开高德开放平台

2、创建应用

3、添加新key:dd9dde5da25a5811031cb1beb5a******

sha1值获取:找到系统默认的debug.keystore(C:\Users\Administrator\.android\debug.keystore)

cmd窗口或android studio 中的Terminal中执行命令:keytool -v -list -keystore keystore地址

4、添加jar和so库(不要添加v4包)

so库添加方式:

第一种:使用默认配置,不需要修改build.gradle。在 main 目录下创建文件夹 jniLibs (如果有就不需要创建了),将下载文件的 armeabi 文件夹复制到这个目录下,如果已经有这个目录,将下载的 so 库复制到这个目录即可。

第二种:使用自定义配置,将下载文件的 armeabi 文件夹复制到 libs 目录,如果有这个目录,请将下载的 so 库复制到这个目录,然后打开build.gradle,找到 sourceSets 标签:

sourceSets{

main{

jniLibs.srcDirs = ['libs']

}

}

5、配置

1、配置AndroidManifest.xml

1、声明Service组件

<service android:name="com.amap.api.location.APSService"></service>

2、声明权限

<!--用于进行网络定位-->

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>

<!--用于访问GPS定位-->

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>

<!--用于获取运营商信息,用于支持提供运营商信息相关的接口-->

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>

<!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>

<!--用于获取wifi的获取权限,wifi信息会用来进行网络定位-->

<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>

<!--用于访问网络,网络定位需要上网-->

<uses-permission android:name="android.permission.INTERNET"></uses-permission>

<!--用于读取手机当前的状态-->

<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>

<!--用于写入缓存数据到扩展存储卡-->

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>

<!--用于申请调用A-GPS模块-->

<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"></uses-permission>

<!--用于申请获取蓝牙信息进行室内定位-->

<uses-permission android:name="android.permission.BLUETOOTH"></uses-permission>

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"></uses-permission>

3、设置高德Key

<meta-data android:name="com.amap.api.v2.apikey" android:value="key">//开发者申请的key       

            

</meta-data>

下面实现定位和蓝点显示:

1、声明成员变量

//声明AMapLocationClient类对象

public AMapLocationClient mLocationClient = null;

2、初始化定位

//初始化定位

mLocationClient = new AMapLocationClient(getApplicationContext());

3、设置定位回调监听

mLocationClient.setLocationListener(new AMapLocationListener(){

 @Override

             public void onLocationChanged(AMapLocation aMapLocation) {

//获取定位结果

}

});

4、定位结果处理

if (aMapLocation != null) {

            if (aMapLocation.getErrorCode() == 0) {

                //可在其中解析amapLocation获取相应内容。

                int locationType = aMapLocation.getLocationType();//获取当前定位结果来源,如网络定位结果,详见定位类型表

                double latitude = aMapLocation.getLatitude();//获取纬度

                double longitude = aMapLocation.getLongitude();//获取经度

                float accuracy = aMapLocation.getAccuracy();//获取精度信息

                String address = aMapLocation.getAddress();//地址,如果option中设置isNeedAddress为false,则没有此结果,网络定位结果中会有地址信息,GPS定位不返回地址。

                aMapLocation.getCountry();//国家信息

                aMapLocation.getProvince();//省信息

                aMapLocation.getCity();//城市信息

                aMapLocation.getDistrict();//城区信息

                aMapLocation.getStreet();//街道信息

                aMapLocation.getStreetNum();//街道门牌号信息

                aMapLocation.getCityCode();//城市编码

                aMapLocation.getAdCode();//地区编码

                aMapLocation.getAoiName();//获取当前定位点的AOI信息

                aMapLocation.getBuildingId();//获取当前室内定位的建筑物Id

                aMapLocation.getFloor();//获取当前室内定位的楼层

                //获取定位时间

                SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                Date date = new Date(aMapLocation.getTime());

                df.format(date);

                Log.e("TAG", "纬度:" + latitude + "   经度:" + longitude + "  地址:" + address);

            } else {

                //定位失败时,可通过ErrCode(错误码)信息来确定失败的原因,errInfo是错误信息,详见错误码表。

                Log.e("AmapError", "location Error, ErrCode:"

                    + aMapLocation.getErrorCode() + ", errInfo:"

                    + aMapLocation.getErrorInfo());

            }

}

7、地图

1、在xml中声明MapView控件

2、在activity中初始化MapView

3、在声明周期中调用MapView的声明周期:onCreate\onResume\onPause\onDestroy\onSaveInstanceState

8、蓝点

1、创建MyLocationStyle对象: style = new MyLocationStyle();

2、设置定位间隔时间:style.interval(2000);

3、设置圆形区域:

1、圆形区域填充色:style.radiusFillColor(Color.rgb(0, 255, 255));

2、圆形区域(以定位位置为圆心,定位半径的圆形区域)的边框颜色:style.strokeColor(Color.rgb(0, 100, 255));

3、圆形区域(以定位位置为圆心,定位半径的圆形区域)的边框宽度:style.strokeWidth(2F);

4、设置定位模式和蓝点模式:(选择其一)

myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_SHOW);//只定位一次。

myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) ;//定位一次,且将视角移动到地图中心点。

myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW) ;//连续定位、且将视角移动到地图中心点,定位蓝点跟随设备移动。(1秒1次定位)

myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE);//连续定位、且将视角移动到地图中心点,地图依照设备方向旋转,定位点会跟随设备移动。(1秒1次定位)

myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)默认执行此种模式。

//以下四种模式从5.1.0版本开始提供

myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)默认执行此种模式。

myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动。

myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,并且蓝点会跟随设备移动。

myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_MAP_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,地图依照设备方向旋转,并且蓝点会跟随设备移动。

POI检索,查找位置:

1、创建PoiSearch.Query对象

query = new PoiSearch.Query(keyWord, "", cityCode);

//keyWord表示搜索字符串,

//第二个参数表示POI搜索类型,二者选填其一,选用POI搜索类型时建议填写类型代码,码表可以参考下方(而非文字)

//cityCode表示POI搜索区域,可以是城市编码也可以是城市名称,也可以传空字符串,空字符串代表全国在全国范围内进行搜索

query.setPageSize(10);// 设置每页最多返回多少条poiitem

query.setPageNum(currentPage);//设置查询页码

2、构造 PoiSearch 对象,并设置监听。

poiSearch = new PoiSearch(this, query);

poiSearch.setOnPoiSearchListener(this);

3、调用 PoiSearch 的 searchPOIAsyn() 方法发送请求。

poiSearch.searchPOIAsyn();

4、通过回调接口 onPoiSearched 解析返回的结果,将查询到的 POI 以绘制点的方式显示在地图上。

覆盖物(绘制点)

1、创建绘制点:

LatLng latLng = new LatLng(39.906901,116.397972);

final Marker marker = aMap.addMarker(new MarkerOptions().position(latLng).title("北京").snippet("DefaultMarker"));

2、设置Marker点击事件

// 定义 Marker 点击事件监听

AMap.OnMarkerClickListener markerClickListener = new AMap.OnMarkerClickListener() {

// marker 对象被点击时回调的接口

// 返回 true 则表示接口已响应事件,否则返回false

@Override

public boolean onMarkerClick(Marker marker) {

return false;

}

};

// 绑定 Marker 被点击事件

mAMap.setOnMarkerClickListener(markerClickListener);


路径规划,其中实现了驾车,骑车,以及不行等方式


1、路径规划实现

1、公共交通

aMap.clear();// 清理地图上的所有覆盖物

if (errorCode == AMapException.CODE_AMAP_SUCCESS) {

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

if (result.getPaths().size() > 0) {

BusResultListAdapter mBusResultListAdapter = new BusResultListAdapter(mContext, result);

mBusResultList.setAdapter(mBusResultListAdapter);

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

ToastUtil.show(mContext, R.string.no_result);

}

} else {

ToastUtil.show(mContext, R.string.no_result);

}

} else {

ToastUtil.showerror(this.getApplicationContext(), errorCode);

}

2、自驾

aMap.clear();// 清理地图上的所有覆盖物

if (errorCode == AMapException.CODE_AMAP_SUCCESS) {

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

if (result.getPaths().size() > 0) {

mDriveRouteResult = result;

final DrivePath drivePath = mDriveRouteResult.getPaths()

.get(0);

DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(

mContext, aMap, drivePath,

mDriveRouteResult.getStartPos(),

mDriveRouteResult.getTargetPos(), null);

drivingRouteOverlay.setNodeIconVisibility(false);//设置节点marker是否显示

drivingRouteOverlay.setIsColorfulline(true);//是否用颜色展示交通拥堵情况,默认true

drivingRouteOverlay.removeFromMap();

drivingRouteOverlay.addToMap();

drivingRouteOverlay.zoomToSpan();

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

ToastUtil.show(mContext, R.string.no_result);

}

 

} else {

ToastUtil.show(mContext, R.string.no_result);

}

} else {

ToastUtil.showerror(this.getApplicationContext(), errorCode);

}

3、走路

aMap.clear();// 清理地图上的所有覆盖物

if (errorCode == AMapException.CODE_AMAP_SUCCESS) {

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

if (result.getPaths().size() > 0) {

mWalkRouteResult = result;

final WalkPath walkPath = mWalkRouteResult.getPaths()

.get(0);

WalkRouteOverlay walkRouteOverlay = new WalkRouteOverlay(

this, aMap, walkPath,

mWalkRouteResult.getStartPos(),

mWalkRouteResult.getTargetPos());

walkRouteOverlay.removeFromMap();

walkRouteOverlay.addToMap();

walkRouteOverlay.zoomToSpan();

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

ToastUtil.show(mContext, R.string.no_result);

}

} else {

ToastUtil.show(mContext, R.string.no_result);

}

} else {

ToastUtil.showerror(this.getApplicationContext(), errorCode);

}

4、骑车

aMap.clear();// 清理地图上的所有覆盖物

if (errorCode == AMapException.CODE_AMAP_SUCCESS) {

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

if (result.getPaths().size() > 0) {

mRideRouteResult = result;

final RidePath ridePath = mRideRouteResult.getPaths()

.get(0);

RideRouteOverlay rideRouteOverlay = new RideRouteOverlay(

this, aMap, ridePath,

mRideRouteResult.getStartPos(),

mRideRouteResult.getTargetPos());

rideRouteOverlay.removeFromMap();

rideRouteOverlay.addToMap();

rideRouteOverlay.zoomToSpan();

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

ToastUtil.show(mContext, R.string.no_result);

}

} else {

ToastUtil.show(mContext, R.string.no_result);

}

} else {

ToastUtil.showerror(this.getApplicationContext(), errorCode);

}

2、路径规划之监听中接受数据

需要复制的文件:(需修改包引用)

1、overlay包下所有类

2、com\amap\map3d\demo\util包下:

AMapUtil.java

ChString.java

ToastUtil.java

3、res\drawable-hdpi下:

amap_bus.png

amap_car.png

amap_end.png

amap_man.png

amap_ride.png

amap_start.png

amap_through.png

dir1.png-dir16.png

4、res\values下strings.xml中:<string name="no_result">对不起,没有搜索到相关数据!</string>

至此,简单的定位以及简单的路径规划介绍完毕,下面附上完整代码:


Xml布局代码:

<LinearLayout
    android:id="@+id/li"
    android:weightSum="10"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <EditText
        android:id="@+id/city"
        android:hint="城市"
        android:layout_weight="2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <EditText
        android:id="@+id/content"
        android:hint="具体位置"
        android:layout_weight="6"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/search"
        android:text="搜索"
        android:layout_weight="2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>
<com.amap.api.maps.MapView
    android:id="@+id/map"
    android:layout_below="@+id/li"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>


	JAVA代码:
	
package feng.jiyun.com.gaodeactivity;

import android.location.Location;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.amap.api.maps.AMap;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.DrivePath;
import com.amap.api.services.route.DriveRouteResult;
import com.amap.api.services.route.RideRouteResult;
import com.amap.api.services.route.RouteSearch;
import com.amap.api.services.route.WalkRouteResult;

import java.util.ArrayList;

import feng.jiyun.com.gaodeactivity.overlay.DrivingRouteOverlay;
import feng.jiyun.com.gaodeactivity.overlay.ToastUtil;

public class MainActivity extends AppCompatActivity implements View.OnClickListener, PoiSearch.OnPoiSearchListener, RouteSearch.OnRouteSearchListener {

    private MapView map;
    private AMap amap;
    MyLocationStyle myLocationStyle;
    private EditText city;
    private EditText content;
    private Button search;
    private PoiSearch.Query query;
    private PoiSearch searchs;
    private RouteSearch routeSearch;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView(savedInstanceState);
    }

    private void initView(Bundle savedInstanceState) {
        map = (MapView) findViewById(R.id.map);
        map.onCreate(savedInstanceState);
        amap = map.getMap();
        myLocationStyle = new MyLocationStyle();//初始化定位蓝点样式类myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);//连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)如果不设置myLocationType,默认也会执行此种模式。
        myLocationStyle.interval(2000); //设置连续定位模式下的定位间隔,只在连续定位模式下生效,单次定位模式下不会生效。单位为毫秒。
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动。
        amap.setMyLocationStyle(myLocationStyle);//设置定位蓝点的Style
        amap.getUiSettings().setMyLocationButtonEnabled(true);
        amap.setMyLocationEnabled(true);// 设置为true表示启动显示定位蓝点,false表示隐藏定位蓝点并不进行定位,默认是false。
        city = (EditText) findViewById(R.id.city);
        city.setOnClickListener(this);
        content = (EditText) findViewById(R.id.content);
        content.setOnClickListener(this);
        search = (Button) findViewById(R.id.search);
        search.setOnClickListener(this);
        //路径规划
        amap.setOnMarkerClickListener(new AMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                Location myLocation = amap.getMyLocation();
                String s = myLocation.toString();

                //2、获取终点经纬度
                LatLng position = marker.getPosition();
                LatLonPoint from = new LatLonPoint(myLocation.getLatitude(),myLocation.getLongitude());
                Log.e("TAG",myLocation.getLatitude()+"    "+myLocation.getLongitude());
                LatLonPoint to = new LatLonPoint(position.latitude,position.longitude);
                RouteSearch.FromAndTo fat = new RouteSearch.FromAndTo(from,to);
                RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(fat,RouteSearch.DRIVING_MULTI_STRATEGY_FASTEST_SHORTEST_AVOID_CONGESTION,null,null,"");
                routeSearch = new RouteSearch(MainActivity.this);
                routeSearch.setRouteSearchListener(MainActivity.this);
                routeSearch.calculateDriveRouteAsyn(query);
                return false;
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity执行onDestroy时执行mMapView.onDestroy(),销毁地图
        map.onDestroy();
    }

    @Override
    protected void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView.onResume (),重新绘制加载地图
        map.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView.onPause (),暂停地图的绘制
        map.onPause();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState),保存地图当前的状态
        map.onSaveInstanceState(outState);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.search:
                    submit();
                break;
        }
    }

    private void submit() {
        // validate
        String cityString = city.getText().toString().trim();
        if (TextUtils.isEmpty(cityString)) {
            Toast.makeText(this, "请输入城市", Toast.LENGTH_SHORT).show();
            return;
        }

        String contentString = content.getText().toString().trim();
        if (TextUtils.isEmpty(contentString)) {
            Toast.makeText(this, "请输入具体位置", Toast.LENGTH_SHORT).show();
            return;
        }
        // TODO validate success, do something
        query = new PoiSearch.Query(contentString,"",cityString);
        query.setPageSize(10);// 设置每页最多返回多少条poiitem
        query.setPageNum(1);//设置查询页码
        searchs = new PoiSearch(this, query);
        searchs.setOnPoiSearchListener(this);
        searchs.searchPOIAsyn();
    }

    @Override
    public void onPoiSearched(PoiResult poiResult, int i) {
        ArrayList<PoiItem> pois = poiResult.getPois();
        amap.clear();
        for(PoiItem item:pois){
            LatLonPoint latLonPoint = item.getLatLonPoint();
            LatLng lat = new LatLng(latLonPoint.getLatitude(),latLonPoint.getLongitude());
            MarkerOptions options = new MarkerOptions().position(lat).title(item.toString()).snippet("hello");
            amap.addMarker(options);
        }
    }

    @Override
    public void onPoiItemSearched(PoiItem poiItem, int i) {

    }

    @Override
    public void onBusRouteSearched(BusRouteResult busRouteResult, int i) {
        Log.e("TAG","onBusRouteSearched");
    }

    @Override
    public void onDriveRouteSearched(DriveRouteResult result, int errorCode) {
        amap.clear();// 清理地图上的所有覆盖物
        if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getPaths() != null) {
                if (result.getPaths().size() > 0) {
                    DrivePath drivePath = result.getPaths().get(0);
                    DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(MainActivity.this, amap, drivePath, result.getStartPos(), result.getTargetPos(), null);
                    drivingRouteOverlay.setNodeIconVisibility(false);//设置节点marker是否显示
                    drivingRouteOverlay.setIsColorfulline(true);//是否用颜色展示交通拥堵情况,默认true
                    drivingRouteOverlay.removeFromMap();
                    drivingRouteOverlay.addToMap();
                    drivingRouteOverlay.zoomToSpan();
                } else if (result != null && result.getPaths() == null) {
                    ToastUtil.show(MainActivity.this, R.string.no_result);
                }

            } else {
                ToastUtil.show(MainActivity.this, R.string.no_result);
            }
        } else {
            ToastUtil.showerror(this.getApplicationContext(), errorCode);
        }
    }

    @Override
    public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) {
        Log.e("TAG","onWalkRouteSearched");
    }

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

写的不好,请见谅,如发现问题请及时更正笔者高德地图定位及导航开发流程