Skip to content
This repository was 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
asheemmamoowala merged 2 commits into
masterfrom
9809-camera-for-geom
Oct 9, 2017
Merged

[core][macOS] Compute camera center and zoom for geometry with fixed heading#10107
asheemmamoowala merged 2 commits into
masterfrom
9809-camera-for-geom

Conversation

@asheemmamoowala
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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?

@class MGLAnnotationImage;
@class MGLMapCamera;
@class MGLStyle;
@class MGLShape;
Copy link
Copy Markdown
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!

Comment thread platform/macos/src/MGLMapView.h Outdated
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.
*/
Copy link
Copy Markdown
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
Copy Markdown
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
Copy Markdown
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.

Comment thread src/mbgl/map/map.cpp Outdated
Transform transform(impl->transform.getState());
transform.setAngle(angle);
CameraOptions options = mbgl::cameraForLatLngs(latLngs, transform, padding);
options.angle = angle;
Copy link
Copy Markdown
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
Copy Markdown
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.

Comment thread src/mbgl/map/map.cpp Outdated
}

CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, double heading, const EdgeInsets& padding) const {
double angle = -heading * util::DEG2RAD;
Copy link
Copy Markdown
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.

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
Copy Markdown
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
Copy Markdown
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

Comment thread platform/macos/src/MGLMapView.h Outdated
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
Copy link
Copy Markdown
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.

Comment thread platform/macos/src/MGLMapView.mm Outdated
MGLShapeCollection *shapeCollection = (MGLShapeCollection *)shape;
for(MGLShape *s in shapeCollection.shapes) {
auto shapeLatLngs = coordinatesForShape(s);
latLngs.insert(latLngs.end(), shapeLatLngs.begin(), shapeLatLngs.end());
Copy link
Copy Markdown
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.

@asheemmamoowala asheemmamoowala requested a review from tobrun October 4, 2017 22:07
Copy link
Copy Markdown
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.

Comment thread platform/android/CHANGELOG.md Outdated
Copy link
Copy Markdown
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().

Comment thread platform/ios/CHANGELOG.md Outdated
Copy link
Copy Markdown
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?

Comment thread platform/macos/CHANGELOG.md Outdated
Copy link
Copy Markdown
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).

Comment thread platform/macos/src/MGLMapView.h Outdated
Copy link
Copy Markdown
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
Comment thread platform/ios/CHANGELOG.md Outdated
* 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
Copy Markdown
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
Copy Markdown
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
@asheemmamoowala asheemmamoowala merged commit 9e79659 into master Oct 9, 2017
@asheemmamoowala asheemmamoowala deleted the 9809-camera-for-geom branch October 9, 2017 18:42
@Guardiola31337 Guardiola31337 mentioned this pull request Oct 19, 2017
20 tasks
@Guardiola31337 Guardiola31337 mentioned this pull request Oct 26, 2017
20 tasks
@tobrun tobrun mentioned this pull request Nov 3, 2017
21 tasks
This was referenced Nov 14, 2017
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.

6 participants