Implement map projection functionality (#254)
* Implement map projection functionality * Add missing MGL_EXPORT * Remove the automatic copyright header
This commit is contained in:
committed by
GitHub
parent
ea234edf67
commit
6db27f50ad
@@ -134,6 +134,7 @@ target_sources(
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/map/map.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/map/map_observer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/map/map_options.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/map/map_projection.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/map/mode.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/map/projection_mode.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/math/clamp.hpp
|
||||
@@ -375,6 +376,7 @@ target_sources(
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/map/map_impl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/map/map_impl.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/map/map_options.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/map/map_projection.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/map/transform.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/map/transform.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/map/transform_state.cpp
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
namespace mbgl {
|
||||
|
||||
class RendererFrontend;
|
||||
class TransformState;
|
||||
|
||||
namespace style {
|
||||
class Image;
|
||||
@@ -110,6 +111,9 @@ public:
|
||||
std::vector<ScreenCoordinate> pixelsForLatLngs(const std::vector<LatLng>&) const;
|
||||
std::vector<LatLng> latLngsForPixels(const std::vector<ScreenCoordinate>&) const;
|
||||
|
||||
// Transform
|
||||
TransformState getTransfromState() const;
|
||||
|
||||
// Annotations
|
||||
void addAnnotationImage(std::unique_ptr<style::Image>);
|
||||
void removeAnnotationImage(const std::string&);
|
||||
|
||||
30
include/mbgl/map/map_projection.hpp
Normal file
30
include/mbgl/map/map_projection.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include <mbgl/map/camera.hpp>
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class Transform;
|
||||
|
||||
class MapProjection : private util::noncopyable {
|
||||
public:
|
||||
explicit MapProjection(const Map&);
|
||||
~MapProjection();
|
||||
|
||||
ScreenCoordinate pixelForLatLng(const LatLng&) const;
|
||||
LatLng latLngForPixel(const ScreenCoordinate&) const;
|
||||
|
||||
void setCamera(const CameraOptions&);
|
||||
CameraOptions getCamera() const;
|
||||
|
||||
/// Set the underneath camera so the requested coordinates are visible with the inset.
|
||||
void setVisibleCoordinates(const std::vector<LatLng>&, const EdgeInsets&);
|
||||
|
||||
private:
|
||||
std::unique_ptr<Transform> transform;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
92
platform/ios/platform/darwin/test/MGLMapProjectionTests.m
Normal file
92
platform/ios/platform/darwin/test/MGLMapProjectionTests.m
Normal file
@@ -0,0 +1,92 @@
|
||||
#import <Mapbox/Mapbox.h>
|
||||
#import <XCTest/XCTest.h>
|
||||
#import <TargetConditionals.h>
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#define MGLEdgeInsets UIEdgeInsets
|
||||
#define MGLEdgeInsetsMake UIEdgeInsetsMake
|
||||
#else
|
||||
#define MGLEdgeInsets NSEdgeInsets
|
||||
#define MGLEdgeInsetsMake NSEdgeInsetsMake
|
||||
#endif
|
||||
|
||||
@interface MGLMapProjectionTests : XCTestCase
|
||||
|
||||
@property (nonatomic, retain) MGLMapView *mapView;
|
||||
@property (nonatomic, retain) MGLMapProjection *mapProjection;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MGLMapProjectionTests
|
||||
|
||||
- (void)setUp {
|
||||
[super setUp];
|
||||
|
||||
[MGLSettings setApiKey:@"pk.feedcafedeadbeefbadebede"];
|
||||
NSURL *styleURL = [[NSBundle bundleForClass:[self class]] URLForResource:@"one-liner" withExtension:@"json"];
|
||||
self.mapView = [[MGLMapView alloc] initWithFrame:CGRectMake(0, 0, 200, 200) styleURL:styleURL];
|
||||
|
||||
[self.mapView setVisibleCoordinateBounds:MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(1.0, 1.0),
|
||||
CLLocationCoordinate2DMake(2.0, 2.0))];
|
||||
|
||||
self.mapProjection = self.mapView.mapProjection;
|
||||
}
|
||||
|
||||
- (void)tearDown {
|
||||
self.mapView = nil;
|
||||
self.mapProjection = nil;
|
||||
[MGLSettings setApiKey:nil];
|
||||
|
||||
[super tearDown];
|
||||
}
|
||||
|
||||
- (void)testMapProjectionCamera {
|
||||
XCTAssertTrue([self.mapProjection.camera isEqualToMapCamera:self.mapView.camera],
|
||||
@"Map projection camera must be equal to the map view's one");
|
||||
}
|
||||
|
||||
- (void)testMapProjectionCameraSet {
|
||||
MGLCoordinateBounds newBounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(3.0, 3.0),
|
||||
CLLocationCoordinate2DMake(4.0, 4.0));
|
||||
MGLEdgeInsets paddings = MGLEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
|
||||
|
||||
MGLMapCamera *newCamera = [self.mapView cameraThatFitsCoordinateBounds:newBounds edgePadding:paddings];
|
||||
[self.mapProjection setCamera:newCamera withEdgeInsets:paddings];
|
||||
|
||||
XCTAssertTrue([self.mapProjection.camera isEqualToMapCamera:newCamera],
|
||||
@"Map projection camera must be equal to the one just set");
|
||||
|
||||
CLLocationCoordinate2D topLeftCoordinate = [self.mapProjection convertPoint:CGPointMake(10.0, 10.0)];
|
||||
XCTAssertEqualWithAccuracy(topLeftCoordinate.latitude, 4.0, 1e-3);
|
||||
XCTAssertEqualWithAccuracy(topLeftCoordinate.longitude, 3.0, 1e-3);
|
||||
|
||||
CLLocationCoordinate2D bottomRightCoordinate = [self.mapProjection convertPoint:CGPointMake(190.0, 190.0)];
|
||||
XCTAssertEqualWithAccuracy(bottomRightCoordinate.latitude, 3.0, 1e-3);
|
||||
XCTAssertEqualWithAccuracy(bottomRightCoordinate.longitude, 4.0, 1e-3);
|
||||
|
||||
CLLocationCoordinate2D centerCoordinate = [self.mapProjection convertPoint:CGPointMake(100.0, 100.0)];
|
||||
XCTAssertEqualWithAccuracy(centerCoordinate.latitude, 3.5, 1e-3);
|
||||
XCTAssertEqualWithAccuracy(centerCoordinate.longitude, 3.5, 1e-3);
|
||||
}
|
||||
|
||||
- (void)testMapProjectionVisibleBoundsSet {
|
||||
MGLCoordinateBounds newBounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(3.0, 3.0),
|
||||
CLLocationCoordinate2DMake(4.0, 4.0));
|
||||
MGLEdgeInsets paddings = MGLEdgeInsetsMake(10.0, 10.0, 10.0, 10.0);
|
||||
|
||||
[self.mapProjection setVisibleCoordinateBounds:newBounds edgePadding:paddings];
|
||||
|
||||
CLLocationCoordinate2D topLeftCoordinate = [self.mapProjection convertPoint:CGPointMake(10.0, 10.0)];
|
||||
XCTAssertEqualWithAccuracy(topLeftCoordinate.latitude, 4.0, 1e-3);
|
||||
XCTAssertEqualWithAccuracy(topLeftCoordinate.longitude, 3.0, 1e-3);
|
||||
|
||||
CLLocationCoordinate2D bottomRightCoordinate = [self.mapProjection convertPoint:CGPointMake(190.0, 190.0)];
|
||||
XCTAssertEqualWithAccuracy(bottomRightCoordinate.latitude, 3.0, 1e-3);
|
||||
XCTAssertEqualWithAccuracy(bottomRightCoordinate.longitude, 4.0, 1e-3);
|
||||
|
||||
CLLocationCoordinate2D centerCoordinate = [self.mapProjection convertPoint:CGPointMake(100.0, 100.0)];
|
||||
XCTAssertEqualWithAccuracy(centerCoordinate.latitude, 3.5, 1e-3);
|
||||
XCTAssertEqualWithAccuracy(centerCoordinate.longitude, 3.5, 1e-3);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -415,6 +415,11 @@
|
||||
CAFB3C15234505D500399265 /* MGLMapSnapshotter_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = CAFB3C13234505D500399265 /* MGLMapSnapshotter_Private.h */; };
|
||||
CF75A91522D85E860058A5C4 /* MGLLoggingConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF75A91422D85E860058A5C4 /* MGLLoggingConfiguration.mm */; };
|
||||
CF75A91622D85E860058A5C4 /* MGLLoggingConfiguration.mm in Sources */ = {isa = PBXBuildFile; fileRef = CF75A91422D85E860058A5C4 /* MGLLoggingConfiguration.mm */; };
|
||||
D42DE1E4275F7FEB00B4446E /* MGLMapProjection.h in Headers */ = {isa = PBXBuildFile; fileRef = D42DE1E2275F7FEB00B4446E /* MGLMapProjection.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D42DE1E5275F7FEB00B4446E /* MGLMapProjection.h in Headers */ = {isa = PBXBuildFile; fileRef = D42DE1E2275F7FEB00B4446E /* MGLMapProjection.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D42DE1E6275F7FEB00B4446E /* MGLMapProjection.mm in Sources */ = {isa = PBXBuildFile; fileRef = D42DE1E3275F7FEB00B4446E /* MGLMapProjection.mm */; };
|
||||
D42DE1E7275F7FEB00B4446E /* MGLMapProjection.mm in Sources */ = {isa = PBXBuildFile; fileRef = D42DE1E3275F7FEB00B4446E /* MGLMapProjection.mm */; };
|
||||
D4D7412E2760EEBA00102513 /* MGLMapProjectionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D4D7412D2760EEBA00102513 /* MGLMapProjectionTests.m */; };
|
||||
D717FE7A25F1955A0054E06E /* iosapp_UITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D717FE7925F1955A0054E06E /* iosapp_UITests.swift */; };
|
||||
D717FECB25F19F520054E06E /* XCTestCase+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D717FECA25F19F520054E06E /* XCTestCase+Extensions.swift */; };
|
||||
D7E7CE8825F2EF6A00C175FC /* bench_UITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7E7CE8725F2EF6A00C175FC /* bench_UITests.swift */; };
|
||||
@@ -1069,6 +1074,9 @@
|
||||
CAE7AD5420F46EF5003B6782 /* MGLMapSnapshotterSwiftTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MGLMapSnapshotterSwiftTests.swift; sourceTree = "<group>"; };
|
||||
CAFB3C13234505D500399265 /* MGLMapSnapshotter_Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLMapSnapshotter_Private.h; sourceTree = "<group>"; };
|
||||
CF75A91422D85E860058A5C4 /* MGLLoggingConfiguration.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLoggingConfiguration.mm; sourceTree = "<group>"; };
|
||||
D42DE1E2275F7FEB00B4446E /* MGLMapProjection.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLMapProjection.h; sourceTree = "<group>"; };
|
||||
D42DE1E3275F7FEB00B4446E /* MGLMapProjection.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLMapProjection.mm; sourceTree = "<group>"; };
|
||||
D4D7412D2760EEBA00102513 /* MGLMapProjectionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = MGLMapProjectionTests.m; path = ../../darwin/test/MGLMapProjectionTests.m; sourceTree = "<group>"; };
|
||||
D717FE7725F1955A0054E06E /* iosapp UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "iosapp UITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D717FE7925F1955A0054E06E /* iosapp_UITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iosapp_UITests.swift; sourceTree = "<group>"; };
|
||||
D717FE7B25F1955A0054E06E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
@@ -1903,6 +1911,7 @@
|
||||
96381C0122C6F3950053497D /* MGLMapViewPitchTests.m */,
|
||||
9658C154204761FC00D8A674 /* MGLMapViewScaleBarTests.m */,
|
||||
076171C22139C70900668A35 /* MGLMapViewTests.m */,
|
||||
D4D7412D2760EEBA00102513 /* MGLMapProjectionTests.m */,
|
||||
9686D1BC22D9357700194EA0 /* MGLMapViewZoomTests.mm */,
|
||||
1F95931C1E6DE2E900D5B294 /* MGLNSDateAdditionsTests.mm */,
|
||||
96036A0520059BBA00510F3D /* MGLNSOrthographyAdditionsTests.m */,
|
||||
@@ -2016,6 +2025,8 @@
|
||||
DA737EE01D056A4E005BDA16 /* MGLMapViewDelegate.h */,
|
||||
4BC5769125E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.h */,
|
||||
4BC5769225E3D3D6006E06EB /* MGLUserLocationAnnotationViewStyle.m */,
|
||||
D42DE1E2275F7FEB00B4446E /* MGLMapProjection.h */,
|
||||
D42DE1E3275F7FEB00B4446E /* MGLMapProjection.mm */,
|
||||
);
|
||||
name = Kit;
|
||||
path = src;
|
||||
@@ -2358,6 +2369,7 @@
|
||||
DA17BE301CC4BAC300402C41 /* MGLMapView_Private.h in Headers */,
|
||||
DAD165781CF4CDFF001FF4B9 /* MGLShapeCollection.h in Headers */,
|
||||
DAED38631D62D0FC00D7640F /* NSURL+MGLAdditions.h in Headers */,
|
||||
D42DE1E4275F7FEB00B4446E /* MGLMapProjection.h in Headers */,
|
||||
DA88481E1CBAFA6200AB86E3 /* MGLMultiPoint_Private.h in Headers */,
|
||||
3566C7661D4A77BA008152BC /* MGLShapeSource.h in Headers */,
|
||||
35CE61821D4165D9004F2359 /* UIColor+MGLAdditions.h in Headers */,
|
||||
@@ -2519,6 +2531,7 @@
|
||||
DABFB8681CBE99E500D62B32 /* MGLPolyline.h in Headers */,
|
||||
96E516DF200054FB00A02306 /* MGLShape_Private.h in Headers */,
|
||||
DABFB86F1CBE9A0F00D62B32 /* MGLMapView.h in Headers */,
|
||||
D42DE1E5275F7FEB00B4446E /* MGLMapProjection.h in Headers */,
|
||||
DA6408DC1DA4E7D300908C90 /* MGLVectorStyleLayer.h in Headers */,
|
||||
353933F31D3FB753003F57D7 /* MGLCircleStyleLayer.h in Headers */,
|
||||
558DE7A11E5615E400C7916D /* MGLFoundation_Private.h in Headers */,
|
||||
@@ -3160,6 +3173,7 @@
|
||||
DA0CD5901CF56F6A00A5F5A5 /* MGLFeatureTests.mm in Sources */,
|
||||
556660D81E1D085500E2C41B /* MGLVersionNumber.m in Sources */,
|
||||
4031ACFF1E9FD29F00A3EA26 /* MGLSDKTestHelpers.swift in Sources */,
|
||||
D4D7412E2760EEBA00102513 /* MGLMapProjectionTests.m in Sources */,
|
||||
16376B491FFEED010000563E /* MGLMapViewLayoutTests.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -3189,6 +3203,7 @@
|
||||
967C864D210A9D3C004DF794 /* UIDevice+MGLAdditions.m in Sources */,
|
||||
400533021DB0862B0069F638 /* NSArray+MGLAdditions.mm in Sources */,
|
||||
6F018BAE220031B8003E7269 /* UIView+MGLAdditions.m in Sources */,
|
||||
D42DE1E6275F7FEB00B4446E /* MGLMapProjection.mm in Sources */,
|
||||
96036A03200565C700510F3D /* NSOrthography+MGLAdditions.m in Sources */,
|
||||
35136D421D42274500C20EFD /* MGLRasterStyleLayer.mm in Sources */,
|
||||
3538AA1F1D542239008EC33D /* MGLForegroundStyleLayer.mm in Sources */,
|
||||
@@ -3288,6 +3303,7 @@
|
||||
35136D431D42274500C20EFD /* MGLRasterStyleLayer.mm in Sources */,
|
||||
967C864E210A9D3C004DF794 /* UIDevice+MGLAdditions.m in Sources */,
|
||||
96036A04200565C700510F3D /* NSOrthography+MGLAdditions.m in Sources */,
|
||||
D42DE1E7275F7FEB00B4446E /* MGLMapProjection.mm in Sources */,
|
||||
6F018BB1220031C1003E7269 /* UIView+MGLAdditions.m in Sources */,
|
||||
3538AA201D542239008EC33D /* MGLForegroundStyleLayer.mm in Sources */,
|
||||
DA00FC911D5EEB0D009AABC8 /* MGLAttributionInfo.mm in Sources */,
|
||||
|
||||
75
platform/ios/platform/ios/src/MGLMapProjection.h
Normal file
75
platform/ios/platform/ios/src/MGLMapProjection.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#import "MGLFoundation.h"
|
||||
#import "MGLMapView.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
The aim of this class is to provide the functionality of changing the camera state and
|
||||
converting between map view screen coordinates and geographical coordinates without
|
||||
changing the actual map view camera state.
|
||||
*/
|
||||
MGL_EXPORT
|
||||
@interface MGLMapProjection : NSObject
|
||||
|
||||
/**
|
||||
Initializes and returns the new projection object with the current
|
||||
camera state from the provided map view.
|
||||
|
||||
@param mapView The map view the camera state to use for the initialization.
|
||||
@return An initialized map projection.
|
||||
*/
|
||||
- (instancetype)initWithMapView:(MGLMapView*)mapView;
|
||||
|
||||
/**
|
||||
A camera representing the current projection state
|
||||
*/
|
||||
@property (readonly, copy) MGLMapCamera *camera;
|
||||
|
||||
/**
|
||||
Change the projection state with camera and padding values.
|
||||
|
||||
@param camera The new camera to be used in the projection calculation.
|
||||
@param insets The insets applied on top of the camera be used in the projection calculation.
|
||||
|
||||
@note `MGLMapView` instance frame must not be changed since this projection is initialized,
|
||||
otherwise the calculation may be wrong.
|
||||
*/
|
||||
- (void)setCamera:(MGLMapCamera * _Nonnull)camera withEdgeInsets:(UIEdgeInsets)insets;
|
||||
|
||||
/**
|
||||
Change the projection state to make the provided bounds visible with the specified inset.
|
||||
|
||||
@param bounds The bounds that the viewport should fit.
|
||||
@param insets The insets applied on top of the viewport to be used in the projection calculation.
|
||||
|
||||
@note `MGLMapView` instance frame must not be changed since this projection is initialized,
|
||||
otherwise the calculation may be wrong.
|
||||
*/
|
||||
- (void)setVisibleCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(UIEdgeInsets)insets;
|
||||
|
||||
/**
|
||||
Converts a point in the coordinate system of the map view the projection
|
||||
was initialized with to the geographical coordinate.
|
||||
|
||||
@param point The point to convert.
|
||||
@return The geographic coordinate at the given point.
|
||||
*/
|
||||
- (CLLocationCoordinate2D)convertPoint:(CGPoint)point;
|
||||
|
||||
/**
|
||||
Converts a geographic coordinate to a point in the map view's the projection
|
||||
was initialized with coordinate system.
|
||||
|
||||
@param coordinate The geographic coordinate to convert.
|
||||
@return The point corresponding to the given geographic coordinate.
|
||||
*/
|
||||
- (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate;
|
||||
|
||||
/**
|
||||
The distance in meters spanned by a single point for the current camera.
|
||||
*/
|
||||
@property (readonly) CLLocationDistance metersPerPoint;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
113
platform/ios/platform/ios/src/MGLMapProjection.mm
Normal file
113
platform/ios/platform/ios/src/MGLMapProjection.mm
Normal file
@@ -0,0 +1,113 @@
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/map/map_projection.hpp>
|
||||
#include <mbgl/util/geo.hpp>
|
||||
#include <mbgl/util/projection.hpp>
|
||||
|
||||
#import "MGLMapProjection.h"
|
||||
#import "MGLMapView_Private.h"
|
||||
#import "MGLGeometry_Private.h"
|
||||
|
||||
@interface MGLMapProjection ()
|
||||
|
||||
@property (nonatomic) CGSize mapFrameSize;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MGLMapProjection
|
||||
{
|
||||
std::unique_ptr<mbgl::MapProjection> _mbglProjection;
|
||||
}
|
||||
|
||||
- (instancetype)initWithMapView:(MGLMapView *)mapView
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
_mbglProjection = std::make_unique<mbgl::MapProjection>([mapView mbglMap]);
|
||||
self.mapFrameSize = mapView.frame.size;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (MGLMapCamera*)camera
|
||||
{
|
||||
mbgl::CameraOptions cameraOptions = _mbglProjection->getCamera();
|
||||
|
||||
CLLocationCoordinate2D centerCoordinate = MGLLocationCoordinate2DFromLatLng(*cameraOptions.center);
|
||||
double zoomLevel = *cameraOptions.zoom;
|
||||
CLLocationDirection direction = mbgl::util::wrap(*cameraOptions.bearing, 0., 360.);
|
||||
CGFloat pitch = *cameraOptions.pitch;
|
||||
CLLocationDistance altitude = MGLAltitudeForZoomLevel(zoomLevel, pitch,
|
||||
centerCoordinate.latitude, self.mapFrameSize);
|
||||
return [MGLMapCamera cameraLookingAtCenterCoordinate:centerCoordinate altitude:altitude
|
||||
pitch:pitch heading:direction];
|
||||
}
|
||||
|
||||
- (void)setCamera:(MGLMapCamera * _Nonnull)camera withEdgeInsets:(UIEdgeInsets)insets
|
||||
{
|
||||
mbgl::CameraOptions cameraOptions;
|
||||
if (CLLocationCoordinate2DIsValid(camera.centerCoordinate))
|
||||
{
|
||||
cameraOptions.center = MGLLatLngFromLocationCoordinate2D(camera.centerCoordinate);
|
||||
}
|
||||
cameraOptions.padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
|
||||
cameraOptions.zoom = MGLZoomLevelForAltitude(camera.altitude, camera.pitch,
|
||||
camera.centerCoordinate.latitude,
|
||||
self.mapFrameSize);
|
||||
if (camera.heading >= 0)
|
||||
{
|
||||
cameraOptions.bearing = camera.heading;
|
||||
}
|
||||
if (camera.pitch >= 0)
|
||||
{
|
||||
cameraOptions.pitch = camera.pitch;
|
||||
}
|
||||
|
||||
_mbglProjection->setCamera(cameraOptions);
|
||||
}
|
||||
|
||||
- (void)setVisibleCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(UIEdgeInsets)insets {
|
||||
CLLocationCoordinate2D coordinates[] = {
|
||||
{bounds.ne.latitude, bounds.sw.longitude},
|
||||
bounds.sw,
|
||||
{bounds.sw.latitude, bounds.ne.longitude},
|
||||
bounds.ne,
|
||||
};
|
||||
|
||||
mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets);
|
||||
std::vector<mbgl::LatLng> latLngs;
|
||||
latLngs.reserve(4);
|
||||
for (NSUInteger i = 0; i < 4; i++)
|
||||
{
|
||||
latLngs.push_back({coordinates[i].latitude, coordinates[i].longitude});
|
||||
}
|
||||
|
||||
_mbglProjection->setVisibleCoordinates(latLngs, padding);
|
||||
}
|
||||
|
||||
- (CLLocationCoordinate2D)convertPoint:(CGPoint)point
|
||||
{
|
||||
mbgl::ScreenCoordinate screenCoordinate = mbgl::ScreenCoordinate(point.x, point.y);
|
||||
return MGLLocationCoordinate2DFromLatLng(_mbglProjection->latLngForPixel(screenCoordinate).wrapped());
|
||||
}
|
||||
|
||||
- (CGPoint)convertCoordinate:(CLLocationCoordinate2D)coordinate
|
||||
{
|
||||
if ( !CLLocationCoordinate2DIsValid(coordinate))
|
||||
{
|
||||
return CGPointMake(NAN, NAN);
|
||||
}
|
||||
|
||||
mbgl::LatLng latLng = MGLLatLngFromLocationCoordinate2D(coordinate);
|
||||
mbgl::ScreenCoordinate pixel = _mbglProjection->pixelForLatLng(latLng);
|
||||
return CGPointMake(pixel.x, pixel.y);
|
||||
}
|
||||
|
||||
- (CLLocationDistance)metersPerPoint
|
||||
{
|
||||
mbgl::CameraOptions cameraOptions = _mbglProjection->getCamera();
|
||||
return mbgl::Projection::getMetersPerPixelAtLatitude(cameraOptions.center->latitude(),
|
||||
*cameraOptions.zoom);
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -12,6 +12,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
@class MGLAnnotationView;
|
||||
@class MGLAnnotationImage;
|
||||
@class MGLUserLocation;
|
||||
@class MGLMapProjection;
|
||||
@class MGLPolyline;
|
||||
@class MGLPolygon;
|
||||
@class MGLShape;
|
||||
@@ -1533,6 +1534,12 @@ MGL_EXPORT
|
||||
*/
|
||||
- (CLLocationDistance)metersPerPointAtLatitude:(CLLocationDegrees)latitude;
|
||||
|
||||
/**
|
||||
Returns the new map projection instance initialized with the map view,
|
||||
i.e. with the current camera state.
|
||||
*/
|
||||
- (MGLMapProjection*)mapProjection;
|
||||
|
||||
#pragma mark Annotating the Map
|
||||
|
||||
/**
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
#import "MGLNetworkConfiguration_Private.h"
|
||||
#import "MGLReachability.h"
|
||||
#import "MGLSettings_Private.h"
|
||||
#import "MGLMapProjection.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
@@ -4360,6 +4361,10 @@ static void *windowScreenContext = &windowScreenContext;
|
||||
return mbgl::Projection::getMetersPerPixelAtLatitude(latitude, zoomLevel);
|
||||
}
|
||||
|
||||
- (MGLMapProjection*)mapProjection {
|
||||
return [[MGLMapProjection alloc] initWithMapView:self];
|
||||
}
|
||||
|
||||
#pragma mark - Camera Change Reason -
|
||||
|
||||
- (void)resetCameraChangeReason
|
||||
|
||||
@@ -54,6 +54,7 @@ FOUNDATION_EXTERN MGL_EXPORT MGLExceptionName const _Nonnull MGLUnderlyingMapUna
|
||||
/// Synchronously render a frame of the map.
|
||||
- (BOOL)renderSync;
|
||||
|
||||
- (mbgl::Map &)mbglMap;
|
||||
- (nonnull mbgl::Renderer *)renderer;
|
||||
|
||||
/** Returns whether the map view is currently loading or processing any assets required to render the map */
|
||||
|
||||
@@ -36,6 +36,7 @@ FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[];
|
||||
#import "MGLLocationManager.h"
|
||||
#import "MGLLoggingConfiguration.h"
|
||||
#import "MGLMapCamera.h"
|
||||
#import "MGLMapProjection.h"
|
||||
#import "MGLMapSnapshotter.h"
|
||||
#import "MGLMapView.h"
|
||||
#import "MGLMapViewDelegate.h"
|
||||
|
||||
@@ -3,14 +3,13 @@
|
||||
|
||||
#import "../../darwin/src/MGLGeometry_Private.h"
|
||||
#import "MGLMockGestureRecognizers.h"
|
||||
#import "MGLMapView_Private.h"
|
||||
|
||||
#include <mbgl/map/map.hpp>
|
||||
#include <mbgl/map/camera.hpp>
|
||||
|
||||
@interface MGLMapView (MGLMapViewGestureRecognizerTests)
|
||||
|
||||
- (mbgl::Map &)mbglMap;
|
||||
|
||||
- (void)handlePinchGesture:(UIPinchGestureRecognizer *)pinch;
|
||||
- (void)handleRotateGesture:(UIRotationGestureRecognizer *)rotate;
|
||||
- (void)handleDoubleTapGesture:(UITapGestureRecognizer *)doubleTap;
|
||||
|
||||
@@ -426,6 +426,12 @@ std::vector<LatLng> Map::latLngsForPixels(const std::vector<ScreenCoordinate>& s
|
||||
return ret;
|
||||
}
|
||||
|
||||
#pragma mark - Transform
|
||||
|
||||
TransformState Map::getTransfromState() const {
|
||||
return impl->transform.getState();
|
||||
}
|
||||
|
||||
#pragma mark - Annotations
|
||||
|
||||
void Map::addAnnotationImage(std::unique_ptr<style::Image> image) {
|
||||
|
||||
@@ -76,4 +76,9 @@ public:
|
||||
std::unique_ptr<StillImageRequest> stillImageRequest;
|
||||
};
|
||||
|
||||
// Forward declaration of this method is required for the MapProjection class
|
||||
CameraOptions cameraForLatLngs(const std::vector<LatLng>& latLngs,
|
||||
const Transform& transform,
|
||||
const EdgeInsets& padding);
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
39
src/mbgl/map/map_projection.cpp
Normal file
39
src/mbgl/map/map_projection.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include <mbgl/map/map_projection.hpp>
|
||||
#include <mbgl/map/map_impl.hpp>
|
||||
#include <mbgl/map/transform.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
MapProjection::MapProjection(const Map& map)
|
||||
: transform(std::make_unique<Transform>(map.getTransfromState())) {}
|
||||
|
||||
MapProjection::~MapProjection() = default;
|
||||
|
||||
ScreenCoordinate MapProjection::pixelForLatLng(const LatLng& latLng) const {
|
||||
// The implementation is just a copy from map.cpp
|
||||
LatLng unwrappedLatLng = latLng.wrapped();
|
||||
unwrappedLatLng.unwrapForShortestPath(transform->getLatLng());
|
||||
return transform->latLngToScreenCoordinate(unwrappedLatLng);
|
||||
}
|
||||
|
||||
LatLng MapProjection::latLngForPixel(const ScreenCoordinate& pixel) const {
|
||||
// The implementation is just a copy from map.cpp
|
||||
return transform->screenCoordinateToLatLng(pixel);
|
||||
}
|
||||
|
||||
void MapProjection::setCamera(const CameraOptions& camera) {
|
||||
transform->jumpTo(camera);
|
||||
}
|
||||
|
||||
CameraOptions MapProjection::getCamera() const {
|
||||
return transform->getCameraOptions(nullopt);
|
||||
}
|
||||
|
||||
void MapProjection::setVisibleCoordinates(const std::vector<LatLng>& latLngs,
|
||||
const EdgeInsets& padding) {
|
||||
transform->jumpTo(mbgl::cameraForLatLngs(latLngs, *transform, padding)
|
||||
.withBearing(-transform->getBearing() * util::RAD2DEG)
|
||||
.withPitch(transform->getPitch() * util::RAD2DEG));
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
Reference in New Issue
Block a user