[android][ios][macOS] Implement bindings for Map::cameraForGeometry. On macOS, also added -[MGLMapView setCamera: withDuration: animationTimingFunction: edgePadding: completionHandler:] for parity with iOS

This commit is contained in:
Asheem Mamoowala
2017-10-09 11:50:48 -07:00
parent df20b0cbec
commit 24bd336b88
11 changed files with 123 additions and 4 deletions

View File

@@ -59,6 +59,7 @@ Mapbox welcomes participation and contributions from everyone. If you'd like to
- build release package once during ci build [#9351](https://github.com/mapbox/mapbox-gl-native/pull/9351)
* 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)
* 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

View File

@@ -44,6 +44,7 @@ import com.mapbox.mapboxsdk.style.light.Light;
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;
@@ -1666,6 +1667,30 @@ public final class MapboxMap {
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
//

View File

@@ -29,6 +29,7 @@ import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException;
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;
@@ -232,6 +233,13 @@ final class NativeMapView {
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;
@@ -873,6 +881,8 @@ final class NativeMapView {
private native CameraPosition nativeGetCameraForLatLngBounds(LatLngBounds latLngBounds);
private native CameraPosition nativeGetCameraForGeometry(Geometry geometry, double bearing);
private native void nativeResetPosition();
private native double nativeGetPitch();

View File

@@ -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();
@@ -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"),

View File

@@ -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"
@@ -104,6 +105,8 @@ public:
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&);

View File

@@ -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

View File

@@ -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:(CLLocationDirection)direction edgePadding:(UIEdgeInsets)insets;
/**
Returns the point in this view’s coordinate system on which to "anchor" in
response to a user-initiated gesture.

View File

@@ -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"
@@ -3011,6 +3012,16 @@ public:
return [self cameraForCameraOptions:cameraOptions];
}
- (MGLMapCamera *)cameraThatFitsShape:(MGLShape *)shape direction:(CLLocationDirection)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());

View File

@@ -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

View File

@@ -10,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN
@class MGLAnnotationImage;
@class MGLMapCamera;
@class MGLStyle;
@class MGLShape;
@protocol MGLAnnotation;
@protocol MGLMapViewDelegate;
@@ -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
@@ -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:(CLLocationDirection)direction edgePadding:(NSEdgeInsets)insets;
/**
A Boolean value indicating whether the receiver automatically adjusts its
content insets.

View File

@@ -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"
@@ -1121,6 +1122,10 @@ public:
}
- (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));
@@ -1148,7 +1153,7 @@ public:
[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"];
}
@@ -1194,17 +1199,17 @@ public:
[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);
@@ -1267,6 +1272,15 @@ public:
return [self cameraForCameraOptions:cameraOptions];
}
- (MGLMapCamera *)cameraThatFitsShape:(MGLShape *)shape direction:(CLLocationDirection)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;