diff --git a/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt b/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt index 7088cc5..a1c5655 100644 --- a/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt +++ b/android/src/main/java/com/luggmaps/core/GoogleMapProvider.kt @@ -16,6 +16,7 @@ import com.google.android.gms.maps.GoogleMapOptions import com.google.android.gms.maps.MapView import com.google.android.gms.maps.OnMapReadyCallback import com.google.android.gms.maps.model.BitmapDescriptorFactory +import com.google.android.gms.maps.model.CameraPosition import com.google.android.gms.maps.model.Circle import com.google.android.gms.maps.model.CircleOptions import com.google.android.gms.maps.model.GroundOverlay @@ -1143,7 +1144,11 @@ class GoogleMapProvider(private val context: Context) : val map = googleMap ?: return val position = LatLng(latitude, longitude) val targetZoom = if (zoom > 0) zoom.toFloat() else map.cameraPosition.zoom - val cameraUpdate = CameraUpdateFactory.newLatLngZoom(position, targetZoom) + val cameraPosition = CameraPosition.Builder(map.cameraPosition) + .target(position) + .zoom(targetZoom) + .build() + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) when { duration < 0 -> map.animateCamera(cameraUpdate) duration > 0 -> map.animateCamera(cameraUpdate, duration, null) diff --git a/docs/MAPVIEW.md b/docs/MAPVIEW.md index 097dab9..6611e54 100644 --- a/docs/MAPVIEW.md +++ b/docs/MAPVIEW.md @@ -201,7 +201,7 @@ mapRef.current?.setEdgeInsets( ### moveCamera -Move the camera to a coordinate with optional zoom and animation duration. +Move the camera to a coordinate with optional zoom and animation duration. The current heading and pitch are preserved. ```ts moveCamera(coordinate: Coordinate, options: MoveCameraOptions): void @@ -214,7 +214,7 @@ interface MoveCameraOptions { ### fitCoordinates -Fit multiple coordinates in the visible map area. +Fit multiple coordinates in the visible map area. Resets heading to north (`0°`). ```ts fitCoordinates(coordinates: Coordinate[], options?: FitCoordinatesOptions): void diff --git a/ios/core/AppleMapProvider.mm b/ios/core/AppleMapProvider.mm index a2a5781..25e5748 100644 --- a/ios/core/AppleMapProvider.mm +++ b/ios/core/AppleMapProvider.mm @@ -1778,11 +1778,11 @@ - (void)moveCamera:(double)latitude } else if (duration > 0) { CLLocationCoordinate2D center = CLLocationCoordinate2DMake(latitude, longitude); - MKCoordinateRegion region = [_mapView regionForCenterCoordinate:center - zoomLevel:targetZoom]; + MKMapCamera *camera = [_mapView cameraForCenterCoordinate:center + zoomLevel:targetZoom]; [UIView animateWithDuration:duration / 1000.0 animations:^{ - [self->_mapView setRegion:region animated:NO]; + [self->_mapView setCamera:camera animated:NO]; }]; } else { [_mapView diff --git a/ios/core/GoogleMapProvider.mm b/ios/core/GoogleMapProvider.mm index 595e8ba..40805ee 100644 --- a/ios/core/GoogleMapProvider.mm +++ b/ios/core/GoogleMapProvider.mm @@ -1129,9 +1129,11 @@ - (void)moveCamera:(double)latitude return; float targetZoom = zoom > 0 ? (float)zoom : _mapView.camera.zoom; - GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:latitude - longitude:longitude - zoom:targetZoom]; + GMSCameraPosition *camera = [GMSCameraPosition + cameraWithTarget:CLLocationCoordinate2DMake(latitude, longitude) + zoom:targetZoom + bearing:_mapView.camera.bearing + viewingAngle:_mapView.camera.viewingAngle]; if (duration < 0) { [_mapView animateToCameraPosition:camera]; } else if (duration > 0) { diff --git a/ios/extensions/MKMapView+Zoom.h b/ios/extensions/MKMapView+Zoom.h index 67ec48a..ebb1c2a 100644 --- a/ios/extensions/MKMapView+Zoom.h +++ b/ios/extensions/MKMapView+Zoom.h @@ -8,6 +8,11 @@ NS_ASSUME_NONNULL_BEGIN zoomLevel:(double)zoomLevel animated:(BOOL)animated; +/// Returns a camera for the given center and zoom level, preserving the current +/// heading and pitch +- (MKMapCamera *)cameraForCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate + zoomLevel:(double)zoomLevel; + - (MKCoordinateRegion)regionForCenterCoordinate: (CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel; diff --git a/ios/extensions/MKMapView+Zoom.m b/ios/extensions/MKMapView+Zoom.m index a05456f..9dd42a9 100644 --- a/ios/extensions/MKMapView+Zoom.m +++ b/ios/extensions/MKMapView+Zoom.m @@ -22,9 +22,8 @@ - (MKCoordinateSpan)coordinateSpanForZoomLevel:(double)zoomLevel centerCoordinat // Constant for altitude/zoom conversion (meters at zoom level 0) static const double kAltitudeAtZoomZero = 220000000.0; -- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate - zoomLevel:(double)zoomLevel - animated:(BOOL)animated +- (MKMapCamera *)cameraForCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate + zoomLevel:(double)zoomLevel { // Use camera API directly to avoid region/margin interaction CLLocationDistance altitude = kAltitudeAtZoomZero / pow(2, zoomLevel); @@ -33,6 +32,15 @@ - (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate eyeAltitude:altitude]; camera.pitch = self.camera.pitch; camera.heading = self.camera.heading; + return camera; +} + +- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate + zoomLevel:(double)zoomLevel + animated:(BOOL)animated +{ + MKMapCamera *camera = [self cameraForCenterCoordinate:centerCoordinate + zoomLevel:zoomLevel]; [self setCamera:camera animated:animated]; }