summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2018-01-25 10:46:27 -0800
committerGitHub <noreply@github.com>2018-01-25 10:46:27 -0800
commitb6747a84f4ba6bd48ab2d461e04cffa7fc8d5348 (patch)
treee01efa0e57e6dc5a0a55db2f68bc964cb6fb1606
parenta4546a84de28cfddfcb1e5a4ba8b0516a4b4dfa4 (diff)
downloadqtlocation-mapboxgl-b6747a84f4ba6bd48ab2d461e04cffa7fc8d5348.tar.gz
[ios, macos] Hook up hillshade style layers, raster DEM sources to iOS/macOS (#11036)
* [ios, macos] Finished implementing MGLHillshadeStyleLayer * [macos] Added icon for hillshade layer Also set the background layer icon to mirror in right-to-left locales. * [ios, macos] Implemented raster DEM source * [macos] Added Enhance Terrain debugging command * [ios, macos] Simplified raster DEM source example
-rw-r--r--platform/darwin/scripts/style-spec-overrides-v8.json3
-rw-r--r--platform/darwin/src/MGLForegroundStyleLayer.h9
-rw-r--r--platform/darwin/src/MGLHillshadeStyleLayer.h25
-rw-r--r--platform/darwin/src/MGLHillshadeStyleLayer.mm29
-rw-r--r--platform/darwin/src/MGLRasterDEMSource.h37
-rw-r--r--platform/darwin/src/MGLRasterDEMSource.mm17
-rw-r--r--platform/darwin/src/MGLRasterSource.mm11
-rw-r--r--platform/darwin/src/MGLRasterSource_Private.h13
-rw-r--r--platform/darwin/src/MGLStyle.mm8
-rw-r--r--platform/darwin/src/MGLStyleLayer.h.ejs4
-rw-r--r--platform/darwin/src/MGLStyleLayer.mm.ejs2
-rw-r--r--platform/darwin/test/MGLDocumentationExampleTests.swift47
-rw-r--r--platform/darwin/test/MGLHillshadeStyleLayerTests.mm18
-rw-r--r--platform/darwin/test/MGLStyleLayerTests.mm.ejs2
-rw-r--r--platform/ios/CHANGELOG.md3
-rw-r--r--platform/ios/ios.xcodeproj/project.pbxproj28
-rw-r--r--platform/ios/jazzy.yml2
-rw-r--r--platform/ios/src/Mapbox.h2
-rw-r--r--platform/macos/CHANGELOG.md3
-rw-r--r--platform/macos/app/Assets.xcassets/Layers/background.imageset/Contents.json3
-rw-r--r--platform/macos/app/Assets.xcassets/Layers/hillshade.imageset/Contents.json16
-rw-r--r--platform/macos/app/Assets.xcassets/Layers/hillshade.imageset/hillshade.pdf70
-rw-r--r--platform/macos/app/Base.lproj/MainMenu.xib50
-rw-r--r--platform/macos/app/MapDocument.m65
-rw-r--r--platform/macos/app/StyleLayerIconTransformer.m5
-rw-r--r--platform/macos/app/resources/hillshade.svg87
-rw-r--r--platform/macos/jazzy.yml2
-rw-r--r--platform/macos/macos.xcodeproj/project.pbxproj24
-rw-r--r--platform/macos/src/Mapbox.h2
29 files changed, 496 insertions, 91 deletions
diff --git a/platform/darwin/scripts/style-spec-overrides-v8.json b/platform/darwin/scripts/style-spec-overrides-v8.json
index 3da2443096..12cfa31575 100644
--- a/platform/darwin/scripts/style-spec-overrides-v8.json
+++ b/platform/darwin/scripts/style-spec-overrides-v8.json
@@ -26,6 +26,9 @@
"raster": {
"doc": "An `MGLRasterStyleLayer` is a style layer that renders georeferenced raster imagery on the map, especially raster tiles.\n\nUse a raster style layer to configure the color parameters of raster tiles loaded by an `MGLRasterSource` object or raster images loaded by an `MGLImageSource` object. For example, you could use a raster style layer to render <a href=\"https://www.mapbox.com/satellite/\">Mapbox Satellite</a> imagery, a <a href=\"https://www.mapbox.com/help/define-tileset/#raster-tilesets\">raster tile set</a> uploaded to Mapbox Studio, or a raster map authored in <a href=\"https://tilemill-project.github.io/tilemill/\">TileMill</a>, the classic Mapbox Editor, or Mapbox Studio Classic.\n\nRaster 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."
},
+ "hillshade": {
+ "doc": "An `MGLHillshadeStyleLayer` is a style layer that renders raster <a href=\"https://en.wikipedia.org/wiki/Digital_elevation_model\">digital elevation model</a> (DEM) tiles on the map.\n\nUse a hillshade style layer to configure the color parameters of raster tiles loaded by an `MGLRasterDEMSource` object. For example, you could use a hillshade style layer to render <a href=\"https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb\">Mapbox Terrain-RGB</a> data.\n\nTo display posterized hillshading based on vector shapes, as with the <a href=\"https://www.mapbox.com/vector-tiles/mapbox-terrain/\">Mapbox Terrain</a> source, use an `MGLVectorSource` object in conjunction with several `MGLFillStyleLayer` objects."
+ },
"background": {
"doc": "An `MGLBackgroundStyleLayer` is a style layer that covers the entire map. Use a background style layer to configure a color or pattern to show below all other map content. If the style’s other layers use the Mapbox Streets source, the background style layer is responsible for drawing land, whereas the oceans and other bodies of water are drawn by `MGLFillStyleLayer` objects.\n\nA background style layer is typically the bottommost layer in a style, because it covers the entire map and can occlude any layers below it. You can therefore access it by getting the last item in the `MGLStyle.layers` array.\n\nIf the background style layer is transparent or omitted from the style, any portion of the map view that does not show another style layer is transparent."
}
diff --git a/platform/darwin/src/MGLForegroundStyleLayer.h b/platform/darwin/src/MGLForegroundStyleLayer.h
index bcd323fb99..7e05023ef1 100644
--- a/platform/darwin/src/MGLForegroundStyleLayer.h
+++ b/platform/darwin/src/MGLForegroundStyleLayer.h
@@ -11,10 +11,11 @@ NS_ASSUME_NONNULL_BEGIN
`MGLForegroundStyleLayer` is an abstract superclass for style layers whose
content is defined by an `MGLSource` object.
- Create instances of `MGLRasterStyleLayer` and the concrete subclasses of
- `MGLVectorStyleLayer` in order to use `MGLForegroundStyleLayer`'s methods.
- Do not create instances of `MGLForegroundStyleLayer` directly, and do not
- create your own subclasses of this class.
+ Create instances of `MGLRasterStyleLayer`, `MGLHillshadeStyleLayer`, and the
+ concrete subclasses of `MGLVectorStyleLayer` in order to use
+ `MGLForegroundStyleLayer`'s methods. Do not create instances of
+ `MGLForegroundStyleLayer` directly, and do not create your own subclasses of
+ this class.
*/
MGL_EXPORT
@interface MGLForegroundStyleLayer : MGLStyleLayer
diff --git a/platform/darwin/src/MGLHillshadeStyleLayer.h b/platform/darwin/src/MGLHillshadeStyleLayer.h
index 199bf214c2..b2eeb59aba 100644
--- a/platform/darwin/src/MGLHillshadeStyleLayer.h
+++ b/platform/darwin/src/MGLHillshadeStyleLayer.h
@@ -2,7 +2,7 @@
// Edit platform/darwin/scripts/generate-style-code.js, then run `make darwin-style-code`.
#import "MGLFoundation.h"
-#import "MGLVectorStyleLayer.h"
+#import "MGLForegroundStyleLayer.h"
NS_ASSUME_NONNULL_BEGIN
@@ -24,8 +24,20 @@ typedef NS_ENUM(NSUInteger, MGLHillshadeIlluminationAnchor) {
};
/**
- Client-side hillshading visualization based on DEM data. Currently, the
- implementation only supports Mapbox Terrain RGB tiles
+ An `MGLHillshadeStyleLayer` is a style layer that renders raster <a
+ href="https://en.wikipedia.org/wiki/Digital_elevation_model">digital elevation
+ model</a> (DEM) tiles on the map.
+
+ Use a hillshade style layer to configure the color parameters of raster tiles
+ loaded by an `MGLRasterDEMSource` object. For example, you could use a
+ hillshade style layer to render <a
+ href="https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb">Mapbox
+ Terrain-RGB</a> data.
+
+ To display posterized hillshading based on vector shapes, as with the <a
+ href="https://www.mapbox.com/vector-tiles/mapbox-terrain/">Mapbox Terrain</a>
+ source, use an `MGLVectorSource` object in conjunction with several
+ `MGLFillStyleLayer` objects.
You can access an existing hillshade style layer using the
`-[MGLStyle layerWithIdentifier:]` method if you know its identifier;
@@ -36,10 +48,15 @@ typedef NS_ENUM(NSUInteger, MGLHillshadeIlluminationAnchor) {
### Example
```swift
+ let layer = MGLHillshadeStyleLayer(identifier: "hills", source: source)
+ layer.hillshadeExaggeration = NSExpression(forConstantValue: 0.6)
+ if let canalShadowLayer = mapView.style?.layer(withIdentifier: "waterway-river-canal-shadow") {
+ mapView.style?.insertLayer(layer, below: canalShadowLayer)
+ }
```
*/
MGL_EXPORT
-@interface MGLHillshadeStyleLayer : MGLVectorStyleLayer
+@interface MGLHillshadeStyleLayer : MGLForegroundStyleLayer
/**
Returns a hillshade style layer initialized with an identifier and source.
diff --git a/platform/darwin/src/MGLHillshadeStyleLayer.mm b/platform/darwin/src/MGLHillshadeStyleLayer.mm
index 538a99daf6..2383c1ce26 100644
--- a/platform/darwin/src/MGLHillshadeStyleLayer.mm
+++ b/platform/darwin/src/MGLHillshadeStyleLayer.mm
@@ -46,35 +46,6 @@ namespace mbgl {
return @(self.rawLayer->getSourceID().c_str());
}
-- (NSString *)sourceLayerIdentifier
-{
- MGLAssertStyleLayerIsValid();
-
- auto layerID = self.rawLayer->getSourceLayer();
- return layerID.empty() ? nil : @(layerID.c_str());
-}
-
-- (void)setSourceLayerIdentifier:(NSString *)sourceLayerIdentifier
-{
- MGLAssertStyleLayerIsValid();
-
- self.rawLayer->setSourceLayer(sourceLayerIdentifier.UTF8String ?: "");
-}
-
-- (void)setPredicate:(NSPredicate *)predicate
-{
- MGLAssertStyleLayerIsValid();
-
- self.rawLayer->setFilter(predicate ? predicate.mgl_filter : mbgl::style::NullFilter());
-}
-
-- (NSPredicate *)predicate
-{
- MGLAssertStyleLayerIsValid();
-
- return [NSPredicate mgl_predicateWithFilter:self.rawLayer->getFilter()];
-}
-
#pragma mark - Accessing the Paint Attributes
- (void)setHillshadeAccentColor:(NSExpression *)hillshadeAccentColor {
diff --git a/platform/darwin/src/MGLRasterDEMSource.h b/platform/darwin/src/MGLRasterDEMSource.h
new file mode 100644
index 0000000000..d00912ca79
--- /dev/null
+++ b/platform/darwin/src/MGLRasterDEMSource.h
@@ -0,0 +1,37 @@
+#import "MGLFoundation.h"
+
+#import "MGLRasterSource.h"
+
+/**
+ `MGLRasterDEMSource` is a map content source that supplies rasterized
+ <a href="https://en.wikipedia.org/wiki/Digital_elevation_model">digital elevation model</a>
+ (DEM) tiles to be shown on the map. The location of and metadata about the
+ tiles are defined either by an option dictionary or by an external file that
+ conforms to the
+ <a href="https://github.com/mapbox/tilejson-spec/">TileJSON specification</a>.
+ A raster DEM source is added to an `MGLStyle` object along with one or more
+ `MGLHillshadeStyleLayer` objects. Use a hillshade style layer to control the
+ appearance of content supplied by the raster DEM source.
+
+ Each
+ <a href="https://www.mapbox.com/mapbox-gl-style-spec/#sources-raster-dem"><code>raster-dem</code></a>
+ source defined by the style JSON file is represented at runtime by an
+ `MGLRasterDEMSource` object that you can use to initialize new style layers.
+ You can also add and remove sources dynamically using methods such as
+ `-[MGLStyle addSource:]` and `-[MGLStyle sourceWithIdentifier:]`.
+
+ Currently, raster DEM sources only support the format used by
+ <a href="https://www.mapbox.com/help/access-elevation-data/#mapbox-terrain-rgb">Mapbox Terrain-RGB</a>.
+
+ ### Example
+
+ ```swift
+ let terrainRGBURL = URL(string: "mapbox://mapbox.terrain-rgb")!
+ let source = MGLRasterDEMSource(identifier: "hills", configurationURL: terrainRGBURL)
+ mapView.style?.addSource(source)
+ ```
+ */
+MGL_EXPORT
+@interface MGLRasterDEMSource : MGLRasterSource
+
+@end
diff --git a/platform/darwin/src/MGLRasterDEMSource.mm b/platform/darwin/src/MGLRasterDEMSource.mm
new file mode 100644
index 0000000000..d8639b70e3
--- /dev/null
+++ b/platform/darwin/src/MGLRasterDEMSource.mm
@@ -0,0 +1,17 @@
+#import "MGLRasterDEMSource.h"
+
+#import "MGLRasterSource_Private.h"
+#import "NSURL+MGLAdditions.h"
+
+#import <mbgl/style/sources/raster_dem_source.hpp>
+
+@implementation MGLRasterDEMSource
+
+- (std::unique_ptr<mbgl::style::RasterSource>)pendingSourceWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL tileSize:(CGFloat)tileSize {
+ NSString *configurationURLString = configurationURL.mgl_URLByStandardizingScheme.absoluteString;
+ return std::make_unique<mbgl::style::RasterDEMSource>(identifier.UTF8String,
+ configurationURLString.UTF8String,
+ uint16_t(round(tileSize)));
+}
+
+@end
diff --git a/platform/darwin/src/MGLRasterSource.mm b/platform/darwin/src/MGLRasterSource.mm
index 8fc18ba69d..c47cc199eb 100644
--- a/platform/darwin/src/MGLRasterSource.mm
+++ b/platform/darwin/src/MGLRasterSource.mm
@@ -33,12 +33,17 @@ static const CGFloat MGLRasterSourceRetinaTileSize = 512;
}
- (instancetype)initWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL tileSize:(CGFloat)tileSize {
- auto source = std::make_unique<mbgl::style::RasterSource>(identifier.UTF8String,
- configurationURL.mgl_URLByStandardizingScheme.absoluteString.UTF8String,
- uint16_t(round(tileSize)));
+ auto source = [self pendingSourceWithIdentifier:identifier configurationURL:configurationURL tileSize:tileSize];
return self = [super initWithPendingSource:std::move(source)];
}
+- (std::unique_ptr<mbgl::style::RasterSource>)pendingSourceWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL tileSize:(CGFloat)tileSize {
+ NSString *configurationURLString = configurationURL.mgl_URLByStandardizingScheme.absoluteString;
+ return std::make_unique<mbgl::style::RasterSource>(identifier.UTF8String,
+ configurationURLString.UTF8String,
+ uint16_t(round(tileSize)));
+}
+
- (instancetype)initWithIdentifier:(NSString *)identifier tileURLTemplates:(NS_ARRAY_OF(NSString *) *)tileURLTemplates options:(nullable NS_DICTIONARY_OF(MGLTileSourceOption, id) *)options {
mbgl::Tileset tileSet = MGLTileSetFromTileURLTemplates(tileURLTemplates, options);
diff --git a/platform/darwin/src/MGLRasterSource_Private.h b/platform/darwin/src/MGLRasterSource_Private.h
index 76790bd053..6f40fbc5a9 100644
--- a/platform/darwin/src/MGLRasterSource_Private.h
+++ b/platform/darwin/src/MGLRasterSource_Private.h
@@ -1,8 +1,21 @@
#import "MGLRasterSource.h"
+#include <memory>
+
+namespace mbgl {
+ namespace style {
+ class RasterSource;
+ }
+}
+
NS_ASSUME_NONNULL_BEGIN
@interface MGLRasterSource (Private)
+
+@property (nonatomic, readonly) mbgl::style::RasterSource *rawSource;
+
+- (std::unique_ptr<mbgl::style::RasterSource>)pendingSourceWithIdentifier:(NSString *)identifier configurationURL:(NSURL *)configurationURL tileSize:(CGFloat)tileSize;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm
index fefd8fcf37..5128944312 100644
--- a/platform/darwin/src/MGLStyle.mm
+++ b/platform/darwin/src/MGLStyle.mm
@@ -8,6 +8,7 @@
#import "MGLLineStyleLayer.h"
#import "MGLCircleStyleLayer.h"
#import "MGLSymbolStyleLayer.h"
+#import "MGLHillshadeStyleLayer.h"
#import "MGLRasterStyleLayer.h"
#import "MGLBackgroundStyleLayer.h"
#import "MGLOpenGLStyleLayer.h"
@@ -19,6 +20,7 @@
#import "MGLVectorSource.h"
#import "MGLVectorSource_Private.h"
#import "MGLRasterSource.h"
+#import "MGLRasterDEMSource.h"
#import "MGLShapeSource.h"
#import "MGLImageSource.h"
@@ -34,12 +36,14 @@
#include <mbgl/style/layers/line_layer.hpp>
#include <mbgl/style/layers/symbol_layer.hpp>
#include <mbgl/style/layers/raster_layer.hpp>
+#include <mbgl/style/layers/hillshade_layer.hpp>
#include <mbgl/style/layers/circle_layer.hpp>
#include <mbgl/style/layers/background_layer.hpp>
#include <mbgl/style/layers/custom_layer.hpp>
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/sources/vector_source.hpp>
#include <mbgl/style/sources/raster_source.hpp>
+#include <mbgl/style/sources/raster_dem_source.hpp>
#include <mbgl/style/sources/image_source.hpp>
#import "NSDate+MGLAdditions.h"
@@ -231,6 +235,8 @@ static NSURL *MGLStyleURL_trafficNight;
return [[MGLShapeSource alloc] initWithRawSource:geoJSONSource mapView:self.mapView];
} else if (auto rasterSource = rawSource->as<mbgl::style::RasterSource>()) {
return [[MGLRasterSource alloc] initWithRawSource:rasterSource mapView:self.mapView];
+ } else if (auto rasterDEMSource = rawSource->as<mbgl::style::RasterDEMSource>()) {
+ return [[MGLRasterDEMSource alloc] initWithRawSource:rasterDEMSource mapView:self.mapView];
} else if (auto imageSource = rawSource->as<mbgl::style::ImageSource>()) {
return [[MGLImageSource alloc] initWithRawSource:imageSource mapView:self.mapView];
} else {
@@ -395,6 +401,8 @@ static NSURL *MGLStyleURL_trafficNight;
return [[MGLSymbolStyleLayer alloc] initWithRawLayer:symbolLayer];
} else if (auto rasterLayer = rawLayer->as<mbgl::style::RasterLayer>()) {
return [[MGLRasterStyleLayer alloc] initWithRawLayer:rasterLayer];
+ } else if (auto hillshadeLayer = rawLayer->as<mbgl::style::HillshadeLayer>()) {
+ return [[MGLHillshadeStyleLayer alloc] initWithRawLayer:hillshadeLayer];
} else if (auto circleLayer = rawLayer->as<mbgl::style::CircleLayer>()) {
return [[MGLCircleStyleLayer alloc] initWithRawLayer:circleLayer];
} else if (auto backgroundLayer = rawLayer->as<mbgl::style::BackgroundLayer>()) {
diff --git a/platform/darwin/src/MGLStyleLayer.h.ejs b/platform/darwin/src/MGLStyleLayer.h.ejs
index db16df3de5..05f450a4f8 100644
--- a/platform/darwin/src/MGLStyleLayer.h.ejs
+++ b/platform/darwin/src/MGLStyleLayer.h.ejs
@@ -11,7 +11,7 @@
#import "MGLFoundation.h"
#import "MGL<%-
(type === 'background' ? '' :
- (type === 'raster' ? 'Foreground' :
+ (type === 'raster' || type === 'hillshade' ? 'Foreground' :
'Vector'))
%>StyleLayer.h"
@@ -78,7 +78,7 @@ typedef NS_ENUM(NSUInteger, MGL<%- camelize(property.name) %>) {
MGL_EXPORT
@interface MGL<%- camelize(type) %>StyleLayer : MGL<%-
(type === 'background' ? '' :
- (type === 'raster' ? 'Foreground' :
+ (type === 'raster' || type === 'hillshade' ? 'Foreground' :
'Vector'))
%>StyleLayer
<% if (type === 'background') { -%>
diff --git a/platform/darwin/src/MGLStyleLayer.mm.ejs b/platform/darwin/src/MGLStyleLayer.mm.ejs
index 8101c1f463..41b029791f 100644
--- a/platform/darwin/src/MGLStyleLayer.mm.ejs
+++ b/platform/darwin/src/MGLStyleLayer.mm.ejs
@@ -83,7 +83,7 @@ namespace mbgl {
return @(self.rawLayer->getSourceID().c_str());
}
-<% if (type !== 'raster') { -%>
+<% if (type !== 'raster' && type !== 'hillshade') { -%>
- (NSString *)sourceLayerIdentifier
{
MGLAssertStyleLayerIsValid();
diff --git a/platform/darwin/test/MGLDocumentationExampleTests.swift b/platform/darwin/test/MGLDocumentationExampleTests.swift
index d3e2bf91f2..9bf9924869 100644
--- a/platform/darwin/test/MGLDocumentationExampleTests.swift
+++ b/platform/darwin/test/MGLDocumentationExampleTests.swift
@@ -88,6 +88,26 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate {
XCTAssertNotNil(mapView.style?.source(withIdentifier: "clouds"))
}
+
+ func testMGLRasterDEMSource() {
+ // We want to use mapbox.terrain-rgb in the example, but using a mapbox:
+ // URL requires setting an access token. So this identically named
+ // subclass of MGLRasterDEMSource swaps in a nonexistent URL.
+ class MGLRasterDEMSource: Mapbox.MGLRasterDEMSource {
+ override init(identifier: String, configurationURL: URL, tileSize: CGFloat = 256) {
+ let bogusURL = URL(string: "https://example.com/raster-rgb.json")!
+ super.init(identifier: identifier, configurationURL: bogusURL, tileSize: tileSize)
+ }
+ }
+
+ //#-example-code
+ let terrainRGBURL = URL(string: "mapbox://mapbox.terrain-rgb")!
+ let source = MGLRasterDEMSource(identifier: "hills", configurationURL: terrainRGBURL)
+ mapView.style?.addSource(source)
+ //#-end-example-code
+
+ XCTAssertNotNil(mapView.style?.source(withIdentifier: "hills"))
+ }
func testMGLVectorSource() {
//#-example-code
@@ -256,6 +276,33 @@ class MGLDocumentationExampleTests: XCTestCase, MGLMapViewDelegate {
XCTAssertNotNil(mapView.style?.layer(withIdentifier: "clouds"))
}
+ func testMGLHillshadeStyleLayer() {
+ let source = MGLRasterDEMSource(identifier: "dem", tileURLTemplates: ["https://example.com/raster-rgb/{z}/{x}/{y}.png"], options: [
+ .minimumZoomLevel: 9,
+ .maximumZoomLevel: 16,
+ .tileSize: 256,
+ .attributionInfos: [
+ MGLAttributionInfo(title: NSAttributedString(string: "© Mapbox"), url: URL(string: "http://mapbox.com"))
+ ]
+ ])
+ mapView.style?.addSource(source)
+
+ let canals = MGLVectorSource(identifier: "canals", configurationURL: URL(string: "https://example.com/style.json")!)
+ mapView.style?.addSource(canals)
+ let canalShadowLayer = MGLLineStyleLayer(identifier: "waterway-river-canal-shadow", source: canals)
+ mapView.style?.addLayer(canalShadowLayer)
+
+ //#-example-code
+ let layer = MGLHillshadeStyleLayer(identifier: "hills", source: source)
+ layer.hillshadeExaggeration = NSExpression(forConstantValue: 0.6)
+ if let canalShadowLayer = mapView.style?.layer(withIdentifier: "waterway-river-canal-shadow") {
+ mapView.style?.insertLayer(layer, below: canalShadowLayer)
+ }
+ //#-end-example-code
+
+ XCTAssertNotNil(mapView.style?.layer(withIdentifier: "hills"))
+ }
+
func testMGLVectorStyleLayer$predicate() {
let terrain = MGLVectorSource(identifier: "terrain", configurationURL: URL(string: "https://example.com/style.json")!)
mapView.style?.addSource(terrain)
diff --git a/platform/darwin/test/MGLHillshadeStyleLayerTests.mm b/platform/darwin/test/MGLHillshadeStyleLayerTests.mm
index 8f37b52790..b0b7ddd5ee 100644
--- a/platform/darwin/test/MGLHillshadeStyleLayerTests.mm
+++ b/platform/darwin/test/MGLHillshadeStyleLayerTests.mm
@@ -18,24 +18,6 @@
return @"hillshade";
}
-- (void)testPredicates {
- MGLPointFeature *feature = [[MGLPointFeature alloc] init];
- MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"sourceID" shape:feature options:nil];
- MGLHillshadeStyleLayer *layer = [[MGLHillshadeStyleLayer alloc] initWithIdentifier:@"layerID" source:source];
-
- XCTAssertNil(layer.sourceLayerIdentifier);
- layer.sourceLayerIdentifier = @"layerID";
- XCTAssertEqualObjects(layer.sourceLayerIdentifier, @"layerID");
- layer.sourceLayerIdentifier = nil;
- XCTAssertNil(layer.sourceLayerIdentifier);
-
- XCTAssertNil(layer.predicate);
- layer.predicate = [NSPredicate predicateWithValue:NO];
- XCTAssertEqualObjects(layer.predicate, [NSPredicate predicateWithValue:NO]);
- layer.predicate = nil;
- XCTAssertNil(layer.predicate);
-}
-
- (void)testProperties {
MGLPointFeature *feature = [[MGLPointFeature alloc] init];
MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"sourceID" shape:feature options:nil];
diff --git a/platform/darwin/test/MGLStyleLayerTests.mm.ejs b/platform/darwin/test/MGLStyleLayerTests.mm.ejs
index 0487066255..e26c63e662 100644
--- a/platform/darwin/test/MGLStyleLayerTests.mm.ejs
+++ b/platform/darwin/test/MGLStyleLayerTests.mm.ejs
@@ -23,7 +23,7 @@
return @"<%- type %>";
}
-<% if (type !== 'background' && type !== 'raster') { -%>
+<% if (type !== 'background' && type !== 'raster' && type !== 'hillshade') { -%>
- (void)testPredicates {
MGLPointFeature *feature = [[MGLPointFeature alloc] init];
MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"sourceID" shape:feature options:nil];
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index 0301a78efc..75a77720ae 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -11,7 +11,8 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
### Styles and rendering
* The layout and paint properties on subclasses of `MGLStyleLayer` are now of type `NSExpression` instead of `MGLStyleValue`. A new “Predicates and Expressions” guide provides an overview of the supported operators. ([#10726](https://github.com/mapbox/mapbox-gl-native/pull/10726))
-* Added `MGLComputedShapeSource` source class that allows applications to supply vector data on a per-tile basis.
+* Added an `MGLComputedShapeSource` class that allows applications to supply vector data to a style layer on a per-tile basis. ([#9983](https://github.com/mapbox/mapbox-gl-native/pull/9983))
+* A style can now display smooth hillshading and customize its appearance at runtime using the `MGLHillshadeStyleLayer` class. Hillshading is based on a rasterized digital elevation model supplied by the `MGLRasterDEMSource` class. ([#10642](https://github.com/mapbox/mapbox-gl-native/pull/10642))
* Properties such as `MGLSymbolStyleLayer.iconAllowsOverlap` and `MGLSymbolStyleLayer.iconIgnoresPlacement` now account for symbols in other sources. ([#10436](https://github.com/mapbox/mapbox-gl-native/pull/10436))
* Improved the reliability of collision detection between symbols near the edges of tiles, as well as between symbols when the map is tilted. It is no longer necessary to enable `MGLSymbolStyleLayer.symbolAvoidsEdges` to prevent symbols in adjacent tiles from overlapping with each other. ([#10436](https://github.com/mapbox/mapbox-gl-native/pull/10436))
* Symbols can fade in and out as the map pans, rotates, or tilts. ([#10436](https://github.com/mapbox/mapbox-gl-native/pull/10436))
diff --git a/platform/ios/ios.xcodeproj/project.pbxproj b/platform/ios/ios.xcodeproj/project.pbxproj
index f9ac67a203..d44fee3430 100644
--- a/platform/ios/ios.xcodeproj/project.pbxproj
+++ b/platform/ios/ios.xcodeproj/project.pbxproj
@@ -509,6 +509,10 @@
DAC25FCD200FD83F009BE98E /* NSExpression+MGLPrivateAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC25FCB200FD83E009BE98E /* NSExpression+MGLPrivateAdditions.h */; };
DAC49C5C1CD02BC9009E1AA3 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DAC49C5F1CD02BC9009E1AA3 /* Localizable.stringsdict */; };
DAC49C5D1CD02BC9009E1AA3 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DAC49C5F1CD02BC9009E1AA3 /* Localizable.stringsdict */; };
+ DACA86262019218600E9693A /* MGLRasterDEMSource.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA86242019218500E9693A /* MGLRasterDEMSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DACA86272019218600E9693A /* MGLRasterDEMSource.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA86242019218500E9693A /* MGLRasterDEMSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DACA86282019218600E9693A /* MGLRasterDEMSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = DACA86252019218500E9693A /* MGLRasterDEMSource.mm */; };
+ DACA86292019218600E9693A /* MGLRasterDEMSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = DACA86252019218500E9693A /* MGLRasterDEMSource.mm */; };
DAD1656C1CF41981001FF4B9 /* MGLFeature.h in Headers */ = {isa = PBXBuildFile; fileRef = DAD165691CF41981001FF4B9 /* MGLFeature.h */; settings = {ATTRIBUTES = (Public, ); }; };
DAD1656D1CF41981001FF4B9 /* MGLFeature.h in Headers */ = {isa = PBXBuildFile; fileRef = DAD165691CF41981001FF4B9 /* MGLFeature.h */; settings = {ATTRIBUTES = (Public, ); }; };
DAD1656E1CF41981001FF4B9 /* MGLFeature_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAD1656A1CF41981001FF4B9 /* MGLFeature_Private.h */; };
@@ -530,6 +534,11 @@
DAF0D8141DFE0EC500B28378 /* MGLVectorSource_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF0D8121DFE0EC500B28378 /* MGLVectorSource_Private.h */; };
DAF0D8181DFE6B2800B28378 /* MGLAttributionInfo_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF0D8171DFE6B2800B28378 /* MGLAttributionInfo_Private.h */; };
DAF0D8191DFE6B2800B28378 /* MGLAttributionInfo_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF0D8171DFE6B2800B28378 /* MGLAttributionInfo_Private.h */; };
+ DAF25719201901E200367EF5 /* MGLHillshadeStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAF25717201901E100367EF5 /* MGLHillshadeStyleLayer.mm */; };
+ DAF2571A201901E200367EF5 /* MGLHillshadeStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAF25717201901E100367EF5 /* MGLHillshadeStyleLayer.mm */; };
+ DAF2571B201901E200367EF5 /* MGLHillshadeStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF25718201901E200367EF5 /* MGLHillshadeStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DAF2571C201901E200367EF5 /* MGLHillshadeStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF25718201901E200367EF5 /* MGLHillshadeStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DAF25720201902BC00367EF5 /* MGLHillshadeStyleLayerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAF2571F201902BB00367EF5 /* MGLHillshadeStyleLayerTests.mm */; };
DD0902A91DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.m */; };
DD0902AA1DB1929D00C5BDCE /* MGLNetworkConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = DD0902A21DB18DE700C5BDCE /* MGLNetworkConfiguration.m */; };
DD0902AB1DB192A800C5BDCE /* MGLNetworkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = DD0902A41DB18F1B00C5BDCE /* MGLNetworkConfiguration.h */; };
@@ -1046,6 +1055,8 @@
DABCABC01CB80717000A7C39 /* locations.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = locations.hpp; sourceTree = "<group>"; };
DAC25FCB200FD83E009BE98E /* NSExpression+MGLPrivateAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSExpression+MGLPrivateAdditions.h"; sourceTree = "<group>"; };
DAC49C621CD07D74009E1AA3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = en; path = en.lproj/Localizable.stringsdict; sourceTree = "<group>"; };
+ DACA86242019218500E9693A /* MGLRasterDEMSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLRasterDEMSource.h; sourceTree = "<group>"; };
+ DACA86252019218500E9693A /* MGLRasterDEMSource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLRasterDEMSource.mm; sourceTree = "<group>"; };
DACBC60B20118ABE00C4D7E2 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Localizable.strings; sourceTree = "<group>"; };
DACBC60C20118AD000C4D7E2 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Foundation.strings; sourceTree = "<group>"; };
DACBC60D20118ADE00C4D7E2 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -1067,6 +1078,9 @@
DAF0D80F1DFE0EA000B28378 /* MGLRasterSource_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLRasterSource_Private.h; sourceTree = "<group>"; };
DAF0D8121DFE0EC500B28378 /* MGLVectorSource_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLVectorSource_Private.h; sourceTree = "<group>"; };
DAF0D8171DFE6B2800B28378 /* MGLAttributionInfo_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAttributionInfo_Private.h; sourceTree = "<group>"; };
+ DAF25717201901E100367EF5 /* MGLHillshadeStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLHillshadeStyleLayer.mm; sourceTree = "<group>"; };
+ DAF25718201901E200367EF5 /* MGLHillshadeStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLHillshadeStyleLayer.h; sourceTree = "<group>"; };
+ DAF2571F201902BB00367EF5 /* MGLHillshadeStyleLayerTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLHillshadeStyleLayerTests.mm; path = ../../darwin/test/MGLHillshadeStyleLayerTests.mm; sourceTree = "<group>"; };
DAFBD0D21E3FA7A1000CD6BF /* zh-Hant */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Foundation.strings"; sourceTree = "<group>"; };
DAFBD0D31E3FA7A1000CD6BF /* zh-Hant */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
DAFBD0D41E3FA7A2000CD6BF /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Root.strings"; sourceTree = "<group>"; };
@@ -1185,6 +1199,8 @@
3566C76A1D4A8DFA008152BC /* MGLRasterSource.h */,
DAF0D80F1DFE0EA000B28378 /* MGLRasterSource_Private.h */,
3566C76B1D4A8DFA008152BC /* MGLRasterSource.mm */,
+ DACA86242019218500E9693A /* MGLRasterDEMSource.h */,
+ DACA86252019218500E9693A /* MGLRasterDEMSource.mm */,
3566C7641D4A77BA008152BC /* MGLShapeSource.h */,
40F8876F1D7A1DB8008ECB67 /* MGLShapeSource_Private.h */,
3566C7651D4A77BA008152BC /* MGLShapeSource.mm */,
@@ -1214,6 +1230,8 @@
35D13AC21D3D19DD00AFB4E0 /* MGLFillStyleLayer.mm */,
3538AA1B1D542239008EC33D /* MGLForegroundStyleLayer.h */,
3538AA1C1D542239008EC33D /* MGLForegroundStyleLayer.mm */,
+ DAF25718201901E200367EF5 /* MGLHillshadeStyleLayer.h */,
+ DAF25717201901E100367EF5 /* MGLHillshadeStyleLayer.mm */,
353933F71D3FB79F003F57D7 /* MGLLineStyleLayer.h */,
35136D3E1D42273000C20EFD /* MGLLineStyleLayer.mm */,
DA7262091DEEE3480043BB89 /* MGLOpenGLStyleLayer.h */,
@@ -1284,6 +1302,7 @@
DA3C6FF21E2859E700F962BE /* test-Bridging-Header.h */,
FAE1CDC81E9D79C600C40B5B /* MGLFillExtrusionStyleLayerTests.mm */,
3575797F1D501E09000B822E /* MGLFillStyleLayerTests.mm */,
+ DAF2571F201902BB00367EF5 /* MGLHillshadeStyleLayerTests.mm */,
357579821D502AE6000B822E /* MGLRasterStyleLayerTests.mm */,
357579841D502AF5000B822E /* MGLSymbolStyleLayerTests.mm */,
357579861D502AFE000B822E /* MGLLineStyleLayerTests.mm */,
@@ -1843,6 +1862,7 @@
556660DB1E1D8E8D00E2C41B /* MGLFoundation.h in Headers */,
35D13AC31D3D19DD00AFB4E0 /* MGLFillStyleLayer.h in Headers */,
DA88483A1CBAFB8500AB86E3 /* MGLAnnotationImage.h in Headers */,
+ DAF2571B201901E200367EF5 /* MGLHillshadeStyleLayer.h in Headers */,
DA35A2BB1CCA9A6900E826B2 /* MGLClockDirectionFormatter.h in Headers */,
353933FE1D3FB7DD003F57D7 /* MGLSymbolStyleLayer.h in Headers */,
DA8848861CBB033F00AB86E3 /* Fabric+FABKits.h in Headers */,
@@ -1897,6 +1917,7 @@
35D3A1E61E9BE7EB002B38EE /* MGLScaleBar.h in Headers */,
0778DD431F67556700A73B34 /* MGLComputedShapeSource.h in Headers */,
DA8848311CBAFA6200AB86E3 /* NSString+MGLAdditions.h in Headers */,
+ DACA86262019218600E9693A /* MGLRasterDEMSource.h in Headers */,
353933F81D3FB79F003F57D7 /* MGLLineStyleLayer.h in Headers */,
92F2C3ED1F0E3C3A00268EC0 /* MGLRendererFrontend.h in Headers */,
DAAF722D1DA903C700312FA4 /* MGLStyleValue_Private.h in Headers */,
@@ -2017,6 +2038,7 @@
96E516E92000560B00A02306 /* MGLAnnotationImage_Private.h in Headers */,
96E516E52000560B00A02306 /* MGLOfflinePack_Private.h in Headers */,
DD9BE4F91EB263D20079A3AF /* UIViewController+MGLAdditions.h in Headers */,
+ DAF2571C201901E200367EF5 /* MGLHillshadeStyleLayer.h in Headers */,
DABFB8621CBE99E500D62B32 /* MGLOfflinePack.h in Headers */,
96E516FA20005A3D00A02306 /* MGLUserLocationHeadingArrowLayer.h in Headers */,
96E516E62000560B00A02306 /* MGLOfflineRegion_Private.h in Headers */,
@@ -2102,6 +2124,7 @@
96E5170320005A6800A02306 /* FABKitProtocol.h in Headers */,
96E516E12000551100A02306 /* MGLMultiPoint_Private.h in Headers */,
3EA934623AD0000B7D99C3FB /* MGLRendererConfiguration.h in Headers */,
+ DACA86272019218600E9693A /* MGLRasterDEMSource.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2538,6 +2561,7 @@
FAE1CDCB1E9D79CB00C40B5B /* MGLFillExtrusionStyleLayerTests.mm in Sources */,
DA35A2AA1CCA058D00E826B2 /* MGLCoordinateFormatterTests.m in Sources */,
357579831D502AE6000B822E /* MGLRasterStyleLayerTests.mm in Sources */,
+ DAF25720201902BC00367EF5 /* MGLHillshadeStyleLayerTests.mm in Sources */,
353D23961D0B0DFE002BE09D /* MGLAnnotationViewTests.m in Sources */,
35E208A71D24210F00EC9A46 /* MGLNSDataAdditionsTests.m in Sources */,
DA0CD5901CF56F6A00A5F5A5 /* MGLFeatureTests.mm in Sources */,
@@ -2584,6 +2608,7 @@
1F06668D1EC64F8E001C16D7 /* MGLLight.mm in Sources */,
DA35A2B81CCA9A5D00E826B2 /* MGLClockDirectionFormatter.m in Sources */,
DAD1657A1CF4CDFF001FF4B9 /* MGLShapeCollection.mm in Sources */,
+ DAF25719201901E200367EF5 /* MGLHillshadeStyleLayer.mm in Sources */,
35136D451D42275100C20EFD /* MGLSymbolStyleLayer.mm in Sources */,
35599DED1D46F14E0048254D /* MGLStyleValue.mm in Sources */,
DA8848211CBAFA6200AB86E3 /* MGLOfflinePack.mm in Sources */,
@@ -2613,6 +2638,7 @@
07D947541F67489200E37934 /* MGLAbstractShapeSource.mm in Sources */,
355AE0011E9281DA00F3939D /* MGLScaleBar.mm in Sources */,
DA88481D1CBAFA6200AB86E3 /* MGLMapCamera.mm in Sources */,
+ DACA86282019218600E9693A /* MGLRasterDEMSource.mm in Sources */,
DA8848261CBAFA6200AB86E3 /* MGLPolygon.mm in Sources */,
35B82BFA1D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm in Sources */,
DA8848521CBAFB9800AB86E3 /* MGLAPIClient.m in Sources */,
@@ -2673,6 +2699,7 @@
DAD1657B1CF4CDFF001FF4B9 /* MGLShapeCollection.mm in Sources */,
DAA4E4251CBB730400178DFB /* MGLShape.mm in Sources */,
35136D461D42275100C20EFD /* MGLSymbolStyleLayer.mm in Sources */,
+ DAF2571A201901E200367EF5 /* MGLHillshadeStyleLayer.mm in Sources */,
35599DEE1D46F14E0048254D /* MGLStyleValue.mm in Sources */,
DAA4E42B1CBB730400178DFB /* NSString+MGLAdditions.m in Sources */,
DAA4E4261CBB730400178DFB /* MGLStyle.mm in Sources */,
@@ -2702,6 +2729,7 @@
4018B1C81CDC287F00F666AF /* MGLAnnotationView.mm in Sources */,
07D8C6FB1F67560100381808 /* MGLComputedShapeSource.mm in Sources */,
DAA4E4341CBB730400178DFB /* MGLFaux3DUserLocationAnnotationView.m in Sources */,
+ DACA86292019218600E9693A /* MGLRasterDEMSource.mm in Sources */,
35B82BFB1D6C5F8400B1B721 /* NSPredicate+MGLAdditions.mm in Sources */,
DAA4E4311CBB730400178DFB /* MGLMapboxEvents.m in Sources */,
966FCF4F1F3A5C9200F2B6DE /* MGLUserLocationHeadingBeamLayer.m in Sources */,
diff --git a/platform/ios/jazzy.yml b/platform/ios/jazzy.yml
index 005e7698ab..b3662adc70 100644
--- a/platform/ios/jazzy.yml
+++ b/platform/ios/jazzy.yml
@@ -83,6 +83,7 @@ custom_categories:
- MGLShapeSource
- MGLComputedShapeSource
- MGLRasterSource
+ - MGLRasterDEMSource
- MGLVectorSource
- name: Style Layers
children:
@@ -94,6 +95,7 @@ custom_categories:
- MGLCircleStyleLayer
- MGLFillStyleLayer
- MGLFillExtrusionStyleLayer
+ - MGLHillshadeStyleLayer
- MGLLineStyleLayer
- MGLSymbolStyleLayer
- name: Offline Maps
diff --git a/platform/ios/src/Mapbox.h b/platform/ios/src/Mapbox.h
index 204d495aef..d105189bb8 100644
--- a/platform/ios/src/Mapbox.h
+++ b/platform/ios/src/Mapbox.h
@@ -45,6 +45,7 @@ FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[];
#import "MGLSymbolStyleLayer.h"
#import "MGLRasterStyleLayer.h"
#import "MGLCircleStyleLayer.h"
+#import "MGLHillshadeStyleLayer.h"
#import "MGLBackgroundStyleLayer.h"
#import "MGLOpenGLStyleLayer.h"
#import "MGLSource.h"
@@ -54,6 +55,7 @@ FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[];
#import "MGLAbstractShapeSource.h"
#import "MGLComputedShapeSource.h"
#import "MGLRasterSource.h"
+#import "MGLRasterDEMSource.h"
#import "MGLImageSource.h"
#import "MGLTilePyramidOfflineRegion.h"
#import "MGLTypes.h"
diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md
index 4e26aa443a..c8373b2bf5 100644
--- a/platform/macos/CHANGELOG.md
+++ b/platform/macos/CHANGELOG.md
@@ -5,7 +5,8 @@
### Styles and rendering
* The layout and paint properties on subclasses of `MGLStyleLayer` are now of type `NSExpression` instead of `MGLStyleValue`. A new “Predicates and Expressions” guide provides an overview of the supported operators. ([#10726](https://github.com/mapbox/mapbox-gl-native/pull/10726))
-* Added `MGLComputedShapeSource` source class that allows applications to supply vector data on a per-tile basis.
+* Added an `MGLComputedShapeSource` class that allows applications to supply vector data to a style layer on a per-tile basis. ([#9983](https://github.com/mapbox/mapbox-gl-native/pull/9983))
+* A style can now display smooth hillshading and customize its appearance at runtime using the `MGLHillshadeStyleLayer` class. Hillshading is based on a rasterized digital elevation model supplied by the `MGLRasterDEMSource` class. ([#10642](https://github.com/mapbox/mapbox-gl-native/pull/10642))
* Properties such as `MGLSymbolStyleLayer.iconAllowsOverlap` and `MGLSymbolStyleLayer.iconIgnoresPlacement` now account for symbols in other sources. ([#10436](https://github.com/mapbox/mapbox-gl-native/pull/10436))
* Improved the reliability of collision detection between symbols near the edges of tiles, as well as between symbols when the map is tilted. It is no longer necessary to enable `MGLSymbolStyleLayer.symbolAvoidsEdges` to prevent symbols in adjacent tiles from overlapping with each other. ([#10436](https://github.com/mapbox/mapbox-gl-native/pull/10436))
* Symbols can fade in and out as the map pans, rotates, or tilts. ([#10436](https://github.com/mapbox/mapbox-gl-native/pull/10436))
diff --git a/platform/macos/app/Assets.xcassets/Layers/background.imageset/Contents.json b/platform/macos/app/Assets.xcassets/Layers/background.imageset/Contents.json
index 3d2c878879..7473a40333 100644
--- a/platform/macos/app/Assets.xcassets/Layers/background.imageset/Contents.json
+++ b/platform/macos/app/Assets.xcassets/Layers/background.imageset/Contents.json
@@ -2,7 +2,8 @@
"images" : [
{
"idiom" : "universal",
- "filename" : "background.pdf"
+ "filename" : "background.pdf",
+ "language-direction" : "left-to-right"
}
],
"info" : {
diff --git a/platform/macos/app/Assets.xcassets/Layers/hillshade.imageset/Contents.json b/platform/macos/app/Assets.xcassets/Layers/hillshade.imageset/Contents.json
new file mode 100644
index 0000000000..f9922cad46
--- /dev/null
+++ b/platform/macos/app/Assets.xcassets/Layers/hillshade.imageset/Contents.json
@@ -0,0 +1,16 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "hillshade.pdf",
+ "language-direction" : "left-to-right"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ },
+ "properties" : {
+ "template-rendering-intent" : "template"
+ }
+} \ No newline at end of file
diff --git a/platform/macos/app/Assets.xcassets/Layers/hillshade.imageset/hillshade.pdf b/platform/macos/app/Assets.xcassets/Layers/hillshade.imageset/hillshade.pdf
new file mode 100644
index 0000000000..bf409e708c
--- /dev/null
+++ b/platform/macos/app/Assets.xcassets/Layers/hillshade.imageset/hillshade.pdf
@@ -0,0 +1,70 @@
+%PDF-1.5
+%
+3 0 obj
+<< /Length 4 0 R
+ /Filter /FlateDecode
+>>
+stream
+xeNA
+@ sv} xŃ(Vo"L0# jXˆ6w:!,P㒒hK灴a U18|= _?ݜ{YXS2یݮ*5/ﺠ>ݪ,
+endstream
+endobj
+4 0 obj
+ 145
+endobj
+2 0 obj
+<<
+ /ExtGState <<
+ /a0 << /CA 1 /ca 1 >>
+ /a1 << /CA 0.156863 /ca 0.156863 >>
+ >>
+>>
+endobj
+5 0 obj
+<< /Type /Page
+ /Parent 1 0 R
+ /MediaBox [ 0 0 12 12 ]
+ /Contents 3 0 R
+ /Group <<
+ /Type /Group
+ /S /Transparency
+ /I true
+ /CS /DeviceRGB
+ >>
+ /Resources 2 0 R
+>>
+endobj
+1 0 obj
+<< /Type /Pages
+ /Kids [ 5 0 R ]
+ /Count 1
+>>
+endobj
+6 0 obj
+<< /Creator (cairo 1.14.8 (http://cairographics.org))
+ /Producer (cairo 1.14.8 (http://cairographics.org))
+>>
+endobj
+7 0 obj
+<< /Type /Catalog
+ /Pages 1 0 R
+>>
+endobj
+xref
+0 8
+0000000000 65535 f
+0000000585 00000 n
+0000000259 00000 n
+0000000015 00000 n
+0000000237 00000 n
+0000000373 00000 n
+0000000650 00000 n
+0000000777 00000 n
+trailer
+<< /Size 8
+ /Root 7 0 R
+ /Info 6 0 R
+>>
+startxref
+829
+%%EOF
diff --git a/platform/macos/app/Base.lproj/MainMenu.xib b/platform/macos/app/Base.lproj/MainMenu.xib
index d014676caa..72e9c5a189 100644
--- a/platform/macos/app/Base.lproj/MainMenu.xib
+++ b/platform/macos/app/Base.lproj/MainMenu.xib
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="12121" systemVersion="16E195" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
- <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="12121"/>
+ <deployment identifier="macosx"/>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@@ -554,6 +555,21 @@
<action selector="drawAnimatedAnnotation:" target="-1" id="CYM-WB-s97"/>
</connections>
</menuItem>
+ <menuItem title="Show All Annnotations" keyEquivalent="A" id="yMj-uM-8SN">
+ <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
+ <connections>
+ <action selector="showAllAnnotations:" target="-1" id="ahr-OR-Em2"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Remove All Annotations" id="6rC-68-vk0">
+ <string key="keyEquivalent" base64-UTF8="YES">
+CA
+</string>
+ <connections>
+ <action selector="removeAllAnnotations:" target="-1" id="6v3-0E-LsR"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="cbI-Nd-MAp"/>
<menuItem title="Add Lime Green Layer" id="UWY-vl-t2m">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
@@ -565,25 +581,17 @@
<connections>
<action selector="addAnimatedImageSource:" target="-1" id="TuN-Pa-hTG"/>
</connections>
- </menuItem>
+ </menuItem>
<menuItem title="Add Graticule" id="Msk-p2-Lwt">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="insertGraticuleLayer:" target="-1" id="LE5-lz-kx4"/>
</connections>
</menuItem>
- <menuItem title="Show All Annnotations" keyEquivalent="A" id="yMj-uM-8SN">
- <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
- <connections>
- <action selector="showAllAnnotations:" target="-1" id="ahr-OR-Em2"/>
- </connections>
- </menuItem>
- <menuItem title="Remove All Annotations" id="6rC-68-vk0">
- <string key="keyEquivalent" base64-UTF8="YES">
- CA
- </string>
+ <menuItem title="Enhance Terrain" id="2ZT-uE-kUR">
+ <modifierMask key="keyEquivalentModifierMask"/>
<connections>
- <action selector="removeAllAnnotations:" target="-1" id="6v3-0E-LsR"/>
+ <action selector="enhanceTerrain:" target="-1" id="TXX-Yv-ZY1"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="wQq-Mx-QY0"/>
@@ -666,7 +674,7 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="109" y="131" width="350" height="84"/>
- <rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="1280" height="777"/>
<view key="contentView" id="eA4-n3-qPe">
<rect key="frame" x="0.0" y="0.0" width="350" height="84"/>
<autoresizingMask key="autoresizingMask"/>
@@ -742,7 +750,7 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" utility="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="830" y="430" width="400" height="300"/>
- <rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="1280" height="777"/>
<view key="contentView" id="8ha-hw-zOD">
<rect key="frame" x="0.0" y="0.0" width="400" height="300"/>
<autoresizingMask key="autoresizingMask"/>
@@ -751,7 +759,7 @@
<rect key="frame" x="-1" y="20" width="402" height="281"/>
<clipView key="contentView" id="J9U-Yx-o2S">
<rect key="frame" x="1" y="0.0" width="400" height="280"/>
- <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+ <autoresizingMask key="autoresizingMask"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="lastColumnOnly" autosaveColumns="NO" headerView="MAZ-Iq-hBi" id="Ato-Vu-HYT">
<rect key="frame" x="0.0" y="0.0" width="423" height="257"/>
@@ -772,7 +780,7 @@
<binding destination="dWe-R6-sRz" name="value" keyPath="arrangedObjects.stateImage" id="2wd-1J-TZt"/>
</connections>
</tableColumn>
- <tableColumn editable="NO" width="116" minWidth="40" maxWidth="1000" id="2hD-LN-h0L">
+ <tableColumn identifier="" editable="NO" width="116" minWidth="40" maxWidth="1000" id="2hD-LN-h0L">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Name">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@@ -792,7 +800,7 @@
</binding>
</connections>
</tableColumn>
- <tableColumn editable="NO" width="50" minWidth="40" maxWidth="1000" id="pkI-c7-xoD">
+ <tableColumn identifier="" editable="NO" width="50" minWidth="40" maxWidth="1000" id="pkI-c7-xoD">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Downloaded Resources">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@@ -826,7 +834,7 @@
<binding destination="dWe-R6-sRz" name="value" keyPath="arrangedObjects.countOfResourcesExpected" id="mh2-k0-vvB"/>
</connections>
</tableColumn>
- <tableColumn editable="NO" width="50" minWidth="40" maxWidth="1000" id="kCO-Cd-bQt">
+ <tableColumn identifier="" editable="NO" width="50" minWidth="40" maxWidth="1000" id="kCO-Cd-bQt">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" title="Downloaded Tiles">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
@@ -847,7 +855,7 @@
</binding>
</connections>
</tableColumn>
- <tableColumn editable="NO" width="60" minWidth="10" maxWidth="3.4028234663852886e+38" id="WO5-Ci-HgG">
+ <tableColumn identifier="" editable="NO" width="60" minWidth="10" maxWidth="3.4028234663852886e+38" id="WO5-Ci-HgG">
<tableHeaderCell key="headerCell" lineBreakMode="truncatingTail" borderStyle="border" alignment="left" title="Downloaded Tiles Size">
<font key="font" metaFont="smallSystem"/>
<color key="textColor" name="headerTextColor" catalog="System" colorSpace="catalog"/>
diff --git a/platform/macos/app/MapDocument.m b/platform/macos/app/MapDocument.m
index 94b0cffcdc..602ed1aa41 100644
--- a/platform/macos/app/MapDocument.m
+++ b/platform/macos/app/MapDocument.m
@@ -50,6 +50,25 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
return flattenedShapes;
}
+@interface MGLVectorSource (MBXAdditions)
+
+@property (nonatomic, readonly, getter=isMapboxTerrain) BOOL mapboxTerrain;
+
+@end
+
+@implementation MGLVectorSource (MBXAdditions)
+
+- (BOOL)isMapboxTerrain {
+ NSURL *url = self.configurationURL;
+ if (![url.scheme isEqualToString:@"mapbox"]) {
+ return NO;
+ }
+ NSArray *identifiers = [url.host componentsSeparatedByString:@","];
+ return [identifiers containsObject:@"mapbox.mapbox-terrain-v2"] || [identifiers containsObject:@"mapbox.mapbox-terrain-v1"];
+}
+
+@end
+
@interface MapDocument () <NSWindowDelegate, NSSharingServicePickerDelegate, NSMenuDelegate, NSSplitViewDelegate, MGLMapViewDelegate, MGLComputedShapeSourceDataSource>
@property (weak) IBOutlet NSArrayController *styleLayersArrayController;
@@ -739,6 +758,49 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
[self.mapView.style removeSource:source];
}
+- (IBAction)enhanceTerrain:(id)sender {
+ // Find all the identifiers of Mapbox Terrain sources used in the style.
+ NSMutableSet *terrainSourceIdentifiers = [NSMutableSet set];
+ for (MGLVectorSource *source in self.mapView.style.sources) {
+ if (![source isKindOfClass:[MGLVectorSource class]]) {
+ continue;
+ }
+
+ if (source.mapboxTerrain) {
+ [terrainSourceIdentifiers addObject:source.identifier];
+ }
+ }
+
+ // Find and remove all the style layers using those sources.
+ NSUInteger hillshadeIndex = NSNotFound;
+ NSEnumerator *layerEnumerator = self.mapView.style.layers.objectEnumerator;
+ MGLVectorStyleLayer *layer;
+ for (NSUInteger i = 0; (layer = layerEnumerator.nextObject); i++) {
+ if (![layer isKindOfClass:[MGLVectorStyleLayer class]]) {
+ continue;
+ }
+
+ if ([terrainSourceIdentifiers containsObject:layer.sourceIdentifier]
+ && [layer.sourceLayerIdentifier isEqualToString:@"hillshade"]) {
+ hillshadeIndex = i;
+ [self.mapView.style removeLayer:layer];
+ }
+ }
+
+ if (hillshadeIndex == NSNotFound) {
+ return;
+ }
+
+ // Add a Mapbox Terrain-RGB source.
+ NSURL *terrainRGBURL = [NSURL URLWithString:@"mapbox://mapbox.terrain-rgb"];
+ MGLRasterDEMSource *terrainRGBSource = [[MGLRasterDEMSource alloc] initWithIdentifier:@"terrain" configurationURL:terrainRGBURL];
+ [self.mapView.style addSource:terrainRGBSource];
+
+ // Insert a hillshade layer where the Mapbox Terrain–based layers were.
+ MGLHillshadeStyleLayer *hillshadeLayer = [[MGLHillshadeStyleLayer alloc] initWithIdentifier:@"hillshade" source:terrainRGBSource];
+ [self.mapView.style insertLayer:hillshadeLayer atIndex:hillshadeIndex];
+}
+
#pragma mark Offline packs
- (IBAction)addOfflinePack:(id)sender {
@@ -1058,6 +1120,9 @@ NS_ARRAY_OF(id <MGLAnnotation>) *MBXFlattenedShapes(NS_ARRAY_OF(id <MGLAnnotatio
if (menuItem.action == @selector(showAllAnnotations:) || menuItem.action == @selector(removeAllAnnotations:)) {
return self.mapView.annotations.count > 0;
}
+ if (menuItem.action == @selector(enhanceTerrain:)) {
+ return YES;
+ }
if (menuItem.action == @selector(startWorldTour:)) {
return !_isTouringWorld;
}
diff --git a/platform/macos/app/StyleLayerIconTransformer.m b/platform/macos/app/StyleLayerIconTransformer.m
index ff2b964b87..50fe06a2c6 100644
--- a/platform/macos/app/StyleLayerIconTransformer.m
+++ b/platform/macos/app/StyleLayerIconTransformer.m
@@ -31,7 +31,10 @@
if ([layer isKindOfClass:[MGLSymbolStyleLayer class]]) {
return [NSImage imageNamed:@"symbol"];
}
-
+ if ([layer isKindOfClass:[MGLHillshadeStyleLayer class]]) {
+ return [NSImage imageNamed:@"hillshade"];
+ }
+
return nil;
}
diff --git a/platform/macos/app/resources/hillshade.svg b/platform/macos/app/resources/hillshade.svg
new file mode 100644
index 0000000000..d3f0d72999
--- /dev/null
+++ b/platform/macos/app/resources/hillshade.svg
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 16"
+ id="svg4148"
+ version="1.1"
+ inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+ sodipodi:docname="hillshade.svg"
+ inkscape:export-filename="/Users/mxn/Desktop/symbol.png"
+ inkscape:export-xdpi="90.000244"
+ inkscape:export-ydpi="90.000244">
+ <defs
+ id="defs4150" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="23.25"
+ inkscape:cx="6.2795699"
+ inkscape:cy="11.122067"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ units="px"
+ inkscape:window-width="1280"
+ inkscape:window-height="755"
+ inkscape:window-x="0"
+ inkscape:window-y="1"
+ inkscape:window-maximized="1"
+ inkscape:snap-bbox="true" />
+ <metadata
+ id="metadata4153">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3622)">
+ <path
+ sodipodi:type="star"
+ style="opacity:1;fill:#ffffff;fill-opacity:0;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path839"
+ sodipodi:sides="3"
+ sodipodi:cx="12.189357"
+ sodipodi:cy="1045.3247"
+ sodipodi:r1="12.575057"
+ sodipodi:r2="6.2875285"
+ sodipodi:arg1="0.52359878"
+ sodipodi:arg2="1.5707963"
+ inkscape:flatsided="true"
+ inkscape:rounded="0"
+ inkscape:randomized="0"
+ d="m 23.079676,1051.6122 -21.7806381,0 10.8903191,-18.8625 z"
+ inkscape:transform-center-y="-2.1749516"
+ transform="matrix(0.6563034,0,0,0.75784422,8.3706122e-5,254.83559)" />
+ <path
+ transform="matrix(0.6563034,0,0,0.75784422,8.3706122e-5,254.83559)"
+ style="opacity:1;fill:#000000;fill-opacity:0.15686275;fill-rule:evenodd;stroke:none;stroke-width:1.50017999;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ inkscape:transform-center-y="-2.1749516"
+ d="m 23.079676,1051.6122 h -7.842948 l -3.047371,-18.8625 z"
+ id="path841"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ </g>
+</svg>
diff --git a/platform/macos/jazzy.yml b/platform/macos/jazzy.yml
index 99f1119411..682ccd99ff 100644
--- a/platform/macos/jazzy.yml
+++ b/platform/macos/jazzy.yml
@@ -68,6 +68,7 @@ custom_categories:
- MGLShapeSource
- MGLComputedShapeSource
- MGLRasterSource
+ - MGLRasterDEMSource
- MGLVectorSource
- name: Style Layers
children:
@@ -79,6 +80,7 @@ custom_categories:
- MGLCircleStyleLayer
- MGLFillStyleLayer
- MGLFillExtrusionStyleLayer
+ - MGLHillshadeStyleLayer
- MGLLineStyleLayer
- MGLSymbolStyleLayer
- name: Offline Maps
diff --git a/platform/macos/macos.xcodeproj/project.pbxproj b/platform/macos/macos.xcodeproj/project.pbxproj
index c232216814..090902fca4 100644
--- a/platform/macos/macos.xcodeproj/project.pbxproj
+++ b/platform/macos/macos.xcodeproj/project.pbxproj
@@ -23,8 +23,6 @@
1F7454AB1ED1DDBD00021D39 /* MGLLightTest.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F7454AA1ED1DDBD00021D39 /* MGLLightTest.mm */; };
1F95931B1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1F95931A1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm */; };
1F9EF4061FBA1B0E0063FBB0 /* mapbox_helmet.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 1F9EF4051FBA1B0D0063FBB0 /* mapbox_helmet.pdf */; };
- 1FCDF1421F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FCDF1401F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h */; };
- 1FCDF1431F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1FCDF1411F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m */; };
30E5781B1DAA857E0050F07E /* NSImage+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30E578141DAA7D920050F07E /* NSImage+MGLAdditions.h */; };
3508EC641D749D39009B0EE4 /* NSExpression+MGLAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */; settings = {ATTRIBUTES = (Public, ); }; };
3508EC651D749D39009B0EE4 /* NSExpression+MGLAdditions.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */; };
@@ -164,6 +162,8 @@
DAB2CCE51DF632ED001B2FE1 /* LimeGreenStyleLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAB2CCE41DF632ED001B2FE1 /* LimeGreenStyleLayer.m */; };
DAC25FCA200FD5E2009BE98E /* NSExpression+MGLPrivateAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC25FC9200FD5E2009BE98E /* NSExpression+MGLPrivateAdditions.h */; };
DAC2ABC51CC6D343006D18C4 /* MGLAnnotationImage_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC2ABC41CC6D343006D18C4 /* MGLAnnotationImage_Private.h */; };
+ DACA8622201920BE00E9693A /* MGLRasterDEMSource.h in Headers */ = {isa = PBXBuildFile; fileRef = DACA8620201920BE00E9693A /* MGLRasterDEMSource.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DACA8623201920BE00E9693A /* MGLRasterDEMSource.mm in Sources */ = {isa = PBXBuildFile; fileRef = DACA8621201920BE00E9693A /* MGLRasterDEMSource.mm */; };
DACB0C391E18DFFD005DDBEA /* MGLStyle+MBXAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = DACB0C381E18DFFD005DDBEA /* MGLStyle+MBXAdditions.m */; };
DACC22141CF3D3E200D220D9 /* MGLFeature.h in Headers */ = {isa = PBXBuildFile; fileRef = DACC22121CF3D3E200D220D9 /* MGLFeature.h */; settings = {ATTRIBUTES = (Public, ); }; };
DACC22151CF3D3E200D220D9 /* MGLFeature.mm in Sources */ = {isa = PBXBuildFile; fileRef = DACC22131CF3D3E200D220D9 /* MGLFeature.mm */; };
@@ -249,6 +249,9 @@
DAEDC4371D606291000224FF /* MGLAttributionButtonTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DAEDC4361D606291000224FF /* MGLAttributionButtonTests.m */; };
DAF0D80E1DFE0E5D00B28378 /* MGLPointCollection_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF0D80D1DFE0E5D00B28378 /* MGLPointCollection_Private.h */; };
DAF0D8161DFE6B1800B28378 /* MGLAttributionInfo_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF0D8151DFE6B1800B28378 /* MGLAttributionInfo_Private.h */; };
+ DAF25715201901C200367EF5 /* MGLHillshadeStyleLayer.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAF25713201901C100367EF5 /* MGLHillshadeStyleLayer.mm */; };
+ DAF25716201901C200367EF5 /* MGLHillshadeStyleLayer.h in Headers */ = {isa = PBXBuildFile; fileRef = DAF25714201901C200367EF5 /* MGLHillshadeStyleLayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ DAF25721201902C100367EF5 /* MGLHillshadeStyleLayerTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DAF2571D201902A500367EF5 /* MGLHillshadeStyleLayerTests.mm */; };
DD0902B21DB1AC6400C5BDCE /* MGLNetworkConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = DD0902AF1DB1AC6400C5BDCE /* MGLNetworkConfiguration.m */; };
DD0902B31DB1AC6400C5BDCE /* MGLNetworkConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = DD0902B01DB1AC6400C5BDCE /* MGLNetworkConfiguration.h */; };
DD58A4C91D822C6700E1F038 /* MGLExpressionTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = DD58A4C71D822C6200E1F038 /* MGLExpressionTests.mm */; };
@@ -302,8 +305,6 @@
1F7454AA1ED1DDBD00021D39 /* MGLLightTest.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLLightTest.mm; sourceTree = "<group>"; };
1F95931A1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = MGLNSDateAdditionsTests.mm; path = ../../darwin/test/MGLNSDateAdditionsTests.mm; sourceTree = "<group>"; };
1F9EF4051FBA1B0D0063FBB0 /* mapbox_helmet.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = mapbox_helmet.pdf; sourceTree = "<group>"; };
- 1FCDF1401F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLVectorSource+MGLAdditions.h"; sourceTree = "<group>"; };
- 1FCDF1411F2A4F3600A46694 /* MGLVectorSource+MGLAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLVectorSource+MGLAdditions.m"; sourceTree = "<group>"; };
30E578141DAA7D920050F07E /* NSImage+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSImage+MGLAdditions.h"; path = "src/NSImage+MGLAdditions.h"; sourceTree = SOURCE_ROOT; };
3508EC621D749D39009B0EE4 /* NSExpression+MGLAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSExpression+MGLAdditions.h"; sourceTree = "<group>"; };
3508EC631D749D39009B0EE4 /* NSExpression+MGLAdditions.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSExpression+MGLAdditions.mm"; sourceTree = "<group>"; };
@@ -511,6 +512,8 @@
DAB2CCE41DF632ED001B2FE1 /* LimeGreenStyleLayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LimeGreenStyleLayer.m; sourceTree = "<group>"; };
DAC25FC9200FD5E2009BE98E /* NSExpression+MGLPrivateAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSExpression+MGLPrivateAdditions.h"; sourceTree = "<group>"; };
DAC2ABC41CC6D343006D18C4 /* MGLAnnotationImage_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAnnotationImage_Private.h; sourceTree = "<group>"; };
+ DACA8620201920BE00E9693A /* MGLRasterDEMSource.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MGLRasterDEMSource.h; sourceTree = "<group>"; };
+ DACA8621201920BE00E9693A /* MGLRasterDEMSource.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLRasterDEMSource.mm; sourceTree = "<group>"; };
DACB0C371E18DFFD005DDBEA /* MGLStyle+MBXAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MGLStyle+MBXAdditions.h"; sourceTree = "<group>"; };
DACB0C381E18DFFD005DDBEA /* MGLStyle+MBXAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MGLStyle+MBXAdditions.m"; sourceTree = "<group>"; };
DACBC6082011885800C4D7E2 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -613,6 +616,9 @@
DAEDC4361D606291000224FF /* MGLAttributionButtonTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLAttributionButtonTests.m; sourceTree = "<group>"; };
DAF0D80D1DFE0E5D00B28378 /* MGLPointCollection_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLPointCollection_Private.h; sourceTree = "<group>"; };
DAF0D8151DFE6B1800B28378 /* MGLAttributionInfo_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLAttributionInfo_Private.h; sourceTree = "<group>"; };
+ DAF25713201901C100367EF5 /* MGLHillshadeStyleLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLHillshadeStyleLayer.mm; sourceTree = "<group>"; };
+ DAF25714201901C200367EF5 /* MGLHillshadeStyleLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MGLHillshadeStyleLayer.h; sourceTree = "<group>"; };
+ DAF2571D201902A500367EF5 /* MGLHillshadeStyleLayerTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MGLHillshadeStyleLayerTests.mm; sourceTree = "<group>"; };
DAFBD0D51E3FA969000CD6BF /* zh-Hant */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = "<group>"; };
DAFBD0D61E3FA983000CD6BF /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Foundation.strings"; sourceTree = "<group>"; };
DD0902AF1DB1AC6400C5BDCE /* MGLNetworkConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MGLNetworkConfiguration.m; sourceTree = "<group>"; };
@@ -666,6 +672,8 @@
35602BF91D3EA99F0050646F /* MGLFillStyleLayer.mm */,
35602BFD1D3EA9B40050646F /* MGLForegroundStyleLayer.h */,
35602BFE1D3EA9B40050646F /* MGLForegroundStyleLayer.mm */,
+ DAF25714201901C200367EF5 /* MGLHillshadeStyleLayer.h */,
+ DAF25713201901C100367EF5 /* MGLHillshadeStyleLayer.mm */,
DA8F25891D51CA540010E6B5 /* MGLLineStyleLayer.h */,
DA8F258A1D51CA540010E6B5 /* MGLLineStyleLayer.mm */,
DA7262051DEEDD460043BB89 /* MGLOpenGLStyleLayer.h */,
@@ -703,6 +711,8 @@
352742831D4C244700A1ECE6 /* MGLRasterSource.h */,
DA7DC9821DED647F0027472F /* MGLRasterSource_Private.h */,
352742841D4C244700A1ECE6 /* MGLRasterSource.mm */,
+ DACA8620201920BE00E9693A /* MGLRasterDEMSource.h */,
+ DACA8621201920BE00E9693A /* MGLRasterDEMSource.mm */,
352742871D4C245800A1ECE6 /* MGLShapeSource.h */,
DA87A99B1DC9D8DD00810D09 /* MGLShapeSource_Private.h */,
352742881D4C245800A1ECE6 /* MGLShapeSource.mm */,
@@ -870,6 +880,7 @@
DA2207BA1DC076930002F84D /* test-Bridging-Header.h */,
DAA999001E9F5EC5002E6EA6 /* MGLFillExtrusionStyleLayerTests.mm */,
DA8F25741D51C5F40010E6B5 /* MGLFillStyleLayerTests.mm */,
+ DAF2571D201902A500367EF5 /* MGLHillshadeStyleLayerTests.mm */,
DA8F25751D51C5F40010E6B5 /* MGLRasterStyleLayerTests.mm */,
DA8F25761D51C5F40010E6B5 /* MGLSymbolStyleLayerTests.mm */,
DA8F25771D51C5F40010E6B5 /* MGLLineStyleLayerTests.mm */,
@@ -1162,6 +1173,7 @@
DA8F259C1D51CB000010E6B5 /* MGLStyleValue_Private.h in Headers */,
DAE6C35B1CC31E0400DB3429 /* MGLAnnotation.h in Headers */,
DAE6C3B61CC31EF300DB3429 /* MGLMapView_Private.h in Headers */,
+ DAF25716201901C200367EF5 /* MGLHillshadeStyleLayer.h in Headers */,
92092EF01F5EB10E00AF5130 /* MGLMapSnapshotter.h in Headers */,
3527428D1D4C24AB00A1ECE6 /* MGLCircleStyleLayer.h in Headers */,
DA00FC8A1D5EEAC3009AABC8 /* MGLAttributionInfo.h in Headers */,
@@ -1189,6 +1201,7 @@
DA7DC9811DED5F5C0027472F /* MGLVectorSource_Private.h in Headers */,
DAE6C3861CC31E2A00DB3429 /* MGLGeometry_Private.h in Headers */,
DAE6C3841CC31E2A00DB3429 /* MGLAccountManager_Private.h in Headers */,
+ DACA8622201920BE00E9693A /* MGLRasterDEMSource.h in Headers */,
DAE6C3691CC31E0400DB3429 /* MGLTypes.h in Headers */,
07D9474D1F67441B00E37934 /* MGLAbstractShapeSource_Private.h in Headers */,
DAE6C3991CC31E2A00DB3429 /* NSException+MGLAdditions.h in Headers */,
@@ -1466,6 +1479,7 @@
07A019EF1ED665CD00ACD43E /* MGLImageSource.mm in Sources */,
92092EF11F5EB10E00AF5130 /* MGLMapSnapshotter.mm in Sources */,
40ABDB561DB0022100372083 /* NSImage+MGLAdditions.mm in Sources */,
+ DAF25715201901C200367EF5 /* MGLHillshadeStyleLayer.mm in Sources */,
DAE6C3901CC31E2A00DB3429 /* MGLPointAnnotation.mm in Sources */,
DAE6C3981CC31E2A00DB3429 /* NSBundle+MGLAdditions.m in Sources */,
DAE6C3B71CC31EF300DB3429 /* MGLMapView.mm in Sources */,
@@ -1525,6 +1539,7 @@
DAD165751CF4CD7A001FF4B9 /* MGLShapeCollection.mm in Sources */,
35C5D8481D6DD66D00E95907 /* NSComparisonPredicate+MGLAdditions.mm in Sources */,
DA35A2AE1CCA091800E826B2 /* MGLCompassDirectionFormatter.m in Sources */,
+ DACA8623201920BE00E9693A /* MGLRasterDEMSource.mm in Sources */,
DA8F258C1D51CA540010E6B5 /* MGLLineStyleLayer.mm in Sources */,
DA8F25941D51CA750010E6B5 /* MGLSymbolStyleLayer.mm in Sources */,
3529039C1D6C63B80002C7DF /* NSPredicate+MGLAdditions.mm in Sources */,
@@ -1551,6 +1566,7 @@
DA87A9A41DCACC5000810D09 /* MGLSymbolStyleLayerTests.mm in Sources */,
40E1601D1DF217D6005EA6D9 /* MGLStyleLayerTests.m in Sources */,
1F95931B1E6DE2B600D5B294 /* MGLNSDateAdditionsTests.mm in Sources */,
+ DAF25721201902C100367EF5 /* MGLHillshadeStyleLayerTests.mm in Sources */,
DA87A9A61DCACC5000810D09 /* MGLCircleStyleLayerTests.mm in Sources */,
DA87A99E1DC9DC2100810D09 /* MGLPredicateTests.mm in Sources */,
DD58A4C91D822C6700E1F038 /* MGLExpressionTests.mm in Sources */,
diff --git a/platform/macos/src/Mapbox.h b/platform/macos/src/Mapbox.h
index 402c556998..7ea9a9dd1d 100644
--- a/platform/macos/src/Mapbox.h
+++ b/platform/macos/src/Mapbox.h
@@ -44,6 +44,7 @@ FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[];
#import "MGLRasterStyleLayer.h"
#import "MGLCircleStyleLayer.h"
#import "MGLBackgroundStyleLayer.h"
+#import "MGLHillshadeStyleLayer.h"
#import "MGLOpenGLStyleLayer.h"
#import "MGLSource.h"
#import "MGLTileSource.h"
@@ -52,6 +53,7 @@ FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[];
#import "MGLAbstractShapeSource.h"
#import "MGLComputedShapeSource.h"
#import "MGLRasterSource.h"
+#import "MGLRasterDEMSource.h"
#import "MGLImageSource.h"
#import "MGLTilePyramidOfflineRegion.h"
#import "MGLTypes.h"