[iOS][macOS] Export MGLImageSource, add and update documentation. Use animated ImageSource demo in iOS test app

This commit is contained in:
Asheem Mamoowala
2017-06-13 12:55:01 -07:00
parent b7c7d3fdab
commit 7f36e0cf76
24 changed files with 172 additions and 164 deletions

View File

@@ -48,17 +48,18 @@ typedef struct MGLCoordinateBounds {
/**
A quadrilateral area as measured on a two-dimensional map projection.
`MGLCoordinateQuad` differs from `MGLCoordinateBounds` in that it allows
representation of non-axis aligned bounds and non-rectangular quadrilaterals
representation of non-axis aligned bounds and non-rectangular quadrilaterals.
The coordinates are described in counter clockwise order from top left.
*/
typedef struct MGLCoordinateQuad {
/** Coordinate at the top left corner. */
CLLocationCoordinate2D topLeft;
/** Coordinate at the top right corner. */
CLLocationCoordinate2D topRight;
/** Coordinate at the bottom right corner. */
CLLocationCoordinate2D bottomRight;
/** Coordinate at the bottom left corner. */
CLLocationCoordinate2D bottomLeft;
/** Coordinate at the bottom right corner. */
CLLocationCoordinate2D bottomRight;
/** Coordinate at the top right corner. */
CLLocationCoordinate2D topRight;
} MGLCoordinateQuad;
@@ -73,6 +74,33 @@ NS_INLINE MGLCoordinateBounds MGLCoordinateBoundsMake(CLLocationCoordinate2D sw,
return bounds;
}
/**
Creates a new `MGLCoordinateQuad` structure from the given top left,
bottom left, bottom right, and top right coordinates.
*/
NS_INLINE MGLCoordinateQuad MGLCoordinateQuadMake(CLLocationCoordinate2D topLeft, CLLocationCoordinate2D bottomLeft, CLLocationCoordinate2D bottomRight, CLLocationCoordinate2D topRight) {
MGLCoordinateQuad quad;
quad.topLeft = topLeft;
quad.bottomLeft = bottomLeft;
quad.bottomRight = bottomRight;
quad.topRight = topRight;
return quad;
}
/**
Creates a new `MGLCoordinateQuad` structure from the given `MGLCoordinateBounds`.
The returned quad uses the bounds' northeast coordinate as the top right, and the
southwest coordinate at the bottom left.
*/
NS_INLINE MGLCoordinateQuad MGLCoordinateQuadFromCoordinateBounds(MGLCoordinateBounds bounds) {
MGLCoordinateQuad quad;
quad.topLeft = CLLocationCoordinate2DMake(bounds.ne.latitude, bounds.sw.longitude);
quad.bottomLeft = bounds.sw;
quad.bottomRight = CLLocationCoordinate2DMake(bounds.sw.latitude, bounds.ne.longitude);
quad.topRight = bounds.ne;
return quad;
}
/** Returns `YES` if the two coordinate bounds are equal to each other. */
NS_INLINE BOOL MGLCoordinateBoundsEqualToCoordinateBounds(MGLCoordinateBounds bounds1, MGLCoordinateBounds bounds2) {
return (bounds1.sw.latitude == bounds2.sw.latitude &&
@@ -134,6 +162,15 @@ NS_INLINE NSString *MGLStringFromCoordinateBounds(MGLCoordinateBounds bounds) {
bounds.ne.latitude, bounds.ne.longitude];
}
/** Returns a formatted string for the given coordinate quad. */
NS_INLINE NSString *MGLStringFromCoordinateQuad(MGLCoordinateQuad quad) {
return [NSString stringWithFormat:@"{ topleft = {%.1f, %.1f}, bottomleft = {%.1f, %.1f}}, bottomright = {%.1f, %.1f}, topright = {%.1f, %.1f}",
quad.topLeft.latitude, quad.topLeft.longitude,
quad.bottomLeft.latitude, quad.bottomLeft.longitude,
quad.bottomRight.latitude, quad.bottomRight.longitude,
quad.topRight.latitude, quad.topRight.longitude];
}
/** Returns radians, converted from degrees. */
NS_INLINE CGFloat MGLRadiansFromDegrees(CLLocationDegrees degrees) {
return (CGFloat)(degrees * M_PI) / 180;

View File

@@ -66,16 +66,9 @@ NS_INLINE std::array<mbgl::LatLng, 4> MGLLatLngArrayFromCoordinateQuad(MGLCoordi
NS_INLINE MGLCoordinateQuad MGLCoordinateQuadFromLatLngArray(std::array<mbgl::LatLng, 4> quad) {
return { MGLLocationCoordinate2DFromLatLng(quad[0]),
MGLLocationCoordinate2DFromLatLng(quad[1]),
MGLLocationCoordinate2DFromLatLng(quad[3]),
MGLLocationCoordinate2DFromLatLng(quad[2]),
MGLLocationCoordinate2DFromLatLng(quad[3]) };
}
NS_INLINE MGLCoordinateQuad MGLCoordinateQuadFromCoordinateBounds(MGLCoordinateBounds bounds) {
return { { bounds.ne.latitude, bounds.sw.longitude },
bounds.ne,
{ bounds.sw.latitude, bounds.ne.longitude },
bounds.sw };
MGLLocationCoordinate2DFromLatLng(quad[1]) };
}
#if TARGET_OS_IPHONE

View File

@@ -8,12 +8,17 @@ NS_ASSUME_NONNULL_BEGIN
MGL_EXPORT
/**
`MGLImageSource` is a map content source that supplies a georeferenced raster
image to be shown on the map. The geographic location of the raster image content,
supplied with `MGLCoordinateQuad`, can be non-axis aligned.
`MGLImageSource` supports raster content from `NSURL` or an `MGLImage`.
Supported image formats are : PNG, TIFF, JPEG, GIF (single frame rendering),
and BMP.
`MGLImageSource` is a content source that is used for a georeferenced raster
image to be shown on the map. The georeferenced image scales and rotates as the
user zooms and rotates the map. Images may also be used as icons or patterns
in a style layer. To register an image for use as an icon or pattern,
use the `-[MGLStyle setImage:forName:]` method. To configure a point
annotation’s image, use the `MGLAnnotationImage` class.
The geographic location of the raster image content, supplied with
`MGLCoordinateQuad`, can be non-axis aligned.
`MGLImageSource` supports raster content from `NSURL`, `NSImage` (macOS), or
`UIImage` (iOS).
An image source is added to an `MGLStyle` object along with one or more
`MGLRasterStyleLayer` objects. Use a raster style layer to control the
appearance of content supplied by the image source.
@@ -28,30 +33,22 @@ MGL_EXPORT
### Example
```swift
let coordinates: MGLCoordinateQuad = MGLCoordinateQuad(
let coordinates = MGLCoordinateQuad(
topLeft: CLLocationCoordinate2D(latitude: 46.437, longitude: -80.425),
topRight: CLLocationCoordinate2D(latitude: 46.437, longitude: -71.516),
bottomLeft: CLLocationCoordinate2D(latitude: 37.936, longitude: -80.425),
bottomRight: CLLocationCoordinate2D(latitude: 37.936, longitude: -71.516),
bottomLeft: CLLocationCoordinate2D(latitude: 37.936, longitude: -80.425))
let source = MGLImageSource(identifier: "images", coordinates: coordinates, imageURL: URL(string: "https://www.mapbox.com/mapbox-gl-js/assets/radar.gif")!)
topRight: CLLocationCoordinate2D(latitude: 46.437, longitude: -71.516))
let source = MGLImageSource(identifier: "radar", coordinateQuad: coordinates, url: URL(string: "https://www.mapbox.com/mapbox-gl-js/assets/radar.gif")!)
mapView.style?.addSource(source)
```
*/
MGL_EXPORT
@interface MGLImageSource : MGLSource
#pragma mark Initializing a Source
/**
Returns a georeferenced image source with an identifier and coordinates
@param identifier A string that uniquely identifies the source.
@param coordinateQuad The top left, top right, bottom right, and bottom left coordinates for the image.
@return An initialized image source.
*/
- (instancetype)initWithIdentifier:(NSString *)identifier coordinates:(MGLCoordinateQuad)coordinateQuad NS_DESIGNATED_INITIALIZER;
/**
Returns a georeferenced image source with an identifier, coordinates and a URL
Returns a georeferenced image source with an identifier, coordinates and a URL.
@param identifier A string that uniquely identifies the source.
@param coordinateQuad the top left, top right, bottom right, and bottom left coordinates for the image.
@@ -59,75 +56,37 @@ MGL_EXPORT
current application’s resource bundle.
@return An initialized shape source.
*/
- (instancetype)initWithIdentifier:(NSString *)identifier coordinates:(MGLCoordinateQuad)coordinateQuad imageURL:(NSURL *)url;
- (instancetype)initWithIdentifier:(NSString *)identifier coordinateQuad:(MGLCoordinateQuad)coordinateQuad URL:(NSURL *)url;
/**
Returns a georeferenced image source with an identifier, coordinates and an image
Returns a georeferenced image source with an identifier, coordinates and an image.
@param identifier A string that uniquely identifies the source.
@param coordinateQuad The top left, top right, bottom right, and bottom left coordinates for the image.
@param image The image to display for the sourcde.
@param image The image to display for the source.
@return An initialized shape source.
*/
- (instancetype)initWithIdentifier:(NSString *)identifier coordinates:(MGLCoordinateQuad)coordinateQuad image:(MGLImage *)image;
/**
Returns a georeferenced image source with an identifier and coordinates
@param identifier A string that uniquely identifies the source.
@param bounds The aligned coordinate bounds for the image.
@return An initialized image source.
*/
- (instancetype)initWithIdentifier:(NSString *)identifier bounds:(MGLCoordinateBounds)bounds;
/**
Returns a georeferenced image source with an identifier, coordinates and a URL
@param identifier A string that uniquely identifies the source.
@param bounds The aligned coordinate bounds for the image.@param url An HTTP(S) URL, absolute file URL, or local file URL relative to the
current application’s resource bundle.
@return An initialized shape source.
*/
- (instancetype)initWithIdentifier:(NSString *)identifier bounds:(MGLCoordinateBounds)bounds imageURL:(NSURL *)url;
/**
Returns a georeferenced image source with an identifier, coordinates and an image
@param identifier A string that uniquely identifies the source.
@param bounds The aligned coordinate bounds for the image.
@param image The image to display for the sourcde.
@return An initialized shape source.
*/
- (instancetype)initWithIdentifier:(NSString *)identifier bounds:(MGLCoordinateBounds)bounds image:(MGLImage *)image;
- (instancetype)initWithIdentifier:(NSString *)identifier coordinateQuad:(MGLCoordinateQuad)coordinateQuad image:(MGLImage *)image;
#pragma mark Accessing a Source’s Content
/**
The URL to the source image.
If the receiver was initialized using `-initWithIdentifier:coordinates:` or
`-initWithIdentifier:coordinates:image:`, or the `image` property is set,
this property is set to `nil`.
If the receiver was initialized using `-initWithIdentifier:coordinateQuad:image:` or
the `image` property is set, this property is set to `nil`.
*/
@property (nonatomic, copy, nullable)NSURL *URL;
/**
The source image.
If the receiver was initialized using `-initWithIdentifier:coordinates:` or
`-initWithIdentifier:coordinates:imageURL:`, or if the `URL` property is set,
this property is set to `nil`.
If the receiver was initialized using `-initWithIdentifier:coordinateQuad:URL:` or if the `URL` property is set, this property is set to `nil`.
*/
@property (nonatomic, retain, nullable)MGLImage *image;
/**
The coordinates at which the source image will be placed.
If the receiver was initialized using `-initWithIdentifier:bounds:`,
`-initWithIdentifier:bounds:image:`, or `initWithIdentifier:bounds:imageURL`,
the bounds will be converted to an `MGLCoordinateQuad`.
The coordinates at which the corners of the source image will be placed.
*/
@property (nonatomic) MGLCoordinateQuad coordinates;
@end

View File

@@ -1,4 +1,4 @@
#import "MGLImageSource_Private.h"
#import "MGLImageSource.h"
#import "MGLGeometry_Private.h"
#import "MGLSource_Private.h"
@@ -14,6 +14,7 @@
#include <mbgl/util/premultiply.hpp>
@interface MGLImageSource ()
- (instancetype)initWithIdentifier:(NSString *)identifier coordinateQuad:(MGLCoordinateQuad)coordinateQuad NS_DESIGNATED_INITIALIZER;
@property (nonatomic, readonly) mbgl::style::ImageSource *rawSource;
@@ -21,7 +22,7 @@
@implementation MGLImageSource
- (instancetype)initWithIdentifier:(NSString *)identifier coordinates:(MGLCoordinateQuad)coordinateQuad {
- (instancetype)initWithIdentifier:(NSString *)identifier coordinateQuad:(MGLCoordinateQuad)coordinateQuad {
const auto coordsArray = MGLLatLngArrayFromCoordinateQuad(coordinateQuad);
auto source = std::make_unique<mbgl::style::ImageSource>(identifier.UTF8String, coordsArray);
@@ -29,35 +30,20 @@
}
- (instancetype)initWithIdentifier:(NSString *)identifier coordinates:(MGLCoordinateQuad)coordinateQuad imageURL:(NSURL *)url {
self = [self initWithIdentifier:identifier coordinates: coordinateQuad];
- (instancetype)initWithIdentifier:(NSString *)identifier coordinateQuad:(MGLCoordinateQuad)coordinateQuad URL:(NSURL *)url {
self = [self initWithIdentifier:identifier coordinateQuad: coordinateQuad];
self.URL = url;
return self;
}
- (instancetype)initWithIdentifier:(NSString *)identifier coordinates:(MGLCoordinateQuad)coordinateQuad image:(MGLImage *)image {
self = [self initWithIdentifier:identifier coordinates: coordinateQuad];
- (instancetype)initWithIdentifier:(NSString *)identifier coordinateQuad:(MGLCoordinateQuad)coordinateQuad image:(MGLImage *)image {
self = [self initWithIdentifier:identifier coordinateQuad: coordinateQuad];
self.image = image;
return self;
}
- (instancetype)initWithIdentifier:(NSString *)identifier bounds:(MGLCoordinateBounds)bounds {
self = [self initWithIdentifier:identifier coordinates:MGLCoordinateQuadFromCoordinateBounds(bounds)];
return self;
}
- (instancetype)initWithIdentifier:(NSString *)identifier bounds:(MGLCoordinateBounds)bounds imageURL:(NSURL *)url {
self = [self initWithIdentifier:identifier coordinates:MGLCoordinateQuadFromCoordinateBounds(bounds) imageURL:url];
return self;
}
- (instancetype)initWithIdentifier:(NSString *)identifier bounds:(MGLCoordinateBounds)bounds image:(MGLImage *)image {
self = [self initWithIdentifier:identifier coordinates:MGLCoordinateQuadFromCoordinateBounds(bounds) image:image];
return self;
}
- (NSURL *)URL {
auto url = self.rawSource->getURL();
return url ? [NSURL URLWithString:@(url->c_str())] : nil;
@@ -74,8 +60,10 @@
- (void)setImage:(MGLImage *)image {
if (image != nullptr) {
mbgl::UnassociatedImage unassociatedImage = mbgl::util::unpremultiply(image.mgl_PremultipliedImage);
mbgl::UnassociatedImage unassociatedImage = mbgl::util::unpremultiply(image.mgl_premultipliedImage);
self.rawSource->setImage(std::move(unassociatedImage));
} else {
self.rawSource->setImage(mbgl::UnassociatedImage({0,0}));
}
_image = image;
}
@@ -89,8 +77,8 @@
}
- (NSString *)description {
return [NSString stringWithFormat:@"<%@: %p; identifier = %@; URL = %@; image = %@>",
NSStringFromClass([self class]), (void *)self, self.identifier, self.URL, self.image];
return [NSString stringWithFormat:@"<%@: %p; identifier = %@; coordinates = %@; URL = %@; image = %@>",
NSStringFromClass([self class]), (void *)self, self.identifier, MGLStringFromCoordinateQuad(self.coordinates), self.URL, self.image];
}
- (mbgl::style::ImageSource *)rawSource {

View File

@@ -1,9 +0,0 @@
#import "MGLImageSource.h"
NS_ASSUME_NONNULL_BEGIN
@interface MGLImageSource (Private)
@end
NS_ASSUME_NONNULL_END

View File

@@ -154,7 +154,7 @@ typedef NS_ENUM(NSUInteger, MGLResourceKind) {
/** JSON part of a sprite sheet. It is constructed of the prefix in
https://www.mapbox.com/mapbox-gl-js/style-spec/#root-sprite and a JSON file extension. */
MGLResourceKindSpriteJSON,
/** Image **/
/** Image data for a georeferenced image source. **/
MGLResourceKindImage,
};

View File

@@ -17,8 +17,9 @@ NS_ASSUME_NONNULL_BEGIN
`-[MGLStyle addSource:]` and `-[MGLStyle sourceWithIdentifier:]`.
Do not create instances of this class directly, and do not create your own
subclasses of this class. Instead, create instances of `MGLShapeSource` and the
concrete subclasses of `MGLTileSource`, `MGLVectorSource` and `MGLRasterSource`.
subclasses of this class. Instead, create instances of `MGLShapeSource`,
`MGLImageSource` and the concrete subclasses of `MGLTileSource`,
`MGLVectorSource` and `MGLRasterSource`.
*/
MGL_EXPORT
@interface MGLSource : NSObject

View File

@@ -106,16 +106,16 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate {
func testMGLImageSource() {
//#-example-code
let coordinates: MGLCoordinateQuad = MGLCoordinateQuad(
let coordinates = MGLCoordinateQuad(
topLeft: CLLocationCoordinate2D(latitude: 46.437, longitude: -80.425),
topRight: CLLocationCoordinate2D(latitude: 46.437, longitude: -71.516),
bottomLeft: CLLocationCoordinate2D(latitude: 37.936, longitude: -80.425),
bottomRight: CLLocationCoordinate2D(latitude: 37.936, longitude: -71.516),
bottomLeft: CLLocationCoordinate2D(latitude: 37.936, longitude: -80.425))
let source = MGLImageSource(identifier: "images", coordinates: coordinates, imageURL: URL(string: "https://www.mapbox.com/mapbox-gl-js/assets/radar.gif")!)
topRight: CLLocationCoordinate2D(latitude: 46.437, longitude: -71.516))
let source = MGLImageSource(identifier: "radar", coordinateQuad: coordinates, url: URL(string: "https://www.mapbox.com/mapbox-gl-js/assets/radar.gif")!)
mapView.style?.addSource(source)
//#-end-example-code
XCTAssertNotNil(mapView.style?.source(withIdentifier: "images"))
XCTAssertNotNil(mapView.style?.source(withIdentifier: "radar"))
}
func testMGLCircleStyleLayer() {

View File

@@ -12,7 +12,7 @@
- (void)testMGLImageSourceWithImageURL {
MGLCoordinateQuad quad = { { 80, 37}, { 81, 37}, { 81, 39}, { 80, 39}};
MGLImageSource *source = [[MGLImageSource alloc] initWithIdentifier:@"source-id" coordinates:quad imageURL: [NSURL URLWithString:@"http://host/image.png"]];
MGLImageSource *source = [[MGLImageSource alloc] initWithIdentifier:@"source-id" coordinateQuad:quad URL:[NSURL URLWithString:@"http://host/image.png"]];
XCTAssertNotNil(source.URL);
XCTAssertEqualObjects(source.URL.absoluteString, @"http://host/image.png");
@@ -32,7 +32,7 @@
XCTAssertNotNil(image);
MGLCoordinateQuad quad = { { 80, 37}, { 81, 37}, { 81, 39}, { 80, 39}};
MGLImageSource *source = [[MGLImageSource alloc] initWithIdentifier:@"source-id" coordinates:quad image:image];
MGLImageSource *source = [[MGLImageSource alloc] initWithIdentifier:@"source-id" coordinateQuad:quad image:image];
XCTAssertNotNil(source.image);
XCTAssertEqualObjects(source.image, image);

View File

@@ -211,7 +211,7 @@
[self.style addSource:rasterSource];
// Attempt to remove an image source with the same identifier as the raster source
MGLImageSource *imageSource = [[MGLImageSource alloc] initWithIdentifier:@"some-identifier" coordinates: { }];
MGLImageSource *imageSource = [[MGLImageSource alloc] initWithIdentifier:@"some-identifier" coordinateQuad: { } URL:[NSURL URLWithString:@"http://host/image.png"]];
[self.style removeSource:imageSource];
// The raster source should still be added
XCTAssertTrue([[self.style sourceWithIdentifier:rasterSource.identifier] isMemberOfClass:[MGLRasterSource class]]);

View File

@@ -1317,15 +1317,33 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
{
MGLCoordinateQuad coordinateQuad = {
{ 46.437, -80.425 },
{ 46.437, -71.516 },
{ 37.936, -80.425 },
{ 37.936, -71.516 },
{ 37.936, -80.425 } };
{ 46.437, -71.516 } };
MGLImageSource *imageSource = [[MGLImageSource alloc] initWithIdentifier:@"style-image-source-id" coordinateQuad:coordinateQuad URL:[NSURL URLWithString:@"https://www.mapbox.com/mapbox-gl-js/assets/radar0.gif"]];
MGLImageSource *imageSource = [[MGLImageSource alloc] initWithIdentifier:@"style-image-source-id" coordinates:coordinateQuad imageURL:[NSURL URLWithString:@"https://www.mapbox.com/mapbox-gl-js/assets/radar.gif"]];
[self.mapView.style addSource:imageSource];
MGLRasterStyleLayer *rasterLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"style-raster-image-layer-id" source:imageSource];
[self.mapView.style addLayer:rasterLayer];
[NSTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(updateAnimatedImageSource:)
userInfo:imageSource
repeats:YES];
}
- (void)updateAnimatedImageSource:(NSTimer *)timer {
static int radarSuffix = 0;
MGLImageSource *imageSource = (MGLImageSource *)timer.userInfo;
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"https://www.mapbox.com/mapbox-gl-js/assets/radar%d.gif", radarSuffix++]];
[imageSource setValue:url forKey:@"URL"];
if (radarSuffix > 3) {
radarSuffix = 0;
}
}
-(void)styleCountryLabelsLanguage

View File

@@ -127,8 +127,9 @@ In style JSON | In the SDK
`geojson` | `MGLShapeSource`
`raster` | `MGLRasterSource`
`vector` | `MGLVectorSource`
`image` | `MGLImageSource`
`canvas`, `image`, and `video` sources are not supported.
`canvas` and `video` sources are not supported.
### Tile sources
@@ -169,6 +170,12 @@ To create a shape source from local GeoJSON data, first
[convert the GeoJSON data into a shape](working-with-geojson-data.html#converting-geojson-data-into-shape-objects),
then use the `-[MGLShapeSource initWithIdentifier:shape:options:]` method.
### Image sources
Image sources accept a non-axis aligned quadrilateral as their geographic coordinates.
These coordinates, in `MGLCoordinateQuad`, are described in counterclockwise order,
in contrast to the clockwise order defined in the style specification.
## Configuring the map content’s appearance
Each layer defined by the style JSON file is represented at runtime by a style

View File

@@ -9,8 +9,6 @@
/* Begin PBXBuildFile section */
071BBAFF1EE7613E001FB02A /* MGLImageSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 071BBAFD1EE75CD4001FB02A /* MGLImageSource.mm */; };
071BBB001EE7613F001FB02A /* MGLImageSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 071BBAFD1EE75CD4001FB02A /* MGLImageSource.mm */; };
071BBB011EE76142001FB02A /* MGLImageSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 071BBAFB1EE75CD4001FB02A /* MGLImageSource_Private.h */; };
071BBB021EE76143001FB02A /* MGLImageSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 071BBAFB1EE75CD4001FB02A /* MGLImageSource_Private.h */; };
071BBB031EE76146001FB02A /* MGLImageSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 071BBAFC1EE75CD4001FB02A /* MGLImageSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
071BBB041EE76147001FB02A /* MGLImageSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 071BBAFC1EE75CD4001FB02A /* MGLImageSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
071BBB071EE77631001FB02A /* MGLImageSourceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 071BBB051EE7761A001FB02A /* MGLImageSourceTests.m */; };
@@ -545,7 +543,6 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
071BBAFB1EE75CD4001FB02A /* MGLImageSource_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLImageSource_Private.h; sourceTree = "<group>"; };
071BBAFC1EE75CD4001FB02A /* MGLImageSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLImageSource.h; sourceTree = "<group>"; };
071BBAFD1EE75CD4001FB02A /* MGLImageSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLImageSource.mm; sourceTree = "<group>"; };
071BBB051EE7761A001FB02A /* MGLImageSourceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = MGLImageSourceTests.m; path = ../../darwin/test/MGLImageSourceTests.m; sourceTree = "<group>"; };
@@ -988,7 +985,6 @@
isa = PBXGroup;
children = (
071BBAFC1EE75CD4001FB02A /* MGLImageSource.h */,
071BBAFB1EE75CD4001FB02A /* MGLImageSource_Private.h */,
071BBAFD1EE75CD4001FB02A /* MGLImageSource.mm */,
3566C76A1D4A8DFA008152BC /* MGLRasterSource.h */,
DAF0D80F1DFE0EA000B28378 /* MGLRasterSource_Private.h */,
@@ -1721,7 +1717,6 @@
DA8847F21CBAFA5100AB86E3 /* MGLMapCamera.h in Headers */,
3538AA1D1D542239008EC33D /* MGLForegroundStyleLayer.h in Headers */,
DA8847F51CBAFA5100AB86E3 /* MGLOfflineRegion.h in Headers */,
071BBB011EE76142001FB02A /* MGLImageSource_Private.h in Headers */,
DA737EE11D056A4E005BDA16 /* MGLMapViewDelegate.h in Headers */,
DA8848851CBB033F00AB86E3 /* FABKitProtocol.h in Headers */,
DA88481B1CBAFA6200AB86E3 /* MGLGeometry_Private.h in Headers */,
@@ -1757,7 +1752,6 @@
FA68F14B1E9D656600F9F6C2 /* MGLFillExtrusionStyleLayer.h in Headers */,
353933FC1D3FB7C0003F57D7 /* MGLRasterStyleLayer.h in Headers */,
3566C76D1D4A8DFA008152BC /* MGLRasterSource.h in Headers */,
071BBB021EE76143001FB02A /* MGLImageSource_Private.h in Headers */,
DAED38641D62D0FC00D7640F /* NSURL+MGLAdditions.h in Headers */,
DABFB85E1CBE99E500D62B32 /* MGLAnnotation.h in Headers */,
DABFB8641CBE99E500D62B32 /* MGLOfflineStorage.h in Headers */,

View File

@@ -75,6 +75,7 @@ custom_categories:
children:
- MGLSource
- MGLTileSource
- MGLImageSource
- MGLShapeSource
- MGLRasterSource
- MGLVectorSource
@@ -108,6 +109,9 @@ custom_categories:
- MGLCoordinateBoundsMake
- MGLCoordinateBoundsOffset
- MGLCoordinateInCoordinateBounds
- MGLCoordinateQuad
- MGLCoordinateQuadMake
- MGLCoordinateQuadFromCoordinateBounds
- MGLCoordinateSpan
- MGLCoordinateSpanEqualToCoordinateSpan
- MGLCoordinateSpanMake
@@ -115,6 +119,7 @@ custom_categories:
- MGLDegreesFromRadians
- MGLRadiansFromDegrees
- MGLStringFromCoordinateBounds
- MGLStringFromCoordinateQuad
- name: Formatters
children:
- MGLClockDirectionFormatter

View File

@@ -10,7 +10,7 @@ NS_ASSUME_NONNULL_BEGIN
- (std::unique_ptr<mbgl::style::Image>)mgl_styleImageWithIdentifier:(NSString *)identifier;
- (mbgl::PremultipliedImage)mgl_PremultipliedImage;
- (mbgl::PremultipliedImage)mgl_premultipliedImage;
@end

View File

@@ -25,11 +25,11 @@
- (std::unique_ptr<mbgl::style::Image>)mgl_styleImageWithIdentifier:(NSString *)identifier {
BOOL isTemplate = self.renderingMode == UIImageRenderingModeAlwaysTemplate;
return std::make_unique<mbgl::style::Image>([identifier UTF8String],
self.mgl_PremultipliedImage,
self.mgl_premultipliedImage,
float(self.scale), isTemplate);
}
-(mbgl::PremultipliedImage)mgl_PremultipliedImage {
-(mbgl::PremultipliedImage)mgl_premultipliedImage {
return MGLPremultipliedImageFromCGImage(self.CGImage);
}
@end

View File

@@ -622,10 +622,10 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
MGLImage *image = [[NSBundle bundleForClass:[self class]] imageForResource:@"southeast_0"];
MGLCoordinateBounds bounds = { {22.551103322318994, -90.24006072802854}, {36.928147474567794, -75.1441643681673} };
MGLImageSource *imageSource = [[MGLImageSource alloc] initWithIdentifier:@"radar-source" bounds:bounds image:image];
MGLImageSource *imageSource = [[MGLImageSource alloc] initWithIdentifier:@"animated-radar-source" coordinateQuad:MGLCoordinateQuadFromCoordinateBounds(bounds) image:image];
[self.mapView.style addSource:imageSource];
MGLRasterStyleLayer * imageLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"radar-layer" source:imageSource];
MGLRasterStyleLayer * imageLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"animated-radar-layer" source:imageSource];
[self.mapView.style addLayer:imageLayer];
[NSTimer scheduledTimerWithTimeInterval:1.0
@@ -637,12 +637,15 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
- (void)updateAnimatedImageSource:(NSTimer *)timer {
static int radarSuffix = 0;
MGLImageSource *imageSource = (MGLImageSource *)timer.userInfo;
double timeInterval = timer.fireDate.timeIntervalSinceReferenceDate;
int radarSuffix = (int)timeInterval % 4;
MGLImage *image = [[NSBundle bundleForClass:[self class]] imageForResource:[NSString stringWithFormat:@"southeast_%d", radarSuffix]];
MGLImage *image = [[NSBundle bundleForClass:[self class]] imageForResource:[NSString stringWithFormat:@"southeast_%d", radarSuffix++]];
[imageSource setValue:image forKey:@"image"];
if(radarSuffix > 3) {
radarSuffix = 0 ;
}
}
- (IBAction)insertCustomStyleLayer:(id)sender {
@@ -741,10 +744,11 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"ams" URL:geoJSONURL options:nil];
[self.mapView.style addSource:source];
MGLFillStyleLayer *fillLayer = [[MGLFillStyleLayer alloc] initWithIdentifier:@"test" source:source];
fillLayer.fillColor = [MGLStyleValue<NSColor *> valueWithRawValue:[NSColor greenColor]];
fillLayer.predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"type", @"park"];
[self.mapView.style addLayer:fillLayer];
MGLCircleStyleLayer *circleLayer = [[MGLCircleStyleLayer alloc] initWithIdentifier:@"test" source:source];
circleLayer.circleColor = [MGLStyleValue<NSColor *> valueWithRawValue:[NSColor greenColor]];
circleLayer.circleRadius = [MGLStyleValue<NSNumber *> valueWithRawValue:[NSNumber numberWithInteger:40]];
// fillLayer.predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"type", @"park"];
[self.mapView.style addLayer:circleLayer];
MGLSource *streetsSource = [self.mapView.style sourceWithIdentifier:@"composite"];
if (streetsSource) {
@@ -764,12 +768,12 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
[self.mapView.style addLayer:theaterLayer];
}
MGLImage *image = [[NSBundle bundleForClass:[self class]] imageForResource:@"RadarImage"];
NSURL *imageURL = [NSURL URLWithString:@"https://www.mapbox.com/mapbox-gl-js/assets/radar.gif"];
MGLCoordinateQuad quad = { {46.437, -80.425},
{46.437, -71.516},
{37.936, -80.425},
{37.936, -71.516},
{37.936, -80.425} };
MGLImageSource *imageSource = [[MGLImageSource alloc] initWithIdentifier:@"radar-source" coordinates:quad image:image];
{46.437, -71.516} };
MGLImageSource *imageSource = [[MGLImageSource alloc] initWithIdentifier:@"radar-source" coordinateQuad:quad URL:imageURL];
[self.mapView.style addSource:imageSource];
MGLRasterStyleLayer * imageLayer = [[MGLRasterStyleLayer alloc] initWithIdentifier:@"radar-layer" source:imageSource];

View File

@@ -116,8 +116,9 @@ In style JSON | In the SDK
`geojson` | `MGLShapeSource`
`raster` | `MGLRasterSource`
`vector` | `MGLVectorSource`
`image` | `MGLImageSource`
`canvas`, `image`, and `video` sources are not supported.
`canvas` and `video` sources are not supported.
### Tile sources
@@ -158,6 +159,12 @@ To create a shape source from local GeoJSON data, first
[convert the GeoJSON data into a shape](working-with-geojson-data.html#converting-geojson-data-into-shape-objects),
then use the `-[MGLShapeSource initWithIdentifier:shape:options:]` method.
### Image sources
Image sources accept a non-axis aligned quadrilateral as their geographic coordinates.
These coordinates, in `MGLCoordinateQuad`, are described in counterclockwise order,
in contrast to the clockwise order defined in the style specification.
## Configuring the map content’s appearance
Each layer defined by the style JSON file is represented at runtime by a style

View File

@@ -274,7 +274,6 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
07A019EA1ED662D800ACD43E /* MGLImageSource_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLImageSource_Private.h; sourceTree = "<group>"; };
07A019EB1ED662D800ACD43E /* MGLImageSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLImageSource.h; sourceTree = "<group>"; };
07A019EC1ED662D800ACD43E /* MGLImageSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLImageSource.mm; sourceTree = "<group>"; };
07BA4CAB1EE21887004528F5 /* MGLImageSourceTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLImageSourceTests.m; sourceTree = "<group>"; };
@@ -671,7 +670,6 @@
DA8F25951D51CAC70010E6B5 /* MGLVectorSource.h */,
DA7DC9801DED5F5C0027472F /* MGLVectorSource_Private.h */,
DA8F25961D51CAC70010E6B5 /* MGLVectorSource.mm */,
07A019EA1ED662D800ACD43E /* MGLImageSource_Private.h */,
07A019EB1ED662D800ACD43E /* MGLImageSource.h */,
07A019EC1ED662D800ACD43E /* MGLImageSource.mm */,
);

View File

@@ -20,6 +20,7 @@
#import "MGLPolyline.h"
#import "MGLAnnotationImage.h"
#import "MGLMapViewDelegate.h"
#import "MGLImageSource.h"
#import <mbgl/map/map.hpp>
#import <mbgl/map/view.hpp>
@@ -943,13 +944,16 @@ public:
}
}
- (void)sourceDidChange {
- (void)sourceDidChange:(MGLSource *)source {
if (!_mbglMap) {
return;
}
[self installAttributionView];
// Attribution only applies to tiled sources
if ([source isKindOfClass:[MGLTileSource class]]) {
[self installAttributionView];
}
self.needsUpdateConstraints = YES;
self.needsDisplay = YES;
}
#pragma mark Printing
@@ -2847,8 +2851,10 @@ public:
[nativeView mapViewDidFinishLoadingStyle];
}
void onSourceChanged(mbgl::style::Source&) override {
[nativeView sourceDidChange];
void onSourceChanged(mbgl::style::Source& source) override {
NSString *identifier = @(source.getID().c_str());
MGLSource * nativeSource = [nativeView.style sourceWithIdentifier:identifier];
[nativeView sourceDidChange:nativeSource];
}
mbgl::gl::ProcAddress initializeExtension(const char* name) override {

View File

@@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN
- (std::unique_ptr<mbgl::style::Image>)mgl_styleImageWithIdentifier:(NSString *)identifier;
- (mbgl::PremultipliedImage) mgl_PremultipliedImage;
- (mbgl::PremultipliedImage) mgl_premultipliedImage;
@end

View File

@@ -33,7 +33,7 @@
}
- (std::unique_ptr<mbgl::style::Image>)mgl_styleImageWithIdentifier:(NSString *)identifier {
mbgl::PremultipliedImage cPremultipliedImage = self.mgl_PremultipliedImage;
mbgl::PremultipliedImage cPremultipliedImage = self.mgl_premultipliedImage;
auto imageWidth = cPremultipliedImage.size.width;
return std::make_unique<mbgl::style::Image>([identifier UTF8String],
std::move(cPremultipliedImage),
@@ -41,7 +41,7 @@
[self isTemplate]);
}
- (mbgl::PremultipliedImage)mgl_PremultipliedImage {
- (mbgl::PremultipliedImage)mgl_premultipliedImage {
// Create a bitmap image representation from the image, respecting backing
// scale factor and any resizing done on the image at runtime.
// http://www.cocoabuilder.com/archive/cocoa/82430-nsimage-getting-raw-bitmap-data.html#82431

View File

@@ -20,7 +20,7 @@ const ImageSource::Impl& ImageSource::impl() const {
void ImageSource::setCoordinates(const std::array<LatLng, 4>& coords_) {
baseImpl = makeMutable<Impl>(impl(), coords_);
observer->onSourceChanged(*this);
observer->onSourceLoaded(*this);
}
std::array<LatLng, 4> ImageSource::getCoordinates() const {
@@ -44,7 +44,7 @@ void ImageSource::setImage(UnassociatedImage&& image_) {
}
loaded = true;
baseImpl = makeMutable<Impl>(impl(), std::move(image_));
observer->onSourceChanged(*this);
observer->onSourceLoaded(*this);
}
optional<std::string> ImageSource::getURL() const {

View File

@@ -518,7 +518,7 @@ TEST(Source, ImageSourceImageUpdate) {
response.data = std::make_unique<std::string>(util::read_file("test/fixtures/image/no_profile.png"));
return response;
};
test.styleObserver.sourceChanged = [&] (Source&) {
test.styleObserver.sourceLoaded = [&] (Source&) {
// Should be called (test will hang if it doesn't)
test.end();
};