Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[android][ios][macOS] Implement bindings for Map::cameraForGeometry
Browse files Browse the repository at this point in the history
…. On macOS, also added -[MGLMapView setCamera: withDuration: animationTimingFunction: edgePadding: completionHandler:] for parity with iOS
  • Loading branch information
Asheem Mamoowala committed Oct 9, 2017
1 parent 2366487 commit 9e79659
Show file tree
Hide file tree
Showing 11 changed files with 123 additions and 5 deletions.
2 changes: 1 addition & 1 deletion platform/android/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to

* Add support for ImageSource [#9110](https://github.com/mapbox/mapbox-gl-native/pull/9110)
* Increased the default maximum zoom level from 20 to 22. ([#9835](https://github.com/mapbox/mapbox-gl-native/pull/9835))
* TBA
* Added `MapboxMap.getCameraForGeometry()` to get a camera with zoom level and center coordinate computed to fit a shape. ([#10107](https://github.com/mapbox/mapbox-gl-native/pull/10107))

### 5.1.4 - September 25, 2017

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import com.mapbox.mapboxsdk.style.sources.Source;
import com.mapbox.services.android.telemetry.location.LocationEngine;
import com.mapbox.services.commons.geojson.Feature;
import com.mapbox.services.commons.geojson.Geometry;

import java.lang.reflect.ParameterizedType;
import java.util.List;
Expand Down Expand Up @@ -1666,6 +1667,30 @@ public CameraPosition getCameraForLatLngBounds(@Nullable LatLngBounds latLngBoun
return cameraPosition;
}

/**
* Get a camera position that fits a provided shape with a given bearing and padding.
*
* @param geometry the geometry to constrain the map with
* @param bearing the bearing at which to compute the geometry's bounds
* @param padding the padding to apply to the bounds
* @return the camera position that fits the bounds and padding
*/
public CameraPosition getCameraForGeometry(Geometry geometry, double bearing, int[] padding) {
// calculate and set additional bounds padding
int[] mapPadding = getPadding();
for (int i = 0; i < padding.length; i++) {
padding[i] = mapPadding[i] + padding[i];
}
projection.setContentPadding(padding, myLocationViewSettings.getPadding());

// get padded camera position from LatLngBounds
CameraPosition cameraPosition = nativeMapView.getCameraForGeometry(geometry, bearing);

// reset map padding
setPadding(mapPadding);
return cameraPosition;
}

//
// Padding
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.mapbox.mapboxsdk.style.sources.Source;
import com.mapbox.mapboxsdk.utils.BitmapUtils;
import com.mapbox.services.commons.geojson.Feature;
import com.mapbox.services.commons.geojson.Geometry;

import java.nio.ByteBuffer;
import java.util.ArrayList;
Expand Down Expand Up @@ -232,6 +233,13 @@ public CameraPosition getCameraForLatLngBounds(LatLngBounds latLngBounds) {
return nativeGetCameraForLatLngBounds(latLngBounds);
}

public CameraPosition getCameraForGeometry(Geometry geometry, double bearing) {
if (isDestroyedOn("getCameraForGeometry")) {
return null;
}
return nativeGetCameraForGeometry(geometry, bearing);
}

public void resetPosition() {
if (isDestroyedOn("resetPosition")) {
return;
Expand Down Expand Up @@ -873,6 +881,8 @@ private native void nativeInitialize(NativeMapView nativeMapView,

private native CameraPosition nativeGetCameraForLatLngBounds(LatLngBounds latLngBounds);

private native CameraPosition nativeGetCameraForGeometry(Geometry geometry, double bearing);

private native void nativeResetPosition();

private native double nativeGetPitch();
Expand Down
6 changes: 6 additions & 0 deletions platform/android/src/native_map_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,11 @@ jni::Object<CameraPosition> NativeMapView::getCameraForLatLngBounds(jni::JNIEnv&
return CameraPosition::New(env, map->cameraForLatLngBounds(mbgl::android::LatLngBounds::getLatLngBounds(env, jBounds), insets));
}

jni::Object<CameraPosition> NativeMapView::getCameraForGeometry(jni::JNIEnv& env, jni::Object<geojson::Geometry> jGeometry, double bearing) {
auto geometry = geojson::Geometry::convert(env, jGeometry);
return CameraPosition::New(env, map->cameraForGeometry(geometry, insets, bearing));
}

void NativeMapView::setReachability(jni::JNIEnv&, jni::jboolean reachable) {
if (reachable) {
mbgl::NetworkStatus::Reachable();
Expand Down Expand Up @@ -949,6 +954,7 @@ void NativeMapView::registerNative(jni::JNIEnv& env) {
METHOD(&NativeMapView::getLatLng, "nativeGetLatLng"),
METHOD(&NativeMapView::setLatLng, "nativeSetLatLng"),
METHOD(&NativeMapView::getCameraForLatLngBounds, "nativeGetCameraForLatLngBounds"),
METHOD(&NativeMapView::getCameraForGeometry, "nativeGetCameraForGeometry"),
METHOD(&NativeMapView::setReachability, "nativeSetReachability"),
METHOD(&NativeMapView::resetPosition, "nativeResetPosition"),
METHOD(&NativeMapView::getPitch, "nativeGetPitch"),
Expand Down
3 changes: 3 additions & 0 deletions platform/android/src/native_map_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "graphics/pointf.hpp"
#include "graphics/rectf.hpp"
#include "geojson/feature.hpp"
#include "geojson/geometry.hpp"
#include "geometry/lat_lng.hpp"
#include "geometry/projected_meters.hpp"
#include "style/layers/layers.hpp"
Expand Down Expand Up @@ -104,6 +105,8 @@ class NativeMapView : public MapObserver {

jni::Object<CameraPosition> getCameraForLatLngBounds(jni::JNIEnv&, jni::Object<mbgl::android::LatLngBounds>);

jni::Object<CameraPosition> getCameraForGeometry(jni::JNIEnv&, jni::Object<geojson::Geometry>, double bearing);

void setReachability(jni::JNIEnv&, jni::jboolean);

void resetPosition(jni::JNIEnv&);
Expand Down
1 change: 1 addition & 0 deletions platform/ios/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* Increased the default maximum zoom level from 20 to 22. ([#9835](https://github.com/mapbox/mapbox-gl-native/pull/9835))
* Added an `overlays` property to `MGLMapView`. ([#8617](https://github.com/mapbox/mapbox-gl-native/pull/8617))
* Selecting an annotation no longer sets the user tracking mode to `MGLUserTrackingModeNone`. ([#10094](https://github.com/mapbox/mapbox-gl-native/pull/10094))
* Added `-[MGLMapView cameraThatFitsShape:direction:edgePadding:]` to get a camera with zoom level and center coordinate computed to fit a shape. ([#10107](https://github.com/mapbox/mapbox-gl-native/pull/10107))

### Other changes

Expand Down
14 changes: 14 additions & 0 deletions platform/ios/src/MGLMapView.h
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,20 @@ MGL_EXPORT IB_DESIGNABLE
*/
- (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(UIEdgeInsets)insets;

/**
Returns the camera that best fits the given shape, with the specified direction,
optionally with some additional padding on each side.
@param shape The shape to fit to the receiver’s viewport.
@param direction The direction of the viewport, measured in degrees clockwise from true north.
@param insets The minimum padding (in screen points) that would be visible
around the returned camera object if it were set as the receiver’s camera.
@return A camera object centered on the shape's center with zoom level as high
(close to the ground) as possible while still including the entire shape. The
camera object uses the current pitch.
*/
- (MGLMapCamera *)cameraThatFitsShape:(MGLShape *)shape direction:(double)direction edgePadding:(UIEdgeInsets)insets;

/**
Returns the point in this view’s coordinate system on which to "anchor" in
response to a user-initiated gesture.
Expand Down
11 changes: 11 additions & 0 deletions platform/ios/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <mbgl/util/projection.hpp>

#import "Mapbox.h"
#import "MGLShape_Private.h"
#import "MGLFeature_Private.h"
#import "MGLGeometry_Private.h"
#import "MGLMultiPoint_Private.h"
Expand Down Expand Up @@ -3011,6 +3012,16 @@ - (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds edg
return [self cameraForCameraOptions:cameraOptions];
}

- (MGLMapCamera *)cameraThatFitsShape:(MGLShape *)shape direction:(double)direction edgePadding:(UIEdgeInsets)insets {
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInset);

mbgl::CameraOptions cameraOptions = _mbglMap->cameraForGeometry([shape geometryObject], padding, direction);

return [self cameraForCameraOptions:cameraOptions];

}

- (MGLMapCamera *)cameraForCameraOptions:(const mbgl::CameraOptions &)cameraOptions
{
CLLocationCoordinate2D centerCoordinate = MGLLocationCoordinate2DFromLatLng(cameraOptions.center ? *cameraOptions.center : _mbglMap->getLatLng());
Expand Down
1 change: 1 addition & 0 deletions platform/macos/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* Fixed several bugs and performance issues related to the use of annotations backed by `MGLAnnotationImage`s. The limits on the number and size of images and glyphs has been effectively eliminated and should now depend on hardware constraints. These fixes also apply to images used to represent icons in `MGLSymbolStyleLayer`s. ([#9213](https://github.com/mapbox/mapbox-gl-native/pull/9213))
* Increased the default maximum zoom level from 20 to 22. ([#9835](https://github.com/mapbox/mapbox-gl-native/pull/9835))
* Added an `overlays` property to `MGLMapView`. ([#8617](https://github.com/mapbox/mapbox-gl-native/pull/8617))
* Added `-[MGLMapView cameraThatFitsShape:direction:edgePadding:]` to get a camera with zoom level and center coordinate computed to fit a shape. ([#10107](https://github.com/mapbox/mapbox-gl-native/pull/10107))

### Other changes

Expand Down
33 changes: 33 additions & 0 deletions platform/macos/src/MGLMapView.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN
@class MGLAnnotationImage;
@class MGLMapCamera;
@class MGLStyle;
@class MGLShape;

@protocol MGLAnnotation;
@protocol MGLMapViewDelegate;
Expand Down Expand Up @@ -322,6 +323,24 @@ MGL_EXPORT IB_DESIGNABLE
*/
- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion;

/**
Moves the viewpoint to a different location with respect to the map with an
optional transition duration and timing function.
@param camera The new viewpoint.
@param duration The amount of time, measured in seconds, that the transition
animation should take. Specify `0` to jump to the new viewpoint
instantaneously.
@param function A timing function used for the animation. Set this parameter to
`nil` for a transition that matches most system animations. If the duration
is `0`, this parameter is ignored.
@param edgePadding The minimum padding (in screen points) that would be visible
around the returned camera object if it were set as the receiver’s camera.
@param completion The block to execute after the animation finishes.
*/
- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function edgePadding:(NSEdgeInsets)edgePadding completionHandler:(nullable void (^)(void))completion;


/**
Moves the viewpoint to a different location using a transition animation that
evokes powered flight and a default duration based on the length of the flight
Expand Down Expand Up @@ -456,6 +475,20 @@ MGL_EXPORT IB_DESIGNABLE
*/
- (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(NSEdgeInsets)insets;

/**
Returns the camera that best fits the given shape, with the specified direction,
optionally with some additional padding on each side.
@param shape The shape to fit to the receiver’s viewport.
@param direction The direction of the viewport, measured in degrees clockwise from true north.
@param insets The minimum padding (in screen points) that would be visible
around the returned camera object if it were set as the receiver’s camera.
@return A camera object centered on the shape's center with zoom level as high
(close to the ground) as possible while still including the entire shape. The
camera object uses the current pitch.
*/
- (MGLMapCamera *)cameraThatFitsShape:(MGLShape *)shape direction:(double)direction edgePadding:(NSEdgeInsets)insets;

/**
A Boolean value indicating whether the receiver automatically adjusts its
content insets.
Expand Down
22 changes: 18 additions & 4 deletions platform/macos/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#import "MGLMultiPoint_Private.h"
#import "MGLOfflineStorage_Private.h"
#import "MGLStyle_Private.h"
#import "MGLShape_Private.h"

#import "MGLAccountManager.h"
#import "MGLMapCamera.h"
Expand Down Expand Up @@ -1121,6 +1122,10 @@ - (void)setCamera:(MGLMapCamera *)camera animated:(BOOL)animated {
}

- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion {
[self setCamera:camera withDuration:duration animationTimingFunction:function edgePadding:self.contentInsets completionHandler:completion];
}

- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function edgePadding:(NSEdgeInsets)edgePadding completionHandler:(nullable void (^)(void))completion {
mbgl::AnimationOptions animationOptions;
if (duration > 0) {
animationOptions.duration.emplace(MGLDurationFromTimeInterval(duration));
Expand Down Expand Up @@ -1148,7 +1153,7 @@ - (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration a

[self willChangeValueForKey:@"camera"];
_mbglMap->cancelTransitions();
mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera];
mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:edgePadding];
_mbglMap->easeTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"camera"];
}
Expand Down Expand Up @@ -1194,17 +1199,17 @@ - (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration

[self willChangeValueForKey:@"camera"];
_mbglMap->cancelTransitions();
mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera];
mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:self.contentInsets];
_mbglMap->flyTo(cameraOptions, animationOptions);
[self didChangeValueForKey:@"camera"];
}

/// Returns a CameraOptions object that specifies parameters for animating to
/// the given camera.
- (mbgl::CameraOptions)cameraOptionsObjectForAnimatingToCamera:(MGLMapCamera *)camera {
- (mbgl::CameraOptions)cameraOptionsObjectForAnimatingToCamera:(MGLMapCamera *)camera edgePadding:(NSEdgeInsets) edgePadding {
mbgl::CameraOptions options;
options.center = MGLLatLngFromLocationCoordinate2D(camera.centerCoordinate);
options.padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInsets);
options.padding = MGLEdgeInsetsFromNSEdgeInsets(edgePadding);
options.zoom = MGLZoomLevelForAltitude(camera.altitude, camera.pitch,
camera.centerCoordinate.latitude,
self.frame.size);
Expand Down Expand Up @@ -1267,6 +1272,15 @@ - (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds edg
return [self cameraForCameraOptions:cameraOptions];
}

- (MGLMapCamera *)cameraThatFitsShape:(MGLShape *)shape direction:(double)direction edgePadding:(NSEdgeInsets)insets {
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInsets);

mbgl::CameraOptions cameraOptions = _mbglMap->cameraForGeometry([shape geometryObject], padding, direction);

return [self cameraForCameraOptions:cameraOptions];
}

- (MGLMapCamera *)cameraForCameraOptions:(const mbgl::CameraOptions &)cameraOptions {
CLLocationCoordinate2D centerCoordinate = MGLLocationCoordinate2DFromLatLng(cameraOptions.center ? *cameraOptions.center : _mbglMap->getLatLng());
double zoomLevel = cameraOptions.zoom ? *cameraOptions.zoom : self.zoomLevel;
Expand Down

0 comments on commit 9e79659

Please sign in to comment.