[core] Remove RapidJSON and GeoJSONVT dependencies from SourceInfo
It's going to be exposed in the public core API as part of #3374.
This commit is contained in:
@@ -28,6 +28,9 @@
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/gl/debugging.hpp>
|
||||
|
||||
#include <mapbox/geojsonvt.hpp>
|
||||
#include <mapbox/geojsonvt/convert.hpp>
|
||||
|
||||
#include <rapidjson/error/en.h>
|
||||
|
||||
#include <algorithm>
|
||||
@@ -35,6 +38,84 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace {
|
||||
|
||||
void parse(const JSValue& value, std::vector<std::string>& target, const char* name) {
|
||||
if (!value.HasMember(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const JSValue& property = value[name];
|
||||
if (!property.IsArray()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
|
||||
if (!property[i].IsString()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
|
||||
target.emplace_back(std::string(property[i].GetString(), property[i].GetStringLength()));
|
||||
}
|
||||
}
|
||||
|
||||
void parse(const JSValue& value, std::string& target, const char* name) {
|
||||
if (!value.HasMember(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const JSValue& property = value[name];
|
||||
if (!property.IsString()) {
|
||||
return;
|
||||
}
|
||||
|
||||
target = { property.GetString(), property.GetStringLength() };
|
||||
}
|
||||
|
||||
void parse(const JSValue& value, uint16_t& target, const char* name) {
|
||||
if (!value.HasMember(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const JSValue& property = value[name];
|
||||
if (!property.IsUint()) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int uint = property.GetUint();
|
||||
if (uint > std::numeric_limits<uint16_t>::max()) {
|
||||
return;
|
||||
}
|
||||
|
||||
target = uint;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
void parse(const JSValue& value, std::array<float, N>& target, const char* name) {
|
||||
if (!value.HasMember(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const JSValue& property = value[name];
|
||||
if (!property.IsArray() || property.Size() != N) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
|
||||
if (!property[i].IsNumber()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
|
||||
target[i] = property[i].GetDouble();
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
Source::Source() {}
|
||||
|
||||
Source::~Source() = default;
|
||||
@@ -91,9 +172,9 @@ void Source::load() {
|
||||
}
|
||||
|
||||
if (info.type == SourceType::Vector || info.type == SourceType::Raster) {
|
||||
info.parseTileJSONProperties(d);
|
||||
parseTileJSON(d);
|
||||
} else if (info.type == SourceType::GeoJSON) {
|
||||
info.parseGeoJSON(d);
|
||||
parseGeoJSON(d);
|
||||
}
|
||||
|
||||
loaded = true;
|
||||
@@ -101,6 +182,28 @@ void Source::load() {
|
||||
});
|
||||
}
|
||||
|
||||
void Source::parseTileJSON(const JSValue& value) {
|
||||
parse(value, info.tiles, "tiles");
|
||||
parse(value, info.min_zoom, "minzoom");
|
||||
parse(value, info.max_zoom, "maxzoom");
|
||||
parse(value, info.attribution, "attribution");
|
||||
parse(value, info.center, "center");
|
||||
parse(value, info.bounds, "bounds");
|
||||
}
|
||||
|
||||
void Source::parseGeoJSON(const JSValue& value) {
|
||||
using namespace mapbox::geojsonvt;
|
||||
|
||||
try {
|
||||
geojsonvt = std::make_unique<GeoJSONVT>(Convert::convert(value, 0));
|
||||
} catch (const std::exception& ex) {
|
||||
Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", ex.what());
|
||||
// Create an empty GeoJSON VT object to make sure we're not infinitely waiting for
|
||||
// tiles to load.
|
||||
geojsonvt = std::make_unique<GeoJSONVT>(std::vector<ProjectedFeature>{});
|
||||
}
|
||||
}
|
||||
|
||||
void Source::updateMatrices(const mat4 &projMatrix, const TransformState &transform) {
|
||||
for (const auto& pair : tiles) {
|
||||
Tile &tile = *pair.second;
|
||||
@@ -217,7 +320,7 @@ TileData::State Source::addTile(const TileID& id, const StyleUpdateParameters& p
|
||||
} else if (info.type == SourceType::Annotations) {
|
||||
monitor = std::make_unique<AnnotationTileMonitor>(normalized_id, parameters.data);
|
||||
} else if (info.type == SourceType::GeoJSON) {
|
||||
monitor = std::make_unique<GeoJSONTileMonitor>(info.geojsonvt.get(), normalized_id);
|
||||
monitor = std::make_unique<GeoJSONTileMonitor>(geojsonvt.get(), normalized_id);
|
||||
} else {
|
||||
Log::Warning(Event::Style, "Source type '%s' is not implemented", SourceTypeClass(info.type).c_str());
|
||||
return TileData::State::invalid;
|
||||
|
||||
@@ -5,10 +5,17 @@
|
||||
#include <mbgl/map/source_info.hpp>
|
||||
|
||||
#include <mbgl/util/mat4.hpp>
|
||||
#include <mbgl/util/rapidjson.hpp>
|
||||
|
||||
#include <forward_list>
|
||||
#include <map>
|
||||
|
||||
namespace mapbox {
|
||||
namespace geojsonvt {
|
||||
class GeoJSONVT;
|
||||
} // namespace geojsonvt
|
||||
} // namespace mapbox
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class StyleUpdateParameters;
|
||||
@@ -35,6 +42,9 @@ public:
|
||||
Source();
|
||||
~Source();
|
||||
|
||||
void parseTileJSON(const JSValue&);
|
||||
void parseGeoJSON(const JSValue&);
|
||||
|
||||
bool loaded = false;
|
||||
void load();
|
||||
bool isLoading() const;
|
||||
@@ -76,6 +86,8 @@ private:
|
||||
|
||||
double getZoom(const TransformState &state) const;
|
||||
|
||||
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> geojsonvt;
|
||||
|
||||
// Stores the time when this source was most recently updated.
|
||||
TimePoint updated = TimePoint::min();
|
||||
|
||||
|
||||
@@ -1,117 +1,11 @@
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/map/source_info.hpp>
|
||||
#include <mbgl/map/tile_id.hpp>
|
||||
#include <mbgl/util/mapbox.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/util/token.hpp>
|
||||
|
||||
#include <mapbox/geojsonvt.hpp>
|
||||
#include <mapbox/geojsonvt/convert.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace {
|
||||
|
||||
void parse(const JSValue& value, std::vector<std::string>& target, const char* name) {
|
||||
if (!value.HasMember(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const JSValue& property = value[name];
|
||||
if (!property.IsArray()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
|
||||
if (!property[i].IsString()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
|
||||
target.emplace_back(std::string(property[i].GetString(), property[i].GetStringLength()));
|
||||
}
|
||||
}
|
||||
|
||||
void parse(const JSValue& value, std::string& target, const char* name) {
|
||||
if (!value.HasMember(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const JSValue& property = value[name];
|
||||
if (!property.IsString()) {
|
||||
return;
|
||||
}
|
||||
|
||||
target = { property.GetString(), property.GetStringLength() };
|
||||
}
|
||||
|
||||
void parse(const JSValue& value, uint16_t& target, const char* name) {
|
||||
if (!value.HasMember(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const JSValue& property = value[name];
|
||||
if (!property.IsUint()) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int uint = property.GetUint();
|
||||
if (uint > std::numeric_limits<uint16_t>::max()) {
|
||||
return;
|
||||
}
|
||||
|
||||
target = uint;
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
void parse(const JSValue& value, std::array<float, N>& target, const char* name) {
|
||||
if (!value.HasMember(name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const JSValue& property = value[name];
|
||||
if (!property.IsArray() || property.Size() != N) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
|
||||
if (!property[i].IsNumber()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (rapidjson::SizeType i = 0; i < property.Size(); i++) {
|
||||
target[i] = property[i].GetDouble();
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace
|
||||
|
||||
// Destructor in implementation file because header only contains forward declarations.
|
||||
SourceInfo::~SourceInfo() = default;
|
||||
|
||||
void SourceInfo::parseTileJSONProperties(const JSValue& value) {
|
||||
parse(value, tiles, "tiles");
|
||||
parse(value, min_zoom, "minzoom");
|
||||
parse(value, max_zoom, "maxzoom");
|
||||
parse(value, attribution, "attribution");
|
||||
parse(value, center, "center");
|
||||
parse(value, bounds, "bounds");
|
||||
}
|
||||
|
||||
void SourceInfo::parseGeoJSON(const JSValue& value) {
|
||||
using namespace mapbox::geojsonvt;
|
||||
|
||||
try {
|
||||
geojsonvt = std::make_unique<GeoJSONVT>(Convert::convert(value, 0));
|
||||
} catch (const std::exception& ex) {
|
||||
Log::Error(Event::ParseStyle, "Failed to parse GeoJSON data: %s", ex.what());
|
||||
// Create an empty GeoJSON VT object to make sure we're not infinitely waiting for
|
||||
// tiles to load.
|
||||
geojsonvt = std::make_unique<GeoJSONVT>(std::vector<ProjectedFeature>{});
|
||||
}
|
||||
}
|
||||
|
||||
std::string SourceInfo::tileURL(const TileID& id, float pixelRatio) const {
|
||||
std::string result = tiles.at(0);
|
||||
result = util::mapbox::normalizeTileURL(result, url, type);
|
||||
|
||||
@@ -2,30 +2,19 @@
|
||||
#define MBGL_MAP_SOURCE_INFO
|
||||
|
||||
#include <mbgl/style/types.hpp>
|
||||
#include <mbgl/map/tile_id.hpp>
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/rapidjson.hpp>
|
||||
|
||||
#include <mapbox/variant.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
namespace mapbox {
|
||||
namespace geojsonvt {
|
||||
class GeoJSONVT;
|
||||
} // namespace geojsonvt
|
||||
} // namespace mapbox
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class SourceInfo : private util::noncopyable {
|
||||
public:
|
||||
~SourceInfo();
|
||||
class TileID;
|
||||
|
||||
class SourceInfo {
|
||||
public:
|
||||
SourceType type = SourceType::Vector;
|
||||
std::string url;
|
||||
std::vector<std::string> tiles;
|
||||
@@ -36,11 +25,8 @@ public:
|
||||
std::array<float, 3> center = { { 0, 0, 0 } };
|
||||
std::array<float, 4> bounds = { { -180, -90, 180, 90 } };
|
||||
std::string source_id = "";
|
||||
std::unique_ptr<mapbox::geojsonvt::GeoJSONVT> geojsonvt;
|
||||
|
||||
void parseTileJSONProperties(const JSValue&);
|
||||
void parseGeoJSON(const JSValue&);
|
||||
std::string tileURL(const TileID& id, float pixelRatio) const;
|
||||
std::string tileURL(const TileID&, float pixelRatio) const;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -112,7 +112,7 @@ bool StyleParser::parseVectorSource(Source& source, const JSValue& sourceVal) {
|
||||
|
||||
} else {
|
||||
// ...or the TileJSON directly.
|
||||
source.info.parseTileJSONProperties(sourceVal);
|
||||
source.parseTileJSON(sourceVal);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -149,7 +149,7 @@ bool StyleParser::parseRasterSource(Source& source, const JSValue& sourceVal) {
|
||||
|
||||
} else {
|
||||
// ...or the TileJSON directly.
|
||||
source.info.parseTileJSONProperties(sourceVal);
|
||||
source.parseTileJSON(sourceVal);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -167,7 +167,7 @@ bool StyleParser::parseGeoJSONSource(Source& source, const JSValue& sourceVal) {
|
||||
source.info.url = { dataVal.GetString(), dataVal.GetStringLength() };
|
||||
} else if (dataVal.IsObject()) {
|
||||
// We need to parse dataVal as a GeoJSON object
|
||||
source.info.parseGeoJSON(dataVal);
|
||||
source.parseGeoJSON(dataVal);
|
||||
} else {
|
||||
Log::Error(Event::ParseStyle, "GeoJSON data must be a URL or an object");
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user