高德地图SDK Android版开发 3 显示定位

前言

本文主要介绍高德地图显示定位相关的功能和接口,以及使用方法。

高德地图有两种方式在地图中显示定位。

方式一自Android 3D地图 SDK 5.0.0版本之后,SDK集成了显示定位,可以简单的实现位置的显示。

方式二:获取定位数据,将定位数据在地图中显示。

本文先简单定位数据包括哪些数据,再依次介绍如何通过两种方式实现显示定位。

定位数据

两种显示定位方式中,定位数据从接口层面有稍许差别,

定位信息类说明
方式一android.location.Location地理位置的数据类。
包含纬度,经度,时间戳和其他信息,如方位,高度和速度。
方式二com.amap.api.location.AMapLocation定位信息类。定位完成后的位置信息。

下图为AMapLocation的部分接口:

Location
MyLocationData
+String getCountry()
+String getProvince()
+String getCity()
+String getCityCode()

显示定位的第一种方式

定位模式

高德地图有多种定位模式,可实现定位或连续定位、是否将视角移动到地图中心点,是否依照设备方向旋转,多种组合方式。

定位模式说明
1LOCATION_TYPE_SHOW只定位一次。
2LOCATION_TYPE_LOCATE定位一次,且将视角移动到地图中心点。
3LOCATION_TYPE_FOLLOW连续定位,且将视角移动到地图中心点,定位蓝点跟随设备移动。(1秒1次定位)
4LOCATION_TYPE_MAP_ROTATE连续定位、且将视角移动到地图中心点,地图依照设备方向旋转,定位点会跟随设备移动。(1秒1次定位)
5LOCATION_TYPE_LOCATION_ROTATE连续定位、且将视角移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。(1秒1次定位)默认执行此种模式。
6LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER从5.1.0版本开始提供
连续定位、蓝点不会移动到地图中心点,定位点依照设备方向旋转,并且蓝点会跟随设备移动。
7LOCATION_TYPE_FOLLOW_NO_CENTER从5.1.0版本开始提供
连续定位、蓝点不会移动到地图中心点,并且蓝点会跟随设备移动。
8LOCATION_TYPE_MAP_ROTATE_NO_CENTER从5.1.0版本开始提供
连续定位、蓝点不会移动到地图中心点,地图依照设备方向旋转,并且蓝点会跟随设备移动。

定位样式类

MyLocationStyle定位样式类,可设置定位模式,是否显示定位,设置定位请求的时间间隔,以及个性化显示样式。

MyLocationStyle
+MyLocationStyle myLocationType(type)
+MyLocationStyle interval(interval)
+MyLocationStyle showMyLocation(visible)
+MyLocationStyle myLocationIcon(icon)
+MyLocationStyle anchor(float u, float v)
+MyLocationStyle radiusFillColor(int color)
+MyLocationStyle strokeColor(int color)
+MyLocationStyle strokeWidth(float width)
类型方法说明
MyLocationStylemyLocationType(int type)设置我的位置展示模式。
MyLocationStyleinterval(long interval)设置发起定位请求的时间间隔,
单位:毫秒,默认值:1000毫秒,
如果传小于1000的任何值将执行单次定位。
MyLocationStyleshowMyLocation(boolean myLocationVisible)设置是否显示定位小蓝点,true 显示,false不显示。
MyLocationStylemyLocationIcon(BitmapDescriptor myLocationIcon)设置定位(当前位置)的icon图标。
MyLocationStyleanchor(float u, float v)设置定位图标的锚点。
MyLocationStyleradiusFillColor(int color)设置圆形区域(以定位位置为圆心,定位半径的圆形区域)的填充颜色。
MyLocationStylestrokeColor(int color)设置圆形区域(以定位位置为圆心,定位半径的圆形区域)的边框颜色。
MyLocationStylestrokeWidth(float width)设置圆形区域(以定位位置为圆心,定位半径的圆形区域)的边框宽度。

地图类

地图类中与定位相关的接口包括:定位图层的样式,是否打开定位图层,用户定位信息监听接口。

AMap
+void setMyLocationStyle(style)
+void setMyLocationEnabled(enabled)
+void setOnMyLocationChangeListener(listener)
类型方法说明
voidsetMyLocationStyle(MyLocationStyle style)设置定位图层的样式。
voidvoid setMyLocationEnabled(boolean enabled)设置是否打开定位图层。
voidvoid setOnMyLocationChangeListener(AMap.OnMyLocationChangeListener listener)设置用户定位信息监听接口。

MapLocation类

创建一个地图定位类MapLocation,主要包括以下功能:

  1. 地图加载完成时,设置定位模式,打开定位图层,并监听位置数据。
  2. 地图销毁时,关闭定位图层。
  3. 设置定位图层的开启和关闭。

完整代码如下:

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

显示定位的第二种方式

第二种方式,在地图中显示定位,主要有两个步骤:

  1. 获取定位数据。
  2. 将定位数据在地图中显示。

下面先介绍如何在地图中显示定位,最后简单介绍下如何获取定位数据。

显示定位

点标记的用法

利用点标记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类主要包括以下功能:

  1. 地图加载完成时,打开定位图层。
  2. 地图销毁时,关闭定位图层。
  3. 设置定位图层的开启和关闭。
  4. 设置位置坐标。
  5. 更新位置信息。

完整代码如下:

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

模拟定位显示

  1. 地图加载完成时,开启定位图层并设置模拟位置。
  2. 地图视图销毁时,关闭定位图层。

部分代码如下:

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)

定位服务

AMap
+void setLocationSource(locationSource)
+void setMyLocationEnabled(enabled)
LocationSource
+void activate(OnLocationChangedListener)
+void deactivate()
AMapLocationClient
+void setLocationListener(AMapLocationListener)
+void setLocationOption(AMapLocationClientOption)
+void startLocation()
+void stopLocation()
AMapLocationClientOption
AMapLocationListener
+void onLocationChanged(AMapLocation)
Marker
  1. LocationSource定位源接口类为地图提供定位数据。包含activatedeactivate回调方法。
    • activate激活定位源中,设置定位初始化及启动定位。
    • deactivate停止定位中,写停止定位的相关调用。
  2. AMapLocationClient定位服务类。提供单次定位、持续定位、最后位置相关功能。主要接口如下:
    • setLocationListener 设置定位回调监听
    • setLocationOption 设置定位参数
    • startLocation()开始定位
    • stopLocation() 停止定位
  3. AMapLocationListener 定位回调接口。包含onLocationChanged回调方法。
    • 当定位完成后调用onLocationChanged方法,得到位置坐标并更新Marker的位置。

部分示例代码

  1. 设置定位源,并打开定位图层
locationSource = new MyLocationSource(context);
// 设置定位监听
map.setLocationSource(locationSource);
// 设置默认定位按钮是否显示
map.getUiSettings().setMyLocationButtonEnabled(true);
// 设置为true表示显示定位层并可触发定位,false表示隐藏定位层并不可触发定位,默认是false
map.setMyLocationEnabled(true);
  1. 定义定位源
    • 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;
    }
}
  1. 定位回调接口
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显示定位的两种方式,第一种方法很便捷并有多种定位模式。若多种定位模式无法满足需求,可根据第二种方法实现自定义的定位需求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值