[FAQ] Huawei の地図サービスで位置がずれる理由と解決策 (2) - Location 6.7.0.300 以降のバージョンにのみ適用されます

1. 問題の説明:

中国本土におけるファーウェイの地図サービスの「現在地」機能は、地図上の現在位置がユーザーの実際の位置から大きく乖離していることをユーザーに表示します。

具体的な違いは以下の図で確認できます。

ここに画像の説明を挿入

2. 大きな逸脱の理由:

  1. 中国本土で Huawei Map SDK が使用する地理座標系は GCJ02 です。

  2. 「現在地」コントロールをクリックすると、取得される経度と緯度の地理座標系は WGS-84 になります。

  3. 上記 2 つの理由、つまり、マップ ビューで使用される地理座標系と「現在地」の位置情報ソースが一致していないため、「現在地」の位置が不正確になるという問題が発生します。

3. 解決策:

  1. まず、Huawei Location SDKを使用して、測位(GCJ02地理座標系)を通じてユーザーの現在位置の緯度と経度情報を取得します。

  2. HUAWEI Map SDK が提供する huaweiMap.setLocationSource(LocationSource locationSource) メソッドを使用して、「現在地」レイヤーの位置情報ソースを設定します。

4. 注意すべき事項:

Location SDK を使用して GCJ-02 座標系の緯度と経度を直接取得する方法は、SDK バージョン 6.7.0.300 以降にのみ適用できます。これは、Location SDK のバージョン 6.7.0.300 より前のバージョンでは緯度および経度の直接取得がサポートされていないためです。 GCJ-02 座標系の。

5 つの具体的な実装手順:

  1. 現在地をオンにしてマップ インスタンスを作成する

a. アクティビティのレイアウト ファイルにマップ コントロールを追加し、マップ プロパティを設定します。

<?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. アクティビティで SDK を初期化し、マップをロードします。

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. マップを表示し、[現在地 UI コントロール] をクリックします。3 つのスクリーンショットから、「現在地」と「ユーザーの実際の場所」の間に大きな乖離があることがわかります。

ここに画像の説明を挿入

ここに画像の説明を挿入
ここに画像の説明を挿入

  1. Huawei Location SDK を使用してユーザーの現在位置を取得する

a. F​​usedLocationProviderClient オブジェクトを宣言します。

// 声明fusedLocationProviderClient对象

private FusedLocationProviderClient fusedLocationProviderClient;

b. 位置更新コールバック用の LocationCallback を作成します。

/**
 * 定义位置更新回调
 */
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. FusedLocationProviderClient オブジェクトを初期化し、位置タイプと GCJ02 座標タイプを設定して、位置を有効にします。

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. ユーザーの現在位置 (WGS-84 座標系) を取得するために測位を開始すると、次の結果が得られます。

ここに画像の説明を挿入

e. Location の位置をマークするマーカーを作成します。このメソッドは、LocationCallback コールバックで呼び出すことができます。

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. 以下の図 2 から、Location SDK の測位によって取得された GCJ02 の座標位置は、ユーザーの実際の位置から偏差がないことがわかります。

ここに画像の説明を挿入
ここに画像の説明を挿入

  1. huaweiMap.setLocationSource(LocationSouce locationSouce) メソッドを使用して、Location SDK によって取得された GCJ-02 座標系の緯度と経度を、位置レイヤーの位置ソースとして設定します。具体的な実装は次のとおりです。

  2. 新しい MyLocationSouce クラスを作成して、位置情報ソースを定義します。

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. MyLocationSouce クラスを初期化し、MyLocationSouce を位置レイヤーの位置ソースとして設定します。
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. LocationCallback コールバック メソッドの位置ソースとして GCJ-02 座標系の緯度と経度を設定します。
/**
     * 定义位置更新回调
     */
    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. 結果を示す:

以下の 2 つの図からわかるように、位置レイヤーはユーザーの実際の位置とずれることなく一致しています。

ここに画像の説明を挿入
ここに画像の説明を挿入

6. Map SDK と Location SDK で必要な権限のリストは次のとおりです。

  1. Map SDK が追加する必要がある権限のリスト:
<!-- 您调用地图服务能力,必须在“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. Location SDK が追加する必要がある権限のリスト (権限の部分リスト):
<!-- 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. 参考資料:

  1. Huawei Map SDK アクセスガイド:

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

  1. マップ インスタンスを作成します。

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

  1. 現在地機能をオンにします。

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

  1. マーカー タグを作成して設定します。

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

  1. 位置レイヤーの位置ソースを設定します。

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

  1. Huawei Location SDK アクセスガイド:

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

  1. ユーザーの現在位置を取得するための融合測位開発:

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

  1. 位置測位設定座標系

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

さらに詳しく>>

Map Service Alliance の公式 Web サイトにアクセスしてください

マップ サービス開発ガイダンス ドキュメントを入手する

HMS コア アライアンスの公式 Web サイトにアクセスしてください

HMS コア開発ガイダンス ドキュメントを入手する

私たちをフォローして、HMS Coreの最新技術情報を初めて学びましょう~

おすすめ

転載: blog.csdn.net/HUAWEI_HMSCore/article/details/131393828