diff options
author | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2017-06-13 12:55:01 -0700 |
---|---|---|
committer | Asheem Mamoowala <asheem.mamoowala@mapbox.com> | 2017-06-19 09:50:08 -0700 |
commit | 7f36e0cf769f6fe7a759b1cf6c56948c4c141fef (patch) | |
tree | 2b72187a6306df9d97d4b57007bd64c86a4bf4c7 /platform | |
parent | b7c7d3fdab283d7bf03d8acf68b9cfd478d6973f (diff) | |
download | qtlocation-mapboxgl-7f36e0cf769f6fe7a759b1cf6c56948c4c141fef.tar.gz |
[iOS][macOS] Export `MGLImageSource`, add and update documentation. Use animated ImageSource demo in iOS test app
Diffstat (limited to 'platform')
22 files changed, 169 insertions, 161 deletions
diff --git a/platform/darwin/src/MGLGeometry.h b/platform/darwin/src/MGLGeometry.h index 003a7638e7..3a3e59fb3e 100644 --- a/platform/darwin/src/MGLGeometry.h +++ b/platform/darwin/src/MGLGeometry.h @@ -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; diff --git a/platform/darwin/src/MGLGeometry_Private.h b/platform/darwin/src/MGLGeometry_Private.h index bdc838667a..88fcf5b576 100644 --- a/platform/darwin/src/MGLGeometry_Private.h +++ b/platform/darwin/src/MGLGeometry_Private.h @@ -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 diff --git a/platform/darwin/src/MGLImageSource.h b/platform/darwin/src/MGLImageSource.h index 9ef2c6719a..21487d9739 100644 --- a/platform/darwin/src/MGLImageSource.h +++ b/platform/darwin/src/MGLImageSource.h @@ -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 diff --git a/platform/darwin/src/MGLImageSource.mm b/platform/darwin/src/MGLImageSource.mm index 9872a65aff..0a2dc2713f 100644 --- a/platform/darwin/src/MGLImageSource.mm +++ b/platform/darwin/src/MGLImageSource.mm @@ -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 { diff --git a/platform/darwin/src/MGLImageSource_Private.h b/platform/darwin/src/MGLImageSource_Private.h deleted file mode 100644 index 54f6e00afa..0000000000 --- a/platform/darwin/src/MGLImageSource_Private.h +++ /dev/null @@ -1,9 +0,0 @@ -#import "MGLImageSource.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface MGLImageSource (Private) - -@end - -NS_ASSUME_NONNULL_END diff --git a/platform/darwin/src/MGLOfflineStorage.h b/platform/darwin/src/MGLOfflineStorage.h index 90ba15c84c..b009f893b3 100644 --- a/platform/darwin/src/MGLOfflineStorage.h +++ b/platform/darwin/src/MGLOfflineStorage.h @@ -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, }; diff --git a/platform/darwin/src/MGLSource.h b/platform/darwin/src/MGLSource.h index 8bf48907cc..f990aedd67 100644 --- a/platform/darwin/src/MGLSource.h +++ b/platform/darwin/src/MGLSource.h @@ -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 diff --git a/platform/darwin/test/MGLDocumentationExampleTests.swift b/platform/darwin/test/MGLDocumentationExampleTests.swift index 2a441d2774..ae72b35d82 100644 --- a/platform/darwin/test/MGLDocumentationExampleTests.swift +++ b/platform/darwin/test/MGLDocumentationExampleTests.swift @@ -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() { diff --git a/platform/darwin/test/MGLImageSourceTests.m b/platform/darwin/test/MGLImageSourceTests.m index 3349a7463b..38fcd38709 100644 --- a/platform/darwin/test/MGLImageSourceTests.m +++ b/platform/darwin/test/MGLImageSourceTests.m @@ -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); diff --git a/platform/darwin/test/MGLStyleTests.mm b/platform/darwin/test/MGLStyleTests.mm index 7f82dddfac..608cfdfd2d 100644 --- a/platform/darwin/test/MGLStyleTests.mm +++ b/platform/darwin/test/MGLStyleTests.mm @@ -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]]); diff --git a/platform/ios/app/MBXViewController.m b/platform/ios/app/MBXViewController.m index 756f4d5516..29c5c65012 100644 --- a/platform/ios/app/MBXViewController.m +++ b/platform/ios/app/MBXViewController.m @@ -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 diff --git a/platform/ios/docs/guides/For Style Authors.md b/platform/ios/docs/guides/For Style Authors.md index 734e0dc9ee..8b7bc05f2c 100644 --- a/platform/ios/docs/guides/For Style Authors.md +++ b/platform/ios/docs/guides/For Style Authors.md @@ -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 diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj index 0ed3fdbe8c..a906c4fd77 100644 --- a/platform/ios/ios.xcodeproj/project.pbxproj +++ b/platform/ios/ios.xcodeproj/project.pbxproj @@ -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 */, diff --git a/platform/ios/jazzy.yml b/platform/ios/jazzy.yml index 31380faa2c..ba56c312eb 100644 --- a/platform/ios/jazzy.yml +++ b/platform/ios/jazzy.yml @@ -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 diff --git a/platform/ios/src/UIImage+MGLAdditions.h b/platform/ios/src/UIImage+MGLAdditions.h index 671a5ced85..6e15e07cb5 100644 --- a/platform/ios/src/UIImage+MGLAdditions.h +++ b/platform/ios/src/UIImage+MGLAdditions.h @@ -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 diff --git a/platform/ios/src/UIImage+MGLAdditions.mm b/platform/ios/src/UIImage+MGLAdditions.mm index 029366c01e..5e28d18190 100644 --- a/platform/ios/src/UIImage+MGLAdditions.mm +++ b/platform/ios/src/UIImage+MGLAdditions.mm @@ -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 diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m index 281497ac92..94bf18dea1 100644 --- a/platform/macos/app/MapDocument.m +++ b/platform/macos/app/MapDocument.m @@ -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]; diff --git a/platform/macos/docs/guides/For Style Authors.md b/platform/macos/docs/guides/For Style Authors.md index 164b1b58bf..3cacc81376 100644 --- a/platform/macos/docs/guides/For Style Authors.md +++ b/platform/macos/docs/guides/For Style Authors.md @@ -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 diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj index 248f913a35..723bbc6f4b 100644 --- a/platform/macos/macos.xcodeproj/project.pbxproj +++ b/platform/macos/macos.xcodeproj/project.pbxproj @@ -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 */, ); diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index a8a84522a5..d2cb5e7100 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -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 { diff --git a/platform/macos/src/NSImage+MGLAdditions.h b/platform/macos/src/NSImage+MGLAdditions.h index 0e57784bc5..c08fc57bea 100644 --- a/platform/macos/src/NSImage+MGLAdditions.h +++ b/platform/macos/src/NSImage+MGLAdditions.h @@ -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 diff --git a/platform/macos/src/NSImage+MGLAdditions.mm b/platform/macos/src/NSImage+MGLAdditions.mm index e4ef38eea5..6abe53e9ae 100644 --- a/platform/macos/src/NSImage+MGLAdditions.mm +++ b/platform/macos/src/NSImage+MGLAdditions.mm @@ -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 |