diff options
42 files changed, 726 insertions, 647 deletions
diff --git a/benchmark/api/query.benchmark.cpp b/benchmark/api/query.benchmark.cpp index cf5e2516de..5d4e48fbe0 100644 --- a/benchmark/api/query.benchmark.cpp +++ b/benchmark/api/query.benchmark.cpp @@ -6,6 +6,7 @@ #include <mbgl/gl/headless_backend.hpp> #include <mbgl/gl/offscreen_view.hpp> #include <mbgl/util/default_thread_pool.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/storage/default_file_source.hpp> #include <mbgl/storage/network_status.hpp> @@ -25,7 +26,7 @@ public: map.setStyleJSON(util::read_file("benchmark/fixtures/api/query_style.json")); map.setLatLngZoom({ 40.726989, -73.992857 }, 15); // Manhattan - map.addImage(std::make_unique<style::Image>("test-icon", + map.getStyle().addImage(std::make_unique<style::Image>("test-icon", decodeImage(util::read_file("benchmark/fixtures/api/default_marker.png")), 1.0)); mbgl::benchmark::render(map, view); diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index 172b2854b3..8b85e59d7f 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -332,6 +332,7 @@ set(MBGL_CORE_FILES include/mbgl/style/position.hpp include/mbgl/style/property_value.hpp include/mbgl/style/source.hpp + include/mbgl/style/style.hpp include/mbgl/style/transition_options.hpp include/mbgl/style/types.hpp include/mbgl/style/undefined.hpp @@ -359,7 +360,8 @@ set(MBGL_CORE_FILES src/mbgl/style/source_impl.hpp src/mbgl/style/source_observer.hpp src/mbgl/style/style.cpp - src/mbgl/style/style.hpp + src/mbgl/style/style_impl.cpp + src/mbgl/style/style_impl.hpp src/mbgl/style/types.cpp # style/conversion diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 33b40a8e77..85c95d6491 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -9,7 +9,6 @@ #include <mbgl/util/noncopyable.hpp> #include <mbgl/util/size.hpp> #include <mbgl/annotation/annotation.hpp> -#include <mbgl/style/transition_options.hpp> #include <mbgl/map/camera.hpp> #include <mbgl/map/query.hpp> @@ -28,9 +27,7 @@ class Scheduler; namespace style { class Image; -class Source; -class Layer; -class Light; +class Style; } // namespace style class Map : private util::noncopyable { @@ -58,15 +55,15 @@ public: // Main render function. void render(View&); - // Styling - style::TransitionOptions getTransitionOptions() const; - void setTransitionOptions(const style::TransitionOptions&); - + // Style void setStyleURL(const std::string&); void setStyleJSON(const std::string&); std::string getStyleURL() const; std::string getStyleJSON() const; + style::Style& getStyle(); + const style::Style& getStyle() const; + // Transition void cancelTransitions(); void setGestureInProgress(bool); @@ -156,34 +153,6 @@ public: void updateAnnotation(AnnotationID, const Annotation&); void removeAnnotation(AnnotationID); - // Sources - std::vector<style::Source*> getSources(); - style::Source* getSource(const std::string& sourceID); - void addSource(std::unique_ptr<style::Source>); - std::unique_ptr<style::Source> removeSource(const std::string& sourceID); - - // Layers - std::vector<style::Layer*> getLayers(); - style::Layer* getLayer(const std::string& layerID); - void addLayer(std::unique_ptr<style::Layer>, const optional<std::string>& beforeLayerID = {}); - std::unique_ptr<style::Layer> removeLayer(const std::string& layerID); - - // Images - void addImage(std::unique_ptr<style::Image>); - void removeImage(const std::string&); - const style::Image* getImage(const std::string&); - - // Light - void setLight(std::unique_ptr<style::Light>); - style::Light* getLight(); - - // Defaults - std::string getStyleName() const; - LatLng getDefaultLatLng() const; - double getDefaultZoom() const; - double getDefaultBearing() const; - double getDefaultPitch() const; - // Feature queries std::vector<Feature> queryRenderedFeatures(const ScreenCoordinate&, const RenderedQueryOptions& options = {}); std::vector<Feature> queryRenderedFeatures(const ScreenBox&, const RenderedQueryOptions& options = {}); diff --git a/include/mbgl/style/style.hpp b/include/mbgl/style/style.hpp new file mode 100644 index 0000000000..82ff1b3078 --- /dev/null +++ b/include/mbgl/style/style.hpp @@ -0,0 +1,75 @@ +#pragma once + +#include <mbgl/style/transition_options.hpp> +#include <mbgl/util/geo.hpp> + +#include <string> +#include <vector> +#include <memory> + +namespace mbgl { + +class FileSource; +class Scheduler; + +namespace style { + +class Light; +class Image; +class Source; +class Layer; + +class Style { +public: + Style(Scheduler&, FileSource&, float pixelRatio); + ~Style(); + + // Defaults + std::string getName() const; + LatLng getDefaultLatLng() const; + double getDefaultZoom() const; + double getDefaultBearing() const; + double getDefaultPitch() const; + + // TransitionOptions + TransitionOptions getTransitionOptions() const; + void setTransitionOptions(const TransitionOptions&); + + // Light + Light* getLight(); + const Light* getLight() const; + + void setLight(std::unique_ptr<Light>); + + // Images + const Image* getImage(const std::string&) const; + void addImage(std::unique_ptr<Image>); + void removeImage(const std::string&); + + // Sources + std::vector< Source*> getSources(); + std::vector<const Source*> getSources() const; + + Source* getSource(const std::string&); + const Source* getSource(const std::string&) const; + + void addSource(std::unique_ptr<Source>); + std::unique_ptr<Source> removeSource(const std::string& sourceID); + + // Layers + std::vector< Layer*> getLayers(); + std::vector<const Layer*> getLayers() const; + + Layer* getLayer(const std::string&); + const Layer* getLayer(const std::string&) const; + + void addLayer(std::unique_ptr<Layer>, const optional<std::string>& beforeLayerID = {}); + std::unique_ptr<Layer> removeLayer(const std::string& layerID); + + // Private implementation + class Impl; + const std::unique_ptr<Impl> impl; +}; + +} // namespace style +} // namespace mbgl diff --git a/platform/android/src/conversion/constant.hpp b/platform/android/src/conversion/constant.hpp index 2a0b710f73..f1c72eb5dd 100644 --- a/platform/android/src/conversion/constant.hpp +++ b/platform/android/src/conversion/constant.hpp @@ -3,6 +3,7 @@ #include "conversion.hpp" #include <mbgl/util/optional.hpp> +#include <mbgl/util/color.hpp> #include <jni/jni.hpp> #include <string> diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 7696be5b18..e09a58d25f 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -25,6 +25,7 @@ #include <mbgl/util/logging.hpp> #include <mbgl/util/platform.hpp> #include <mbgl/util/projection.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/style/filter.hpp> @@ -745,25 +746,25 @@ jdouble NativeMapView::getTopOffsetPixelsForAnnotationSymbol(JNIEnv& env, jni::S } jlong NativeMapView::getTransitionDuration(JNIEnv&) { - const auto transitionOptions = map->getTransitionOptions(); + const auto transitionOptions = map->getStyle().getTransitionOptions(); return std::chrono::duration_cast<std::chrono::milliseconds>(transitionOptions.duration.value_or(mbgl::Duration::zero())).count(); } void NativeMapView::setTransitionDuration(JNIEnv&, jlong duration) { - auto transitionOptions = map->getTransitionOptions(); + auto transitionOptions = map->getStyle().getTransitionOptions(); transitionOptions.duration.emplace(mbgl::Milliseconds(duration)); - map->setTransitionOptions(transitionOptions); + map->getStyle().setTransitionOptions(transitionOptions); } jlong NativeMapView::getTransitionDelay(JNIEnv&) { - const auto transitionOptions = map->getTransitionOptions(); + const auto transitionOptions = map->getStyle().getTransitionOptions(); return std::chrono::duration_cast<std::chrono::milliseconds>(transitionOptions.delay.value_or(mbgl::Duration::zero())).count(); } void NativeMapView::setTransitionDelay(JNIEnv&, jlong delay) { - auto transitionOptions = map->getTransitionOptions(); + auto transitionOptions = map->getStyle().getTransitionOptions(); transitionOptions.delay.emplace(mbgl::Milliseconds(delay)); - map->setTransitionOptions(transitionOptions); + map->getStyle().setTransitionOptions(transitionOptions); } jni::Array<jlong> NativeMapView::queryPointAnnotations(JNIEnv& env, jni::Object<RectF> rect) { @@ -821,7 +822,7 @@ jni::Array<jni::Object<geojson::Feature>> NativeMapView::queryRenderedFeaturesFo } jni::Object<Light> NativeMapView::getLight(JNIEnv& env) { - mbgl::style::Light* light = map->getLight(); + mbgl::style::Light* light = map->getStyle().getLight(); if (light) { return jni::Object<Light>(Light::createJavaLightPeer(env, *map, *light)); } else { @@ -832,7 +833,7 @@ jni::Object<Light> NativeMapView::getLight(JNIEnv& env) { jni::Array<jni::Object<Layer>> NativeMapView::getLayers(JNIEnv& env) { // Get the core layers - std::vector<style::Layer*> layers = map->getLayers(); + std::vector<style::Layer*> layers = map->getStyle().getLayers(); // Convert jni::Array<jni::Object<Layer>> jLayers = jni::Array<jni::Object<Layer>>::New(env, layers.size(), Layer::javaClass); @@ -850,7 +851,7 @@ jni::Array<jni::Object<Layer>> NativeMapView::getLayers(JNIEnv& env) { jni::Object<Layer> NativeMapView::getLayer(JNIEnv& env, jni::String layerId) { // Find the layer - mbgl::style::Layer* coreLayer = map->getLayer(jni::Make<std::string>(env, layerId)); + mbgl::style::Layer* coreLayer = map->getStyle().getLayer(jni::Make<std::string>(env, layerId)); if (!coreLayer) { mbgl::Log::Debug(mbgl::Event::JNI, "No layer found"); return jni::Object<Layer>(); @@ -877,7 +878,7 @@ void NativeMapView::addLayerAbove(JNIEnv& env, jlong nativeLayerPtr, jni::String Layer *layer = reinterpret_cast<Layer *>(nativeLayerPtr); // Find the sibling - auto layers = map->getLayers(); + auto layers = map->getStyle().getLayers(); auto siblingId = jni::Make<std::string>(env, above); size_t index = 0; @@ -912,7 +913,7 @@ void NativeMapView::addLayerAt(JNIEnv& env, jlong nativeLayerPtr, jni::jint inde assert(nativeLayerPtr != 0); Layer *layer = reinterpret_cast<Layer *>(nativeLayerPtr); - auto layers = map->getLayers(); + auto layers = map->getStyle().getLayers(); // Check index int numLayers = layers.size() - 1; @@ -935,7 +936,7 @@ void NativeMapView::addLayerAt(JNIEnv& env, jlong nativeLayerPtr, jni::jint inde * Remove by layer id. */ jni::Object<Layer> NativeMapView::removeLayerById(JNIEnv& env, jni::String id) { - std::unique_ptr<mbgl::style::Layer> coreLayer = map->removeLayer(jni::Make<std::string>(env, id)); + std::unique_ptr<mbgl::style::Layer> coreLayer = map->getStyle().removeLayer(jni::Make<std::string>(env, id)); if (coreLayer) { return jni::Object<Layer>(createJavaLayerPeer(env, *map, std::move(coreLayer))); } else { @@ -947,7 +948,7 @@ jni::Object<Layer> NativeMapView::removeLayerById(JNIEnv& env, jni::String id) { * Remove layer at index. */ jni::Object<Layer> NativeMapView::removeLayerAt(JNIEnv& env, jni::jint index) { - auto layers = map->getLayers(); + auto layers = map->getStyle().getLayers(); // Check index int numLayers = layers.size() - 1; @@ -956,7 +957,7 @@ jni::Object<Layer> NativeMapView::removeLayerAt(JNIEnv& env, jni::jint index) { return jni::Object<Layer>(); } - std::unique_ptr<mbgl::style::Layer> coreLayer = map->removeLayer(layers.at(index)->getID()); + std::unique_ptr<mbgl::style::Layer> coreLayer = map->getStyle().removeLayer(layers.at(index)->getID()); if (coreLayer) { return jni::Object<Layer>(createJavaLayerPeer(env, *map, std::move(coreLayer))); } else { @@ -971,7 +972,7 @@ void NativeMapView::removeLayer(JNIEnv&, jlong layerPtr) { assert(layerPtr != 0); mbgl::android::Layer *layer = reinterpret_cast<mbgl::android::Layer *>(layerPtr); - std::unique_ptr<mbgl::style::Layer> coreLayer = map->removeLayer(layer->get().getID()); + std::unique_ptr<mbgl::style::Layer> coreLayer = map->getStyle().removeLayer(layer->get().getID()); if (coreLayer) { layer->setLayer(std::move(coreLayer)); } @@ -979,7 +980,7 @@ void NativeMapView::removeLayer(JNIEnv&, jlong layerPtr) { jni::Array<jni::Object<Source>> NativeMapView::getSources(JNIEnv& env) { // Get the core sources - std::vector<style::Source*> sources = map->getSources(); + std::vector<style::Source*> sources = map->getStyle().getSources(); // Convert jni::Array<jni::Object<Source>> jSources = jni::Array<jni::Object<Source>>::New(env, sources.size(), Source::javaClass); @@ -996,7 +997,7 @@ jni::Array<jni::Object<Source>> NativeMapView::getSources(JNIEnv& env) { jni::Object<Source> NativeMapView::getSource(JNIEnv& env, jni::String sourceId) { // Find the source - mbgl::style::Source* coreSource = map->getSource(jni::Make<std::string>(env, sourceId)); + mbgl::style::Source* coreSource = map->getStyle().getSource(jni::Make<std::string>(env, sourceId)); if (!coreSource) { mbgl::Log::Debug(mbgl::Event::JNI, "No source found"); return jni::Object<Source>(); @@ -1018,7 +1019,7 @@ void NativeMapView::addSource(JNIEnv& env, jni::jlong sourcePtr) { } jni::Object<Source> NativeMapView::removeSourceById(JNIEnv& env, jni::String id) { - std::unique_ptr<mbgl::style::Source> coreSource = map->removeSource(jni::Make<std::string>(env, id)); + std::unique_ptr<mbgl::style::Source> coreSource = map->getStyle().removeSource(jni::Make<std::string>(env, id)); if (coreSource) { return jni::Object<Source>(createJavaSourcePeer(env, *map, *coreSource)); } else { @@ -1030,7 +1031,7 @@ void NativeMapView::removeSource(JNIEnv&, jlong sourcePtr) { assert(sourcePtr != 0); mbgl::android::Source *source = reinterpret_cast<mbgl::android::Source *>(sourcePtr); - std::unique_ptr<mbgl::style::Source> coreSource = map->removeSource(source->get().getID()); + std::unique_ptr<mbgl::style::Source> coreSource = map->getStyle().removeSource(source->get().getID()); if (coreSource) { source->setSource(std::move(coreSource)); } @@ -1047,14 +1048,14 @@ void NativeMapView::addImage(JNIEnv& env, jni::String name, jni::jint w, jni::ji jni::GetArrayRegion(env, *pixels, 0, size, reinterpret_cast<jbyte*>(premultipliedImage.data.get())); - map->addImage(std::make_unique<mbgl::style::Image>( + map->getStyle().addImage(std::make_unique<mbgl::style::Image>( jni::Make<std::string>(env, name), std::move(premultipliedImage), float(scale))); } void NativeMapView::removeImage(JNIEnv& env, jni::String name) { - map->removeImage(jni::Make<std::string>(env, name)); + map->getStyle().removeImage(jni::Make<std::string>(env, name)); } // Private methods // diff --git a/platform/android/src/style/android_conversion.hpp b/platform/android/src/style/android_conversion.hpp index 6327ed96d0..082fe411e2 100644 --- a/platform/android/src/style/android_conversion.hpp +++ b/platform/android/src/style/android_conversion.hpp @@ -2,6 +2,7 @@ #include "value.hpp" +#include <mbgl/util/feature.hpp> #include <mbgl/util/logging.hpp> #include <mbgl/style/conversion.hpp> #include <mbgl/util/optional.hpp> diff --git a/platform/android/src/style/conversion/transition_options.hpp b/platform/android/src/style/conversion/transition_options.hpp index 3614878f43..ae65a32194 100644 --- a/platform/android/src/style/conversion/transition_options.hpp +++ b/platform/android/src/style/conversion/transition_options.hpp @@ -3,6 +3,7 @@ #include "../../conversion/conversion.hpp" #include <jni/jni.hpp> +#include <mbgl/style/transition_options.hpp> #include "../../jni/local_object.hpp" #include "../transition_options.hpp" diff --git a/platform/android/src/style/layers/layer.cpp b/platform/android/src/style/layers/layer.cpp index 965b304dcf..02a1f0be82 100644 --- a/platform/android/src/style/layers/layer.cpp +++ b/platform/android/src/style/layers/layer.cpp @@ -3,6 +3,7 @@ #include <jni/jni.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/transition_options.hpp> #include <mbgl/util/logging.hpp> @@ -53,7 +54,7 @@ namespace android { } // Add layer to map - _map.addLayer(releaseCoreLayer(), before); + _map.getStyle().addLayer(releaseCoreLayer(), before); // Save pointer to the map this->map = &_map; diff --git a/platform/android/src/style/sources/source.cpp b/platform/android/src/style/sources/source.cpp index e0e9bb9870..05f981953a 100644 --- a/platform/android/src/style/sources/source.cpp +++ b/platform/android/src/style/sources/source.cpp @@ -3,6 +3,7 @@ #include <jni/jni.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/util/logging.hpp> // Java -> C++ conversion @@ -55,7 +56,7 @@ namespace android { } // Add source to map - _map.addSource(releaseCoreSource()); + _map.getStyle().addSource(releaseCoreSource()); // Save pointer to the map this->map = &_map; diff --git a/platform/darwin/src/MGLOpenGLStyleLayer.h b/platform/darwin/src/MGLOpenGLStyleLayer.h index bdad5f9d07..0b494e8062 100644 --- a/platform/darwin/src/MGLOpenGLStyleLayer.h +++ b/platform/darwin/src/MGLOpenGLStyleLayer.h @@ -8,6 +8,7 @@ NS_ASSUME_NONNULL_BEGIN @class MGLMapView; +@class MGLStyle; typedef struct MGLStyleLayerDrawingContext { CGSize size; @@ -21,7 +22,7 @@ typedef struct MGLStyleLayerDrawingContext { MGL_EXPORT @interface MGLOpenGLStyleLayer : MGLStyleLayer -@property (nonatomic, weak, readonly) MGLMapView *mapView; +@property (nonatomic, weak, readonly) MGLStyle *style; - (instancetype)initWithIdentifier:(NSString *)identifier; diff --git a/platform/darwin/src/MGLOpenGLStyleLayer.mm b/platform/darwin/src/MGLOpenGLStyleLayer.mm index 39eda758eb..36a3c20c97 100644 --- a/platform/darwin/src/MGLOpenGLStyleLayer.mm +++ b/platform/darwin/src/MGLOpenGLStyleLayer.mm @@ -4,7 +4,6 @@ #import "MGLStyle_Private.h" #import "MGLStyleLayer_Private.h" -#include <mbgl/map/map.hpp> #include <mbgl/style/layers/custom_layer.hpp> #include <mbgl/math/wrap.hpp> @@ -17,7 +16,7 @@ */ void MGLPrepareCustomStyleLayer(void *context) { MGLOpenGLStyleLayer *layer = (__bridge MGLOpenGLStyleLayer *)context; - [layer didMoveToMapView:layer.mapView]; + [layer didMoveToMapView:layer.style.mapView]; } /** @@ -37,7 +36,7 @@ void MGLDrawCustomStyleLayer(void *context, const mbgl::style::CustomLayerRender .pitch = static_cast<CGFloat>(params.pitch), .fieldOfView = static_cast<CGFloat>(params.fieldOfView), }; - [layer drawInMapView:layer.mapView withContext:drawingContext]; + [layer drawInMapView:layer.style.mapView withContext:drawingContext]; } /** @@ -49,7 +48,7 @@ void MGLDrawCustomStyleLayer(void *context, const mbgl::style::CustomLayerRender */ void MGLFinishCustomStyleLayer(void *context) { MGLOpenGLStyleLayer *layer = (__bridge MGLOpenGLStyleLayer *)context; - [layer willMoveFromMapView:layer.mapView]; + [layer willMoveFromMapView:layer.style.mapView]; } /** @@ -75,12 +74,12 @@ void MGLFinishCustomStyleLayer(void *context) { @property (nonatomic, readonly) mbgl::style::CustomLayer *rawLayer; /** - The map view whose style currently contains the layer. + The style currently containing the layer. - If the layer is not currently part of any map view’s style, this property is + If the layer is not currently part of any style, this property is set to `nil`. */ -@property (nonatomic, weak, readwrite) MGLMapView *mapView; +@property (nonatomic, weak, readwrite) MGLStyle *style; @end @@ -112,24 +111,24 @@ void MGLFinishCustomStyleLayer(void *context) { #pragma mark - Adding to and removing from a map view -- (void)setMapView:(MGLMapView *)mapView { - if (_mapView && mapView) { +- (void)setStyle:(MGLStyle *)style { + if (_style && style) { [NSException raise:@"MGLLayerReuseException" format:@"%@ cannot be added to more than one MGLStyle at a time.", self]; } - _mapView.style.openGLLayers[self.identifier] = nil; - _mapView = mapView; - _mapView.style.openGLLayers[self.identifier] = self; + _style.openGLLayers[self.identifier] = nil; + _style = style; + _style.openGLLayers[self.identifier] = self; } -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer { - self.mapView = mapView; - [super addToMapView:mapView belowLayer:otherLayer]; +- (void)addToStyle:(MGLStyle *)style belowLayer:(MGLStyleLayer *)otherLayer { + self.style = style; + [super addToStyle:style belowLayer:otherLayer]; } -- (void)removeFromMapView:(MGLMapView *)mapView { - [super removeFromMapView:mapView]; - self.mapView = nil; +- (void)removeFromStyle:(MGLStyle *)style { + [super removeFromStyle:style]; + self.style = nil; } /** @@ -193,7 +192,7 @@ void MGLFinishCustomStyleLayer(void *context) { causing the `-drawInMapView:withContext:` method to be called. */ - (void)setNeedsDisplay { - [self.mapView setNeedsGLDisplay]; + [self.style.mapView setNeedsGLDisplay]; } @end diff --git a/platform/darwin/src/MGLShapeSource.mm b/platform/darwin/src/MGLShapeSource.mm index 023a81bba8..11b1d8eca8 100644 --- a/platform/darwin/src/MGLShapeSource.mm +++ b/platform/darwin/src/MGLShapeSource.mm @@ -1,5 +1,6 @@ #import "MGLShapeSource_Private.h" +#import "MGLStyle_Private.h" #import "MGLMapView_Private.h" #import "MGLSource_Private.h" #import "MGLFeature_Private.h" @@ -96,8 +97,8 @@ const MGLShapeSourceOption MGLShapeSourceOptionSimplificationTolerance = @"MGLSh } std::vector<mbgl::Feature> features; - if (self.mapView) { - features = self.mapView.mbglMap->querySourceFeatures(self.rawSource->getID(), { {}, optionalFilter }); + if (self.style) { + features = self.style.mapView.mbglMap->querySourceFeatures(self.rawSource->getID(), { {}, optionalFilter }); } return MGLFeaturesFromMBGLFeatures(features); } diff --git a/platform/darwin/src/MGLSource.mm b/platform/darwin/src/MGLSource.mm index eb859ba2c0..ee012f4d66 100644 --- a/platform/darwin/src/MGLSource.mm +++ b/platform/darwin/src/MGLSource.mm @@ -1,7 +1,7 @@ #import "MGLSource_Private.h" -#import "MGLMapView_Private.h" +#import "MGLStyle_Private.h" -#include <mbgl/map/map.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/source.hpp> @interface MGLSource () @@ -10,7 +10,7 @@ // special internal source types like mbgl::AnnotationSource. @property (nonatomic, readonly) mbgl::style::Source *rawSource; -@property (nonatomic, readonly, weak) MGLMapView *mapView; +@property (nonatomic, readonly, weak) MGLStyle *style; @end @@ -43,21 +43,21 @@ return self; } -- (void)addToMapView:(MGLMapView *)mapView { +- (void)addToStyle:(MGLStyle *)style { if (_pendingSource == nullptr) { [NSException raise:@"MGLRedundantSourceException" format:@"This instance %@ was already added to %@. Adding the same source instance " \ - "to the style more than once is invalid.", self, mapView.style]; + "to the style more than once is invalid.", self, style]; } - _mapView = mapView; - mapView.mbglMap->addSource(std::move(_pendingSource)); + _style = style; + style.rawStyle->addSource(std::move(_pendingSource)); } -- (void)removeFromMapView:(MGLMapView *)mapView { - if (self.rawSource == mapView.mbglMap->getSource(self.identifier.UTF8String)) { - _pendingSource = mapView.mbglMap->removeSource(self.identifier.UTF8String); - _mapView = nil; +- (void)removeFromStyle:(MGLStyle *)style { + if (self.rawSource == style.rawStyle->getSource(self.identifier.UTF8String)) { + _pendingSource = style.rawStyle->removeSource(self.identifier.UTF8String); + _style = nil; } } diff --git a/platform/darwin/src/MGLSource_Private.h b/platform/darwin/src/MGLSource_Private.h index 91bfac6390..ba78973279 100644 --- a/platform/darwin/src/MGLSource_Private.h +++ b/platform/darwin/src/MGLSource_Private.h @@ -18,7 +18,7 @@ struct SourceWrapper { __weak MGLSource *source; }; -@class MGLMapView; +@class MGLStyle; @interface MGLSource (Private) @@ -44,33 +44,33 @@ struct SourceWrapper { @property (nonatomic, readonly) mbgl::style::Source *rawSource; /** - The map view whose style currently contains the source. + The style which currently contains the source. - If the source is not currently part of any map view’s style, this property is + If the source is not currently part of a style, this property is set to `nil`. */ -@property (nonatomic, readonly, weak) MGLMapView *mapView; +@property (nonatomic, readonly, weak) MGLStyle *style; /** - Adds the mbgl source that this object represents to the mbgl map. + Adds the mbgl source that this object represents to the style. Once a mbgl source is added, ownership of the object is transferred to the - `mbgl::Map` and this object no longer has an active unique_ptr reference to the + `mbgl::Style` and this object no longer has an active unique_ptr reference to the `mbgl::Source`. If this object's mbgl source is in that state, the mbgl source can still be changed but the changes will not be visible until the `MGLSource` - is added back to the map via `-[MGLStyle addSource:]` and styled with a + is added back to the style via `-[MGLStyle addSource:]` and styled with a `MGLLayer`. */ -- (void)addToMapView:(MGLMapView *)mapView; +- (void)addToStyle:(MGLStyle *)style; /** - Removes the mbgl source that this object represents from the mbgl map. + Removes the mbgl source that this object represents from the style. When a mbgl source is removed, ownership of the object is transferred back to the `MGLSource` instance and the unique_ptr reference is valid again. It is safe to add the source back to the style after it is removed. */ -- (void)removeFromMapView:(MGLMapView *)mapView; +- (void)removeFromStyle:(MGLStyle *)style; @end diff --git a/platform/darwin/src/MGLStyle.mm b/platform/darwin/src/MGLStyle.mm index 592ab86780..6d9a12c3e0 100644 --- a/platform/darwin/src/MGLStyle.mm +++ b/platform/darwin/src/MGLStyle.mm @@ -2,6 +2,7 @@ #import "MGLMapView_Private.h" #import "MGLStyleLayer.h" +#import "MGLStyleLayer_Private.h" #import "MGLFillStyleLayer.h" #import "MGLFillExtrusionStyleLayer.h" #import "MGLLineStyleLayer.h" @@ -11,14 +12,9 @@ #import "MGLBackgroundStyleLayer.h" #import "MGLOpenGLStyleLayer.h" -#import "MGLStyle_Private.h" -#import "MGLStyleLayer_Private.h" +#import "MGLSource.h" #import "MGLSource_Private.h" #import "MGLLight_Private.h" - -#import "NSDate+MGLAdditions.h" - -#import "MGLSource.h" #import "MGLTileSource_Private.h" #import "MGLVectorSource.h" #import "MGLRasterSource.h" @@ -29,6 +25,7 @@ #include <mbgl/map/map.hpp> #include <mbgl/util/default_styles.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/style/light.hpp> #include <mbgl/style/layers/fill_layer.hpp> @@ -44,6 +41,8 @@ #include <mbgl/style/sources/raster_source.hpp> #include <mbgl/style/sources/image_source.hpp> +#import "NSDate+MGLAdditions.h" + #if TARGET_OS_IPHONE #import "UIImage+MGLAdditions.h" #else @@ -52,7 +51,8 @@ @interface MGLStyle() -@property (nonatomic, readwrite, weak) MGLMapView *mapView; +@property (nonatomic, readonly, weak) MGLMapView *mapView; +@property (nonatomic, readonly) mbgl::style::Style *rawStyle; @property (readonly, copy, nullable) NSURL *URL; @property (nonatomic, readwrite, strong) NS_MUTABLE_DICTIONARY_OF(NSString *, MGLOpenGLStyleLayer *) *openGLLayers; @@ -114,9 +114,10 @@ static NSURL *MGLStyleURL_emerald; #pragma mark - -- (instancetype)initWithMapView:(MGLMapView *)mapView { +- (instancetype)initWithRawStyle:(mbgl::style::Style *)rawStyle mapView:(MGLMapView *)mapView { if (self = [super init]) { _mapView = mapView; + _rawStyle = rawStyle; _openGLLayers = [NSMutableDictionary dictionary]; } return self; @@ -127,14 +128,14 @@ static NSURL *MGLStyleURL_emerald; } - (NSString *)name { - std::string name = self.mapView.mbglMap->getStyleName(); + std::string name = self.rawStyle->getName(); return name.empty() ? nil : @(name.c_str()); } #pragma mark Sources - (NS_SET_OF(__kindof MGLSource *) *)sources { - auto rawSources = self.mapView.mbglMap->getSources(); + auto rawSources = self.rawStyle->getSources(); NS_MUTABLE_SET_OF(__kindof MGLSource *) *sources = [NSMutableSet setWithCapacity:rawSources.size()]; for (auto rawSource = rawSources.begin(); rawSource != rawSources.end(); ++rawSource) { MGLSource *source = [self sourceFromMBGLSource:*rawSource]; @@ -153,8 +154,7 @@ static NSURL *MGLStyleURL_emerald; } - (NSUInteger)countOfSources { - auto rawSources = self.mapView.mbglMap->getSources(); - return rawSources.size(); + return self.rawStyle->getSources().size(); } - (MGLSource *)memberOfSources:(MGLSource *)object { @@ -163,7 +163,7 @@ static NSURL *MGLStyleURL_emerald; - (MGLSource *)sourceWithIdentifier:(NSString *)identifier { - auto rawSource = self.mapView.mbglMap->getSource(identifier.UTF8String); + auto rawSource = self.rawStyle->getSource(identifier.UTF8String); return rawSource ? [self sourceFromMBGLSource:rawSource] : nil; } @@ -197,7 +197,7 @@ static NSURL *MGLStyleURL_emerald; } try { - [source addToMapView:self.mapView]; + [source addToStyle:self]; } catch (std::runtime_error & err) { [NSException raise:@"MGLRedundantSourceIdentifierException" format:@"%s", err.what()]; } @@ -211,14 +211,14 @@ static NSURL *MGLStyleURL_emerald; @"Make sure the source was created as a member of a concrete subclass of MGLSource.", source]; } - [source removeFromMapView:self.mapView]; + [source removeFromStyle:self]; } - (nullable NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor { // It’d be incredibly convenient to use -sources here, but this operation // depends on the sources being sorted in ascending order by creation, as // with the std::vector used in mbgl. - auto rawSources = self.mapView.mbglMap->getSources(); + auto rawSources = self.rawStyle->getSources(); NSMutableArray *infos = [NSMutableArray arrayWithCapacity:rawSources.size()]; for (auto rawSource = rawSources.begin(); rawSource != rawSources.end(); ++rawSource) { MGLTileSource *source = (MGLTileSource *)[self sourceFromMBGLSource:*rawSource]; @@ -236,7 +236,7 @@ static NSURL *MGLStyleURL_emerald; - (NS_ARRAY_OF(__kindof MGLStyleLayer *) *)layers { - auto layers = self.mapView.mbglMap->getLayers(); + auto layers = self.rawStyle->getLayers(); NS_MUTABLE_ARRAY_OF(__kindof MGLStyleLayer *) *styleLayers = [NSMutableArray arrayWithCapacity:layers.size()]; for (auto layer : layers) { MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:layer]; @@ -256,12 +256,12 @@ static NSURL *MGLStyleURL_emerald; - (NSUInteger)countOfLayers { - return self.mapView.mbglMap->getLayers().size(); + return self.rawStyle->getLayers().size(); } - (MGLStyleLayer *)objectInLayersAtIndex:(NSUInteger)index { - auto layers = self.mapView.mbglMap->getLayers(); + auto layers = self.rawStyle->getLayers(); if (index >= layers.size()) { [NSException raise:NSRangeException format:@"No style layer at index %lu.", (unsigned long)index]; @@ -273,7 +273,7 @@ static NSURL *MGLStyleURL_emerald; - (void)getLayers:(MGLStyleLayer **)buffer range:(NSRange)inRange { - auto layers = self.mapView.mbglMap->getLayers(); + auto layers = self.rawStyle->getLayers(); if (NSMaxRange(inRange) > layers.size()) { [NSException raise:NSRangeException format:@"Style layer range %@ is out of bounds.", NSStringFromRange(inRange)]; @@ -293,21 +293,21 @@ static NSURL *MGLStyleURL_emerald; @"Make sure the style layer was created as a member of a concrete subclass of MGLStyleLayer.", styleLayer]; } - auto layers = self.mapView.mbglMap->getLayers(); + auto layers = self.rawStyle->getLayers(); if (index > layers.size()) { [NSException raise:NSRangeException format:@"Cannot insert style layer at out-of-bounds index %lu.", (unsigned long)index]; } else if (index == 0) { try { MGLStyleLayer *sibling = layers.size() ? [self layerFromMBGLLayer:layers.at(0)] : nil; - [styleLayer addToMapView:self.mapView belowLayer:sibling]; + [styleLayer addToStyle:self belowLayer:sibling]; } catch (const std::runtime_error & err) { [NSException raise:@"MGLRedundantLayerIdentifierException" format:@"%s", err.what()]; } } else { try { MGLStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(index)]; - [styleLayer addToMapView:self.mapView belowLayer:sibling]; + [styleLayer addToStyle:self belowLayer:sibling]; } catch (std::runtime_error & err) { [NSException raise:@"MGLRedundantLayerIdentifierException" format:@"%s", err.what()]; } @@ -316,14 +316,14 @@ static NSURL *MGLStyleURL_emerald; - (void)removeObjectFromLayersAtIndex:(NSUInteger)index { - auto layers = self.mapView.mbglMap->getLayers(); + auto layers = self.rawStyle->getLayers(); if (index >= layers.size()) { [NSException raise:NSRangeException format:@"Cannot remove style layer at out-of-bounds index %lu.", (unsigned long)index]; } auto layer = layers.at(index); MGLStyleLayer *styleLayer = [self layerFromMBGLLayer:layer]; - [styleLayer removeFromMapView:self.mapView]; + [styleLayer removeFromStyle:self]; } - (MGLStyleLayer *)layerFromMBGLLayer:(mbgl::style::Layer *)rawLayer @@ -358,7 +358,7 @@ static NSURL *MGLStyleURL_emerald; - (MGLStyleLayer *)layerWithIdentifier:(NSString *)identifier { - auto mbglLayer = self.mapView.mbglMap->getLayer(identifier.UTF8String); + auto mbglLayer = self.rawStyle->getLayer(identifier.UTF8String); return mbglLayer ? [self layerFromMBGLLayer:mbglLayer] : nil; } @@ -371,7 +371,7 @@ static NSURL *MGLStyleURL_emerald; layer]; } [self willChangeValueForKey:@"layers"]; - [layer removeFromMapView:self.mapView]; + [layer removeFromStyle:self]; [self didChangeValueForKey:@"layers"]; } @@ -385,7 +385,7 @@ static NSURL *MGLStyleURL_emerald; } [self willChangeValueForKey:@"layers"]; try { - [layer addToMapView:self.mapView belowLayer:nil]; + [layer addToStyle:self belowLayer:nil]; } catch (std::runtime_error & err) { [NSException raise:@"MGLRedundantLayerIdentifierException" format:@"%s", err.what()]; } @@ -414,7 +414,7 @@ static NSURL *MGLStyleURL_emerald; } [self willChangeValueForKey:@"layers"]; try { - [layer addToMapView:self.mapView belowLayer:sibling]; + [layer addToStyle:self belowLayer:sibling]; } catch (std::runtime_error & err) { [NSException raise:@"MGLRedundantLayerIdentifierException" format:@"%s", err.what()]; } @@ -437,7 +437,7 @@ static NSURL *MGLStyleURL_emerald; sibling]; } - auto layers = self.mapView.mbglMap->getLayers(); + auto layers = self.rawStyle->getLayers(); std::string siblingIdentifier = sibling.identifier.UTF8String; NSUInteger index = 0; for (auto layer : layers) { @@ -456,14 +456,14 @@ static NSURL *MGLStyleURL_emerald; sibling]; } else if (index + 1 == layers.size()) { try { - [layer addToMapView:self.mapView belowLayer:nil]; + [layer addToStyle:self belowLayer:nil]; } catch (std::runtime_error & err) { [NSException raise:@"MGLRedundantLayerIdentifierException" format:@"%s", err.what()]; } } else { MGLStyleLayer *sibling = [self layerFromMBGLLayer:layers.at(index + 1)]; try { - [layer addToMapView:self.mapView belowLayer:sibling]; + [layer addToStyle:self belowLayer:sibling]; } catch (std::runtime_error & err) { [NSException raise:@"MGLRedundantLayerIdentifierException" format:@"%s", err.what()]; } @@ -516,7 +516,7 @@ static NSURL *MGLStyleURL_emerald; format:@"Cannot assign image %@ to a nil name.", image]; } - self.mapView.mbglMap->addImage([image mgl_styleImageWithIdentifier:name]); + self.rawStyle->addImage([image mgl_styleImageWithIdentifier:name]); } - (void)removeImageForName:(NSString *)name @@ -526,7 +526,7 @@ static NSURL *MGLStyleURL_emerald; format:@"Cannot remove image with nil name."]; } - self.mapView.mbglMap->removeImage([name UTF8String]); + self.rawStyle->removeImage([name UTF8String]); } - (MGLImage *)imageForName:(NSString *)name @@ -536,7 +536,7 @@ static NSURL *MGLStyleURL_emerald; format:@"Cannot get image with nil name."]; } - auto styleImage = self.mapView.mbglMap->getImage([name UTF8String]); + auto styleImage = self.rawStyle->getImage([name UTF8String]); return styleImage ? [[MGLImage alloc] initWithMGLStyleImage:styleImage] : nil; } @@ -544,17 +544,17 @@ static NSURL *MGLStyleURL_emerald; - (void)setTransition:(MGLTransition)transition { - auto transitionOptions = self.mapView.mbglMap->getTransitionOptions(); + auto transitionOptions = self.rawStyle->getTransitionOptions(); transitionOptions.duration = MGLDurationFromTimeInterval(transition.duration); transitionOptions.delay = MGLDurationFromTimeInterval(transition.delay); - self.mapView.mbglMap->setTransitionOptions(transitionOptions); + self.rawStyle->setTransitionOptions(transitionOptions); } - (MGLTransition)transition { MGLTransition transition; - const mbgl::style::TransitionOptions transitionOptions = self.mapView.mbglMap->getTransitionOptions(); + const mbgl::style::TransitionOptions transitionOptions = self.rawStyle->getTransitionOptions(); transition.delay = MGLTimeIntervalFromDuration(transitionOptions.delay.value_or(mbgl::Duration::zero())); transition.duration = MGLTimeIntervalFromDuration(transitionOptions.duration.value_or(mbgl::Duration::zero())); @@ -567,12 +567,12 @@ static NSURL *MGLStyleURL_emerald; - (void)setLight:(MGLLight *)light { std::unique_ptr<mbgl::style::Light> mbglLight = std::make_unique<mbgl::style::Light>([light mbglLight]); - self.mapView.mbglMap->setLight(std::move(mbglLight)); + self.rawStyle->setLight(std::move(mbglLight)); } - (MGLLight *)light { - auto mbglLight = self.mapView.mbglMap->getLight(); + auto mbglLight = self.rawStyle->getLight(); MGLLight *light = [[MGLLight alloc] initWithMBGLLight:mbglLight]; return light; } diff --git a/platform/darwin/src/MGLStyleLayer.mm b/platform/darwin/src/MGLStyleLayer.mm index 4bfaea934b..6400b8fcbf 100644 --- a/platform/darwin/src/MGLStyleLayer.mm +++ b/platform/darwin/src/MGLStyleLayer.mm @@ -1,7 +1,7 @@ #import "MGLStyleLayer_Private.h" -#import "MGLMapView_Private.h" +#import "MGLStyle_Private.h" -#include <mbgl/map/map.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/layer.hpp> @interface MGLStyleLayer () @@ -30,26 +30,26 @@ return self; } -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(MGLStyleLayer *)otherLayer +- (void)addToStyle:(MGLStyle *)style belowLayer:(MGLStyleLayer *)otherLayer { if (_pendingLayer == nullptr) { [NSException raise:@"MGLRedundantLayerException" format:@"This instance %@ was already added to %@. Adding the same layer instance " \ - "to the style more than once is invalid.", self, mapView.style]; + "to the style more than once is invalid.", self, style]; } if (otherLayer) { const mbgl::optional<std::string> belowLayerId{otherLayer.identifier.UTF8String}; - mapView.mbglMap->addLayer(std::move(_pendingLayer), belowLayerId); + style.rawStyle->addLayer(std::move(_pendingLayer), belowLayerId); } else { - mapView.mbglMap->addLayer(std::move(_pendingLayer)); + style.rawStyle->addLayer(std::move(_pendingLayer)); } } -- (void)removeFromMapView:(MGLMapView *)mapView +- (void)removeFromStyle:(MGLStyle *)style { - if (self.rawLayer == mapView.mbglMap->getLayer(self.identifier.UTF8String)) { - _pendingLayer = mapView.mbglMap->removeLayer(self.identifier.UTF8String); + if (self.rawLayer == style.rawStyle->getLayer(self.identifier.UTF8String)) { + _pendingLayer = style.rawStyle->removeLayer(self.identifier.UTF8String); } } diff --git a/platform/darwin/src/MGLStyleLayer_Private.h b/platform/darwin/src/MGLStyleLayer_Private.h index ed8ec31755..9bee013c3d 100644 --- a/platform/darwin/src/MGLStyleLayer_Private.h +++ b/platform/darwin/src/MGLStyleLayer_Private.h @@ -34,7 +34,7 @@ struct LayerWrapper { } \ } while (NO); -@class MGLMapView; +@class MGLStyle; @interface MGLStyleLayer (Private) @@ -69,7 +69,7 @@ struct LayerWrapper { `mbgl::Map` and this object no longer has an active unique_ptr reference to the `mbgl::style::Layer`. */ -- (void)addToMapView:(MGLMapView *)mapView belowLayer:(nullable MGLStyleLayer *)otherLayer; +- (void)addToStyle:(MGLStyle *)style belowLayer:(nullable MGLStyleLayer *)otherLayer; /** Removes the mbgl style layer that this object represents from the mbgl map. @@ -78,7 +78,7 @@ struct LayerWrapper { to the `MGLStyleLayer` instance and the unique_ptr reference is valid again. It is safe to add the layer back to the style after it is removed. */ -- (void)removeFromMapView:(MGLMapView *)mapView; +- (void)removeFromStyle:(MGLStyle *)style; @end diff --git a/platform/darwin/src/MGLStyle_Private.h b/platform/darwin/src/MGLStyle_Private.h index 23ce8fbee0..92b08e844b 100644 --- a/platform/darwin/src/MGLStyle_Private.h +++ b/platform/darwin/src/MGLStyle_Private.h @@ -5,15 +5,22 @@ NS_ASSUME_NONNULL_BEGIN +namespace mbgl { + namespace style { + class Style; + } +} + @class MGLAttributionInfo; @class MGLMapView; @class MGLOpenGLStyleLayer; @interface MGLStyle (Private) -- (instancetype)initWithMapView:(MGLMapView *)mapView; +- (instancetype)initWithRawStyle:(mbgl::style::Style *)rawStyle mapView:(MGLMapView *)mapView; @property (nonatomic, readonly, weak) MGLMapView *mapView; +@property (nonatomic, readonly) mbgl::style::Style *rawStyle; - (nullable NS_ARRAY_OF(MGLAttributionInfo *) *)attributionInfosWithFontSize:(CGFloat)fontSize linkColor:(nullable MGLColor *)linkColor; diff --git a/platform/darwin/src/MGLVectorSource.mm b/platform/darwin/src/MGLVectorSource.mm index 5e9f4f4a6e..7265690f4d 100644 --- a/platform/darwin/src/MGLVectorSource.mm +++ b/platform/darwin/src/MGLVectorSource.mm @@ -3,6 +3,7 @@ #import "MGLFeature_Private.h" #import "MGLSource_Private.h" #import "MGLTileSource_Private.h" +#import "MGLStyle_Private.h" #import "MGLMapView_Private.h" #import "NSPredicate+MGLAdditions.h" #import "NSURL+MGLAdditions.h" @@ -62,8 +63,8 @@ } std::vector<mbgl::Feature> features; - if (self.mapView) { - features = self.mapView.mbglMap->querySourceFeatures(self.rawSource->getID(), { optionalSourceLayerIDs, optionalFilter }); + if (self.style) { + features = self.style.mapView.mbglMap->querySourceFeatures(self.rawSource->getID(), { optionalSourceLayerIDs, optionalFilter }); } return MGLFeaturesFromMBGLFeatures(features); } diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp index 06a852b3f3..1beaf2b52b 100644 --- a/platform/glfw/glfw_view.cpp +++ b/platform/glfw/glfw_view.cpp @@ -2,6 +2,7 @@ #include "ny_route.hpp" #include <mbgl/annotation/annotation.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/style/transition_options.hpp> #include <mbgl/style/layers/fill_extrusion_layer.hpp> @@ -585,11 +586,11 @@ void GLFWView::toggle3DExtrusions(bool visible) { show3DExtrusions = visible; // Satellite-only style does not contain building extrusions data. - if (!map->getSource("composite")) { + if (!map->getStyle().getSource("composite")) { return; } - if (auto layer = map->getLayer("3d-buildings")) { + if (auto layer = map->getStyle().getLayer("3d-buildings")) { layer->setVisibility(mbgl::style::VisibilityType(!show3DExtrusions)); return; } @@ -617,7 +618,7 @@ void GLFWView::toggle3DExtrusions(bool visible) { auto baseSourceFn = mbgl::style::SourceFunction<float> { "min_height", mbgl::style::IdentityStops<float>() }; extrusionLayer->setFillExtrusionBase({ baseSourceFn }); - map->addLayer(std::move(extrusionLayer)); + map->getStyle().addLayer(std::move(extrusionLayer)); } namespace mbgl { diff --git a/platform/ios/src/MGLMapView.mm b/platform/ios/src/MGLMapView.mm index 8ae3049e3e..0d00fe75fb 100644 --- a/platform/ios/src/MGLMapView.mm +++ b/platform/ios/src/MGLMapView.mm @@ -15,6 +15,7 @@ #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/storage/default_file_source.hpp> #include <mbgl/storage/network_status.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/style/transition_options.hpp> #include <mbgl/style/layers/custom_layer.hpp> @@ -2152,10 +2153,10 @@ public: - (void)resetPosition { - CGFloat pitch = _mbglMap->getDefaultPitch(); - CLLocationDirection heading = mbgl::util::wrap(_mbglMap->getDefaultBearing(), 0., 360.); - CLLocationDistance distance = MGLAltitudeForZoomLevel(_mbglMap->getDefaultZoom(), pitch, 0, self.frame.size); - self.camera = [MGLMapCamera cameraLookingAtCenterCoordinate:MGLLocationCoordinate2DFromLatLng(_mbglMap->getDefaultLatLng()) + CGFloat pitch = _mbglMap->getStyle().getDefaultPitch(); + CLLocationDirection heading = mbgl::util::wrap(_mbglMap->getStyle().getDefaultBearing(), 0., 360.); + CLLocationDistance distance = MGLAltitudeForZoomLevel(_mbglMap->getStyle().getDefaultZoom(), pitch, 0, self.frame.size); + self.camera = [MGLMapCamera cameraLookingAtCenterCoordinate:MGLLocationCoordinate2DFromLatLng(_mbglMap->getStyle().getDefaultLatLng()) fromDistance:distance pitch:pitch heading:heading]; @@ -4986,7 +4987,7 @@ public: return; } - self.style = [[MGLStyle alloc] initWithMapView:self]; + self.style = [[MGLStyle alloc] initWithRawStyle:&_mbglMap->getStyle() mapView:self]; if ([self.delegate respondsToSelector:@selector(mapView:didFinishLoadingStyle:)]) { [self.delegate mapView:self didFinishLoadingStyle:self.style]; diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index d2cb5e7100..756f237fba 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -937,7 +937,7 @@ public: return; } - self.style = [[MGLStyle alloc] initWithMapView:self]; + self.style = [[MGLStyle alloc] initWithRawStyle:&_mbglMap->getStyle() mapView:self]; if ([self.delegate respondsToSelector:@selector(mapView:didFinishLoadingStyle:)]) { [self.delegate mapView:self didFinishLoadingStyle:self.style]; diff --git a/platform/node/src/node_map.cpp b/platform/node/src/node_map.cpp index 4254cd2abe..324b53f843 100644 --- a/platform/node/src/node_map.cpp +++ b/platform/node/src/node_map.cpp @@ -9,6 +9,7 @@ #include <mbgl/style/conversion/source.hpp> #include <mbgl/style/conversion/layer.hpp> #include <mbgl/style/conversion/filter.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/map/backend_scope.hpp> #include <mbgl/map/query.hpp> @@ -563,7 +564,7 @@ void NodeMap::AddSource(const Nan::FunctionCallbackInfo<v8::Value>& info) { return; } - nodeMap->map->addSource(std::move(*source)); + nodeMap->map->getStyle().addSource(std::move(*source)); } void NodeMap::AddLayer(const Nan::FunctionCallbackInfo<v8::Value>& info) { @@ -584,7 +585,7 @@ void NodeMap::AddLayer(const Nan::FunctionCallbackInfo<v8::Value>& info) { return; } - nodeMap->map->addLayer(std::move(*layer)); + nodeMap->map->getStyle().addLayer(std::move(*layer)); } void NodeMap::RemoveLayer(const Nan::FunctionCallbackInfo<v8::Value>& info) { @@ -602,7 +603,7 @@ void NodeMap::RemoveLayer(const Nan::FunctionCallbackInfo<v8::Value>& info) { return Nan::ThrowTypeError("First argument must be a string"); } - nodeMap->map->removeLayer(*Nan::Utf8String(info[0])); + nodeMap->map->getStyle().removeLayer(*Nan::Utf8String(info[0])); } void NodeMap::AddImage(const Nan::FunctionCallbackInfo<v8::Value>& info) { @@ -664,7 +665,7 @@ void NodeMap::AddImage(const Nan::FunctionCallbackInfo<v8::Value>& info) { mbgl::UnassociatedImage cImage({ imageWidth, imageHeight}, std::move(data)); mbgl::PremultipliedImage cPremultipliedImage = mbgl::util::premultiply(std::move(cImage)); - nodeMap->map->addImage(std::make_unique<mbgl::style::Image>(*Nan::Utf8String(info[0]), std::move(cPremultipliedImage), pixelRatio)); + nodeMap->map->getStyle().addImage(std::make_unique<mbgl::style::Image>(*Nan::Utf8String(info[0]), std::move(cPremultipliedImage), pixelRatio)); } void NodeMap::RemoveImage(const Nan::FunctionCallbackInfo<v8::Value>& info) { @@ -682,7 +683,7 @@ void NodeMap::RemoveImage(const Nan::FunctionCallbackInfo<v8::Value>& info) { return Nan::ThrowTypeError("First argument must be a string"); } - nodeMap->map->removeImage(*Nan::Utf8String(info[0])); + nodeMap->map->getStyle().removeImage(*Nan::Utf8String(info[0])); } void NodeMap::SetLayoutProperty(const Nan::FunctionCallbackInfo<v8::Value>& info) { @@ -700,7 +701,7 @@ void NodeMap::SetLayoutProperty(const Nan::FunctionCallbackInfo<v8::Value>& info return Nan::ThrowTypeError("First argument must be a string"); } - mbgl::style::Layer* layer = nodeMap->map->getLayer(*Nan::Utf8String(info[0])); + mbgl::style::Layer* layer = nodeMap->map->getStyle().getLayer(*Nan::Utf8String(info[0])); if (!layer) { return Nan::ThrowTypeError("layer not found"); } @@ -732,7 +733,7 @@ void NodeMap::SetPaintProperty(const Nan::FunctionCallbackInfo<v8::Value>& info) return Nan::ThrowTypeError("First argument must be a string"); } - mbgl::style::Layer* layer = nodeMap->map->getLayer(*Nan::Utf8String(info[0])); + mbgl::style::Layer* layer = nodeMap->map->getStyle().getLayer(*Nan::Utf8String(info[0])); if (!layer) { return Nan::ThrowTypeError("layer not found"); } @@ -785,7 +786,7 @@ void NodeMap::SetFilter(const Nan::FunctionCallbackInfo<v8::Value>& info) { return Nan::ThrowTypeError("First argument must be a string"); } - mbgl::style::Layer* layer = nodeMap->map->getLayer(*Nan::Utf8String(info[0])); + mbgl::style::Layer* layer = nodeMap->map->getStyle().getLayer(*Nan::Utf8String(info[0])); if (!layer) { return Nan::ThrowTypeError("layer not found"); } diff --git a/platform/qt/src/qmapboxgl.cpp b/platform/qt/src/qmapboxgl.cpp index 7bc02c9d1c..cb48308682 100644 --- a/platform/qt/src/qmapboxgl.cpp +++ b/platform/qt/src/qmapboxgl.cpp @@ -9,6 +9,7 @@ #include <mbgl/map/map.hpp> #include <mbgl/map/backend_scope.hpp> #include <mbgl/math/minmax.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/conversion.hpp> #include <mbgl/style/conversion/layer.hpp> #include <mbgl/style/conversion/source.hpp> @@ -751,7 +752,7 @@ void QMapboxGL::setTransitionOptions(qint64 duration, qint64 delay) { return std::chrono::duration_cast<mbgl::Duration>(mbgl::Milliseconds(value)); }; - d_ptr->mapObj->setTransitionOptions(mbgl::style::TransitionOptions{ convert(duration), convert(delay) }); + d_ptr->mapObj->getStyle().setTransitionOptions(mbgl::style::TransitionOptions{ convert(duration), convert(delay) }); } mbgl::Annotation asMapboxGLAnnotation(const QMapbox::Annotation & annotation) { @@ -866,7 +867,7 @@ void QMapboxGL::setLayoutProperty(const QString& layer, const QString& property, { using namespace mbgl::style; - Layer* layer_ = d_ptr->mapObj->getLayer(layer.toStdString()); + Layer* layer_ = d_ptr->mapObj->getStyle().getLayer(layer.toStdString()); if (!layer_) { qWarning() << "Layer not found:" << layer; return; @@ -932,7 +933,7 @@ void QMapboxGL::setPaintProperty(const QString& layer, const QString& property, { using namespace mbgl::style; - Layer* layer_ = d_ptr->mapObj->getLayer(layer.toStdString()); + Layer* layer_ = d_ptr->mapObj->getStyle().getLayer(layer.toStdString()); if (!layer_) { qWarning() << "Layer not found:" << layer; return; @@ -1181,7 +1182,7 @@ void QMapboxGL::addSource(const QString &id, const QVariantMap ¶ms) return; } - d_ptr->mapObj->addSource(std::move(*source)); + d_ptr->mapObj->getStyle().addSource(std::move(*source)); } /*! @@ -1189,7 +1190,7 @@ void QMapboxGL::addSource(const QString &id, const QVariantMap ¶ms) */ bool QMapboxGL::sourceExists(const QString& sourceID) { - return !!d_ptr->mapObj->getSource(sourceID.toStdString()); + return !!d_ptr->mapObj->getStyle().getSource(sourceID.toStdString()); } /*! @@ -1203,7 +1204,7 @@ void QMapboxGL::updateSource(const QString &id, const QVariantMap ¶ms) using namespace mbgl::style; using namespace mbgl::style::conversion; - auto source = d_ptr->mapObj->getSource(id.toStdString()); + auto source = d_ptr->mapObj->getStyle().getSource(id.toStdString()); if (!source) { addSource(id, params); return; @@ -1233,8 +1234,8 @@ void QMapboxGL::removeSource(const QString& id) { auto sourceIDStdString = id.toStdString(); - if (d_ptr->mapObj->getSource(sourceIDStdString)) { - d_ptr->mapObj->removeSource(sourceIDStdString); + if (d_ptr->mapObj->getStyle().getSource(sourceIDStdString)) { + d_ptr->mapObj->getStyle().removeSource(sourceIDStdString); } } @@ -1253,7 +1254,7 @@ void QMapboxGL::addCustomLayer(const QString &id, void *context, const QString& before) { - d_ptr->mapObj->addLayer(std::make_unique<mbgl::style::CustomLayer>( + d_ptr->mapObj->getStyle().addLayer(std::make_unique<mbgl::style::CustomLayer>( id.toStdString(), reinterpret_cast<mbgl::style::CustomLayerInitializeFunction>(initFn), // This cast is safe as long as both mbgl:: and QMapbox:: @@ -1296,7 +1297,7 @@ void QMapboxGL::addLayer(const QVariantMap ¶ms, const QString& before) return; } - d_ptr->mapObj->addLayer(std::move(*layer), + d_ptr->mapObj->getStyle().addLayer(std::move(*layer), before.isEmpty() ? mbgl::optional<std::string>() : mbgl::optional<std::string>(before.toStdString())); } @@ -1305,7 +1306,7 @@ void QMapboxGL::addLayer(const QVariantMap ¶ms, const QString& before) */ bool QMapboxGL::layerExists(const QString& id) { - return !!d_ptr->mapObj->getLayer(id.toStdString()); + return !!d_ptr->mapObj->getStyle().getLayer(id.toStdString()); } /*! @@ -1313,7 +1314,7 @@ bool QMapboxGL::layerExists(const QString& id) */ void QMapboxGL::removeLayer(const QString& id) { - d_ptr->mapObj->removeLayer(id.toStdString()); + d_ptr->mapObj->getStyle().removeLayer(id.toStdString()); } /*! @@ -1330,7 +1331,7 @@ void QMapboxGL::addImage(const QString &id, const QImage &image) { if (image.isNull()) return; - d_ptr->mapObj->addImage(toStyleImage(id, image)); + d_ptr->mapObj->getStyle().addImage(toStyleImage(id, image)); } /*! @@ -1338,7 +1339,7 @@ void QMapboxGL::addImage(const QString &id, const QImage &image) */ void QMapboxGL::removeImage(const QString &id) { - d_ptr->mapObj->removeImage(id.toStdString()); + d_ptr->mapObj->getStyle().removeImage(id.toStdString()); } /*! @@ -1366,7 +1367,7 @@ void QMapboxGL::setFilter(const QString& layer, const QVariant& filter) using namespace mbgl::style; using namespace mbgl::style::conversion; - Layer* layer_ = d_ptr->mapObj->getLayer(layer.toStdString()); + Layer* layer_ = d_ptr->mapObj->getStyle().getLayer(layer.toStdString()); if (!layer_) { qWarning() << "Layer not found:" << layer; return; @@ -1596,7 +1597,7 @@ void QMapboxGLPrivate::onDidFinishLoadingStyle() void QMapboxGLPrivate::onSourceChanged(mbgl::style::Source&) { std::string attribution; - for (const auto& source : mapObj->getSources()) { + for (const auto& source : mapObj->getStyle().getSources()) { // Avoid duplicates by using the most complete attribution HTML snippet. if (source->getAttribution() && (attribution.size() < source->getAttribution()->size())) attribution = *source->getAttribution(); diff --git a/src/mbgl/annotation/annotation_manager.cpp b/src/mbgl/annotation/annotation_manager.cpp index 58bda6052e..a69dba1bf2 100644 --- a/src/mbgl/annotation/annotation_manager.cpp +++ b/src/mbgl/annotation/annotation_manager.cpp @@ -4,7 +4,7 @@ #include <mbgl/annotation/symbol_annotation_impl.hpp> #include <mbgl/annotation/line_annotation_impl.hpp> #include <mbgl/annotation/fill_annotation_impl.hpp> -#include <mbgl/style/style.hpp> +#include <mbgl/style/style_impl.hpp> #include <mbgl/style/layers/symbol_layer.hpp> #include <mbgl/style/layers/symbol_layer_impl.hpp> #include <mbgl/storage/file_source.hpp> @@ -149,8 +149,9 @@ std::unique_ptr<AnnotationTileData> AnnotationManager::getTileData(const Canonic return tileData; } -void AnnotationManager::updateStyle(Style& style) { - // Create annotation source, point layer, and point bucket +void AnnotationManager::updateStyle(Style::Impl& style) { + // Create annotation source, point layer, and point bucket. We do everything via Style::Impl + // because we don't want annotation mutations to trigger Style::Impl::styleMutated to be set. if (!style.getSource(SourceID)) { style.addSource(std::make_unique<AnnotationSource>()); diff --git a/src/mbgl/annotation/annotation_manager.hpp b/src/mbgl/annotation/annotation_manager.hpp index c2ed5ba89f..6906791db7 100644 --- a/src/mbgl/annotation/annotation_manager.hpp +++ b/src/mbgl/annotation/annotation_manager.hpp @@ -4,6 +4,7 @@ #include <mbgl/annotation/symbol_annotation_impl.hpp> #include <mbgl/style/image.hpp> #include <mbgl/map/update.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/util/noncopyable.hpp> #include <mutex> @@ -20,10 +21,6 @@ class AnnotationTileData; class SymbolAnnotationImpl; class ShapeAnnotationImpl; -namespace style { -class Style; -} // namespace style - class AnnotationManager : private util::noncopyable { public: AnnotationManager(); @@ -37,7 +34,7 @@ public: void removeImage(const std::string&); double getTopOffsetPixelsForImage(const std::string&); - void updateStyle(style::Style&); + void updateStyle(style::Style::Impl&); void updateData(); void addTile(AnnotationTile&); diff --git a/src/mbgl/annotation/fill_annotation_impl.cpp b/src/mbgl/annotation/fill_annotation_impl.cpp index 484870c45c..5dc36edab0 100644 --- a/src/mbgl/annotation/fill_annotation_impl.cpp +++ b/src/mbgl/annotation/fill_annotation_impl.cpp @@ -1,6 +1,6 @@ #include <mbgl/annotation/fill_annotation_impl.hpp> #include <mbgl/annotation/annotation_manager.hpp> -#include <mbgl/style/style.hpp> +#include <mbgl/style/style_impl.hpp> #include <mbgl/style/layers/fill_layer.hpp> namespace mbgl { @@ -12,7 +12,7 @@ FillAnnotationImpl::FillAnnotationImpl(AnnotationID id_, FillAnnotation annotati annotation({ ShapeAnnotationGeometry::visit(annotation_.geometry, CloseShapeAnnotation{}), annotation_.opacity, annotation_.color, annotation_.outlineColor }) { } -void FillAnnotationImpl::updateStyle(Style& style) const { +void FillAnnotationImpl::updateStyle(Style::Impl& style) const { Layer* layer = style.getLayer(layerID); if (!layer) { diff --git a/src/mbgl/annotation/fill_annotation_impl.hpp b/src/mbgl/annotation/fill_annotation_impl.hpp index 6376eee880..5c49e447b8 100644 --- a/src/mbgl/annotation/fill_annotation_impl.hpp +++ b/src/mbgl/annotation/fill_annotation_impl.hpp @@ -9,7 +9,7 @@ class FillAnnotationImpl : public ShapeAnnotationImpl { public: FillAnnotationImpl(AnnotationID, FillAnnotation, uint8_t maxZoom); - void updateStyle(style::Style&) const final; + void updateStyle(style::Style::Impl&) const final; const ShapeAnnotationGeometry& geometry() const final; private: diff --git a/src/mbgl/annotation/line_annotation_impl.cpp b/src/mbgl/annotation/line_annotation_impl.cpp index 65379c42a8..8954ecfa58 100644 --- a/src/mbgl/annotation/line_annotation_impl.cpp +++ b/src/mbgl/annotation/line_annotation_impl.cpp @@ -1,6 +1,6 @@ #include <mbgl/annotation/line_annotation_impl.hpp> #include <mbgl/annotation/annotation_manager.hpp> -#include <mbgl/style/style.hpp> +#include <mbgl/style/style_impl.hpp> #include <mbgl/style/layers/line_layer.hpp> namespace mbgl { @@ -12,7 +12,7 @@ LineAnnotationImpl::LineAnnotationImpl(AnnotationID id_, LineAnnotation annotati annotation({ ShapeAnnotationGeometry::visit(annotation_.geometry, CloseShapeAnnotation{}), annotation_.opacity, annotation_.width, annotation_.color }) { } -void LineAnnotationImpl::updateStyle(Style& style) const { +void LineAnnotationImpl::updateStyle(Style::Impl& style) const { Layer* layer = style.getLayer(layerID); if (!layer) { diff --git a/src/mbgl/annotation/line_annotation_impl.hpp b/src/mbgl/annotation/line_annotation_impl.hpp index 7945da5d97..548a094d53 100644 --- a/src/mbgl/annotation/line_annotation_impl.hpp +++ b/src/mbgl/annotation/line_annotation_impl.hpp @@ -9,7 +9,7 @@ class LineAnnotationImpl : public ShapeAnnotationImpl { public: LineAnnotationImpl(AnnotationID, LineAnnotation, uint8_t maxZoom); - void updateStyle(style::Style&) const final; + void updateStyle(style::Style::Impl&) const final; const ShapeAnnotationGeometry& geometry() const final; private: diff --git a/src/mbgl/annotation/shape_annotation_impl.hpp b/src/mbgl/annotation/shape_annotation_impl.hpp index 800b4ec313..ed9e8d015a 100644 --- a/src/mbgl/annotation/shape_annotation_impl.hpp +++ b/src/mbgl/annotation/shape_annotation_impl.hpp @@ -4,6 +4,7 @@ #include <mbgl/annotation/annotation.hpp> #include <mbgl/util/geometry.hpp> +#include <mbgl/style/style.hpp> #include <string> #include <memory> @@ -13,16 +14,12 @@ namespace mbgl { class AnnotationTileData; class CanonicalTileID; -namespace style { -class Style; -} // namespace style - class ShapeAnnotationImpl { public: ShapeAnnotationImpl(const AnnotationID, const uint8_t maxZoom); virtual ~ShapeAnnotationImpl() = default; - virtual void updateStyle(style::Style&) const = 0; + virtual void updateStyle(style::Style::Impl&) const = 0; virtual const ShapeAnnotationGeometry& geometry() const = 0; void updateTileData(const CanonicalTileID&, AnnotationTileData&); diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 73a540a16a..3aed91cda4 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -6,12 +6,8 @@ #include <mbgl/map/transform.hpp> #include <mbgl/map/transform_state.hpp> #include <mbgl/annotation/annotation_manager.hpp> -#include <mbgl/style/style.hpp> -#include <mbgl/style/source.hpp> -#include <mbgl/style/layer.hpp> -#include <mbgl/style/light.hpp> +#include <mbgl/style/style_impl.hpp> #include <mbgl/style/observer.hpp> -#include <mbgl/style/transition_options.hpp> #include <mbgl/renderer/update_parameters.hpp> #include <mbgl/renderer/painter.hpp> #include <mbgl/renderer/render_source.hpp> @@ -101,7 +97,6 @@ public: std::string styleURL; std::string styleJSON; - bool styleMutated = false; bool cameraMutated = false; std::unique_ptr<AsyncRequest> styleRequest; @@ -166,7 +161,7 @@ Map::Impl::Impl(Map& map_, } }) { style = std::make_unique<Style>(scheduler, fileSource, pixelRatio); - style->setObserver(this); + style->impl->setObserver(this); } Map::~Map() { @@ -196,8 +191,8 @@ void Map::renderStill(View& view, StillImageCallback callback) { return; } - if (impl->style->getLastError()) { - callback(impl->style->getLastError()); + if (impl->style->impl->getLastError()) { + callback(impl->style->impl->getLastError()); return; } @@ -228,8 +223,8 @@ void Map::Impl::render(View& view) { transform.updateTransitions(timePoint); - if (style->loaded && updateFlags & Update::AnnotationStyle) { - annotationManager.updateStyle(*style); + if (style->impl->loaded && updateFlags & Update::AnnotationStyle) { + annotationManager.updateStyle(*style->impl); } if (updateFlags & Update::AnnotationData) { @@ -251,19 +246,19 @@ void Map::Impl::render(View& view) { debugOptions, timePoint, transform.getState(), - style->getGlyphURL(), - style->spriteLoaded, + style->impl->getGlyphURL(), + style->impl->spriteLoaded, style->getTransitionOptions(), style->getLight()->impl, - style->getImageImpls(), - style->getSourceImpls(), - style->getLayerImpls(), + style->impl->getImageImpls(), + style->impl->getSourceImpls(), + style->impl->getLayerImpls(), scheduler, fileSource, annotationManager }); - bool loaded = style->isLoaded() && renderStyle->isLoaded(); + bool loaded = style->impl->isLoaded() && renderStyle->isLoaded(); if (mode == MapMode::Continuous) { if (renderState == RenderState::Never) { @@ -334,24 +329,21 @@ void Map::setStyleURL(const std::string& url) { } impl->loading = true; - impl->observer.onWillStartLoadingMap(); impl->styleRequest = nullptr; impl->styleURL = url; impl->styleJSON.clear(); - - impl->style->loaded = false; - impl->styleMutated = false; + impl->style->impl->loaded = false; impl->styleRequest = impl->fileSource.request(Resource::style(impl->styleURL), [this](Response res) { // Once we get a fresh style, or the style is mutated, stop revalidating. - if (res.isFresh() || impl->styleMutated) { + if (res.isFresh() || impl->style->impl->mutated) { impl->styleRequest.reset(); } // Don't allow a loaded, mutated style to be overwritten with a new version. - if (impl->styleMutated && impl->style->loaded) { + if (impl->style->impl->mutated && impl->style->impl->loaded) { return; } @@ -381,26 +373,25 @@ void Map::setStyleJSON(const std::string& json) { } impl->loading = true; - impl->observer.onWillStartLoadingMap(); impl->styleURL.clear(); impl->styleJSON.clear(); - impl->styleMutated = false; + impl->style->impl->mutated = false; impl->loadStyleJSON(json); } void Map::Impl::loadStyleJSON(const std::string& json) { - style->setJSON(json); + style->impl->setJSON(json); styleJSON = json; if (!cameraMutated) { // Zoom first because it may constrain subsequent operations. - map.setZoom(map.getDefaultZoom()); - map.setLatLng(map.getDefaultLatLng()); - map.setBearing(map.getDefaultBearing()); - map.setPitch(map.getDefaultPitch()); + map.setZoom(style->getDefaultZoom()); + map.setLatLng(style->getDefaultLatLng()); + map.setBearing(style->getDefaultBearing()); + map.setPitch(style->getDefaultPitch()); } onUpdate(Update::AnnotationStyle); @@ -414,6 +405,14 @@ std::string Map::getStyleJSON() const { return impl->styleJSON; } +style::Style& Map::getStyle() { + return *impl->style; +} + +const style::Style& Map::getStyle() const { + return *impl->style; +} + #pragma mark - Transitions void Map::cancelTransitions() { @@ -872,92 +871,6 @@ AnnotationIDs Map::queryPointAnnotations(const ScreenBox& box) { return ids; } -#pragma mark - Style API - -std::vector<style::Source*> Map::getSources() { - return impl->style->getSources(); -} - -style::Source* Map::getSource(const std::string& sourceID) { - impl->styleMutated = true; - return impl->style->getSource(sourceID); -} - -void Map::addSource(std::unique_ptr<style::Source> source) { - impl->styleMutated = true; - impl->style->addSource(std::move(source)); -} - -std::unique_ptr<Source> Map::removeSource(const std::string& sourceID) { - impl->styleMutated = true; - return impl->style->removeSource(sourceID); -} - -std::vector<style::Layer*> Map::getLayers() { - return impl->style->getLayers(); -} - -Layer* Map::getLayer(const std::string& layerID) { - impl->styleMutated = true; - return impl->style->getLayer(layerID); -} - -void Map::addLayer(std::unique_ptr<Layer> layer, const optional<std::string>& before) { - impl->styleMutated = true; - impl->style->addLayer(std::move(layer), before); - impl->onUpdate(Update::Repaint); -} - -std::unique_ptr<Layer> Map::removeLayer(const std::string& id) { - impl->styleMutated = true; - impl->onUpdate(Update::Repaint); - return impl->style->removeLayer(id); -} - -void Map::addImage(std::unique_ptr<style::Image> image) { - impl->styleMutated = true; - impl->style->addImage(std::move(image)); -} - -void Map::removeImage(const std::string& id) { - impl->styleMutated = true; - impl->style->removeImage(id); -} - -const style::Image* Map::getImage(const std::string& id) { - return impl->style->getImage(id); -} - -void Map::setLight(std::unique_ptr<style::Light> light) { - impl->style->setLight(std::move(light)); -} - -style::Light* Map::getLight() { - return impl->style->getLight(); -} - -#pragma mark - Defaults - -std::string Map::getStyleName() const { - return impl->style->getName(); -} - -LatLng Map::getDefaultLatLng() const { - return impl->style->getDefaultLatLng(); -} - -double Map::getDefaultZoom() const { - return impl->style->getDefaultZoom(); -} - -double Map::getDefaultBearing() const { - return impl->style->getDefaultBearing(); -} - -double Map::getDefaultPitch() const { - return impl->style->getDefaultPitch(); -} - #pragma mark - Toggles void Map::setDebug(MapDebugOptions debugOptions) { @@ -994,15 +907,7 @@ MapDebugOptions Map::getDebug() const { } bool Map::isFullyLoaded() const { - return impl->style && impl->style->isLoaded() && impl->renderStyle && impl->renderStyle->isLoaded(); -} - -style::TransitionOptions Map::getTransitionOptions() const { - return impl->style->getTransitionOptions(); -} - -void Map::setTransitionOptions(const style::TransitionOptions& options) { - impl->style->setTransitionOptions(options); + return impl->style->impl->isLoaded() && impl->renderStyle && impl->renderStyle->isLoaded(); } void Map::setSourceTileCacheSize(size_t size) { @@ -1056,7 +961,7 @@ void Map::Impl::onResourceError(std::exception_ptr error) { void Map::dumpDebugLogs() const { Log::Info(Event::General, "--------------------------------------------------------------------------------"); Log::Info(Event::General, "MapContext::styleURL: %s", impl->styleURL.c_str()); - impl->style->dumpDebugLogs(); + impl->style->impl->dumpDebugLogs(); if (impl->renderStyle) { impl->renderStyle->dumpDebugLogs(); } diff --git a/src/mbgl/renderer/update_parameters.hpp b/src/mbgl/renderer/update_parameters.hpp index 7c44064b0b..ce79a4f31b 100644 --- a/src/mbgl/renderer/update_parameters.hpp +++ b/src/mbgl/renderer/update_parameters.hpp @@ -3,6 +3,10 @@ #include <mbgl/map/mode.hpp> #include <mbgl/map/transform_state.hpp> #include <mbgl/util/chrono.hpp> +#include <mbgl/style/light.hpp> +#include <mbgl/style/image.hpp> +#include <mbgl/style/source.hpp> +#include <mbgl/style/layer.hpp> namespace mbgl { diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 41b4310dcf..f8dfd48b5c 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -1,308 +1,129 @@ #include <mbgl/style/style.hpp> -#include <mbgl/style/observer.hpp> -#include <mbgl/style/source_impl.hpp> -#include <mbgl/style/layers/symbol_layer.hpp> -#include <mbgl/style/layers/custom_layer.hpp> -#include <mbgl/style/layers/background_layer.hpp> -#include <mbgl/style/layers/fill_layer.hpp> -#include <mbgl/style/layers/fill_extrusion_layer.hpp> -#include <mbgl/style/layers/line_layer.hpp> -#include <mbgl/style/layers/circle_layer.hpp> -#include <mbgl/style/layers/raster_layer.hpp> -#include <mbgl/style/layer_impl.hpp> -#include <mbgl/style/parser.hpp> -#include <mbgl/style/transition_options.hpp> -#include <mbgl/sprite/sprite_loader.hpp> -#include <mbgl/util/exception.hpp> -#include <mbgl/util/string.hpp> -#include <mbgl/util/logging.hpp> +#include <mbgl/style/style_impl.hpp> +#include <mbgl/style/light.hpp> +#include <mbgl/style/image.hpp> +#include <mbgl/style/source.hpp> +#include <mbgl/style/layer.hpp> namespace mbgl { namespace style { -static Observer nullObserver; - -Style::Style(Scheduler& scheduler_, FileSource& fileSource_, float pixelRatio) - : scheduler(scheduler_), - fileSource(fileSource_), - spriteLoader(std::make_unique<SpriteLoader>(pixelRatio)), - light(std::make_unique<Light>()), - observer(&nullObserver) { - spriteLoader->setObserver(this); - light->setObserver(this); +Style::Style(Scheduler& scheduler, FileSource& fileSource, float pixelRatio) + : impl(std::make_unique<Impl>(scheduler, fileSource, pixelRatio)) { } Style::~Style() = default; -void Style::setTransitionOptions(const TransitionOptions& options) { - transitionOptions = options; -} - -TransitionOptions Style::getTransitionOptions() const { - return transitionOptions; -} - -void Style::setJSON(const std::string& json) { - sources.clear(); - layers.clear(); - images.clear(); - - transitionOptions = {}; - transitionOptions.duration = util::DEFAULT_TRANSITION_DURATION; - - Parser parser; - auto error = parser.parse(json); - - if (error) { - std::string message = "Failed to parse style: " + util::toString(error); - Log::Error(Event::ParseStyle, message.c_str()); - observer->onStyleError(std::make_exception_ptr(util::StyleParseException(message))); - observer->onResourceError(error); - return; - } - - for (auto& source : parser.sources) { - addSource(std::move(source)); - } - - for (auto& layer : parser.layers) { - addLayer(std::move(layer)); - } - - name = parser.name; - defaultLatLng = parser.latLng; - defaultZoom = parser.zoom; - defaultBearing = parser.bearing; - defaultPitch = parser.pitch; - setLight(std::make_unique<Light>(parser.light)); - - spriteLoader->load(parser.spriteURL, scheduler, fileSource); - glyphURL = parser.glyphURL; - - loaded = true; - - observer->onStyleLoaded(); -} - -void Style::addSource(std::unique_ptr<Source> source) { - if (sources.get(source->getID())) { - std::string msg = "Source " + source->getID() + " already exists"; - throw std::runtime_error(msg.c_str()); - } - - source->setObserver(this); - source->loadDescription(fileSource); - - sources.add(std::move(source)); -} - -struct SourceIdUsageEvaluator { - const std::string& sourceId; - - bool operator()(BackgroundLayer&) { return false; } - bool operator()(CustomLayer&) { return false; } - - template <class LayerType> - bool operator()(LayerType& layer) { - return layer.getSourceID() == sourceId; - } -}; - -std::unique_ptr<Source> Style::removeSource(const std::string& id) { - // Check if source is in use - SourceIdUsageEvaluator sourceIdEvaluator {id}; - auto layerIt = std::find_if(layers.begin(), layers.end(), [&](const auto& layer) { - return layer->accept(sourceIdEvaluator); - }); - - if (layerIt != layers.end()) { - Log::Warning(Event::General, "Source '%s' is in use, cannot remove", id.c_str()); - return nullptr; - } - - std::unique_ptr<Source> source = sources.remove(id); - - if (source) { - source->setObserver(nullptr); - } - - return source; -} - -std::vector<Layer*> Style::getLayers() { - return layers.getWrappers(); -} - -Layer* Style::getLayer(const std::string& id) const { - return layers.get(id); -} - -Layer* Style::addLayer(std::unique_ptr<Layer> layer, optional<std::string> before) { - // TODO: verify source - - if (layers.get(layer->getID())) { - throw std::runtime_error(std::string{"Layer "} + layer->getID() + " already exists"); - } - - layer->setObserver(this); - - return layers.add(std::move(layer), before); -} - -std::unique_ptr<Layer> Style::removeLayer(const std::string& id) { - std::unique_ptr<Layer> layer = layers.remove(id); - - if (layer) { - layer->setObserver(nullptr); - } - - return layer; -} - -void Style::setLight(std::unique_ptr<Light> light_) { - light = std::move(light_); - light->setObserver(this); - onLightChanged(*light); -} - -Light* Style::getLight() const { - return light.get(); -} - std::string Style::getName() const { - return name; + return impl->getName(); } LatLng Style::getDefaultLatLng() const { - return defaultLatLng; + return impl->getDefaultLatLng(); } double Style::getDefaultZoom() const { - return defaultZoom; + return impl->getDefaultZoom(); } double Style::getDefaultBearing() const { - return defaultBearing; + return impl->getDefaultBearing(); } double Style::getDefaultPitch() const { - return defaultPitch; + return impl->getDefaultPitch(); } -std::vector<Source*> Style::getSources() { - return sources.getWrappers(); +TransitionOptions Style::getTransitionOptions() const { + return impl->getTransitionOptions(); } -Source* Style::getSource(const std::string& id) const { - return sources.get(id); +void Style::setTransitionOptions(const TransitionOptions& options) { + impl->mutated = true; + impl->setTransitionOptions(options); } -bool Style::isLoaded() const { - if (!loaded) { - return false; - } - - if (!spriteLoaded) { - return false; - } - - for (const auto& source: sources) { - if (!source->loaded) { - return false; - } - } - - return true; +void Style::setLight(std::unique_ptr<Light> light) { + impl->setLight(std::move(light)); } -void Style::addImage(std::unique_ptr<style::Image> image) { - images.remove(image->getID()); // We permit using addImage to update. - images.add(std::move(image)); +Light* Style::getLight() { + impl->mutated = true; + return impl->getLight(); } -void Style::removeImage(const std::string& id) { - images.remove(id); +const Light* Style::getLight() const { + return impl->getLight(); } -const style::Image* Style::getImage(const std::string& id) const { - return images.get(id); +const Image* Style::getImage(const std::string& name) const { + return impl->getImage(name); } -void Style::setObserver(style::Observer* observer_) { - observer = observer_; +void Style::addImage(std::unique_ptr<Image> image) { + impl->mutated = true; + impl->addImage(std::move(image)); } -void Style::onSourceLoaded(Source& source) { - sources.update(source); - observer->onSourceLoaded(source); - observer->onUpdate(Update::Repaint); +void Style::removeImage(const std::string& name) { + impl->mutated = true; + impl->removeImage(name); } -void Style::onSourceChanged(Source& source) { - sources.update(source); - observer->onSourceChanged(source); - observer->onUpdate(Update::Repaint); +std::vector<Source*> Style::getSources() { + impl->mutated = true; + return impl->getSources(); } -void Style::onSourceError(Source& source, std::exception_ptr error) { - lastError = error; - Log::Error(Event::Style, "Failed to load source %s: %s", - source.getID().c_str(), util::toString(error).c_str()); - observer->onSourceError(source, error); - observer->onResourceError(error); +std::vector<const Source*> Style::getSources() const { + return const_cast<const Impl&>(*impl).getSources(); } -void Style::onSourceDescriptionChanged(Source& source) { - sources.update(source); - observer->onSourceDescriptionChanged(source); - if (!source.loaded) { - source.loadDescription(fileSource); - } +Source* Style::getSource(const std::string& id) { + impl->mutated = true; + return impl->getSource(id); } -void Style::onSpriteLoaded(std::vector<std::unique_ptr<Image>>&& images_) { - for (auto& image : images_) { - addImage(std::move(image)); - } - spriteLoaded = true; - observer->onUpdate(Update::Repaint); // For *-pattern properties. +const Source* Style::getSource(const std::string& id) const { + return impl->getSource(id); } -void Style::onSpriteError(std::exception_ptr error) { - lastError = error; - Log::Error(Event::Style, "Failed to load sprite: %s", util::toString(error).c_str()); - observer->onResourceError(error); +void Style::addSource(std::unique_ptr<Source> source) { + impl->mutated = true; + impl->addSource(std::move(source)); } -void Style::onLayerChanged(Layer& layer) { - layers.update(layer); - observer->onUpdate(Update::Repaint); +std::unique_ptr<Source> Style::removeSource(const std::string& sourceID) { + impl->mutated = true; + return impl->removeSource(sourceID); } -void Style::onLightChanged(const Light&) { - observer->onUpdate(Update::Repaint); +std::vector<Layer*> Style::getLayers() { + impl->mutated = true; + return impl->getLayers(); } -void Style::dumpDebugLogs() const { - for (const auto& source : sources) { - source->dumpDebugLogs(); - } +std::vector<const Layer*> Style::getLayers() const { + return const_cast<const Impl&>(*impl).getLayers(); } -const std::string& Style::getGlyphURL() const { - return glyphURL; +Layer* Style::getLayer(const std::string& layerID) { + impl->mutated = true; + return impl->getLayer(layerID); } -Immutable<std::vector<Immutable<Image::Impl>>> Style::getImageImpls() const { - return images.getImpls(); +const Layer* Style::getLayer(const std::string& layerID) const { + return impl->getLayer(layerID); } -Immutable<std::vector<Immutable<Source::Impl>>> Style::getSourceImpls() const { - return sources.getImpls(); +void Style::addLayer(std::unique_ptr<Layer> layer, const optional<std::string>& before) { + impl->mutated = true; + impl->addLayer(std::move(layer), before); } -Immutable<std::vector<Immutable<Layer::Impl>>> Style::getLayerImpls() const { - return layers.getImpls(); +std::unique_ptr<Layer> Style::removeLayer(const std::string& id) { + impl->mutated = true; + return impl->removeLayer(id); } } // namespace style diff --git a/src/mbgl/style/style_impl.cpp b/src/mbgl/style/style_impl.cpp new file mode 100644 index 0000000000..7235226f84 --- /dev/null +++ b/src/mbgl/style/style_impl.cpp @@ -0,0 +1,321 @@ +#include <mbgl/style/style_impl.hpp> +#include <mbgl/style/observer.hpp> +#include <mbgl/style/source_impl.hpp> +#include <mbgl/style/layers/symbol_layer.hpp> +#include <mbgl/style/layers/custom_layer.hpp> +#include <mbgl/style/layers/background_layer.hpp> +#include <mbgl/style/layers/fill_layer.hpp> +#include <mbgl/style/layers/fill_extrusion_layer.hpp> +#include <mbgl/style/layers/line_layer.hpp> +#include <mbgl/style/layers/circle_layer.hpp> +#include <mbgl/style/layers/raster_layer.hpp> +#include <mbgl/style/layer_impl.hpp> +#include <mbgl/style/parser.hpp> +#include <mbgl/style/transition_options.hpp> +#include <mbgl/sprite/sprite_loader.hpp> +#include <mbgl/util/exception.hpp> +#include <mbgl/util/string.hpp> +#include <mbgl/util/logging.hpp> + +namespace mbgl { +namespace style { + +static Observer nullObserver; + +Style::Impl::Impl(Scheduler& scheduler_, FileSource& fileSource_, float pixelRatio) + : scheduler(scheduler_), + fileSource(fileSource_), + spriteLoader(std::make_unique<SpriteLoader>(pixelRatio)), + light(std::make_unique<Light>()), + observer(&nullObserver) { + spriteLoader->setObserver(this); + light->setObserver(this); +} + +Style::Impl::~Impl() = default; + +void Style::Impl::setTransitionOptions(const TransitionOptions& options) { + transitionOptions = options; +} + +TransitionOptions Style::Impl::getTransitionOptions() const { + return transitionOptions; +} + +void Style::Impl::setJSON(const std::string& json) { + sources.clear(); + layers.clear(); + images.clear(); + + transitionOptions = {}; + transitionOptions.duration = util::DEFAULT_TRANSITION_DURATION; + + Parser parser; + auto error = parser.parse(json); + + if (error) { + std::string message = "Failed to parse style: " + util::toString(error); + Log::Error(Event::ParseStyle, message.c_str()); + observer->onStyleError(std::make_exception_ptr(util::StyleParseException(message))); + observer->onResourceError(error); + return; + } + + for (auto& source : parser.sources) { + addSource(std::move(source)); + } + + for (auto& layer : parser.layers) { + addLayer(std::move(layer)); + } + + name = parser.name; + defaultLatLng = parser.latLng; + defaultZoom = parser.zoom; + defaultBearing = parser.bearing; + defaultPitch = parser.pitch; + setLight(std::make_unique<Light>(parser.light)); + + spriteLoader->load(parser.spriteURL, scheduler, fileSource); + glyphURL = parser.glyphURL; + + loaded = true; + + observer->onStyleLoaded(); +} + +void Style::Impl::addSource(std::unique_ptr<Source> source) { + if (sources.get(source->getID())) { + std::string msg = "Source " + source->getID() + " already exists"; + throw std::runtime_error(msg.c_str()); + } + + source->setObserver(this); + source->loadDescription(fileSource); + + sources.add(std::move(source)); +} + +struct SourceIdUsageEvaluator { + const std::string& sourceId; + + bool operator()(BackgroundLayer&) { return false; } + bool operator()(CustomLayer&) { return false; } + + template <class LayerType> + bool operator()(LayerType& layer) { + return layer.getSourceID() == sourceId; + } +}; + +std::unique_ptr<Source> Style::Impl::removeSource(const std::string& id) { + // Check if source is in use + SourceIdUsageEvaluator sourceIdEvaluator {id}; + auto layerIt = std::find_if(layers.begin(), layers.end(), [&](const auto& layer) { + return layer->accept(sourceIdEvaluator); + }); + + if (layerIt != layers.end()) { + Log::Warning(Event::General, "Source '%s' is in use, cannot remove", id.c_str()); + return nullptr; + } + + std::unique_ptr<Source> source = sources.remove(id); + + if (source) { + source->setObserver(nullptr); + } + + return source; +} + +std::vector<Layer*> Style::Impl::getLayers() { + return layers.getWrappers(); +} + +std::vector<const Layer*> Style::Impl::getLayers() const { + auto wrappers = layers.getWrappers(); + return std::vector<const Layer*>(wrappers.begin(), wrappers.end()); +} + +Layer* Style::Impl::getLayer(const std::string& id) const { + return layers.get(id); +} + +Layer* Style::Impl::addLayer(std::unique_ptr<Layer> layer, optional<std::string> before) { + // TODO: verify source + + if (layers.get(layer->getID())) { + throw std::runtime_error(std::string{"Layer "} + layer->getID() + " already exists"); + } + + layer->setObserver(this); + observer->onUpdate(Update::Repaint); + + return layers.add(std::move(layer), before); +} + +std::unique_ptr<Layer> Style::Impl::removeLayer(const std::string& id) { + std::unique_ptr<Layer> layer = layers.remove(id); + + if (layer) { + layer->setObserver(nullptr); + observer->onUpdate(Update::Repaint); + } + + return layer; +} + +void Style::Impl::setLight(std::unique_ptr<Light> light_) { + light = std::move(light_); + light->setObserver(this); + onLightChanged(*light); +} + +Light* Style::Impl::getLight() const { + return light.get(); +} + +std::string Style::Impl::getName() const { + return name; +} + +LatLng Style::Impl::getDefaultLatLng() const { + return defaultLatLng; +} + +double Style::Impl::getDefaultZoom() const { + return defaultZoom; +} + +double Style::Impl::getDefaultBearing() const { + return defaultBearing; +} + +double Style::Impl::getDefaultPitch() const { + return defaultPitch; +} + +std::vector<Source*> Style::Impl::getSources() { + return sources.getWrappers(); +} + +std::vector<const Source*> Style::Impl::getSources() const { + auto wrappers = sources.getWrappers(); + return std::vector<const Source*>(wrappers.begin(), wrappers.end()); +} + +Source* Style::Impl::getSource(const std::string& id) const { + return sources.get(id); +} + +bool Style::Impl::isLoaded() const { + if (!loaded) { + return false; + } + + if (!spriteLoaded) { + return false; + } + + for (const auto& source: sources) { + if (!source->loaded) { + return false; + } + } + + return true; +} + +void Style::Impl::addImage(std::unique_ptr<style::Image> image) { + images.remove(image->getID()); // We permit using addImage to update. + images.add(std::move(image)); +} + +void Style::Impl::removeImage(const std::string& id) { + images.remove(id); +} + +const style::Image* Style::Impl::getImage(const std::string& id) const { + return images.get(id); +} + +void Style::Impl::setObserver(style::Observer* observer_) { + observer = observer_; +} + +void Style::Impl::onSourceLoaded(Source& source) { + sources.update(source); + observer->onSourceLoaded(source); + observer->onUpdate(Update::Repaint); +} + +void Style::Impl::onSourceChanged(Source& source) { + sources.update(source); + observer->onSourceChanged(source); + observer->onUpdate(Update::Repaint); +} + +void Style::Impl::onSourceError(Source& source, std::exception_ptr error) { + lastError = error; + Log::Error(Event::Style, "Failed to load source %s: %s", + source.getID().c_str(), util::toString(error).c_str()); + observer->onSourceError(source, error); + observer->onResourceError(error); +} + +void Style::Impl::onSourceDescriptionChanged(Source& source) { + sources.update(source); + observer->onSourceDescriptionChanged(source); + if (!source.loaded) { + source.loadDescription(fileSource); + } +} + +void Style::Impl::onSpriteLoaded(std::vector<std::unique_ptr<Image>>&& images_) { + for (auto& image : images_) { + addImage(std::move(image)); + } + spriteLoaded = true; + observer->onUpdate(Update::Repaint); // For *-pattern properties. +} + +void Style::Impl::onSpriteError(std::exception_ptr error) { + lastError = error; + Log::Error(Event::Style, "Failed to load sprite: %s", util::toString(error).c_str()); + observer->onResourceError(error); +} + +void Style::Impl::onLayerChanged(Layer& layer) { + layers.update(layer); + observer->onUpdate(Update::Repaint); +} + +void Style::Impl::onLightChanged(const Light&) { + observer->onUpdate(Update::Repaint); +} + +void Style::Impl::dumpDebugLogs() const { + for (const auto& source : sources) { + source->dumpDebugLogs(); + } +} + +const std::string& Style::Impl::getGlyphURL() const { + return glyphURL; +} + +Immutable<std::vector<Immutable<Image::Impl>>> Style::Impl::getImageImpls() const { + return images.getImpls(); +} + +Immutable<std::vector<Immutable<Source::Impl>>> Style::Impl::getSourceImpls() const { + return sources.getImpls(); +} + +Immutable<std::vector<Immutable<Layer::Impl>>> Style::Impl::getLayerImpls() const { + return layers.getImpls(); +} + +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style_impl.hpp index 7e8f6f640b..2bdb51a26c 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style_impl.hpp @@ -1,5 +1,6 @@ #pragma once +#include <mbgl/style/style.hpp> #include <mbgl/style/transition_options.hpp> #include <mbgl/style/observer.hpp> #include <mbgl/style/source_observer.hpp> @@ -28,14 +29,14 @@ class SpriteLoader; namespace style { -class Style : public SpriteLoaderObserver, - public SourceObserver, - public LayerObserver, - public LightObserver, - public util::noncopyable { +class Style::Impl : public SpriteLoaderObserver, + public SourceObserver, + public LayerObserver, + public LightObserver, + public util::noncopyable { public: - Style(Scheduler&, FileSource&, float pixelRatio); - ~Style() override; + Impl(Scheduler&, FileSource&, float pixelRatio); + ~Impl() override; void setJSON(const std::string&); @@ -47,13 +48,17 @@ public: return lastError; } - std::vector<Source*> getSources(); + std::vector< Source*> getSources(); + std::vector<const Source*> getSources() const; Source* getSource(const std::string& id) const; + void addSource(std::unique_ptr<Source>); std::unique_ptr<Source> removeSource(const std::string& sourceID); - std::vector<Layer*> getLayers(); + std::vector< Layer*> getLayers(); + std::vector<const Layer*> getLayers() const; Layer* getLayer(const std::string& id) const; + Layer* addLayer(std::unique_ptr<Layer>, optional<std::string> beforeLayerID = {}); std::unique_ptr<Layer> removeLayer(const std::string& layerID); @@ -82,6 +87,7 @@ public: void dumpDebugLogs() const; + bool mutated = false; bool loaded = false; bool spriteLoaded = false; diff --git a/test/api/custom_layer.test.cpp b/test/api/custom_layer.test.cpp index 5a30220cd7..e11ed299a6 100644 --- a/test/api/custom_layer.test.cpp +++ b/test/api/custom_layer.test.cpp @@ -7,6 +7,7 @@ #include <mbgl/gl/offscreen_view.hpp> #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/storage/default_file_source.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/layers/custom_layer.hpp> #include <mbgl/style/layers/fill_layer.hpp> #include <mbgl/util/io.hpp> @@ -95,7 +96,7 @@ TEST(CustomLayer, Basic) { Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still); map.setStyleJSON(util::read_file("test/fixtures/api/water.json")); map.setLatLngZoom({ 37.8, -122.5 }, 10); - map.addLayer(std::make_unique<CustomLayer>( + map.getStyle().addLayer(std::make_unique<CustomLayer>( "custom", [] (void* context) { reinterpret_cast<TestLayer*>(context)->initialize(); @@ -110,7 +111,7 @@ TEST(CustomLayer, Basic) { auto layer = std::make_unique<FillLayer>("landcover", "mapbox"); layer->setSourceLayer("landcover"); layer->setFillColor(Color{ 1.0, 1.0, 0.0, 1.0 }); - map.addLayer(std::move(layer)); + map.getStyle().addLayer(std::move(layer)); test::checkImage("test/fixtures/custom_layer/basic", test::render(map, view), 0.0006, 0.1); } diff --git a/test/api/query.test.cpp b/test/api/query.test.cpp index 5b7f7c00ff..ad4dc6f4de 100644 --- a/test/api/query.test.cpp +++ b/test/api/query.test.cpp @@ -8,6 +8,7 @@ #include <mbgl/util/image.hpp> #include <mbgl/util/io.hpp> #include <mbgl/util/run_loop.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/style/source.hpp> @@ -20,7 +21,7 @@ class QueryTest { public: QueryTest() { map.setStyleJSON(util::read_file("test/fixtures/api/query_style.json")); - map.addImage(std::make_unique<style::Image>("test-icon", + map.getStyle().addImage(std::make_unique<style::Image>("test-icon", decodeImage(util::read_file("test/fixtures/sprites/default_marker.png")), 1.0)); test::render(map, view); diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index 0ff828ce40..9045f1c8c2 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -16,6 +16,7 @@ #include <mbgl/util/io.hpp> #include <mbgl/util/run_loop.hpp> #include <mbgl/util/async_task.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/style/layers/background_layer.hpp> #include <mbgl/util/color.hpp> @@ -247,12 +248,12 @@ TEST(Map, StyleExpired) { fileSource.respond(Resource::Style, response); EXPECT_EQ(1u, fileSource.requests.size()); - map.addLayer(std::make_unique<style::BackgroundLayer>("bg")); + map.getStyle().addLayer(std::make_unique<style::BackgroundLayer>("bg")); EXPECT_EQ(1u, fileSource.requests.size()); fileSource.respond(Resource::Style, response); EXPECT_EQ(0u, fileSource.requests.size()); - EXPECT_NE(nullptr, map.getLayer("bg")); + EXPECT_NE(nullptr, map.getStyle().getLayer("bg")); } TEST(Map, StyleExpiredWithAnnotations) { @@ -289,14 +290,14 @@ TEST(Map, StyleEarlyMutation) { Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still); map.setStyleURL("mapbox://styles/test"); - map.addLayer(std::make_unique<style::BackgroundLayer>("bg")); + map.getStyle().addLayer(std::make_unique<style::BackgroundLayer>("bg")); Response response; response.data = std::make_shared<std::string>(util::read_file("test/fixtures/api/water.json")); fileSource.respond(Resource::Style, response); EXPECT_EQ(0u, fileSource.requests.size()); - EXPECT_NE(nullptr, map.getLayer("water")); + EXPECT_NE(nullptr, map.getStyle().getLayer("water")); } TEST(Map, MapLoadingSignal) { @@ -396,7 +397,7 @@ TEST(Map, AddLayer) { auto layer = std::make_unique<BackgroundLayer>("background"); layer->setBackgroundColor({ { 1, 0, 0, 1 } }); - map.addLayer(std::move(layer)); + map.getStyle().addLayer(std::move(layer)); test::checkImage("test/fixtures/map/add_layer", test::render(map, test.view)); } @@ -422,8 +423,8 @@ TEST(Map, RemoveLayer) { auto layer = std::make_unique<BackgroundLayer>("background"); layer->setBackgroundColor({{ 1, 0, 0, 1 }}); - map.addLayer(std::move(layer)); - map.removeLayer("background"); + map.getStyle().addLayer(std::move(layer)); + map.getStyle().removeLayer("background"); test::checkImage("test/fixtures/map/remove_layer", test::render(map, test.view)); } @@ -489,48 +490,6 @@ TEST(Map, DisabledSources) { test::checkImage("test/fixtures/map/disabled_layers/second", test::render(map, test.view)); } -TEST(Map, AddImage) { - MapTest test; - - Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still); - auto decoded1 = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png")); - auto decoded2 = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png")); - auto image1 = std::make_unique<style::Image>("test-icon", std::move(decoded1), 1.0); - auto image2 = std::make_unique<style::Image>("test-icon", std::move(decoded2), 1.0); - - // No-op. - map.addImage(std::move(image1)); - - map.setStyleJSON(util::read_file("test/fixtures/api/icon_style.json")); - map.addImage(std::move(image2)); - test::checkImage("test/fixtures/map/add_icon", test::render(map, test.view)); -} - -TEST(Map, RemoveImage) { - MapTest test; - - Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still); - auto decoded = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png")); - auto image = std::make_unique<style::Image>("test-icon", std::move(decoded), 1.0); - - map.setStyleJSON(util::read_file("test/fixtures/api/icon_style.json")); - map.addImage(std::move(image)); - map.removeImage("test-icon"); - test::checkImage("test/fixtures/map/remove_icon", test::render(map, test.view)); -} - -TEST(Map, GetImage) { - MapTest test; - - Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still); - auto decoded = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png")); - auto image = std::make_unique<style::Image>("test-icon", std::move(decoded), 1.0); - - map.setStyleJSON(util::read_file("test/fixtures/api/icon_style.json")); - map.addImage(std::move(image)); - test::checkImage("test/fixtures/map/get_icon", map.getImage("test-icon")->getImage()); -} - TEST(Map, DontLoadUnneededTiles) { MapTest test; diff --git a/test/style/style.test.cpp b/test/style/style.test.cpp index 841c7b291b..701e4a6434 100644 --- a/test/style/style.test.cpp +++ b/test/style/style.test.cpp @@ -2,7 +2,7 @@ #include <mbgl/test/stub_file_source.hpp> #include <mbgl/test/fixture_log_observer.hpp> -#include <mbgl/style/style.hpp> +#include <mbgl/style/style_impl.hpp> #include <mbgl/style/source_impl.hpp> #include <mbgl/style/sources/vector_source.hpp> #include <mbgl/style/layer.hpp> @@ -21,7 +21,7 @@ TEST(Style, Properties) { ThreadPool threadPool{ 1 }; StubFileSource fileSource; - Style style { threadPool, fileSource, 1.0 }; + Style::Impl style { threadPool, fileSource, 1.0 }; style.setJSON(R"STYLE({"name": "Test"})STYLE"); ASSERT_EQ("Test", style.getName()); @@ -56,7 +56,7 @@ TEST(Style, DuplicateSource) { ThreadPool threadPool{ 1 }; StubFileSource fileSource; - Style style { threadPool, fileSource, 1.0 }; + Style::Impl style { threadPool, fileSource, 1.0 }; style.setJSON(util::read_file("test/fixtures/resources/style-unused-sources.json")); @@ -78,7 +78,7 @@ TEST(Style, RemoveSourceInUse) { ThreadPool threadPool{ 1 }; StubFileSource fileSource; - Style style { threadPool, fileSource, 1.0 }; + Style::Impl style { threadPool, fileSource, 1.0 }; style.setJSON(util::read_file("test/fixtures/resources/style-unused-sources.json")); diff --git a/test/style/style_layer.test.cpp b/test/style/style_layer.test.cpp index 7d0eb318c0..0e7957c490 100644 --- a/test/style/style_layer.test.cpp +++ b/test/style/style_layer.test.cpp @@ -1,7 +1,7 @@ #include <mbgl/test/util.hpp> #include <mbgl/test/stub_layer_observer.hpp> #include <mbgl/test/stub_file_source.hpp> -#include <mbgl/style/style.hpp> +#include <mbgl/style/style_impl.hpp> #include <mbgl/style/layers/background_layer.hpp> #include <mbgl/style/layers/background_layer_impl.hpp> #include <mbgl/style/layers/circle_layer.hpp> @@ -275,7 +275,7 @@ TEST(Layer, DuplicateLayer) { // Setup style ThreadPool threadPool{ 1 }; StubFileSource fileSource; - Style style { threadPool, fileSource, 1.0 }; + Style::Impl style { threadPool, fileSource, 1.0 }; style.setJSON(util::read_file("test/fixtures/resources/style-unused-sources.json")); // Add initial layer |