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

[WIP] Configurable degrees of freedom for annotation views #5245

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/mbgl/map/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class Image;
class Style;
} // namespace style

using mat4 = std::array<double, 16>;

class Map : private util::noncopyable {
public:
explicit Map(Backend&,
Expand Down Expand Up @@ -139,6 +141,7 @@ class Map : private util::noncopyable {
// Projection
ScreenCoordinate pixelForLatLng(const LatLng&) const;
LatLng latLngForPixel(const ScreenCoordinate&) const;
void getProjMatrix(mat4& matrix, uint16_t nearZ = 1) const;

// Annotations
void addAnnotationImage(std::unique_ptr<style::Image>);
Expand Down
1 change: 1 addition & 0 deletions platform/ios/Mapbox.playground/Contents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class MapDelegate: NSObject, MGLMapViewDelegate {
let av = PlaygroundAnnotationView(reuseIdentifier: "annotation")
av.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
av.centerOffset = CGVector(dx: -15, dy: -15)
av.freeAxes = .X;
let centerView = UIView(frame: CGRectInset(av.bounds, 3, 3))
centerView.backgroundColor = UIColor.whiteColor()
av.addSubview(centerView)
Expand Down
4 changes: 2 additions & 2 deletions platform/ios/app/MBXAnnotationView.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ - (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];

self.layer.borderColor = selected ? [UIColor blackColor].CGColor : [UIColor whiteColor].CGColor;
self.layer.borderWidth = selected ? 2.0 : 0;
self.layer.borderColor = selected ? [UIColor blackColor].CGColor : [UIColor blueColor].CGColor;
self.layer.borderWidth = selected ? 2.0 : 1.0;
}

- (void)setDragState:(MGLAnnotationViewDragState)dragState animated:(BOOL)animated
Expand Down
11 changes: 9 additions & 2 deletions platform/ios/app/MBXViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -1711,23 +1711,30 @@ - (MGLAnnotationView *)mapView:(MGLMapView *)mapView viewForAnnotation:(id<MGLAn
if (!annotationView)
{
annotationView = [[MBXAnnotationView alloc] initWithReuseIdentifier:MBXViewControllerAnnotationViewReuseIdentifer];
annotationView.frame = CGRectMake(0, 0, 10, 10);
annotationView.frame = CGRectMake(0, 0, 30, 30);
annotationView.backgroundColor = [UIColor whiteColor];
annotationView.layer.borderColor = [UIColor blueColor].CGColor;
annotationView.layer.borderWidth = 2;
annotationView.layer.cornerRadius = 4;

// Note that having two long press gesture recognizers on overlapping
// views (`self.view` & `annotationView`) will cause weird behaviour.
// Comment out the pin dropping functionality in the handleLongPress:
// method in this class to make draggable annotation views play nice.
annotationView.draggable = YES;

// uncomment to lay the annotation view flat against the map when the map is tilted
// this currently causes severe performance issues when more than 2k annotations are visible
// annotationView.freeAxes = MGLAnnotationViewBillboardAxisX;

// Uncomment to force annotation view to maintain a constant size when
// the map is tilted. By default, annotation views will shrink and grow
// as they move towards and away from the horizon. Relatedly, annotations
// backed by GL sprites currently ONLY scale with viewing distance.
// annotationView.scalesWithViewingDistance = NO;
} else {
// orange indicates that the annotation view was reused
annotationView.backgroundColor = [UIColor orangeColor];
annotationView.layer.borderColor = [UIColor orangeColor].CGColor;
}
return annotationView;
}
Expand Down
79 changes: 66 additions & 13 deletions platform/ios/src/MGLAnnotationView.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,57 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) {
MGLAnnotationViewDragStateEnding,
};

/**
Options for locking the orientation of an `MGLAnnotationView` along one or more
axes for a billboard effect.
*/
typedef NS_OPTIONS(NSUInteger, MGLAnnotationViewBillboardAxis)
{
/**
Orients the annotation view such that its x-axis is always fixed with
respect to the map.

If this option is unset, the annotation view remains unchanged as the map’s
pitch increases, so that the view appears to stand upright on the tilted
map. If this option is set, the annotation view tilts as the map’s pitch
increases, so that the view appears to lie flat against the tilted map.

For example, you would set this option if the annotation view depicts an
arrow that should always point due south. You would unset this option if
the arrow should always point down towards the ground.
*/
MGLAnnotationViewBillboardAxisX = 0x1 << 0,

/**
Orients the annotation view such that its y-axis is always fixed with
respect to the map.

If this option is unset, the annotation view remains unchanged as the map
is rotated. If this option is set, the annotation view rotates as the map
rotates.

For example, you would set this option if the annotation view should be
aligned with a street, regardless of the direction from which the user
views the street.
*/
MGLAnnotationViewBillboardAxisY = 0x1 << 1,

/**
Orients the annotation view such that its z-axis is always fixed with
respect to the map.

Because `MGLMapView` does not support changes to its bank, or roll, this
option has no effect.
*/
MGLAnnotationViewBillboardAxisZ = 0x1 << 2,

/**
Orients the annotation view such that all three axes are always fixed with
respect to the map.
*/
MGLAnnotationViewBillboardAxisAll = (MGLAnnotationViewBillboardAxisX | MGLAnnotationViewBillboardAxisY | MGLAnnotationViewBillboardAxisZ),
};

/**
The `MGLAnnotationView` class is responsible for marking a point annotation
with a view. Annotation views represent an annotation object, which is an
Expand Down Expand Up @@ -126,8 +177,14 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) {

You specify the reuse identifier when you create the view. You use the
identifier later to retrieve an annotation view that was created previously but
<<<<<<< HEAD
which is currently unused because its annotation is not on-screen.

=======
which is currently unused because its annotation does not lie within the map
view’s viewport.

>>>>>>> 8d2bb2d42... [ios] Annotation view degrees of freedom
If you define distinctly different types of annotations (with distinctly
different annotation views to go with them), you can differentiate between the
annotation types by specifying different reuse identifiers for each one.
Expand All @@ -154,6 +211,15 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) {
*/
@property (nonatomic) CGVector centerOffset;

/**
An option that specifies the annotation view’s degrees of freedom.

By default, none of the axes are free; in other words, the annotation view is
oriented like a billboard with respect to the x-, y-, and z-axes. See
`MGLAnnotationViewBillboardAxis` for available options.
*/
@property (nonatomic, assign) MGLAnnotationViewBillboardAxis freeAxes;

/**
A Boolean value that determines whether the annotation view grows and shrinks
as the distance between the viewpoint and the annotation view changes on a
Expand All @@ -171,19 +237,6 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) {
*/
@property (nonatomic, assign) BOOL scalesWithViewingDistance;

/**
A Boolean value that determines whether the annotation view rotates together
with the map.

When the value of this property is `YES` and the map is rotated, the annotation
view rotates. This is also the behavior of `MGLAnnotationImage` objects. When the
value of this property is `NO` the annotation has its rotation angle fixed.

The default value of this property is `NO`. Set this property to `YES` if the
view’s rotation is important.
*/
@property (nonatomic, assign) BOOL rotatesToMatchCamera;

#pragma mark Managing the Selection State

/**
Expand Down
Loading