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
2 changes: 2 additions & 0 deletions gyp/platform-ios.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
'../include/mbgl/ios/Mapbox.h',
'../platform/ios/MGLMapboxEvents.h',
'../platform/ios/MGLMapboxEvents.m',
'../include/mbgl/ios/MGLMapCamera.h',
'../platform/ios/MGLMapCamera.mm',
'../include/mbgl/ios/MGLMapView.h',
'../include/mbgl/ios/MGLMapView+IBAdditions.h',
'../platform/ios/MGLMapView.mm',
Expand Down
36 changes: 36 additions & 0 deletions include/mbgl/ios/MGLMapCamera.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#import "Mapbox.h"

#pragma once

NS_ASSUME_NONNULL_BEGIN

/** An `MGLMapCamera` object represents a viewpoint from which the user observes some point on an `MGLMapView`. */
@interface MGLMapCamera : NSObject <NSSecureCoding, NSCopying>

/** Coordinate at the center of the map view. */
@property (nonatomic) CLLocationCoordinate2D centerCoordinate;

/** Heading measured in degrees clockwise from true north. */
@property (nonatomic) CLLocationDirection heading;

/** Pitch toward the horizon measured in degrees, with 0 degrees resulting in a two-dimensional map. */
@property (nonatomic) CGFloat pitch;

/** Meters above ground level. */
@property (nonatomic) CLLocationDistance altitude;

/** Returns a new camera with all properties set to 0. */
+ (instancetype)camera;

+ (instancetype)cameraLookingAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
fromEyeCoordinate:(CLLocationCoordinate2D)eyeCoordinate
eyeAltitude:(CLLocationDistance)eyeAltitude;

+ (instancetype)cameraLookingAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
fromDistance:(CLLocationDistance)distance
pitch:(CGFloat)pitch
heading:(CLLocationDirection)heading;

@end

NS_ASSUME_NONNULL_END
19 changes: 14 additions & 5 deletions include/mbgl/ios/MGLMapView.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#import "MGLGeometry.h"
#import "MGLMapCamera.h"

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>

NS_ASSUME_NONNULL_BEGIN

@class MGLAnnotationImage;
@class MGLMapCamera;
@class MGLUserLocation;
@class MGLPolyline;
@class MGLPolygon;
Expand Down Expand Up @@ -135,6 +137,8 @@ IB_DESIGNABLE
* @param animated Specify `YES` if you want the map view to animate scrolling and zooming to the new location or `NO` if you want the map to display the new location immediately. */
- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel animated:(BOOL)animated;

- (void)setCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate zoomLevel:(double)zoomLevel direction:(CLLocationDirection)direction animated:(BOOL)animated;

/** The coordinate bounds visible in the receiver’s viewport.
*
* Changing the value of this property updates the receiver immediately. If you want to animate the change, call `setVisibleCoordinateBounds:animated:` instead. */
Expand Down Expand Up @@ -183,17 +187,22 @@ IB_DESIGNABLE
/** The pitch of the map (measured in degrees).
*
* The default value `0` shows a completely flat map. Maximum value is `60`. */
@property (nonatomic) double pitch;
@property (nonatomic) CGFloat pitch;

/** Changes the pitch of the map.
* @param pitch The pitch of the map (measured in degrees) relative to top-down.
*
* Changing the pitch tilts the map without changing the current center coordinate or zoom level. */
- (void)setPitch:(double)pitch;
* @param pitch The pitch of the map (measured in degrees) relative to top-down.
* @param animated Specify `YES` if you want the map view to animate the change to the new pitch or `NO` if you want the map to display the new pitch immediately.
*
* Changing the pitch tilts the map without changing the current center coordinate or zoom level. */
- (void)setPitch:(CGFloat)pitch animated:(BOOL)animated;

/** Resets the map pitch to head-on. */
- (IBAction)resetPitch;

@property (nonatomic, copy) MGLMapCamera *camera;

- (void)setCamera:(MGLMapCamera *)camera animated:(BOOL)animated;

#pragma mark - Converting Map Coordinates

/** @name Converting Map Coordinates */
Expand Down
1 change: 1 addition & 0 deletions include/mbgl/ios/Mapbox.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#import "MGLAccountManager.h"
#import "MGLAnnotation.h"
#import "MGLAnnotationImage.h"
#import "MGLMapCamera.h"
#import "MGLGeometry.h"
#import "MGLMapView.h"
#import "MGLMultiPoint.h"
Expand Down
23 changes: 23 additions & 0 deletions include/mbgl/map/camera.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef MBGL_MAP_CAMERA
#define MBGL_MAP_CAMERA

#include <mbgl/util/geo.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/util/chrono.hpp>

#include <functional>

namespace mbgl {

struct CameraOptions {
mapbox::util::optional<LatLng> center;
mapbox::util::optional<double> zoom;
mapbox::util::optional<double> angle;
mapbox::util::optional<double> pitch;
mapbox::util::optional<Duration> duration;
mapbox::util::optional<std::function<double(double)> > easing;
};

}

#endif /* MBGL_MAP_CAMERA */
10 changes: 7 additions & 3 deletions include/mbgl/map/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define MBGL_MAP_MAP

#include <mbgl/util/chrono.hpp>
#include <mbgl/map/camera.hpp>
#include <mbgl/map/update.hpp>
#include <mbgl/map/mode.hpp>
#include <mbgl/util/geo.hpp>
Expand Down Expand Up @@ -97,6 +98,9 @@ class Map : private util::noncopyable {
void cancelTransitions();
void setGestureInProgress(bool);

void jumpTo(CameraOptions options);
void easeTo(CameraOptions options);

// Position
void moveBy(double dx, double dy, const Duration& = Duration::zero());
void setLatLng(LatLng latLng, const Duration& = Duration::zero());
Expand All @@ -110,8 +114,8 @@ class Map : private util::noncopyable {
void setZoom(double zoom, const Duration& = Duration::zero());
double getZoom() const;
void setLatLngZoom(LatLng latLng, double zoom, const Duration& = Duration::zero());
void fitBounds(LatLngBounds bounds, EdgeInsets padding, const Duration& duration = Duration::zero());
void fitBounds(AnnotationSegment segment, EdgeInsets padding, const Duration& duration = Duration::zero());
CameraOptions cameraForLatLngBounds(LatLngBounds bounds, EdgeInsets padding);
CameraOptions cameraForLatLngs(std::vector<LatLng> latLngs, EdgeInsets padding);
void resetZoom();
double getMinZoom() const;
double getMaxZoom() const;
Expand All @@ -124,7 +128,7 @@ class Map : private util::noncopyable {
void resetNorth();

// Pitch
void setPitch(double pitch);
void setPitch(double pitch, const Duration& = Duration::zero());
double getPitch() const;

// Size
Expand Down
101 changes: 101 additions & 0 deletions platform/ios/MGLMapCamera.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#import "MGLMapCamera.h"

#include <mbgl/util/projection.hpp>

@implementation MGLMapCamera

+ (BOOL)supportsSecureCoding
{
return YES;
}

+ (instancetype)camera
{
return [[self alloc] init];
}

+ (instancetype)cameraLookingAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
fromEyeCoordinate:(CLLocationCoordinate2D)eyeCoordinate
eyeAltitude:(CLLocationDistance)eyeAltitude
{
mbgl::LatLng centerLatLng = mbgl::LatLng(centerCoordinate.latitude, centerCoordinate.longitude);
mbgl::LatLng eyeLatLng = mbgl::LatLng(eyeCoordinate.latitude, eyeCoordinate.longitude);

mbgl::ProjectedMeters centerMeters = mbgl::Projection::projectedMetersForLatLng(centerLatLng);
mbgl::ProjectedMeters eyeMeters = mbgl::Projection::projectedMetersForLatLng(eyeLatLng);
CLLocationDirection heading = std::atan((centerMeters.northing - eyeMeters.northing) /
(centerMeters.easting - eyeMeters.easting));

double groundDistance = std::sqrt(std::pow(centerMeters.northing - eyeMeters.northing, 2) +
std::pow(centerMeters.easting - eyeMeters.easting, 2));
CGFloat pitch = std::atan(eyeAltitude / groundDistance);

return [[self alloc] initWithCenterCoordinate:centerCoordinate
altitude:eyeAltitude
pitch:pitch
heading:heading];
}

+ (instancetype)cameraLookingAtCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
fromDistance:(CLLocationDistance)distance
pitch:(CGFloat)pitch
heading:(CLLocationDirection)heading
{
return [[self alloc] initWithCenterCoordinate:centerCoordinate
altitude:distance
pitch:(CGFloat)pitch
heading:heading];
}

- (instancetype)initWithCenterCoordinate:(CLLocationCoordinate2D)centerCoordinate
altitude:(CLLocationDistance)altitude
pitch:(CGFloat)pitch
heading:(CLLocationDirection)heading
{
if (self = [super init])
{
_centerCoordinate = centerCoordinate;
_altitude = altitude;
_pitch = pitch;
_heading = heading;
}
return self;
}

- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
if (self = [super init])
{
_centerCoordinate = CLLocationCoordinate2DMake([[coder decodeObjectForKey:@"centerLatitude"] doubleValue],
[[coder decodeObjectForKey:@"centerLongitude"] doubleValue]);
_altitude = [[coder decodeObjectForKey:@"altitude"] doubleValue];
_pitch = [[coder decodeObjectForKey:@"pitch"] doubleValue];
_heading = [[coder decodeObjectForKey:@"heading"] doubleValue];
}
return self;
}

- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeDouble:_centerCoordinate.latitude forKey:@"centerLatitude"];
[coder encodeDouble:_centerCoordinate.longitude forKey:@"centerLongitude"];
[coder encodeDouble:_altitude forKey:@"altitude"];
[coder encodeDouble:_pitch forKey:@"pitch"];
[coder encodeDouble:_heading forKey:@"heading"];
}

- (id)copyWithZone:(nullable NSZone *)zone
{
return [[[self class] allocWithZone:zone] initWithCenterCoordinate:_centerCoordinate
altitude:_altitude
pitch:_pitch
heading:_heading];
}

- (NSString *)description
{
return [NSString stringWithFormat:@"<MKMapCamera %p centerCoordinate:%f, %f altitude:%.0fm heading:%.0f° pitch:%.0f°>",
self, _centerCoordinate.latitude, _centerCoordinate.longitude, _altitude, _heading, _pitch];
}

@end
Loading