1 #include <mbgl/style/sources/image_source.hpp>
2 #include <mbgl/style/sources/image_source_impl.hpp>
3 #include <mbgl/util/geo.hpp>
4 #include <mbgl/style/source_observer.hpp>
5 #include <mbgl/util/premultiply.hpp>
6 #include <mbgl/storage/file_source.hpp>
7 
8 namespace mbgl {
9 namespace style {
10 
ImageSource(std::string id,const std::array<LatLng,4> coords_)11 ImageSource::ImageSource(std::string id, const std::array<LatLng, 4> coords_)
12     : Source(makeMutable<Impl>(std::move(id), coords_)) {
13 }
14 
15 ImageSource::~ImageSource() = default;
16 
impl() const17 const ImageSource::Impl& ImageSource::impl() const {
18     return static_cast<const Impl&>(*baseImpl);
19 }
20 
setCoordinates(const std::array<LatLng,4> & coords_)21 void ImageSource::setCoordinates(const std::array<LatLng, 4>& coords_) {
22     baseImpl = makeMutable<Impl>(impl(), coords_);
23     observer->onSourceChanged(*this);
24 }
25 
getCoordinates() const26 std::array<LatLng, 4> ImageSource::getCoordinates() const {
27     return impl().getCoordinates();
28 }
29 
setURL(const std::string & url_)30 void ImageSource::setURL(const std::string& url_) {
31     url = std::move(url_);
32     // Signal that the source description needs a reload
33     if (loaded || req) {
34         loaded = false;
35         req.reset();
36         observer->onSourceDescriptionChanged(*this);
37     }
38 }
39 
setImage(PremultipliedImage && image_)40 void ImageSource::setImage(PremultipliedImage&& image_) {
41     url = {};
42     if (req) {
43         req.reset();
44     }
45     loaded = true;
46     baseImpl = makeMutable<Impl>(impl(), std::move(image_));
47     observer->onSourceChanged(*this);
48 }
49 
getURL() const50 optional<std::string> ImageSource::getURL() const {
51     return url;
52 }
53 
loadDescription(FileSource & fileSource)54 void ImageSource::loadDescription(FileSource& fileSource) {
55     if (!url) {
56         loaded = true;
57     }
58 
59     if (req ||  loaded) {
60         return;
61     }
62     const Resource imageResource { Resource::Image, *url, {} };
63 
64     req = fileSource.request(imageResource, [this](Response res) {
65         if (res.error) {
66             observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
67         } else if (res.notModified) {
68             return;
69         } else if (res.noContent) {
70             observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty image url")));
71         } else {
72             try {
73                 baseImpl = makeMutable<Impl>(impl(), decodeImage(*res.data));
74             } catch (...) {
75                 observer->onSourceError(*this, std::current_exception());
76             }
77             loaded = true;
78             observer->onSourceLoaded(*this);
79         }
80     });
81 }
82 
83 } // namespace style
84 } // namespace mbgl
85