Skip to content

Instantly share code, notes, and snippets.

@kibotu
Last active February 11, 2021 17:34
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kibotu/f9bda6831573e8226fc3298df8ac73be to your computer and use it in GitHub Desktop.
Save kibotu/f9bda6831573e8226fc3298df8ac73be to your computer and use it in GitHub Desktop.
GoogleMap workaround to keep bearing:
/**
* map.animateCamera(CameraUpdateFactory.newLatLngBounds()) will lose ignore current bearing and rotate the camera
*/
fun GoogleMap.animateToBounds(bounds: LatLngBounds, width: Int, height: Int) = animateCamera(boundsToCameraUpdate(bounds, width, height))
/**
* map.moveCamera(CameraUpdateFactory.newLatLngBounds()) will lose ignore current bearing and rotate the camera
*/
fun GoogleMap.moveCameraToBounds(bounds: LatLngBounds, width: Int, height: Int) = moveCamera(boundsToCameraUpdate(bounds, width, height))
fun GoogleMap.boundsToCameraUpdate(bounds: LatLngBounds, width: Int, height: Int): CameraUpdate {
val zoom = getBoundsZoomLevel(cameraPosition.zoom, bounds, width, height, GeneralMapStrategy.MAX_ZOOM)
return CameraUpdateFactory.newCameraPosition(
CameraPosition.Builder()
.target(bounds.center)
.zoom(if (zoom >= GeneralMapStrategy.MIN_ZOOM) zoom else cameraPosition.zoom)
.bearing(cameraPosition.bearing)
.tilt(cameraPosition.tilt)
.build()
)
}
/**
* north west ----------- north east
* | |
* | |
* | |
* south west ---------- south east
*
* note: only tested for north west hemisphere
*/
fun GoogleMap.getBoundsZoomLevel(currentZoom: Float, bounds: LatLngBounds, mapWidthPx: Int, mapHeightPx: Int, maxZoom: Float, padding: Float? = null): Float {
val nePoint = projection.toScreenLocation(bounds.northeast)
val swPoint = projection.toScreenLocation(bounds.southwest)
val width = (swPoint.x - nePoint.x) + (padding ?: 128f.px)
val height = (swPoint.y - nePoint.y) + (padding ?: 128f.px)
val latZoom = currentZoom + log2(mapWidthPx / width)
val lngZoom = currentZoom + log2(mapHeightPx / height)
val result = min(latZoom, lngZoom)
return min(result, maxZoom)
}
@kibotu
Copy link
Author

kibotu commented Feb 11, 2021

About the padding, no real reason except it looked a bit nicer for my use cases. Regarding zoom I needed 16 to 19 but I suggest playing around with it. You don't have to constraint the user if there is no requirement. Kinda also depends on the map viewport size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment