[FAQ] Reasons and solutions for positioning deviations in Huawei's map service (2) - only applicable to Location 6.7.0.300 and later versions

1. Problem description:

The "My Location" capability of Huawei's map service, in mainland China, shows users that their current location on the map has a large deviation from the user's actual location.

The specific differences can be seen in the picture below:

insert image description here

2. Reasons for large deviations:

  1. The geographic coordinate system used by Huawei Map SDK in Mainland China is GCJ02.

  2. Click the "My Location" control, and the geographic coordinate system of the obtained longitude and latitude is WGS-84.

  3. Because of the above two reasons, that is, the geographical coordinate system used by the map View and the location source of "My Location" are inconsistent, this leads to the problem of inaccurate positioning of "My Location".

3. Solution:

  1. First use the Huawei Location SDK to obtain the latitude and longitude information of the user's current location through positioning (GCJ02 geographic coordinate system).

  2. Use the huaweiMap.setLocationSource(LocationSource locationSource) method provided by the HUAWEI Map SDK to set the location source of the "My Location" layer.

4. Matters needing attention:

Using the Location SDK to directly obtain the latitude and longitude of the GCJ-02 coordinate system is only applicable to SDK versions 6.7.0.300 and later, because versions of the Location SDK earlier than 6.7.0.300 do not support directly obtaining the latitude and longitude of the GCJ-02 coordinate system.

Five, specific implementation steps:

  1. Create a map instance with My Location turned on

a. Add a map control in the layout file of the Activity and set the map properties.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:map="http://schemas.android.com/apk/res-auto"
        android:id="@+id/mapfragment_mapfragmentdemo"
        class="com.huawei.hms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        map:cameraTargetLat="48.893478"
        map:cameraTargetLng="2.334595"
        map:cameraZoom="16" />
</androidx.constraintlayout.widget.ConstraintLayout>

b. Initialize the SDK in the Activity and load the map.

public class HwMyLocationActivity extends AppCompatActivity implements OnMapReadyCallback {
    private HuaweiMap huaweiMap;
    private SupportMapFragment mSupportMapFragment;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //初始化SDK
        MapsInitializer.initialize(this);
        setContentView(R.layout.activity_mylocation);
        mSupportMapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.mapfragment_mapfragmentdemo);
        //加载地图
        mSupportMapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(HuaweiMap huaweiMap) {
        //地图数据加载完成,展示成功。
        this.huaweiMap = huaweiMap;
        huaweiMap.setMyLocationEnabled(true);
    }
}

c. Display the map and click the My Location UI control. From the three screenshots, it can be seen that there is a large deviation between "My Location" and "User's Actual Location".

insert image description here

insert image description here
insert image description here

  1. Use the Huawei Location SDK to obtain the user's current location

a. Declare the FusedLocationProviderClient object.

// 声明fusedLocationProviderClient对象

private FusedLocationProviderClient fusedLocationProviderClient;

b. Create a LocationCallback for location update callback.

/**
 * 定义位置更新回调
 */
LocationCallback mLocationCallback = new LocationCallback() {
    @Override
    public void onLocationResult(LocationResult locationResult) {
        if (locationResult != null) {
            // TODO: 处理位置回调结果
            Log.d("LOG_HwMyLocation", "Latitude" + locationResult.getLastHWLocation().getLatitude() +
                    " ; Longitude:" + locationResult.getLastHWLocation().getLongitude());
        }
    }
};

c. Initialize the FusedLocationProviderClient object, set the location type and GCJ02 coordinate type, and enable location.

private void initLocationClient() {
    // 实例化fusedLocationProviderClient对象
    fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);

    LocationRequest mLocationRequest = new LocationRequest();
    // 设置位置更新的间隔(单位:毫秒)
    mLocationRequest.setInterval(1000);
    // 设置定位类型
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    // 设置回调次数为1
mLocationRequest.setNumUpdates(10);
//设置坐标类型。
//默认传入COORDINATE_TYPE_WGS84返回WGS84坐标位置,
//传入COORDINATE_TYPE_GCJ02,返回GCJ02坐标位置。
mLocationRequest.setCoordinateType(LocationRequest.COORDINATE_TYPE_GCJ02);
    //开启定位
    fusedLocationProviderClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
            .addOnSuccessListener(new OnSuccessListener<Void>() {
                @Override
                public void onSuccess(Void aVoid) {
                    // TODO: 接口调用成功的处理
                    Log.d("LOG_HwMyLocation", "定位开启成功");
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(Exception e) {
                    // TODO: 接口调用失败的处理
                    Log.d("LOG_HwMyLocation", "定位开启失败:"+e.getMessage());
                }
            });
}

d. Start positioning to obtain the current location of the user (WGS-84 coordinate system), and the following results can be obtained:

insert image description here

e. Create a Marker to mark the location of the Location. This method can be called in the LocationCallback callback.

private Marker locationMarker;
//添加定位位置标记
public void addLocationMarker(double Latitude, double Longitude) {
    if (null != locationMarker) {
        locationMarker.remove();
    }
    MarkerOptions options = new MarkerOptions()
            .position(new LatLng(Latitude, Longitude))
            .title("定位位置")
            .snippet("定位所在位置");
    locationMarker = this.huaweiMap.addMarker(options);
}

f. From the figure 2 below, it can be seen that the coordinate position of GCJ02 obtained by the Location SDK positioning has no deviation from the actual location of the user:

insert image description here
insert image description here

  1. Use the huaweiMap.setLocationSource(LocationSouce locationSouce) method to set the latitude and longitude of the GCJ-02 coordinate system obtained by the Location SDK as the location source of my location layer. The specific implementation is as follows:

  2. Create a new MyLocationSouce class to define the location source.

private class MyLocationSouce implements LocationSource {
    private OnLocationChangedListener listener;

    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        listener = onLocationChangedListener;
    }

    @Override
    public void deactivate() {

    }

    /**
     * 改变我的位置图层的定位源
     * @param lat_gcj02 GCJ-02
     * @param log_gcj02 GCJ-02
     */
    public void changeMyLocationSouce(double lat_gcj02, double log_gcj02) {
        Location location = new Location("Provider");

        location.setLatitude(lat_gcj02);
        location.setLongitude(log_gcj02);
        //设置精度
        location.setAccuracy(200);
        //当获取到新的用户位置时,调用此方法,设置定位源
        listener.onLocationChanged(location);
    }
}
  1. Initialize the MyLocationSouce class and set MyLocationSouce as the location source for my location layer:
private MyLocationSouce myLocationSouce;
@Override
public void onMapReady(HuaweiMap huaweiMap) {
    this.huaweiMap = huaweiMap;
    huaweiMap.setMyLocationEnabled(true);
    //初始化LocationSouce并设置我的位置图层的位置源
    if (null == myLocationSouce){
        myLocationSouce = new MyLocationSouce();
    }
    huaweiMap.setLocationSource(myLocationSouce);
}
  1. Set the latitude and longitude of the GCJ-02 coordinate system as the location source in the LocationCallback callback method.
/**
     * 定义位置更新回调
     */
    LocationCallback mLocationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            if (locationResult != null) {
                // TODO: 处理位置回调结果
                Log.d("LOG_HwMyLocation", "Latitude" + locationResult.getLastHWLocation().getLatitude() +
                        " ; Longitude:" + locationResult.getLastHWLocation().getLongitude());
                //将Location SDK获取的GCJ02坐标系的经纬度 标记在地图上
                addLocationMarker(locationResult.getLastHWLocation().getLatitude(), locationResult.getLastHWLocation().getLongitude());
                //设置定位源
                if (null != myLocationSouce) {
                    myLocationSouce.changeMyLocationSouce(locationResult.getLastHWLocation().getLatitude(), locationResult.getLastHWLocation().getLongitude());
                }
            }
        }
    };
  1. Show results:

As can be seen from the two figures below, my location layer is consistent with the user's actual location without deviation.

insert image description here
insert image description here

6. The list of permissions required by Map SDK and Location SDK are:

  1. List of permissions that Map SDK needs to add:
<!-- 您调用地图服务能力,必须在“AndroidManifest”中为您的应用添加下列权限: -->
<!--允许程序访问网络连接-->
<uses-permission android:name="android.permission.INTERNET"/>
<!--允许程序获取网络信息状态-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!--自定义权限,允许程序读取公共数据-->
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
<!--允许改变WLAN状态的开关-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

<!-- 获取设备当前位置需要在“AndroidManifest”中增加以下权限,且Android 6.0以后需动态申请: -->
<!--允许程序通过Wi-Fi或移动基站的方式获取用户粗略的经纬度信息-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!--允许程序通过GPS芯片接收卫星的定位信息-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  1. The list of permissions that the Location SDK needs to add (partial list of permissions):
<!-- Android提供了两种位置权限: ACCESS_COARSE_LOCATION(粗略的位置权限)和ACCESS_FINE_LOCATION(精确的位置权限)。
需要在“AndroidManifest.xml”文件中配置权限,且Android 6.0以后需动态申请: -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

7. Reference materials:

  1. Huawei Map SDK access guide:

https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/android-sdk-brief-introduction-0000001061991343?ha_source=hms1

  1. Create a map instance:

https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/android-sdk-map-instance-creation-0000001062881706?ha_source=hms1

  1. Turn on the My Location feature:

https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/android-sdk-my-location-0000001061775973?ha_source=hms1

  1. Create and set a Marker tag:

https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/android-sdk-map-instance-creation-0000001062881706?ha_source=hms1

  1. Set the location source for my location layer:

https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/huaweimap-0000001050151757#section1664916820220?ha_source=hms1

  1. Huawei Location SDK access guide:

https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/android-introduction-0000001121930588?ha_source=hms1

  1. Fusion positioning development to obtain the current location of the user:

https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/location-develop-steps-0000001050746143?ha_source=hms1

  1. Location positioning setting coordinate type

https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/locationrequest-0000001050986189#section17806162191712?ha_source=hms1

Learn more details>>

Visit the official website of Map Service Alliance

Obtain the map service development guidance document

Visit the official website of HMS Core Alliance

Obtain the HMS Core development guidance document

Follow us and learn about the latest technical information of HMS Core for the first time~

Guess you like

Origin blog.csdn.net/HUAWEI_HMSCore/article/details/131393828