1 #include <mbgl/style/style_impl.hpp>
2 #include <mbgl/style/observer.hpp>
3 #include <mbgl/style/source_impl.hpp>
4 #include <mbgl/style/layers/symbol_layer.hpp>
5 #include <mbgl/style/layers/custom_layer.hpp>
6 #include <mbgl/style/layers/background_layer.hpp>
7 #include <mbgl/style/layers/fill_layer.hpp>
8 #include <mbgl/style/layers/fill_extrusion_layer.hpp>
9 #include <mbgl/style/layers/heatmap_layer.hpp>
10 #include <mbgl/style/layers/line_layer.hpp>
11 #include <mbgl/style/layers/circle_layer.hpp>
12 #include <mbgl/style/layers/raster_layer.hpp>
13 #include <mbgl/style/layers/hillshade_layer.hpp>
14 #include <mbgl/style/layer_impl.hpp>
15 #include <mbgl/style/parser.hpp>
16 #include <mbgl/style/transition_options.hpp>
17 #include <mbgl/sprite/sprite_loader.hpp>
18 #include <mbgl/util/exception.hpp>
19 #include <mbgl/util/string.hpp>
20 #include <mbgl/util/logging.hpp>
21 #include <mbgl/storage/file_source.hpp>
22 #include <mbgl/storage/resource.hpp>
23 #include <mbgl/storage/response.hpp>
24 
25 namespace mbgl {
26 namespace style {
27 
28 static Observer nullObserver;
29 
Impl(Scheduler & scheduler_,FileSource & fileSource_,float pixelRatio)30 Style::Impl::Impl(Scheduler& scheduler_, FileSource& fileSource_, float pixelRatio)
31     : scheduler(scheduler_),
32       fileSource(fileSource_),
33       spriteLoader(std::make_unique<SpriteLoader>(pixelRatio)),
34       light(std::make_unique<Light>()),
35       observer(&nullObserver) {
36     spriteLoader->setObserver(this);
37     light->setObserver(this);
38 }
39 
40 Style::Impl::~Impl() = default;
41 
loadJSON(const std::string & json_)42 void Style::Impl::loadJSON(const std::string& json_) {
43     lastError = nullptr;
44     observer->onStyleLoading();
45 
46     url.clear();
47     parse(json_);
48 }
49 
loadURL(const std::string & url_)50 void Style::Impl::loadURL(const std::string& url_) {
51     lastError = nullptr;
52     observer->onStyleLoading();
53 
54     loaded = false;
55     url = url_;
56 
57     styleRequest = fileSource.request(Resource::style(url), [this](Response res) {
58         // Don't allow a loaded, mutated style to be overwritten with a new version.
59         if (mutated && loaded) {
60             return;
61         }
62 
63         if (res.error) {
64             const std::string message = "loading style failed: " + res.error->message;
65             Log::Error(Event::Setup, message.c_str());
66             observer->onStyleError(std::make_exception_ptr(util::StyleLoadException(message)));
67             observer->onResourceError(std::make_exception_ptr(std::runtime_error(res.error->message)));
68         } else if (res.notModified || res.noContent) {
69             return;
70         } else {
71             parse(*res.data);
72         }
73     });
74 }
75 
parse(const std::string & json_)76 void Style::Impl::parse(const std::string& json_) {
77     Parser parser;
78 
79     if (auto error = parser.parse(json_)) {
80         std::string message = "Failed to parse style: " + util::toString(error);
81         Log::Error(Event::ParseStyle, message.c_str());
82         observer->onStyleError(std::make_exception_ptr(util::StyleParseException(message)));
83         observer->onResourceError(error);
84         return;
85     }
86 
87     mutated = false;
88     loaded = false;
89     json = json_;
90 
91     sources.clear();
92     layers.clear();
93     images.clear();
94 
95     transitionOptions = {};
96     transitionOptions.duration = util::DEFAULT_TRANSITION_DURATION;
97 
98     for (auto& source : parser.sources) {
99         addSource(std::move(source));
100     }
101 
102     for (auto& layer : parser.layers) {
103         addLayer(std::move(layer));
104     }
105 
106     name = parser.name;
107     defaultCamera.center = parser.latLng;
108     defaultCamera.zoom = parser.zoom;
109     defaultCamera.angle = parser.bearing;
110     defaultCamera.pitch = parser.pitch;
111 
112     setLight(std::make_unique<Light>(parser.light));
113 
114     spriteLoaded = false;
115     spriteLoader->load(parser.spriteURL, scheduler, fileSource);
116     glyphURL = parser.glyphURL;
117 
118     loaded = true;
119     observer->onStyleLoaded();
120 }
121 
getJSON() const122 std::string Style::Impl::getJSON() const {
123     return json;
124 }
125 
getURL() const126 std::string Style::Impl::getURL() const {
127     return url;
128 }
129 
setTransitionOptions(const TransitionOptions & options)130 void Style::Impl::setTransitionOptions(const TransitionOptions& options) {
131     transitionOptions = options;
132 }
133 
getTransitionOptions() const134 TransitionOptions Style::Impl::getTransitionOptions() const {
135     return transitionOptions;
136 }
137 
addSource(std::unique_ptr<Source> source)138 void Style::Impl::addSource(std::unique_ptr<Source> source) {
139     if (sources.get(source->getID())) {
140         std::string msg = "Source " + source->getID() + " already exists";
141         throw std::runtime_error(msg.c_str());
142     }
143 
144     source->setObserver(this);
145     source->loadDescription(fileSource);
146 
147     sources.add(std::move(source));
148 }
149 
150 struct SourceIdUsageEvaluator {
151     const std::string& sourceId;
152 
operator ()mbgl::style::SourceIdUsageEvaluator153     bool operator()(BackgroundLayer&) { return false; }
operator ()mbgl::style::SourceIdUsageEvaluator154     bool operator()(CustomLayer&) { return false; }
155 
156     template <class LayerType>
operator ()mbgl::style::SourceIdUsageEvaluator157     bool operator()(LayerType& layer) {
158         return layer.getSourceID() == sourceId;
159     }
160 };
161 
removeSource(const std::string & id)162 std::unique_ptr<Source> Style::Impl::removeSource(const std::string& id) {
163     // Check if source is in use
164     SourceIdUsageEvaluator sourceIdEvaluator {id};
165     auto layerIt = std::find_if(layers.begin(), layers.end(), [&](const auto& layer) {
166         return layer->accept(sourceIdEvaluator);
167     });
168 
169     if (layerIt != layers.end()) {
170         Log::Warning(Event::General, "Source '%s' is in use, cannot remove", id.c_str());
171         return nullptr;
172     }
173 
174     std::unique_ptr<Source> source = sources.remove(id);
175 
176     if (source) {
177         source->setObserver(nullptr);
178     }
179 
180     return source;
181 }
182 
getLayers()183 std::vector<Layer*> Style::Impl::getLayers() {
184     return layers.getWrappers();
185 }
186 
getLayers() const187 std::vector<const Layer*> Style::Impl::getLayers() const {
188     auto wrappers = layers.getWrappers();
189     return std::vector<const Layer*>(wrappers.begin(), wrappers.end());
190 }
191 
getLayer(const std::string & id) const192 Layer* Style::Impl::getLayer(const std::string& id) const {
193     return layers.get(id);
194 }
195 
addLayer(std::unique_ptr<Layer> layer,optional<std::string> before)196 Layer* Style::Impl::addLayer(std::unique_ptr<Layer> layer, optional<std::string> before) {
197     // TODO: verify source
198 
199     if (layers.get(layer->getID())) {
200         throw std::runtime_error(std::string{"Layer "} + layer->getID() + " already exists");
201     }
202 
203     layer->setObserver(this);
204     Layer* result = layers.add(std::move(layer), before);
205     observer->onUpdate();
206 
207     return result;
208 }
209 
removeLayer(const std::string & id)210 std::unique_ptr<Layer> Style::Impl::removeLayer(const std::string& id) {
211     std::unique_ptr<Layer> layer = layers.remove(id);
212 
213     if (layer) {
214         layer->setObserver(nullptr);
215         observer->onUpdate();
216     }
217 
218     return layer;
219 }
220 
setLight(std::unique_ptr<Light> light_)221 void Style::Impl::setLight(std::unique_ptr<Light> light_) {
222     light = std::move(light_);
223     light->setObserver(this);
224     onLightChanged(*light);
225 }
226 
getLight() const227 Light* Style::Impl::getLight() const {
228     return light.get();
229 }
230 
getName() const231 std::string Style::Impl::getName() const {
232     return name;
233 }
234 
getDefaultCamera() const235 CameraOptions Style::Impl::getDefaultCamera() const {
236     return defaultCamera;
237 }
238 
getSources()239 std::vector<Source*> Style::Impl::getSources() {
240     return sources.getWrappers();
241 }
242 
getSources() const243 std::vector<const Source*> Style::Impl::getSources() const {
244     auto wrappers = sources.getWrappers();
245     return std::vector<const Source*>(wrappers.begin(), wrappers.end());
246 }
247 
getSource(const std::string & id) const248 Source* Style::Impl::getSource(const std::string& id) const {
249     return sources.get(id);
250 }
251 
isLoaded() const252 bool Style::Impl::isLoaded() const {
253     if (!loaded) {
254         return false;
255     }
256 
257     if (!spriteLoaded) {
258         return false;
259     }
260 
261     for (const auto& source: sources) {
262         if (!source->loaded) {
263             return false;
264         }
265     }
266 
267     return true;
268 }
269 
addImage(std::unique_ptr<style::Image> image)270 void Style::Impl::addImage(std::unique_ptr<style::Image> image) {
271     images.remove(image->getID()); // We permit using addImage to update.
272     images.add(std::move(image));
273 }
274 
removeImage(const std::string & id)275 void Style::Impl::removeImage(const std::string& id) {
276     images.remove(id);
277 }
278 
getImage(const std::string & id) const279 const style::Image* Style::Impl::getImage(const std::string& id) const {
280     return images.get(id);
281 }
282 
setObserver(style::Observer * observer_)283 void Style::Impl::setObserver(style::Observer* observer_) {
284     observer = observer_;
285 }
286 
onSourceLoaded(Source & source)287 void Style::Impl::onSourceLoaded(Source& source) {
288     sources.update(source);
289     observer->onSourceLoaded(source);
290     observer->onUpdate();
291 }
292 
onSourceChanged(Source & source)293 void Style::Impl::onSourceChanged(Source& source) {
294     sources.update(source);
295     observer->onSourceChanged(source);
296     observer->onUpdate();
297 }
298 
onSourceError(Source & source,std::exception_ptr error)299 void Style::Impl::onSourceError(Source& source, std::exception_ptr error) {
300     lastError = error;
301     Log::Error(Event::Style, "Failed to load source %s: %s",
302                source.getID().c_str(), util::toString(error).c_str());
303     observer->onSourceError(source, error);
304     observer->onResourceError(error);
305 }
306 
onSourceDescriptionChanged(Source & source)307 void Style::Impl::onSourceDescriptionChanged(Source& source) {
308     sources.update(source);
309     observer->onSourceDescriptionChanged(source);
310     if (!source.loaded) {
311         source.loadDescription(fileSource);
312     }
313 }
314 
onSpriteLoaded(std::vector<std::unique_ptr<Image>> && images_)315 void Style::Impl::onSpriteLoaded(std::vector<std::unique_ptr<Image>>&& images_) {
316     for (auto& image : images_) {
317         addImage(std::move(image));
318     }
319     spriteLoaded = true;
320     observer->onUpdate(); // For *-pattern properties.
321 }
322 
onSpriteError(std::exception_ptr error)323 void Style::Impl::onSpriteError(std::exception_ptr error) {
324     lastError = error;
325     Log::Error(Event::Style, "Failed to load sprite: %s", util::toString(error).c_str());
326     observer->onResourceError(error);
327 }
328 
onLayerChanged(Layer & layer)329 void Style::Impl::onLayerChanged(Layer& layer) {
330     layers.update(layer);
331     observer->onUpdate();
332 }
333 
onLightChanged(const Light &)334 void Style::Impl::onLightChanged(const Light&) {
335     observer->onUpdate();
336 }
337 
dumpDebugLogs() const338 void Style::Impl::dumpDebugLogs() const {
339     Log::Info(Event::General, "styleURL: %s", url.c_str());
340     for (const auto& source : sources) {
341         source->dumpDebugLogs();
342     }
343 }
344 
getGlyphURL() const345 const std::string& Style::Impl::getGlyphURL() const {
346     return glyphURL;
347 }
348 
getImageImpls() const349 Immutable<std::vector<Immutable<Image::Impl>>> Style::Impl::getImageImpls() const {
350     return images.getImpls();
351 }
352 
getSourceImpls() const353 Immutable<std::vector<Immutable<Source::Impl>>> Style::Impl::getSourceImpls() const {
354     return sources.getImpls();
355 }
356 
getLayerImpls() const357 Immutable<std::vector<Immutable<Layer::Impl>>> Style::Impl::getLayerImpls() const {
358     return layers.getImpls();
359 }
360 
361 } // namespace style
362 } // namespace mbgl
363