summaryrefslogtreecommitdiff
path: root/src/mbgl/style/sources
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/style/sources')
-rw-r--r--src/mbgl/style/sources/geojson_source.cpp70
-rw-r--r--src/mbgl/style/sources/geojson_source_impl.cpp92
-rw-r--r--src/mbgl/style/sources/geojson_source_impl.hpp16
-rw-r--r--src/mbgl/style/sources/image_source.cpp84
-rw-r--r--src/mbgl/style/sources/image_source_impl.cpp38
-rw-r--r--src/mbgl/style/sources/image_source_impl.hpp30
-rw-r--r--src/mbgl/style/sources/raster_source.cpp74
-rw-r--r--src/mbgl/style/sources/raster_source_impl.cpp29
-rw-r--r--src/mbgl/style/sources/raster_source_impl.hpp16
-rw-r--r--src/mbgl/style/sources/vector_source.cpp71
-rw-r--r--src/mbgl/style/sources/vector_source_impl.cpp22
-rw-r--r--src/mbgl/style/sources/vector_source_impl.hpp14
12 files changed, 426 insertions, 130 deletions
diff --git a/src/mbgl/style/sources/geojson_source.cpp b/src/mbgl/style/sources/geojson_source.cpp
index 992f82b1e7..4e3478322d 100644
--- a/src/mbgl/style/sources/geojson_source.cpp
+++ b/src/mbgl/style/sources/geojson_source.cpp
@@ -1,27 +1,81 @@
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/sources/geojson_source_impl.hpp>
#include <mbgl/style/source_observer.hpp>
+#include <mbgl/style/conversion/json.hpp>
+#include <mbgl/style/conversion/geojson.hpp>
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/util/logging.hpp>
namespace mbgl {
namespace style {
GeoJSONSource::GeoJSONSource(const std::string& id, const GeoJSONOptions& options)
- : Source(SourceType::GeoJSON,
- std::make_unique<GeoJSONSource::Impl>(std::move(id), *this, options)),
- impl(static_cast<Impl*>(baseImpl.get())) {
+ : Source(makeMutable<Impl>(std::move(id), options)) {
}
-void GeoJSONSource::setURL(const std::string& url) {
- impl->setURL(url);
+GeoJSONSource::~GeoJSONSource() = default;
+
+const GeoJSONSource::Impl& GeoJSONSource::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
+}
+
+void GeoJSONSource::setURL(const std::string& url_) {
+ url = std::move(url_);
+
+ // Signal that the source description needs a reload
+ if (loaded || req) {
+ loaded = false;
+ req.reset();
+ observer->onSourceDescriptionChanged(*this);
+ }
}
void GeoJSONSource::setGeoJSON(const mapbox::geojson::geojson& geoJSON) {
- impl->setGeoJSON(geoJSON);
- impl->observer->onSourceChanged(*this);
+ req.reset();
+ baseImpl = makeMutable<Impl>(impl(), geoJSON);
+ observer->onSourceChanged(*this);
}
optional<std::string> GeoJSONSource::getURL() const {
- return impl->getURL();
+ return url;
+}
+
+void GeoJSONSource::loadDescription(FileSource& fileSource) {
+ if (!url) {
+ loaded = true;
+ return;
+ }
+
+ if (req) {
+ return;
+ }
+
+ req = fileSource.request(Resource::source(*url), [this](Response res) {
+ if (res.error) {
+ observer->onSourceError(
+ *this, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ return;
+ } else if (res.noContent) {
+ observer->onSourceError(
+ *this, std::make_exception_ptr(std::runtime_error("unexpectedly empty GeoJSON")));
+ } else {
+ conversion::Error error;
+ optional<GeoJSON> geoJSON = conversion::convertJSON<GeoJSON>(*res.data, error);
+ if (!geoJSON) {
+ Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s",
+ error.message.c_str());
+ // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for
+ // tiles to load.
+ baseImpl = makeMutable<Impl>(impl(), GeoJSON{ FeatureCollection{} });
+ } else {
+ baseImpl = makeMutable<Impl>(impl(), *geoJSON);
+ }
+
+ loaded = true;
+ observer->onSourceLoaded(*this);
+ }
+ });
}
} // namespace style
diff --git a/src/mbgl/style/sources/geojson_source_impl.cpp b/src/mbgl/style/sources/geojson_source_impl.cpp
index 1a686ff9bc..efa4018b46 100644
--- a/src/mbgl/style/sources/geojson_source_impl.cpp
+++ b/src/mbgl/style/sources/geojson_source_impl.cpp
@@ -1,16 +1,13 @@
#include <mbgl/style/sources/geojson_source_impl.hpp>
-#include <mbgl/style/conversion/json.hpp>
-#include <mbgl/style/conversion/geojson.hpp>
-#include <mbgl/style/source_observer.hpp>
+#include <mbgl/util/constants.hpp>
#include <mbgl/tile/tile_id.hpp>
-#include <mbgl/storage/file_source.hpp>
-#include <mbgl/renderer/sources/render_geojson_source.hpp>
-#include <mbgl/util/constants.cpp>
-#include <mbgl/util/logging.hpp>
+#include <mbgl/util/string.hpp>
#include <mapbox/geojsonvt.hpp>
#include <supercluster.hpp>
+#include <cmath>
+
namespace mbgl {
namespace style {
@@ -42,33 +39,14 @@ private:
mapbox::supercluster::Supercluster impl;
};
-GeoJSONSource::Impl::Impl(std::string id_, Source& base_, const GeoJSONOptions options_)
- : Source::Impl(SourceType::GeoJSON, std::move(id_), base_), options(options_) {
-}
-
-GeoJSONSource::Impl::~Impl() = default;
-
-void GeoJSONSource::Impl::setURL(std::string url_) {
- url = std::move(url_);
-
- // Signal that the source description needs a reload
- if (loaded || req) {
- loaded = false;
- req.reset();
- observer->onSourceDescriptionChanged(base);
- }
-}
-
-optional<std::string> GeoJSONSource::Impl::getURL() const {
- return url;
-}
-
-void GeoJSONSource::Impl::setGeoJSON(const GeoJSON& geoJSON) {
- req.reset();
- _setGeoJSON(geoJSON);
+GeoJSONSource::Impl::Impl(std::string id_, GeoJSONOptions options_)
+ : Source::Impl(SourceType::GeoJSON, std::move(id_)),
+ options(std::move(options_)) {
}
-void GeoJSONSource::Impl::_setGeoJSON(const GeoJSON& geoJSON) {
+GeoJSONSource::Impl::Impl(const Impl& other, const GeoJSON& geoJSON)
+ : Source::Impl(other),
+ options(other.options) {
double scale = util::EXTENT / util::tileSize;
if (options.cluster
@@ -77,60 +55,20 @@ void GeoJSONSource::Impl::_setGeoJSON(const GeoJSON& geoJSON) {
mapbox::supercluster::Options clusterOptions;
clusterOptions.maxZoom = options.clusterMaxZoom;
clusterOptions.extent = util::EXTENT;
- clusterOptions.radius = std::round(scale * options.clusterRadius);
+ clusterOptions.radius = ::round(scale * options.clusterRadius);
data = std::make_unique<SuperclusterData>(
geoJSON.get<mapbox::geometry::feature_collection<double>>(), clusterOptions);
} else {
mapbox::geojsonvt::Options vtOptions;
vtOptions.maxZoom = options.maxzoom;
vtOptions.extent = util::EXTENT;
- vtOptions.buffer = std::round(scale * options.buffer);
+ vtOptions.buffer = ::round(scale * options.buffer);
vtOptions.tolerance = scale * options.tolerance;
data = std::make_unique<GeoJSONVTData>(geoJSON, vtOptions);
}
}
-void GeoJSONSource::Impl::loadDescription(FileSource& fileSource) {
- if (!url) {
- loaded = true;
- return;
- }
-
- if (req) {
- return;
- }
-
- req = fileSource.request(Resource::source(*url), [this](Response res) {
- if (res.error) {
- observer->onSourceError(
- base, std::make_exception_ptr(std::runtime_error(res.error->message)));
- } else if (res.notModified) {
- return;
- } else if (res.noContent) {
- observer->onSourceError(
- base, std::make_exception_ptr(std::runtime_error("unexpectedly empty GeoJSON")));
- } else {
- conversion::Error error;
- optional<GeoJSON> geoJSON = conversion::convertJSON<GeoJSON>(*res.data, error);
- if (!geoJSON) {
- Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s",
- error.message.c_str());
- // Create an empty GeoJSON VT object to make sure we're not infinitely waiting for
- // tiles to load.
- _setGeoJSON(GeoJSON{ FeatureCollection{} });
- } else {
- _setGeoJSON(*geoJSON);
- }
-
- loaded = true;
- observer->onSourceLoaded(base);
- }
- });
-}
-
-std::unique_ptr<RenderSource> GeoJSONSource::Impl::createRenderSource() const {
- return std::make_unique<RenderGeoJSONSource>(*this);
-}
+GeoJSONSource::Impl::~Impl() = default;
Range<uint8_t> GeoJSONSource::Impl::getZoomRange() const {
return { 0, options.maxzoom };
@@ -140,5 +78,9 @@ GeoJSONData* GeoJSONSource::Impl::getData() const {
return data.get();
}
+optional<std::string> GeoJSONSource::Impl::getAttribution() const {
+ return {};
+}
+
} // namespace style
} // namespace mbgl
diff --git a/src/mbgl/style/sources/geojson_source_impl.hpp b/src/mbgl/style/sources/geojson_source_impl.hpp
index dece1269f8..a524bab9f2 100644
--- a/src/mbgl/style/sources/geojson_source_impl.hpp
+++ b/src/mbgl/style/sources/geojson_source_impl.hpp
@@ -2,7 +2,7 @@
#include <mbgl/style/source_impl.hpp>
#include <mbgl/style/sources/geojson_source.hpp>
-#include <mbgl/util/variant.hpp>
+#include <mbgl/util/range.hpp>
namespace mbgl {
@@ -19,25 +19,17 @@ public:
class GeoJSONSource::Impl : public Source::Impl {
public:
- Impl(std::string id, Source&, const GeoJSONOptions);
+ Impl(std::string id, GeoJSONOptions);
+ Impl(const GeoJSONSource::Impl&, const GeoJSON&);
~Impl() final;
- void setURL(std::string);
- optional<std::string> getURL() const;
Range<uint8_t> getZoomRange() const;
-
- void setGeoJSON(const GeoJSON&);
GeoJSONData* getData() const;
- void loadDescription(FileSource&) final;
- std::unique_ptr<RenderSource> createRenderSource() const final;
+ optional<std::string> getAttribution() const final;
private:
- void _setGeoJSON(const GeoJSON&);
-
GeoJSONOptions options;
- optional<std::string> url;
- std::unique_ptr<AsyncRequest> req;
std::unique_ptr<GeoJSONData> data;
};
diff --git a/src/mbgl/style/sources/image_source.cpp b/src/mbgl/style/sources/image_source.cpp
new file mode 100644
index 0000000000..9b60ba1a48
--- /dev/null
+++ b/src/mbgl/style/sources/image_source.cpp
@@ -0,0 +1,84 @@
+#include <mbgl/style/sources/image_source.hpp>
+#include <mbgl/style/sources/image_source_impl.hpp>
+#include <mbgl/util/geo.hpp>
+#include <mbgl/style/source_observer.hpp>
+#include <mbgl/util/premultiply.hpp>
+#include <mbgl/storage/file_source.hpp>
+
+namespace mbgl {
+namespace style {
+
+ImageSource::ImageSource(std::string id, const std::array<LatLng, 4> coords_)
+ : Source(makeMutable<Impl>(std::move(id), coords_)) {
+}
+
+ImageSource::~ImageSource() = default;
+
+const ImageSource::Impl& ImageSource::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
+}
+
+void ImageSource::setCoordinates(const std::array<LatLng, 4>& coords_) {
+ baseImpl = makeMutable<Impl>(impl(), coords_);
+ observer->onSourceChanged(*this);
+}
+
+std::array<LatLng, 4> ImageSource::getCoordinates() const {
+ return impl().getCoordinates();
+}
+
+void ImageSource::setURL(const std::string& url_) {
+ url = std::move(url_);
+ // Signal that the source description needs a reload
+ if (loaded || req) {
+ loaded = false;
+ req.reset();
+ observer->onSourceDescriptionChanged(*this);
+ }
+}
+
+void ImageSource::setImage(PremultipliedImage&& image_) {
+ url = {};
+ if (req) {
+ req.reset();
+ }
+ loaded = true;
+ baseImpl = makeMutable<Impl>(impl(), std::move(image_));
+ observer->onSourceChanged(*this);
+}
+
+optional<std::string> ImageSource::getURL() const {
+ return url;
+}
+
+void ImageSource::loadDescription(FileSource& fileSource) {
+ if (!url) {
+ loaded = true;
+ }
+
+ if (req || loaded) {
+ return;
+ }
+ const Resource imageResource { Resource::Image, *url, {}, Resource::Necessity::Required };
+
+ req = fileSource.request(imageResource, [this](Response res) {
+ if (res.error) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ return;
+ } else if (res.noContent) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty image url")));
+ } else {
+ try {
+ baseImpl = makeMutable<Impl>(impl(), decodeImage(*res.data));
+ } catch (...) {
+ observer->onSourceError(*this, std::current_exception());
+ }
+ loaded = true;
+ observer->onSourceLoaded(*this);
+ }
+ });
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/sources/image_source_impl.cpp b/src/mbgl/style/sources/image_source_impl.cpp
new file mode 100644
index 0000000000..c1f31dbdc6
--- /dev/null
+++ b/src/mbgl/style/sources/image_source_impl.cpp
@@ -0,0 +1,38 @@
+#include <mbgl/style/sources/image_source_impl.hpp>
+#include <mbgl/util/geo.hpp>
+
+namespace mbgl {
+namespace style {
+
+ImageSource::Impl::Impl(std::string id_, std::array<LatLng, 4> coords_)
+ : Source::Impl(SourceType::Image, std::move(id_)),
+ coords(std::move(coords_)) {
+}
+
+ImageSource::Impl::Impl(const Impl& other, std::array<LatLng, 4> coords_)
+ : Source::Impl(other),
+ coords(std::move(coords_)),
+ image(other.image) {
+}
+
+ImageSource::Impl::Impl(const Impl& rhs, PremultipliedImage&& image_)
+ : Source::Impl(rhs),
+ coords(rhs.coords),
+ image(std::make_shared<PremultipliedImage>(std::move(image_))) {
+}
+ImageSource::Impl::~Impl() = default;
+
+std::shared_ptr<PremultipliedImage> ImageSource::Impl::getImage() const {
+ return image;
+}
+
+std::array<LatLng, 4> ImageSource::Impl::getCoordinates() const {
+ return coords;
+}
+
+optional<std::string> ImageSource::Impl::getAttribution() const {
+ return {};
+}
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/sources/image_source_impl.hpp b/src/mbgl/style/sources/image_source_impl.hpp
new file mode 100644
index 0000000000..1e1b005a32
--- /dev/null
+++ b/src/mbgl/style/sources/image_source_impl.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <mbgl/style/source_impl.hpp>
+#include <mbgl/style/sources/image_source.hpp>
+#include <mbgl/util/image.hpp>
+#include <mbgl/util/geo.hpp>
+
+namespace mbgl {
+
+namespace style {
+
+class ImageSource::Impl : public Source::Impl {
+public:
+ Impl(std::string id, std::array<LatLng, 4> coords);
+ Impl(const Impl& rhs, std::array<LatLng, 4> coords);
+ Impl(const Impl& rhs, PremultipliedImage&& image);
+
+ ~Impl() final;
+
+ std::shared_ptr<PremultipliedImage> getImage() const;
+ std::array<LatLng, 4> getCoordinates() const;
+
+ optional<std::string> getAttribution() const final;
+private:
+ std::array<LatLng, 4> coords;
+ std::shared_ptr<PremultipliedImage> image;
+};
+
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/sources/raster_source.cpp b/src/mbgl/style/sources/raster_source.cpp
index 94fdbcef12..0a0412a4ed 100644
--- a/src/mbgl/style/sources/raster_source.cpp
+++ b/src/mbgl/style/sources/raster_source.cpp
@@ -1,21 +1,81 @@
#include <mbgl/style/sources/raster_source.hpp>
#include <mbgl/style/sources/raster_source_impl.hpp>
+#include <mbgl/style/source_observer.hpp>
+#include <mbgl/style/conversion/json.hpp>
+#include <mbgl/style/conversion/tileset.hpp>
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/util/mapbox.hpp>
namespace mbgl {
namespace style {
-RasterSource::RasterSource(std::string id, variant<std::string, Tileset> urlOrTileset, uint16_t tileSize)
- : Source(SourceType::Raster, std::make_unique<RasterSource::Impl>(std::move(id), *this, std::move(urlOrTileset), tileSize)),
- impl(static_cast<Impl*>(baseImpl.get())) {
+RasterSource::RasterSource(std::string id, variant<std::string, Tileset> urlOrTileset_, uint16_t tileSize)
+ : Source(makeMutable<Impl>(std::move(id), tileSize)),
+ urlOrTileset(std::move(urlOrTileset_)) {
+}
+
+RasterSource::~RasterSource() = default;
+
+const RasterSource::Impl& RasterSource::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
+}
+
+const variant<std::string, Tileset>& RasterSource::getURLOrTileset() const {
+ return urlOrTileset;
}
optional<std::string> RasterSource::getURL() const {
- auto urlOrTileset = impl->getURLOrTileset();
- if (urlOrTileset.is<std::string>()) {
- return urlOrTileset.get<std::string>();
- } else {
+ if (urlOrTileset.is<Tileset>()) {
return {};
}
+
+ return urlOrTileset.get<std::string>();
+}
+
+uint16_t RasterSource::getTileSize() const {
+ return impl().getTileSize();
+}
+
+void RasterSource::loadDescription(FileSource& fileSource) {
+ if (urlOrTileset.is<Tileset>()) {
+ baseImpl = makeMutable<Impl>(impl(), urlOrTileset.get<Tileset>());
+ loaded = true;
+ return;
+ }
+
+ if (req) {
+ return;
+ }
+
+ const std::string& url = urlOrTileset.get<std::string>();
+ req = fileSource.request(Resource::source(url), [this, url](Response res) {
+ if (res.error) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ return;
+ } else if (res.noContent) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty TileJSON")));
+ } else {
+ conversion::Error error;
+ optional<Tileset> tileset = conversion::convertJSON<Tileset>(*res.data, error);
+ if (!tileset) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(error.message)));
+ return;
+ }
+
+ util::mapbox::canonicalizeTileset(*tileset, url, getType(), getTileSize());
+ bool changed = impl().getTileset() != *tileset;
+
+ baseImpl = makeMutable<Impl>(impl(), *tileset);
+ loaded = true;
+
+ observer->onSourceLoaded(*this);
+
+ if (changed) {
+ observer->onSourceChanged(*this);
+ }
+ }
+ });
}
} // namespace style
diff --git a/src/mbgl/style/sources/raster_source_impl.cpp b/src/mbgl/style/sources/raster_source_impl.cpp
index b85d221f2e..50dae1f07e 100644
--- a/src/mbgl/style/sources/raster_source_impl.cpp
+++ b/src/mbgl/style/sources/raster_source_impl.cpp
@@ -1,17 +1,32 @@
#include <mbgl/style/sources/raster_source_impl.hpp>
-#include <mbgl/renderer/sources/render_raster_source.hpp>
namespace mbgl {
namespace style {
-RasterSource::Impl::Impl(std::string id_, Source& base_,
- variant<std::string, Tileset> urlOrTileset_,
- uint16_t tileSize_)
- : TileSourceImpl(SourceType::Raster, std::move(id_), base_, std::move(urlOrTileset_), tileSize_) {
+RasterSource::Impl::Impl(std::string id_, uint16_t tileSize_)
+ : Source::Impl(SourceType::Raster, std::move(id_)),
+ tileSize(tileSize_) {
}
-std::unique_ptr<RenderSource> RasterSource::Impl::createRenderSource() const {
- return std::make_unique<RenderRasterSource>(*this);
+RasterSource::Impl::Impl(const Impl& other, Tileset tileset_)
+ : Source::Impl(other),
+ tileSize(other.tileSize),
+ tileset(std::move(tileset_)) {
+}
+
+uint16_t RasterSource::Impl::getTileSize() const {
+ return tileSize;
+}
+
+optional<Tileset> RasterSource::Impl::getTileset() const {
+ return tileset;
+}
+
+optional<std::string> RasterSource::Impl::getAttribution() const {
+ if (!tileset) {
+ return {};
+ }
+ return tileset->attribution;
}
} // namespace style
diff --git a/src/mbgl/style/sources/raster_source_impl.hpp b/src/mbgl/style/sources/raster_source_impl.hpp
index 4bc76560f8..c41d5485b2 100644
--- a/src/mbgl/style/sources/raster_source_impl.hpp
+++ b/src/mbgl/style/sources/raster_source_impl.hpp
@@ -1,16 +1,24 @@
#pragma once
#include <mbgl/style/sources/raster_source.hpp>
-#include <mbgl/style/tile_source_impl.hpp>
+#include <mbgl/style/source_impl.hpp>
namespace mbgl {
namespace style {
-class RasterSource::Impl : public TileSourceImpl {
+class RasterSource::Impl : public Source::Impl {
public:
- Impl(std::string id, Source&, variant<std::string, Tileset>, uint16_t tileSize);
+ Impl(std::string id, uint16_t tileSize);
+ Impl(const Impl&, Tileset);
- std::unique_ptr<RenderSource> createRenderSource() const final;
+ optional<Tileset> getTileset() const;
+ uint16_t getTileSize() const;
+
+ optional<std::string> getAttribution() const final;
+
+private:
+ uint16_t tileSize;
+ optional<Tileset> tileset;
};
} // namespace style
diff --git a/src/mbgl/style/sources/vector_source.cpp b/src/mbgl/style/sources/vector_source.cpp
index 4bcd3b8985..ccdd453c75 100644
--- a/src/mbgl/style/sources/vector_source.cpp
+++ b/src/mbgl/style/sources/vector_source.cpp
@@ -1,21 +1,78 @@
#include <mbgl/style/sources/vector_source.hpp>
#include <mbgl/style/sources/vector_source_impl.hpp>
+#include <mbgl/style/source_observer.hpp>
+#include <mbgl/style/conversion/json.hpp>
+#include <mbgl/style/conversion/tileset.hpp>
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/util/mapbox.hpp>
+#include <mbgl/util/constants.hpp>
namespace mbgl {
namespace style {
-VectorSource::VectorSource(std::string id, variant<std::string, Tileset> urlOrTileset)
- : Source(SourceType::Vector, std::make_unique<VectorSource::Impl>(std::move(id), *this, std::move(urlOrTileset))),
- impl(static_cast<Impl*>(baseImpl.get())) {
+VectorSource::VectorSource(std::string id, variant<std::string, Tileset> urlOrTileset_)
+ : Source(makeMutable<Impl>(std::move(id))),
+ urlOrTileset(std::move(urlOrTileset_)) {
+}
+
+VectorSource::~VectorSource() = default;
+
+const VectorSource::Impl& VectorSource::impl() const {
+ return static_cast<const Impl&>(*baseImpl);
+}
+
+const variant<std::string, Tileset>& VectorSource::getURLOrTileset() const {
+ return urlOrTileset;
}
optional<std::string> VectorSource::getURL() const {
- auto urlOrTileset = impl->getURLOrTileset();
- if (urlOrTileset.is<std::string>()) {
- return urlOrTileset.get<std::string>();
- } else {
+ if (urlOrTileset.is<Tileset>()) {
return {};
}
+
+ return urlOrTileset.get<std::string>();
+}
+
+void VectorSource::loadDescription(FileSource& fileSource) {
+ if (urlOrTileset.is<Tileset>()) {
+ baseImpl = makeMutable<Impl>(impl(), urlOrTileset.get<Tileset>());
+ loaded = true;
+ return;
+ }
+
+ if (req) {
+ return;
+ }
+
+ const std::string& url = urlOrTileset.get<std::string>();
+ req = fileSource.request(Resource::source(url), [this, url](Response res) {
+ if (res.error) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(res.error->message)));
+ } else if (res.notModified) {
+ return;
+ } else if (res.noContent) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error("unexpectedly empty TileJSON")));
+ } else {
+ conversion::Error error;
+ optional<Tileset> tileset = conversion::convertJSON<Tileset>(*res.data, error);
+ if (!tileset) {
+ observer->onSourceError(*this, std::make_exception_ptr(std::runtime_error(error.message)));
+ return;
+ }
+
+ util::mapbox::canonicalizeTileset(*tileset, url, getType(), util::tileSize);
+ bool changed = impl().getTileset() != *tileset;
+
+ baseImpl = makeMutable<Impl>(impl(), *tileset);
+ loaded = true;
+
+ observer->onSourceLoaded(*this);
+
+ if (changed) {
+ observer->onSourceChanged(*this);
+ }
+ }
+ });
}
} // namespace style
diff --git a/src/mbgl/style/sources/vector_source_impl.cpp b/src/mbgl/style/sources/vector_source_impl.cpp
index 158abf8575..b06f0557bf 100644
--- a/src/mbgl/style/sources/vector_source_impl.cpp
+++ b/src/mbgl/style/sources/vector_source_impl.cpp
@@ -1,16 +1,26 @@
#include <mbgl/style/sources/vector_source_impl.hpp>
-#include <mbgl/renderer/sources/render_vector_source.hpp>
-#include <mbgl/util/constants.hpp>
namespace mbgl {
namespace style {
-VectorSource::Impl::Impl(std::string id_, Source& base_, variant<std::string, Tileset> urlOrTileset_)
- : TileSourceImpl(SourceType::Vector, std::move(id_), base_, std::move(urlOrTileset_), util::tileSize) {
+VectorSource::Impl::Impl(std::string id_)
+ : Source::Impl(SourceType::Vector, std::move(id_)) {
}
-std::unique_ptr<RenderSource> VectorSource::Impl::createRenderSource() const {
- return std::make_unique<RenderVectorSource>(*this);
+VectorSource::Impl::Impl(const Impl& other, Tileset tileset_)
+ : Source::Impl(other),
+ tileset(std::move(tileset_)) {
+}
+
+optional<Tileset> VectorSource::Impl::getTileset() const {
+ return tileset;
+}
+
+optional<std::string> VectorSource::Impl::getAttribution() const {
+ if (!tileset) {
+ return {};
+ }
+ return tileset->attribution;
}
} // namespace style
diff --git a/src/mbgl/style/sources/vector_source_impl.hpp b/src/mbgl/style/sources/vector_source_impl.hpp
index 844739948c..5e559b9266 100644
--- a/src/mbgl/style/sources/vector_source_impl.hpp
+++ b/src/mbgl/style/sources/vector_source_impl.hpp
@@ -1,16 +1,22 @@
#pragma once
#include <mbgl/style/sources/vector_source.hpp>
-#include <mbgl/style/tile_source_impl.hpp>
+#include <mbgl/style/source_impl.hpp>
namespace mbgl {
namespace style {
-class VectorSource::Impl : public TileSourceImpl {
+class VectorSource::Impl : public Source::Impl {
public:
- Impl(std::string id, Source&, variant<std::string, Tileset>);
+ Impl(std::string id);
+ Impl(const Impl&, Tileset);
- std::unique_ptr<RenderSource> createRenderSource() const final;
+ optional<Tileset> getTileset() const;
+
+ optional<std::string> getAttribution() const final;
+
+private:
+ optional<Tileset> tileset;
};
} // namespace style