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

Offset map center #2600

Closed
maciekish opened this issue Oct 13, 2015 · 21 comments · Fixed by #3589
Closed

Offset map center #2600

maciekish opened this issue Oct 13, 2015 · 21 comments · Fixed by #3589
Assignees
Labels
Android Mapbox Maps SDK for Android feature iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS
Milestone

Comments

@maciekish
Copy link
Contributor

Hi,
Is it possible to easily offset what the map treats as it centre? We want the map to follow the users position more like a navigation app where the "car" is much lower on the screen so that you can see further ahead.

I've looked for a value that defines the center but wasn't able to find anything. We have our own fork so it doesn't matter what the change is as long as it's possible.

Thanks
Maciej

@picciano
Copy link

+1

@Zakay
Copy link

Zakay commented Oct 13, 2015

+1 Both Apple and Google uses this offset thing on their map apps. Would be very useful to have!

@ljbade ljbade added feature iOS Mapbox Maps SDK for iOS labels Oct 13, 2015
@ljbade
Copy link
Contributor

ljbade commented Oct 13, 2015

/cc @1ec5

@incanus
Copy link
Contributor

incanus commented Oct 15, 2015

Both Apple and Google uses this offset thing on their map apps.

Just to clarify, this is in their own user-facing apps, not their developer-facing frameworks.

But agree.

@1ec5
Copy link
Contributor

1ec5 commented Nov 9, 2015

This is in some ways blocked by #1041: currently “user tracking” consists of moving the user dot in response to user location changes, then synchronizing the map’s center point in response. A better approach would be to affix the user dot to a set location on-screen (usually the center point but in this case somewhere near the bottom) and pan the map directly in response to user location changes. The logic in -[MGLMapView locationManager:didUpdateLocations:] may need to be rewritten, especially due to tilting, which is typically used with course tracking mode.

@ljbade
Copy link
Contributor

ljbade commented Nov 9, 2015

@1ec5 Glueing the dot to the screen centre then moving the map was the approach @tobrun took in the Android code.

@RomainQuidet
Copy link
Contributor

Apple MapKit uses 2 APIs for this using insets:

  • (void)setVisibleMapRect:(MKMapRect)mapRect
    edgePadding:(UIEdgeInsets)insets
    animated:(BOOL)animate

and

  • (MKMapRect)mapRectThatFits:(MKMapRect)mapRect
    edgePadding:(UIEdgeInsets)insets

@1ec5
Copy link
Contributor

1ec5 commented Dec 9, 2015

We have -setVisibleCoordinateBounds:edgePadding:animated: already; a -coordinateBoundsThatFits:edgePadding: would certainly complement it. But I think this request is more about having MGLMapView offset the center when automatically panning due to user location tracking.

One thing I’m stuck on is how best to present this option to developers: should it be a percentage or an absolute pixel? Should we measure from the view’s edge to the annotation view’s edge, or to its center? The thought crossed my mind of allowing the annotation view to be constrained using Auto Layout – the map view would effectively pin the map view to the annotation – but maybe that’d be too difficult to work with.

@RomainQuidet
Copy link
Contributor

Ok, it's something not available on Apple MapKit. We have this feature on our map at Mappy, we just expose a property to users in the framework:
@Property (nonatomic, assign) UIEdgeInsets insets;

This inset is used when centering the map at coordinates or at the user position or when setting the region.
This allow users to offset the center easily, add other views above the map and keep the map's center where it should be.
Internal code is quite clean by using the insets property to compute the map center.

@1ec5
Copy link
Contributor

1ec5 commented Dec 9, 2015

So if you have course tracking on and want to push the puck down to the bottom, as depicted in #2600 (comment), you’d set a very large top inset, correct? That sounds reasonable. In fact, under the hood, we’ll want methods like -setCenterCoordinate: to respect an implicit top or bottom inset whenever there’s a top or bottom layout guide.

@RomainQuidet
Copy link
Contributor

Yes, it's working like that.
User defines a mapView frame, and then sets an inset. The frame displays a full map, centered on the inset rectangle center.

@1ec5
Copy link
Contributor

1ec5 commented Dec 14, 2015

Both the iOS and OS X versions of MGLMapView need this functionality regardless of the user tracking mode, because it’s common for there to be a translucent top bar overlay. On iOS, MGLMapView’s center should account for the top and bottom layout guides; on OS X, if the MGLMapView occupies the entire content view and the content view is full size, the center should account for the toolbar.

@bleege bleege added the Android Mapbox Maps SDK for Android label Dec 23, 2015
@lgeromegnace
Copy link

Hi, I'm working at Mappy.
I start working on this issue. I will try to apply the idea previously proposed by @RomainQuidet about using inset. I think mbgl::View interface could be the right place to hold the inset informations and let the Map use it to update the center correctly. This way it will benefit from both android and iOS platforms.
If it works we will make a pull-request.

@tobrun
Copy link
Member

tobrun commented Jan 11, 2016

From the Android side, this is something that should be tackled with #3276

@tobrun
Copy link
Member

tobrun commented Jan 12, 2016

To clarify above, I was looking at this from an Android View being overlaid on a Map,
@1ec5 is tackling this using mbgl, which is the correct way.

@1ec5 1ec5 self-assigned this Jan 14, 2016
1ec5 added a commit that referenced this issue Jan 15, 2016
Moved EdgeInsets to geo.hpp so CameraOptions and Transform can refer to it. Added a padding option to CameraOptions that alters the frame of reference for the center option. Added optional padding parameters to LatLng getters and setters.

Working towards #2600.
This was referenced Jan 15, 2016
@1ec5 1ec5 modified the milestones: ios-v3.1.0, ios-v3.2.0 Jan 16, 2016
1ec5 added a commit that referenced this issue Jan 17, 2016
Moved EdgeInsets to geo.hpp so CameraOptions and Transform can refer to it. Added a padding option to CameraOptions that alters the frame of reference for the center option. Added optional padding parameters to LatLng getters and setters.

Working towards #2600.
1ec5 added a commit that referenced this issue Jan 17, 2016
In user tracking mode, keep the user dot in a fixed location on screen, instead easing the map view so that the fixed location corresponds to the new user location. There is one exception: MGLMapView reacts to the first location update the same way as before, so that it appears to move to where the user dot has been all along.

In course tracking mode, weight the user dot down towards the bottom of the view, since it’s more important to see the road ahead than the road behind.

Fixes #2600, and #1041 to some extent.
@1ec5
Copy link
Contributor

1ec5 commented Jan 17, 2016

#3583 adds content insets and shifts the map’s visual center point to account for any translucent top and bottom bars.

#3589 pushes the visual center even further downward in course tracking mode. Note that in both Apple’s Maps application and Google Maps, the user puck is only offset in turn-by-turn mode, but not before you complete the first step (e.g., leaving the parking lot). So the puck’s position will be configurable.

1ec5 added a commit that referenced this issue Jan 19, 2016
Moved EdgeInsets to geo.hpp so CameraOptions and Transform can refer to it. Added a padding option to CameraOptions that alters the frame of reference for the center option. Added optional padding parameters to LatLng getters and setters.

Working towards #2600.
1ec5 added a commit that referenced this issue Jan 19, 2016
In user tracking mode, keep the user dot in a fixed location on screen, instead easing the map view so that the fixed location corresponds to the new user location. There is one exception: MGLMapView reacts to the first location update the same way as before, so that it appears to move to where the user dot has been all along.

In course tracking mode, weight the user dot down towards the bottom of the view, since it’s more important to see the road ahead than the road behind.

Fixes #2600, and #1041 to some extent.
1ec5 added a commit that referenced this issue Jan 20, 2016
In user tracking mode, keep the user dot in a fixed location on screen, instead easing the map view so that the fixed location corresponds to the new user location. There is one exception: MGLMapView reacts to the first location update the same way as before, so that it appears to move to where the user dot has been all along.

In course tracking mode, weight the user dot down towards the bottom of the view, since it’s more important to see the road ahead than the road behind.

Fixes #2600, and #1041 to some extent.
1ec5 added a commit that referenced this issue Jan 20, 2016
In user tracking mode, keep the user dot in a fixed location on screen, instead easing the map view so that the fixed location corresponds to the new user location. There is one exception: MGLMapView reacts to the first location update the same way as before, so that it appears to move to where the user dot has been all along.

In course tracking mode, weight the user dot down towards the bottom of the view, since it’s more important to see the road ahead than the road behind.

Fixes #2600, and #1041 to some extent.
1ec5 added a commit that referenced this issue Jan 20, 2016
In user tracking mode, keep the user dot in a fixed location on screen, instead easing the map view so that the fixed location corresponds to the new user location. There is one exception: MGLMapView reacts to the first location update the same way as before, so that it appears to move to where the user dot has been all along.

In course tracking mode, weight the user dot down towards the bottom of the view, since it’s more important to see the road ahead than the road behind.

Fixes #2600, and #1041 to some extent.
@1ec5 1ec5 removed the in progress label Jan 20, 2016
@1ec5
Copy link
Contributor

1ec5 commented Apr 22, 2016

We have -setVisibleCoordinateBounds:edgePadding:animated: already; a -coordinateBoundsThatFits:edgePadding: would certainly complement it.

Implemented in #4790.

@leonardodev
Copy link

  • (void)mapView:(MKMapView*)mapView didSelectAnnotationView:(YLAnnotationView*)pinView
    {
    [self moveCenterByOffset:CGPointMake(0, -100) from:pAnnotation.coordinate];
    }

where

  • (void)moveCenterByOffset:(CGPoint)offset from:(CLLocationCoordinate2D)coordinate
    {
    CGPoint point = [self.oMapView convertCoordinate:coordinate toPointToView:self.oMapView];
    point.x += offset.x;
    point.y += offset.y;
    CLLocationCoordinate2D center = [self.oMapView convertPoint:point toCoordinateFromView:self.oMapView];
    [self.oMapView setCenterCoordinate:center animated:YES];
    }

@1ec5
Copy link
Contributor

1ec5 commented Jan 16, 2018

@leonardodev, panning to fit a selected annotation is unrelated to this issue, but it would be great for the SDK to have that functionality built in: #3249.

@Michael11358
Copy link

@leonardodev Great solution, but it doesn't take into account different zoom levels. If I'm on a different zoom level, the coordinate point messes up. Any suggestions to fix that?

@surfnrad
Copy link

I'm confused about whether this was answered for Android. It seems that it was achieved as a feature for iOS. Any insights to Android, particularly Kotlin? Is this possible with Mapbox Maps SDK or is it necessary to switch to Navigation UI?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Android Mapbox Maps SDK for Android feature iOS Mapbox Maps SDK for iOS macOS Mapbox Maps SDK for macOS
Projects
None yet
Development

Successfully merging a pull request may close this issue.

14 participants