[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:
John Firebaugh
2015-12-23 14:37:25 -08:00
parent c972a251da
commit d238e00d9b
5 changed files with 127 additions and 132 deletions

View File

@@ -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;

View File

@@ -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();

View File

@@ -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);

View File

@@ -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

View File

@@ -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;