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

MGLMapCamera(lookingAtCenter:, fromDistance:, pitch:, heading:) is not respecting content insets properly. #12728

Closed
3 of 4 tasks
Gerungofulus opened this issue Aug 23, 2018 · 5 comments · Fixed by #14664
Closed
3 of 4 tasks
Labels
bug Core The cross-platform C++ core, aka mbgl navigation For the Mapbox Navigation SDK for Android or iOS or navigation use cases in general

Comments

@Gerungofulus
Copy link

Gerungofulus commented Aug 23, 2018

Steps to reproduce

  1. Set the content insets with a high (but not invalid) right inset. I tested it with a right inset of 370 in landscape mode.
  2. Use MGLMapCamera(lookingAtCenter:, fromDistance:, pitch:, heading:) to create a new camera looking at some coordinate. I used distance 1840, pitch 60, heading 184.
  3. Call fly(to: newCamera, withDuration: 1.25, completionHandler: nil) with the new camera

Expected behavior

  • The center coordinate is located in the center of the area of the view minus the insets
  • The pitch is set correctly
  • The distance is set correctly
  • A marker oriented into a special direction put right at the center coordinate should point up. In other words: The vanishing point should be located right above the new center coordinate, but it is still located in the center of the view, even though the content insets are set properly. (please see the image below. I also added text to the two crosses)

Configuration

Mapbox SDK versions:
4.2.0
iOS/macOS versions:
11.4.1 (15G77)
Device/simulator models:
iPhone 6s+ in Landscape
Xcode version:
9.4.1 (9F2000)
img_02c88c9455d2-1

@friedbunny friedbunny added bug iOS Mapbox Maps SDK for iOS labels Aug 24, 2018
@1ec5
Copy link
Contributor

1ec5 commented Sep 13, 2018

fly(to:withDuration:completionHandler:) does seem to apply the content insets:

mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:self.contentInsets];
options.padding = MGLEdgeInsetsFromNSEdgeInsets(edgePadding);
ScreenCoordinate center = getScreenCoordinate(padding);
center.y = state.size.height - center.y;

However, I think the problem you’ve identified is that the vanishing point is always located at the center-top of the view. Core GL doesn’t offer any way to move the vanishing point; ultimately, edge insets are implemented by changing the frame of reference for a center coordinate.

/cc @ansis @brunoabinader @d-prukop

@1ec5 1ec5 added Core The cross-platform C++ core, aka mbgl navigation For the Mapbox Navigation SDK for Android or iOS or navigation use cases in general and removed iOS Mapbox Maps SDK for iOS labels Sep 13, 2018
@1ec5
Copy link
Contributor

1ec5 commented Sep 13, 2018

The workaround in @Gerungofulus’s case is to reduce the map view’s width to avoid the area taken up by the right panel. This only works because the right panel appears to be opaque and takes up the whole right side of the map view.

In cases where the panel is translucent or doesn’t extend to the top and bottom edges of the window, a rather unsatisfying workaround would be to extend the map view further to the left, beyond the left edge of the containing view, until the vanishing point shifts sufficiently to the left.

@stale stale bot added the archived Archived because of inactivity label Mar 12, 2019
@stale
Copy link

stale bot commented Mar 12, 2019

This issue has been automatically detected as stale because it has not had recent activity and will be archived. Thank you for your contributions.

@stale stale bot closed this as completed Mar 12, 2019
@1ec5
Copy link
Contributor

1ec5 commented Mar 22, 2019

In cases where the panel is translucent or doesn’t extend to the top and bottom edges of the window, a rather unsatisfying workaround would be to extend the map view further to the left, beyond the left edge of the containing view, until the vanishing point shifts sufficiently to the left.

This is the rather unsatisfying workaround we’ve settled on in the navigation SDK’s CarPlay integration: mapbox/mapbox-navigation-ios#1845.

However, I think the problem you’ve identified is that the vanishing point is always located at the center-top of the view. Core GL doesn’t offer any way to move the vanishing point; ultimately, edge insets are implemented by changing the frame of reference for a center coordinate.

Configuring the vanishing point is an important feature for navigation use cases. It’s common for landscape layouts to overlay a large sidebar that doesn’t completely obscure the map but does shift the horizontal center visually.

@1ec5 1ec5 reopened this Mar 22, 2019
@stale stale bot removed the archived Archived because of inactivity label Mar 22, 2019
astojilj added a commit that referenced this issue May 14, 2019
The change is implemented in TransformState::getProjMatrix, the rest of the code is making sure that existing API contracts stay and there are tests verifyingrendering and render query processing only items within screen and given tolerance around screen edges.

MapView: don't bake edge insets into relalculated camera center. Keep edge insets as property of camera in TransformState (similar to pitch, zoom, bearing) independent from specified camera center. Interpolate edge insets in animation.

iOS Demo app: "Turn On/Off Content Insets" pitch the camera and navigate to convenient location in Denver, where streets are parallel to cardinal directions, to illustrate viewport center offset when edge insets are set.

Tests:
ViewFrustumCulling: although Annotations are deprecated, queryRenderedFeatures related tests in Annotations would need to get ported and decided to add the edge insets related query tests next to them. Verify frustum culling (render+queryRenderedFeatures) With different camera and edge insets setups. TODO: port Annotations tests.

Transform.Padding: Verify that coordinates take proper place on screen after applying edge insets.

LocalGlyphRasterizer: verify text rendering when applying padding.

Related to #11882: both use projection matrix elements [8] and [9].

Alternative approach to this was to increase and offset map origin so that the screen would be a sub-rectangle in larger map viewport. This approach has a drawback of unecessary processing the items that are outside screen area.

Fixes #12107, #12728, navigation-sdks/issues/120
@astojilj
Copy link
Contributor

In cases where the panel is translucent or doesn’t extend to the top and bottom edges of the window, a rather unsatisfying workaround would be to extend the map view further to the left, beyond the left edge of the containing view, until the vanishing point shifts sufficiently to the left.

This is the rather unsatisfying workaround we’ve settled on in the navigation SDK’s CarPlay integration: mapbox/mapbox-navigation-ios#1845.

This is fixed in #14664.
It's waiting for review.
Note that current "workaround" should keep functioning as intended after the PR #14664 lands - if navigation-ios is just enlarging the view and offsetting it.
If MGLMapView.contentInset is specified, center of perspective, and the user puck, will always be centered in the center of content area specified by contentInset; vanishing point would be above it.

astojilj added a commit that referenced this issue May 28, 2019
The change is implemented in TransformState::getProjMatrix, the rest of the code is making sure that existing API contracts stay and there are tests verifyingrendering and render query processing only items within screen and given tolerance around screen edges.

MapView: don't bake edge insets into relalculated camera center. Keep edge insets as property of camera in TransformState (similar to pitch, zoom, bearing) independent from specified camera center. Interpolate edge insets in animation.

iOS Demo app: "Turn On/Off Content Insets" pitch the camera and navigate to convenient location in Denver, where streets are parallel to cardinal directions, to illustrate viewport center offset when edge insets are set.

Tests:
ViewFrustumCulling: although Annotations are deprecated, queryRenderedFeatures related tests in Annotations would need to get ported and decided to add the edge insets related query tests next to them. Verify frustum culling (render+queryRenderedFeatures) With different camera and edge insets setups. TODO: port Annotations tests.

Transform.Padding: Verify that coordinates take proper place on screen after applying edge insets.

LocalGlyphRasterizer: verify text rendering when applying padding.

Related to #11882: both use projection matrix elements [8] and [9].

Alternative approach to this was to increase and offset map origin so that the screen would be a sub-rectangle in larger map viewport. This approach has a drawback of unecessary processing the items that are outside screen area.

Fixes #12107, #12728, navigation-sdks/issues/120
astojilj added a commit that referenced this issue May 28, 2019
The change is implemented in TransformState::getProjMatrix, the rest of the code is making sure that existing API contracts stay and there are tests verifyingrendering and render query processing only items within screen and given tolerance around screen edges.

MapView: don't bake edge insets into relalculated camera center. Keep edge insets as property of camera in TransformState (similar to pitch, zoom, bearing) independent from specified camera center. Interpolate edge insets in animation.

iOS Demo app: "Turn On/Off Content Insets" pitch the camera and navigate to convenient location in Denver, where streets are parallel to cardinal directions, to illustrate viewport center offset when edge insets are set.

Tests:
ViewFrustumCulling: although Annotations are deprecated, queryRenderedFeatures related tests in Annotations would need to get ported and decided to add the edge insets related query tests next to them. Verify frustum culling (render+queryRenderedFeatures) With different camera and edge insets setups. TODO: port Annotations tests.

Transform.Padding: Verify that coordinates take proper place on screen after applying edge insets.

LocalGlyphRasterizer: verify text rendering when applying padding.

Related to #11882: both use projection matrix elements [8] and [9].

Alternative approach to this was to increase and offset map origin so that the screen would be a sub-rectangle in larger map viewport. This approach has a drawback of unecessary processing the items that are outside screen area.

Fixes #12107, #12728, navigation-sdks/issues/120
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Core The cross-platform C++ core, aka mbgl navigation For the Mapbox Navigation SDK for Android or iOS or navigation use cases in general
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants