高德地图SDK Android版开发 3 显示定位
前言
本文主要介绍高德地图显示定位相关的功能和接口,以及使用方法。
高德地图有两种方式在地图中显示定位。
方式一:自Android 3D地图 SDK 5.0.0版本之后,SDK集成了显示定位,可以简单的实现位置的显示。
方式二:获取定位数据,将定位数据在地图中显示。
本文先简单定位数据包括哪些数据,再依次介绍如何通过两种方式实现显示定位。
定位数据
两种显示定位方式中,定位数据从接口层面有稍许差别,
定位信息类 | 说明 | |
---|---|---|
方式一 | android.location.Location | 地理位置的数据类。 包含纬度,经度,时间戳和其他信息,如方位,高度和速度。 |
方式二 | com.amap.api.location.AMapLocation | 定位信息类。定位完成后的位置信息。 |
下图为AMapLocation
的部分接口:
显示定位的第一种方式
定位模式
高德地图有多种定位模式,可实现定位或连续定位、是否将视角移动到地图中心点,是否依照设备方向旋转,多种组合方式。
定位模式 | 说明 | |
---|---|---|
1 | LOCATION_TYPE_SHOW | 只定位一次。 |
2 | LOCATION_TYPE_LOCATE | 定位一次,且将视角移动到地图中心点。 |
3 | LOCATION_TYPE_FOLLOW | 连续定位,且将视角移动到地图中心点,定位蓝点跟随设备移动。(1秒1次定位) |
4 | LOCATION_TYPE_MAP_ROTATE | 连续定位、且将视角移动到地图中心点,地图依照设备方向旋转,定位点会跟随设备移动。(1秒1次定位) |
5 | LOCATION_TYPE_LOCATION_ROTATE | 连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)默认执行此种模式。 |
6 | LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER | 从5.1.0版本开始提供 连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动。 |
7 | LOCATION_TYPE_FOLLOW_NO_CENTER | 从5.1.0版本开始提供 连续定位、蓝点不会移动到地图中心点,并且蓝点会跟随设备移动。 |
8 | LOCATION_TYPE_MAP_ROTATE_NO_CENTER | 从5.1.0版本开始提供 连续定位、蓝点不会移动到地图中心点,地图依照设备方向旋转,并且蓝点会跟随设备移动。 |
定位样式类
MyLocationStyle
定位样式类,可设置定位模式,是否显示定位,设置定位请求的时间间隔,以及个性化显示样式。
类型 | 方法 | 说明 |
---|---|---|
MyLocationStyle | myLocationType(int type) | 设置我的位置展示模式。 |
MyLocationStyle | interval(long interval) | 设置发起定位请求的时间间隔, 单位:毫秒,默认值:1000毫秒, 如果传小于1000的任何值将执行单次定位。 |
MyLocationStyle | showMyLocation(boolean myLocationVisible) | 设置是否显示定位小蓝点,true 显示,false不显示。 |
MyLocationStyle | myLocationIcon(BitmapDescriptor myLocationIcon) | 设置定位(当前位置)的icon图标。 |
MyLocationStyle | anchor(float u, float v) | 设置定位图标的锚点。 |
MyLocationStyle | radiusFillColor(int color) | 设置圆形区域(以定位位置为圆心,定位半径的圆形区域)的填充颜色。 |
MyLocationStyle | strokeColor(int color) | 设置圆形区域(以定位位置为圆心,定位半径的圆形区域)的边框颜色。 |
MyLocationStyle | strokeWidth(float width) | 设置圆形区域(以定位位置为圆心,定位半径的圆形区域)的边框宽度。 |
地图类
地图类中与定位相关的接口包括:定位图层的样式,是否打开定位图层,用户定位信息监听接口。
类型 | 方法 | 说明 |
---|---|---|
void | setMyLocationStyle(MyLocationStyle style) | 设置定位图层的样式。 |
void | void setMyLocationEnabled(boolean enabled) | 设置是否打开定位图层。 |
void | void setOnMyLocationChangeListener(AMap.OnMyLocationChangeListener listener) | 设置用户定位信息监听接口。 |
MapLocation类
创建一个地图定位类MapLocation
,主要包括以下功能:
- 地图加载完成时,设置定位模式,打开定位图层,并监听位置数据。
- 地图销毁时,关闭定位图层。
- 设置定位图层的开启和关闭。
完整代码如下:
package com.example.mapdemo;
import android.location.Location;
import com.amap.api.maps.AMap;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.MyLocationStyle;
public class MapLocation {
private final AMap map;
MapLocation(MapView mapView) {
map = mapView.getMap();
}
/**
* 地图加载完成时,设置定位图层配置信息
*/
public void onMapLoaded() {
// 初始化定位样式类
MyLocationStyle myLocationStyle = new MyLocationStyle();
// 连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)
// 如果不设置myLocationType,默认也会执行此种模式。
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE);
// 设置定位蓝点的Style
map.setMyLocationStyle(myLocationStyle);
map.setOnMyLocationChangeListener(new AMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
System.out.println("location: " + location.toString());
}
});
}
/**
* 地图销毁时,关闭定位图层
*/
public void onMapDestroy() {
map.setMyLocationEnabled(false);
}
/**
* 设置定位图层的开启和关闭
*/
public void setLocationEnabled(boolean enabled) {
// 设置默认定位按钮是否显示,非必需设置。
//aMap.getUiSettings().setMyLocationButtonEnabled(enabled);
// 设置为true表示启动显示定位蓝点,
// false表示隐藏定位蓝点并不进行定位,
// 默认是false。
map.setMyLocationEnabled(enabled);
}
}
显示定位的第二种方式
第二种方式,在地图中显示定位,主要有两个步骤:
- 获取定位数据。
- 将定位数据在地图中显示。
下面先介绍如何在地图中显示定位,最后简单介绍下如何获取定位数据。
显示定位
点标记的用法
利用点标记Marker
类实现在地图上标记位置,示例代码如下:
LatLng latLng = new LatLng(latitude, longitude);
if (locationMarker == null) {
// 在地图上添一个图片标记(marker)对象。
locationMarker = map.addMarker(new MarkerOptions().position(latLng)
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.location_marker))
.anchor(0.5f, 0.5f));
} else {
// 设置 Marker 覆盖物的位置坐标。
LatLng curLatlng = locationMarker.getPosition();
if (curLatlng == null || !curLatlng.equals(latLng)) {
locationMarker.setPosition(latLng);
}
}
MapLocationSimple类
创建一个简单的地图定位类,在地图中显示定位。
MapLocationSimple
类主要包括以下功能:
- 地图加载完成时,打开定位图层。
- 地图销毁时,关闭定位图层。
- 设置定位图层的开启和关闭。
- 设置位置坐标。
- 更新位置信息。
完整代码如下:
package com.example.mapdemo;
import com.amap.api.maps.AMap;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
public class MapLocationSimple {
private AMap map;
private double latitude = 0.0;
private double longitude = 0.0;
//自定义定位小蓝点的Marker
Marker locationMarker;
MapLocationSimple(MapView mapView) {
map = mapView.getMap();
}
/**
* 地图加载完成时 设置一些amap的属性
*/
public void onMapLoaded() {
// 设置默认定位按钮是否显示
map.getUiSettings().setMyLocationButtonEnabled(true);
// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false
map.setMyLocationEnabled(true);
}
/**
* 地图销毁时,关闭定位图层
*/
public void onMapDestroy() {
// 关闭定位图层
map.setMyLocationEnabled(false);
}
/**
* 设置定位图层的开启和关闭
*/
public void setLocationEnabled(boolean enabled) {
if (enabled) {
map.setMyLocationEnabled(true);
updateLocation();
} else {
map.setMyLocationEnabled(false);
}
}
/**
* 设置位置坐标
* @param latitude 纬度
* @param longitude 经度
*/
public void setLocation(double latitude, double longitude) {
this.latitude = latitude;
this.longitude = longitude;
updateLocation();
}
private void updateLocation() {
LatLng latLng = new LatLng(latitude, longitude);
if (locationMarker == null) {
// 在地图上添一个图片标记(marker)对象。
locationMarker = map.addMarker(new MarkerOptions().position(latLng)
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.location_marker))
.anchor(0.5f, 0.5f));
} else {
// 设置 Marker 覆盖物的位置坐标。
LatLng curLatlng = locationMarker.getPosition();
if (curLatlng == null || !curLatlng.equals(latLng)) {
locationMarker.setPosition(latLng);
}
}
}
}
模拟定位显示
- 地图加载完成时,开启定位图层并设置模拟位置。
- 地图视图销毁时,关闭定位图层。
部分代码如下:
public class MainActivity extends AppCompatActivity {
private MapView mapView;
private MapLocationSimple mapLocation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.bmapView);
mapLocation = new MapLocationSimple(mapView);
mapView.getMap().setOnMapLoadedListener(new MapLoadedCallback());
}
/**
* 自定义地图加载完成回调接口
*/
private class MapLoadedCallBack implements BaiduMap.OnMapLoadedCallback {
@Override
public void onMapLoaded() {
// 地图加载完成
mapLocation.onMapLoaded();
// 设置模拟位置
setSimulateLocation();
}
}
/**
* 设置模拟位置
*/
private void setSimulateLocation() {
// 模拟定位位置
double latitude = 39.923615;
double longitude = 116.49094;
// 坐标转换
DPoint sourceLatLng = new DPoint(latitude, longitude);
CoordinateConverter converter = new CoordinateConverter(MainActivity.this);
// CoordType.GPS 待转换坐标类型
converter.from(CoordinateConverter.CoordType.GPS);
// sourceLatLng待转换坐标点 DPoint类型
converter.coord(sourceLatLng);
// 执行转换操作
DPoint desLatLng = converter.convert();
// 设置位置
mapLocation.setLocation(desLatLng.getLatitude(), desLatLng.getLongitude());
// 按照传入的CameraUpdate参数改变地图状态。
LatLng latLng = new LatLng(desLatLng.getLatitude(), desLatLng.getLongitude());
mapView.getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapLocation.onMapDestroy();
mapView.onDestroy();
mapView = null;
}
}
显示效果
获取定位
定位权限
高德官网说明了不同android
版本不同的权限配置,本文不再赘述。
Android 6.0权限说明-实用工具-开发指南-Android 定位SDK|高德地图API (amap.com)
定位服务
LocationSource
定位源接口类为地图提供定位数据。包含activate
和deactivate
回调方法。- 在
activate
激活定位源中,设置定位初始化及启动定位。 - 在
deactivate
停止定位中,写停止定位的相关调用。
- 在
AMapLocationClient
定位服务类。提供单次定位、持续定位、最后位置相关功能。主要接口如下:setLocationListener
设置定位回调监听setLocationOption
设置定位参数startLocation()
开始定位stopLocation()
停止定位
AMapLocationListener
定位回调接口。包含onLocationChanged
回调方法。- 当定位完成后调用
onLocationChanged
方法,得到位置坐标并更新Marker的位置。
- 当定位完成后调用
部分示例代码
- 设置定位源,并打开定位图层
locationSource = new MyLocationSource(context);
// 设置定位监听
map.setLocationSource(locationSource);
// 设置默认定位按钮是否显示
map.getUiSettings().setMyLocationButtonEnabled(true);
// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false
map.setMyLocationEnabled(true);
- 定义定位源
activate
初始化服务类,并开始定位。deactivate
停止定位,并销毁。
/**
* 定义了一个定位源,为地图提供定位数据。
*/
class MyLocationSource implements LocationSource {
/**
* 激活定位源
*/
@Override
public void activate(OnLocationChangedListener listener) {
if (mlocationClient == null) {
try {
// 定位服务类。此类提供单次定位、持续定位、最后位置相关功能。
mlocationClient = new AMapLocationClient(context);
mLocationOption = new AMapLocationClientOption();
// 设置定位监听
mlocationClient.setLocationListener(new MyLocationChange());
// 设置为高精度定位模式
mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
// 是指定位间隔
mLocationOption.setInterval(2000);
// 设置定位参数
mlocationClient.setLocationOption(mLocationOption);
// 此方法为每隔固定时间会发起一次定位请求,为了减少电量消耗或网络流量消耗,
// 注意设置合适的定位时间的间隔(最小间隔支持为2000ms),并且在合适时间调用stopLocation()方法来取消定位请求
// 在定位结束后,在合适的生命周期调用onDestroy()方法
// 在单次定位情况下,定位无论成功与否,都无需调用stopLocation()方法移除请求,定位sdk内部会移除
mlocationClient.startLocation();
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 停止定位
*/
@Override
public void deactivate() {
if (mlocationClient != null) {
mlocationClient.stopLocation();
mlocationClient.onDestroy();
}
mlocationClient = null;
}
}
- 定位回调接口
class MyLocationChange implements AMapLocationListener {
/**
* 定位成功后回调函数
*/
@Override
public void onLocationChanged(AMapLocation amapLocation) {
if (mlocationClient == null || amapLocation == null)
return;
if (amapLocation.getErrorCode() == 0) {
// 添加在地图上显示定位
mapLocation.setLocation(amapLocation.getLatitude(), amapLocation.getLongitude());
} else {
String errText = "定位失败,"
+ amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
Log.e("AmapErr", errText);
}
}
}
总结
高德地图SDK显示定位的两种方式,第一种方法很便捷并有多种定位模式。若多种定位模式无法满足需求,可根据第二种方法实现自定义的定位需求。