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

[core][macOS] Compute camera center and zoom for geometry with fixed heading #10107

Merged
merged 2 commits into from
Oct 9, 2017

Conversation

asheemmamoowala
Copy link
Contributor

Closes #9809

Implement a Map:: cameraForLatLngs variant that allows specifying a heading and returns CameraOptions with zoom, center, and angle.

@asheemmamoowala asheemmamoowala changed the title 9809 camera for geom [core][macOS] Compute camera center and zoom for geometry with fixed heading Oct 2, 2017
Copy link
Contributor

@jfirebaugh jfirebaugh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 core changes

Copy link
Contributor

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for running with this feature. In addition to the comments below, would you do the honors and add a blurb to the iOS and macOS changelogs?

@@ -10,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN
@class MGLAnnotationImage;
@class MGLMapCamera;
@class MGLStyle;
@class MGLShape;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make these changes to the iOS implementation of MGLMapView also? Thanks!

@param animated Specify `YES` to animate the change by smoothly scrolling and
zooming or `NO` to immediately display the given bounds.
*/
- (void)setVisibleShape:(MGLShape *)shape heading:(double)heading edgePadding:(NSEdgeInsets)insets animated:(BOOL)animated;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is reminiscent of -showAnnotation:, which also adds the passed-in annotation (which may be a shape) if it isn't already on the map. It might be nice to generalize that method with these additional parameters, but I'm not sure it's necessary to have one that only changes the camera, since the developer can readily compose -cameraThatFitsShape:heading:edgePadding: with -setCamera:animated:. The reason -setVisibleCoordinateBounds:edgePadding:animated: exists is that there's already a visibleCoordinateBounds property. But there isn't inherently a "visible shape" the way there's a visible coordinate bounds.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@1ec5 I added this method to help with testing in the macOS demo app. and didn't expect it to be added to the mobile SDKs. Maybe there is a case to add this functionality to -showAnnotation but I'd prefer to scope this PR down to just the -cameraTheFitsShape changes.
//cc @d-prukop

Copy link
Contributor

@1ec5 1ec5 Oct 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We try to keep the iOS and macOS SDKs as close as possible. In fact, there’s an entire project tracking macOS SDK parity with the iOS SDK, but it’s generally assumed that the iOS SDK would get new features first because it’s a bigger priority for Mapbox.

Ideally we would find a way to make -cameraThatFitsShape:heading:edgePadding: compatible with one of the -setCamera:… methods, perhaps -setCamera:withDuration:animationTimingFunction:edgePadding:completionHandler:, such that we could add the same method to both SDKs publicly.

Transform transform(impl->transform.getState());
transform.setAngle(angle);
CameraOptions options = mbgl::cameraForLatLngs(latLngs, transform, padding);
options.angle = angle;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value inherits the current pitch, but the developer may want to animate to an arbitrary pitch for the same reason that they'd want to animate to an arbitrary angle.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened this as a separate issue #10115. It depends on us first getting a fix for #2259.

}

CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, double heading, const EdgeInsets& padding) const {
double angle = -heading * util::DEG2RAD;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The convention throughout mbgl seems to be to use the term "angle" for what might be called "heading" or "bearing" elsewhere.

including the entire coordinate bounds. The camera object uses the current
direction and pitch.
*/
- (MGLMapCamera *)cameraThatFitsShape:(MGLShape *)shape heading:(double)heading edgePadding:(NSEdgeInsets)insets;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MGLMapView uses the term "direction" instead of "heading", because "heading" is part of a 3D camera system that's encapsulated in MGLMapCamera. If we allow the heading to be configured but not the pitch, we should use "direction" here for consistency with -setDirection:. On the other hand, if we make the pitch configurable, as suggested below, then this method might take a camera (as matchingCamera:) instead of separate heading and pitch parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given #2259, I didn't want to add pitch just yet.
👍 on direction

@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.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method doesn't use the current direction, and it includes the entire shape, not an entire coordinate bounds.

MGLShapeCollection *shapeCollection = (MGLShapeCollection *)shape;
for(MGLShape *s in shapeCollection.shapes) {
auto shapeLatLngs = coordinatesForShape(s);
latLngs.insert(latLngs.end(), shapeLatLngs.begin(), shapeLatLngs.end());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider having the mbgl::Map method take a Geometry; each MGLShape subclass already has an internal method for converting to a Geometry.

Copy link
Contributor

@1ec5 1ec5 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some final comments regarding the iOS and macOS changes. I’ll leave it to @tobrun to look at the Android side in detail.

@@ -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 and center computed to fit a shape. ([#10107](https://github.com/mapbox/mapbox-gl-native/pull/10107))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is MapboxMap::getCameraForGeometry() the right syntax for referring to an instance method in Java? I thought it was MapboxMap.getCameraForGeometry().

@@ -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:padding:]` to get a camera with zoom and center computed to fit a shape. ([#10107](https://github.com/mapbox/mapbox-gl-native/pull/10107))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We just branched for iOS SDK v3.7.0 and macOS SDK v0.6.0 (in release-agua). Would you mind retitling the “master” section and adding a new “master” section above it?

@@ -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:padding:]` to get a camera with zoom and center computed to fit a shape. ([#10107](https://github.com/mapbox/mapbox-gl-native/pull/10107))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The iOS and macOS SDKs always say “zoom level” and “center coordinate”, to differentiate from the act of zooming and the view’s center (point).

@param animated Specify `YES` to animate the change by smoothly scrolling and
zooming or `NO` to immediately display the given bounds.
*/
- (void)setVisibleShape:(MGLShape *)shape direction:(double)direction edgePadding:(NSEdgeInsets)insets animated:(BOOL)animated;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I continue to think this would be a poor API to expose publicly, per #10107 (comment). For one thing, it isn’t possible to customize the duration or timing function or provide a completion handler, all options that come with -setCamera:withDuration:animationTimingFunction:edgePadding:completionHandler: on iOS.

If it’s really necessary to achieve a padding-less camera fitting a shape, can we remove this method, replace it with -setCamera:withDuration:animationTimingFunction:edgePadding:completionHandler: from iOS, and use the following code to achieve the same effect for the time being?

MGLMapCamera *camera = [mapView cameraThatFitsShape:shape direction:direction edgePadding:edgePadding];
NSEdgeInsets edgePadding = contentInsets;
edgePadding.left *= -1; edgePadding.right *= -1; edgePadding.top *= -1; edgePadding.bottom *= -1;
[mapView setCamera:camera withDuration:5 animationTimingFunction:nil edgePadding:edgePadding completionHandler:nil];

@lilykaiser lilykaiser added the Core The cross-platform C++ core, aka mbgl label Oct 5, 2017
@@ -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:padding:]` 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))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should say edgePadding:, not padding:.

@tobrun
Copy link
Member

tobrun commented Oct 9, 2017

This is working great @asheemmamoowala 👍

ezgif com-video-to-gif 41

I might revisit the public api with overloaded methods (so bearing and padding are optional)
Let's ship this and iterate on it further.

Asheem Mamoowala added 2 commits October 9, 2017 11:04
…. On macOS, also added -[MGLMapView setCamera: withDuration: animationTimingFunction: edgePadding: completionHandler:] for parity with iOS
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Core The cross-platform C++ core, aka mbgl
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants