Skip to content
This repository was archived by the owner on Aug 8, 2023. It is now read-only.
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
4 changes: 4 additions & 0 deletions include/mbgl/map/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/annotation/annotation.hpp>
#include <mbgl/style/transition_options.hpp>
#include <mbgl/map/transform_state.hpp>

#include <cstdint>
#include <string>
Expand Down Expand Up @@ -141,6 +142,9 @@ class Map : private util::noncopyable {
LatLng latLngForProjectedMeters(const ProjectedMeters&) const;
ScreenCoordinate pixelForLatLng(const LatLng&) const;
LatLng latLngForPixel(const ScreenCoordinate&) const;

// Transform
const TransformState& getTransform() const;
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.

Hopefully we’ll be able to expose just the projection matrix rather than the entire TransformState object.


// Annotations
void addAnnotationIcon(const std::string&, std::shared_ptr<const SpriteImage>);
Expand Down
6 changes: 6 additions & 0 deletions platform/ios/app/MBXViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -1169,4 +1169,10 @@ - (void)mapView:(MGLMapView *)mapView tapOnCalloutForAnnotation:(id <MGLAnnotati
point.coordinate = [self.mapView convertPoint:self.mapView.center toCoordinateFromView:self.mapView];
}

-(void)mapView:(MGLMapView *)mapView didSelectAnnotationView:(MGLAnnotationView *)annotationView
{
annotationView.lockAxis = ( (int)annotationView.lockAxis + 1 ) % 4;
NSLog(@"lockAxis[%p]: 0x%x", annotationView, annotationView.lockAxis);
}

@end
31 changes: 31 additions & 0 deletions platform/ios/src/MGLAnnotationView.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,31 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) {
MGLAnnotationViewDragStateEnding,
};

/**
Options for locking the orientation of an `MGLAnnotationView` along one or more
axes for a billboard effect.

By default the billboard will always facing the view flat
*/
typedef NS_OPTIONS(NSUInteger, MGLAnnotationViewBillboardLocking) {

/**
Locking the tilting angle so it tilts with the map
*/
MGLAnnotationViewBillboardLockingTilt = 0x01 << 0,

/**
Locking the heading angle so it rotates with the map
*/
MGLAnnotationViewBillboardLockingHeading = 0x01 << 1,

/**
Billboard tilts and rotates with the map
*/
MGLAnnotationViewBillboardLockingAll = MGLAnnotationViewBillboardLockingTilt |
MGLAnnotationViewBillboardLockingHeading
};

/**
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 @@ -221,6 +246,12 @@ typedef NS_ENUM(NSUInteger, MGLAnnotationViewDragState) {
*/
- (void)setDragState:(MGLAnnotationViewDragState)dragState animated:(BOOL)animated NS_REQUIRES_SUPER;

/**
The current locking of the axis of the annotation view
By default the view is unlocked along both degree of freedom
*/
@property (nonatomic, assign) MGLAnnotationViewBillboardLocking lockAxis;

@end

NS_ASSUME_NONNULL_END
45 changes: 43 additions & 2 deletions platform/ios/src/MGLAnnotationView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ @interface MGLAnnotationView () <UIGestureRecognizerDelegate>

@property (nonatomic, readwrite, nullable) NSString *reuseIdentifier;
@property (nonatomic, readwrite, nullable) id <MGLAnnotation> annotation;

@property (nonatomic, readwrite) CATransform3D lastAppliedScaleTransform;

@property (nonatomic, readwrite) CATransform3D lastAppliedTiltTransform;

@property (nonatomic, readwrite) CATransform3D lastAppliedHeadingTransform;

@property (nonatomic, weak) UIPanGestureRecognizer *panGestureRecognizer;
@property (nonatomic, weak) UILongPressGestureRecognizer *longPressRecognizer;
@property (nonatomic, weak) MGLMapView *mapView;
Expand All @@ -26,9 +32,12 @@ - (instancetype)initWithReuseIdentifier:(NSString *)reuseIdentifier
if (self)
{
_lastAppliedScaleTransform = CATransform3DIdentity;
_lastAppliedTiltTransform = CATransform3DIdentity;
_lastAppliedHeadingTransform = CATransform3DIdentity;
_reuseIdentifier = [reuseIdentifier copy];
_scalesWithViewingDistance = YES;
_enabled = YES;
_lockAxis = MGLAnnotationViewBillboardLockingAll;
}
return self;
}
Expand Down Expand Up @@ -70,15 +79,47 @@ - (void)setCenter:(CGPoint)center
center.y += _centerOffset.dy;

super.center = center;
[self updateScaleTransformForViewingDistance];

[self updateTransform];
}

- (void)setScalesWithViewingDistance:(BOOL)scalesWithViewingDistance
{
if (_scalesWithViewingDistance != scalesWithViewingDistance)
{
_scalesWithViewingDistance = scalesWithViewingDistance;
[self updateScaleTransformForViewingDistance];
[self updateTransform];
}
}

- (void)updateTransform
{
[self updateTiltTransform];
[self updateHeadingTransform];
// [self updateScaleTransformForViewingDistance];
}

- (void)updateHeadingTransform
{
if( _lockAxis & MGLAnnotationViewBillboardLockingHeading ) {
const mbgl::TransformState mapTransform = self.mapView.mbglMap->getTransform();
CATransform3D undoOfLastHeadingTransform = CATransform3DInvert(_lastAppliedHeadingTransform);
CATransform3D newHeadingTransform = CATransform3DMakeRotation(mapTransform.getAngle(), 0, 0, 1);
CATransform3D effectiveTransform = CATransform3DConcat(undoOfLastHeadingTransform, newHeadingTransform);
self.layer.transform = CATransform3DConcat(self.layer.transform, effectiveTransform);
_lastAppliedHeadingTransform = newHeadingTransform;
}
}

- (void)updateTiltTransform
{
if( _lockAxis & MGLAnnotationViewBillboardLockingTilt ) {
const mbgl::TransformState mapTransform = self.mapView.mbglMap->getTransform();
CATransform3D undoOfLastTiltTransform = CATransform3DInvert(_lastAppliedTiltTransform);
CATransform3D newTiltTransform = CATransform3DMakeRotation(mapTransform.getPitch(), 1, 0, 0);
CATransform3D effectiveTransform = CATransform3DConcat(undoOfLastTiltTransform, newTiltTransform);
self.layer.transform = CATransform3DConcat(self.layer.transform, effectiveTransform);
_lastAppliedTiltTransform = newTiltTransform;
}
}

Expand Down
2 changes: 2 additions & 0 deletions platform/ios/src/MGLAnnotationView_Private.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readwrite, nullable) id <MGLAnnotation> annotation;
@property (nonatomic, weak) MGLMapView *mapView;

-(void)updateTransform;

@end

NS_ASSUME_NONNULL_END
6 changes: 6 additions & 0 deletions platform/ios/src/MGLMapView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2989,6 +2989,10 @@ - (void)updateAnnotationContainerViewWithAnnotationViews:(NS_ARRAY_OF(MGLAnnotat
[newAnnotationContainerView addSubviews:annotationViews];
[_glView insertSubview:newAnnotationContainerView atIndex:0];
self.annotationContainerView = newAnnotationContainerView;

CATransform3D perspectiveTransform = CATransform3DIdentity;
perspectiveTransform.m34 = -1.0 / 500;
self.annotationContainerView.layer.sublayerTransform = perspectiveTransform;
}

/// Initialize and return a default annotation image that depicts a round pin
Expand Down Expand Up @@ -4638,6 +4642,8 @@ - (void)updateAnnotationViews
{
annotationView.center = [self convertCoordinate:annotationContext.annotation.coordinate toPointToView:self];
}

// [annotationView updateTransform];
}

[CATransaction commit];
Expand Down
7 changes: 7 additions & 0 deletions src/mbgl/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,13 @@ ScreenCoordinate Map::pixelForLatLng(const LatLng& latLng) const {
LatLng Map::latLngForPixel(const ScreenCoordinate& pixel) const {
return impl->transform.screenCoordinateToLatLng(pixel);
}

#pragma mark - Transform

const TransformState& Map::getTransform() const
{
return impl->transform.getState();
}

#pragma mark - Annotations

Expand Down