[core, ios, osx] cameraThatFitsCoordinateBounds
Added an API to get a camera that you can pass into -[MGLMapView setCamera:] that fits the given coordinate bounds, by analogy with -[MKMapView regionThatFits:] or -[MKMapView mapRectThatFits:edgePadding:]. Added mbgl::Map::getCameraOptions() for getting the current camera options more conveniently.
This commit is contained in:
committed by
Minh Nguyễn
parent
5939dd5b41
commit
466ed55200
@@ -69,6 +69,7 @@ public:
|
||||
bool isPanning() const;
|
||||
|
||||
// Camera
|
||||
CameraOptions getCameraOptions(optional<EdgeInsets>) const;
|
||||
void jumpTo(const CameraOptions&);
|
||||
void easeTo(const CameraOptions&, const AnimationOptions&);
|
||||
void flyTo(const CameraOptions&, const AnimationOptions&);
|
||||
@@ -90,8 +91,8 @@ public:
|
||||
double getZoom() const;
|
||||
void setLatLngZoom(const LatLng&, double zoom, const Duration& = Duration::zero());
|
||||
void setLatLngZoom(const LatLng&, double zoom, optional<EdgeInsets>, const Duration& = Duration::zero());
|
||||
CameraOptions cameraForLatLngBounds(const LatLngBounds&, optional<EdgeInsets>);
|
||||
CameraOptions cameraForLatLngs(const std::vector<LatLng>&, optional<EdgeInsets>);
|
||||
CameraOptions cameraForLatLngBounds(const LatLngBounds&, optional<EdgeInsets>) const;
|
||||
CameraOptions cameraForLatLngs(const std::vector<LatLng>&, optional<EdgeInsets>) const;
|
||||
void resetZoom();
|
||||
void setMinZoom(const double minZoom);
|
||||
double getMinZoom() const;
|
||||
|
||||
@@ -13,6 +13,7 @@ Mapbox welcomes participation and contributions from everyone. Please read [CON
|
||||
- Rendering now occurs on the main thread, fixing a hang when calling `-[MGLMapView styleURL]` before the map view has fully loaded or while the application is in the background. ([#2909](https://github.com/mapbox/mapbox-gl-native/pull/2909))
|
||||
- Added category methods on NSValue for converting to and from the structure types defined in MGLGeometry.h. ([#4802](https://github.com/mapbox/mapbox-gl-native/pull/4802))
|
||||
- Added NSFormatter subclasses for converting geographic coordinates and directions into display strings. ([#4802](https://github.com/mapbox/mapbox-gl-native/pull/4802))
|
||||
- Added a new method, `-[MGLMapView cameraThatFitsCoordinateBounds:]`, to get a camera that you can pass into `-setCamera:` that fits the given coordinate bounds. ([#4790](https://github.com/mapbox/mapbox-gl-native/pull/4790))
|
||||
- Added a `-reloadStyle:` action to MGLMapView to force a reload of the current style. ([#4728](https://github.com/mapbox/mapbox-gl-native/pull/4728))
|
||||
- A more specific user agent string is now sent with style and tile requests. ([#4012](https://github.com/mapbox/mapbox-gl-native/pull/4012))
|
||||
- Mapbox Telemetry is automatically disabled while the host application is running in the iOS Simulator. ([#4726](https://github.com/mapbox/mapbox-gl-native/pull/4726))
|
||||
|
||||
@@ -732,6 +732,31 @@ IB_DESIGNABLE
|
||||
*/
|
||||
- (void)flyToCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration peakAltitude:(CLLocationDistance)peakAltitude completionHandler:(nullable void (^)(void))completion;
|
||||
|
||||
/**
|
||||
Returns the camera that best fits the given coordinate bounds.
|
||||
|
||||
@param bounds The coordinate bounds to fit to the receiver’s viewport.
|
||||
@return A camera object centered on the same location as the coordinate
|
||||
bounds with zoom level as high (close to the ground) as possible while still
|
||||
including the entire coordinate bounds. The camera object uses the current
|
||||
direction and pitch.
|
||||
*/
|
||||
- (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds;
|
||||
|
||||
/**
|
||||
Returns the camera that best fits the given coordinate bounds, optionally with
|
||||
some additional padding on each side.
|
||||
|
||||
@param bounds The coordinate bounds to fit to the receiver’s viewport.
|
||||
@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 same location as the coordinate bounds
|
||||
with zoom level as high (close to the ground) as possible while still
|
||||
including the entire coordinate bounds. The camera object uses the current
|
||||
direction and pitch.
|
||||
*/
|
||||
- (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(UIEdgeInsets)insets;
|
||||
|
||||
/**
|
||||
The distance from the edges of the map view’s frame to the edges of the map
|
||||
view’s logical viewport.
|
||||
|
||||
@@ -2023,14 +2023,8 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
|
||||
|
||||
- (MGLMapCamera *)camera
|
||||
{
|
||||
CGFloat pitch = _mbglMap->getPitch();
|
||||
CLLocationDistance altitude = MGLAltitudeForZoomLevel(self.zoomLevel, pitch,
|
||||
self.centerCoordinate.latitude,
|
||||
self.frame.size);
|
||||
return [MGLMapCamera cameraLookingAtCenterCoordinate:self.centerCoordinate
|
||||
fromDistance:altitude
|
||||
pitch:pitch
|
||||
heading:self.direction];
|
||||
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInset);
|
||||
return [self cameraForCameraOptions:_mbglMap->getCameraOptions(padding)];
|
||||
}
|
||||
|
||||
- (void)setCamera:(MGLMapCamera *)camera
|
||||
@@ -2130,6 +2124,29 @@ mbgl::Duration MGLDurationInSeconds(NSTimeInterval duration)
|
||||
[self didChangeValueForKey:@"camera"];
|
||||
}
|
||||
|
||||
- (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds
|
||||
{
|
||||
return [self cameraThatFitsCoordinateBounds:bounds edgePadding:UIEdgeInsetsZero];
|
||||
}
|
||||
|
||||
- (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(UIEdgeInsets)insets
|
||||
{
|
||||
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
|
||||
padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInset);
|
||||
mbgl::CameraOptions cameraOptions = _mbglMap->cameraForLatLngBounds(MGLLatLngBoundsFromCoordinateBounds(bounds), padding);
|
||||
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;
|
||||
CLLocationDirection direction = cameraOptions.angle ? *cameraOptions.angle : self.direction;
|
||||
CGFloat pitch = cameraOptions.pitch ? *cameraOptions.pitch : _mbglMap->getPitch();
|
||||
CLLocationDistance altitude = MGLAltitudeForZoomLevel(zoomLevel, pitch, centerCoordinate.latitude, self.frame.size);
|
||||
return [MGLMapCamera cameraLookingAtCenterCoordinate:centerCoordinate fromDistance:altitude pitch:pitch heading:direction];
|
||||
}
|
||||
|
||||
/// Returns a CameraOptions object that specifies parameters for animating to
|
||||
/// the given camera.
|
||||
- (mbgl::CameraOptions)cameraOptionsObjectForAnimatingToCamera:(MGLMapCamera *)camera edgePadding:(UIEdgeInsets)insets
|
||||
|
||||
@@ -325,6 +325,41 @@ IB_DESIGNABLE
|
||||
and zooming or `NO` to immediately display the given bounds. */
|
||||
- (void)setVisibleCoordinateBounds:(MGLCoordinateBounds)bounds animated:(BOOL)animated;
|
||||
|
||||
/** Changes the receiver’s viewport to fit the given coordinate bounds and
|
||||
optionally some additional padding on each side.
|
||||
|
||||
@param bounds The bounds that the viewport will show in its entirety.
|
||||
@param insets The minimum padding (in screen points) that will be visible
|
||||
around the given coordinate bounds.
|
||||
@param animated Specify `YES` to animate the change by smoothly scrolling and
|
||||
zooming or `NO` to immediately display the given bounds.
|
||||
*/
|
||||
- (void)setVisibleCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(NSEdgeInsets)insets animated:(BOOL)animated;
|
||||
|
||||
/** Returns the camera that best fits the given coordinate bounds.
|
||||
|
||||
@param bounds The coordinate bounds to fit to the receiver’s viewport.
|
||||
@return A camera object centered on the same location as the coordinate
|
||||
bounds with zoom level as high (close to the ground) as possible while
|
||||
still including the entire coordinate bounds. The camera object uses the
|
||||
current direction and pitch.
|
||||
*/
|
||||
- (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds;
|
||||
|
||||
/** Returns the camera that best fits the given coordinate bounds, optionally
|
||||
with some additional padding on each side.
|
||||
|
||||
@param bounds The coordinate bounds to fit to the receiver’s viewport.
|
||||
@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 same location as the coordinate
|
||||
bounds with zoom level as high (close to the ground) as possible while
|
||||
still including the entire coordinate bounds. The camera object uses the
|
||||
current direction and pitch.
|
||||
*/
|
||||
- (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(NSEdgeInsets)insets;
|
||||
|
||||
/** A Boolean value indicating whether the receiver automatically adjusts its
|
||||
content insets.
|
||||
|
||||
|
||||
@@ -284,7 +284,6 @@
|
||||
DA839E891CC2E3400062CAFB = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DAE6C3C31CC31F6900DB3429 /* Configuration */,
|
||||
DA839E941CC2E3400062CAFB /* Demo App */,
|
||||
DAE6C3291CC30DB200DB3429 /* SDK */,
|
||||
DAE6C3371CC30DB200DB3429 /* SDK Tests */,
|
||||
@@ -461,13 +460,6 @@
|
||||
name = Kit;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DAE6C3C31CC31F6900DB3429 /* Configuration */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
name = Configuration;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DAE6C3C41CC31F7800DB3429 /* Configuration */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
||||
@@ -1003,14 +1003,8 @@ public:
|
||||
}
|
||||
|
||||
- (MGLMapCamera *)camera {
|
||||
CGFloat pitch = _mbglMap->getPitch();
|
||||
CLLocationDistance altitude = MGLAltitudeForZoomLevel(self.zoomLevel, pitch,
|
||||
self.centerCoordinate.latitude,
|
||||
self.frame.size);
|
||||
return [MGLMapCamera cameraLookingAtCenterCoordinate:self.centerCoordinate
|
||||
fromDistance:altitude
|
||||
pitch:pitch
|
||||
heading:self.direction];
|
||||
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInsets);
|
||||
return [self cameraForCameraOptions:_mbglMap->getCameraOptions(padding)];
|
||||
}
|
||||
|
||||
- (void)setCamera:(MGLMapCamera *)camera {
|
||||
@@ -1142,6 +1136,31 @@ public:
|
||||
_mbglMap->easeTo(cameraOptions, animationOptions);
|
||||
}
|
||||
|
||||
- (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds {
|
||||
return [self cameraThatFitsCoordinateBounds:bounds edgePadding:NSEdgeInsetsZero];
|
||||
}
|
||||
|
||||
- (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(NSEdgeInsets)insets {
|
||||
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
|
||||
padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInsets);
|
||||
mbgl::CameraOptions cameraOptions = _mbglMap->cameraForLatLngBounds(MGLLatLngBoundsFromCoordinateBounds(bounds), padding);
|
||||
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;
|
||||
CLLocationDirection direction = cameraOptions.angle ? *cameraOptions.angle : self.direction;
|
||||
CGFloat pitch = cameraOptions.pitch ? *cameraOptions.pitch : _mbglMap->getPitch();
|
||||
CLLocationDistance altitude = MGLAltitudeForZoomLevel(zoomLevel, pitch,
|
||||
centerCoordinate.latitude,
|
||||
self.frame.size);
|
||||
return [MGLMapCamera cameraLookingAtCenterCoordinate:centerCoordinate
|
||||
fromDistance:altitude
|
||||
pitch:pitch
|
||||
heading:direction];
|
||||
}
|
||||
|
||||
- (void)setAutomaticallyAdjustsContentInsets:(BOOL)automaticallyAdjustsContentInsets {
|
||||
_automaticallyAdjustsContentInsets = automaticallyAdjustsContentInsets;
|
||||
[self adjustContentInsets];
|
||||
|
||||
@@ -375,6 +375,10 @@ bool Map::isPanning() const {
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
CameraOptions Map::getCameraOptions(optional<EdgeInsets> padding) const {
|
||||
return impl->transform.getCameraOptions(padding);
|
||||
}
|
||||
|
||||
void Map::jumpTo(const CameraOptions& camera) {
|
||||
impl->transform.jumpTo(camera);
|
||||
@@ -466,7 +470,7 @@ void Map::setLatLngZoom(const LatLng& latLng, double zoom, optional<EdgeInsets>
|
||||
update(Update::RecalculateStyle);
|
||||
}
|
||||
|
||||
CameraOptions Map::cameraForLatLngBounds(const LatLngBounds& bounds, optional<EdgeInsets> padding) {
|
||||
CameraOptions Map::cameraForLatLngBounds(const LatLngBounds& bounds, optional<EdgeInsets> padding) const {
|
||||
AnnotationSegment segment = {
|
||||
bounds.northwest(),
|
||||
bounds.southwest(),
|
||||
@@ -476,7 +480,7 @@ CameraOptions Map::cameraForLatLngBounds(const LatLngBounds& bounds, optional<Ed
|
||||
return cameraForLatLngs(segment, padding);
|
||||
}
|
||||
|
||||
CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, optional<EdgeInsets> padding) {
|
||||
CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, optional<EdgeInsets> padding) const {
|
||||
CameraOptions options;
|
||||
if (latLngs.empty()) {
|
||||
return options;
|
||||
|
||||
@@ -62,6 +62,16 @@ bool Transform::resize(const std::array<uint16_t, 2> size) {
|
||||
|
||||
#pragma mark - Camera
|
||||
|
||||
CameraOptions Transform::getCameraOptions(optional<EdgeInsets> padding) const {
|
||||
CameraOptions camera;
|
||||
camera.center = getLatLng(padding);
|
||||
camera.padding = padding;
|
||||
camera.zoom = getZoom();
|
||||
camera.angle = getAngle();
|
||||
camera.pitch = getPitch();
|
||||
return camera;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change any combination of center, zoom, bearing, and pitch, without
|
||||
* a transition. The map will retain the current values for any options
|
||||
|
||||
@@ -26,6 +26,8 @@ public:
|
||||
bool resize(std::array<uint16_t, 2> size);
|
||||
|
||||
// Camera
|
||||
/** Returns the current camera options. */
|
||||
CameraOptions getCameraOptions(optional<EdgeInsets>) const;
|
||||
|
||||
/** Instantaneously, synchronously applies the given camera options. */
|
||||
void jumpTo(const CameraOptions&);
|
||||
|
||||
Reference in New Issue
Block a user