diff --git a/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/Projection.kt b/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/Projection.kt new file mode 100644 index 00000000..bac205d3 --- /dev/null +++ b/play-services-maps/core/hms/src/main/kotlin/org/microg/gms/maps/hms/Projection.kt @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: 2023 microG Project Team + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.microg.gms.maps.hms + +import android.graphics.Point +import android.util.Log +import com.google.android.gms.dynamic.IObjectWrapper +import com.google.android.gms.dynamic.ObjectWrapper +import com.google.android.gms.dynamic.unwrap +import com.google.android.gms.maps.internal.IProjectionDelegate +import com.google.android.gms.maps.model.LatLng +import com.google.android.gms.maps.model.VisibleRegion +import com.huawei.hms.maps.Projection +import org.microg.gms.maps.hms.utils.toGms +import org.microg.gms.maps.hms.utils.toHms + +class ProjectionImpl(private val projection: Projection) : IProjectionDelegate.Stub() { + + private var lastVisibleRegion: VisibleRegion? = null + + override fun fromScreenLocation(obj: IObjectWrapper?): LatLng? { + Log.d(TAG, "fromScreenLocation") + return try { + obj.unwrap()?.let { + projection.fromScreenLocation(it).toGms() + } + } catch (e: Exception) { + Log.d(TAG, "fromScreenLocation() used from outside UI thread on map with tilt or bearing, expect bugs") + LatLng(0.0, 0.0) + } + } + + override fun toScreenLocation(latLng: LatLng?): IObjectWrapper { + Log.d(TAG, "toScreenLocation: $latLng") + return try { + ObjectWrapper.wrap(latLng?.toHms()?.let { + projection.toScreenLocation(it).let { Point(it.x, it.y) } + }) + } catch (e: Exception) { + Log.d(TAG, "toScreenLocation() used from outside UI thread on map with tilt or bearing, expect bugs") + ObjectWrapper.wrap(Point(0, 0)) + } + } + + override fun getVisibleRegion(): VisibleRegion? { + val visibleRegion = projection.visibleRegion + if (visibleRegion.farLeft.latitude.isNaN() || visibleRegion.farLeft.longitude.isNaN()) { + return lastVisibleRegion + } + lastVisibleRegion = visibleRegion.toGms() + Log.d(TAG, "getVisibleRegion: $visibleRegion") + return lastVisibleRegion + } + + companion object { + private val TAG = "GmsMapProjection" + } +}