From 87edff4047ddaf5a49b31c060bfae55d74d6c0cb Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Tue, 14 Jun 2016 12:36:46 -0700 Subject: [core] Use variant in TileSource A tile source can either specify a URL to TileJSON, or inline TileJSON. --- src/mbgl/style/parser.cpp | 154 ++-------------------------------------------- 1 file changed, 4 insertions(+), 150 deletions(-) (limited to 'src/mbgl/style/parser.cpp') diff --git a/src/mbgl/style/parser.cpp b/src/mbgl/style/parser.cpp index 07db3f0091..09689f22f1 100644 --- a/src/mbgl/style/parser.cpp +++ b/src/mbgl/style/parser.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -21,89 +20,11 @@ #include #include -#include #include namespace mbgl { namespace style { -namespace { - -void parseTileJSONMember(const JSValue& value, std::vector& 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 parseTileJSONMember(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 parseTileJSONMember(const JSValue& value, uint8_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::max()) { - return; - } - - target = uint; -} - -void parseTileJSONMember(const JSValue& value, std::array& target, const char* name) { - if (!value.HasMember(name)) { - return; - } - - const JSValue& property = value[name]; - if (!property.IsArray() || property.Size() > 4) { - 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 - Parser::~Parser() = default; void Parser::parse(const std::string& json) { @@ -174,44 +95,16 @@ void Parser::parseSources(const JSValue& value) { } const std::string id { nameVal.GetString(), nameVal.GetStringLength() }; - - std::unique_ptr tileset; std::unique_ptr source; - // Sources can have URLs, either because they reference an external TileJSON file, or - // because reference a GeoJSON file. They don't have to have one though when all source - // parameters are specified inline. - std::string url; - if (sourceVal.HasMember("url")) { - const JSValue& urlVal = sourceVal["url"]; - if (urlVal.IsString()) { - url = { urlVal.GetString(), urlVal.GetStringLength() }; - } else { - Log::Error(Event::ParseStyle, "source url must be a string"); - continue; - } - } else { - tileset = parseTileJSON(sourceVal); - } - - uint16_t tileSize = util::tileSize; - if (sourceVal.HasMember("tileSize")) { - const JSValue& tileSizeVal = sourceVal["tileSize"]; - if (tileSizeVal.IsNumber() && tileSizeVal.GetUint64() <= std::numeric_limits::max()) { - tileSize = tileSizeVal.GetUint64(); - } else { - Log::Error(Event::ParseStyle, "invalid tileSize"); - continue; - } - } - switch (*type) { - case SourceType::Raster: - source = std::make_unique(id, url, tileSize, std::move(tileset)); + case SourceType::Raster: { + source = RasterSource::parse(id, sourceVal); break; + } case SourceType::Vector: - source = std::make_unique(id, url, std::move(tileset)); + source = VectorSource::parse(id, sourceVal); break; case SourceType::GeoJSON: @@ -230,45 +123,6 @@ void Parser::parseSources(const JSValue& value) { } } -std::unique_ptr parseTileJSON(const std::string& json, const std::string& sourceURL, SourceType type, uint16_t tileSize) { - rapidjson::GenericDocument, rapidjson::CrtAllocator> document; - document.Parse<0>(json.c_str()); - - if (document.HasParseError()) { - std::stringstream message; - message << document.GetErrorOffset() << " - " << rapidjson::GetParseError_En(document.GetParseError()); - throw std::runtime_error(message.str()); - } - - std::unique_ptr result = parseTileJSON(document); - - // TODO: Remove this hack by delivering proper URLs in the TileJSON to begin with. - if (util::mapbox::isMapboxURL(sourceURL)) { - for (auto& url : result->tiles) { - url = util::mapbox::canonicalizeTileURL(url, type, tileSize); - } - } - - return result; -} - -std::unique_ptr parseTileJSON(const JSValue& value) { - auto tileset = std::make_unique(); - parseTileJSONMember(value, tileset->tiles, "tiles"); - parseTileJSONMember(value, tileset->zoomRange.min, "minzoom"); - parseTileJSONMember(value, tileset->zoomRange.max, "maxzoom"); - parseTileJSONMember(value, tileset->attribution, "attribution"); - - std::array array; - parseTileJSONMember(value, array, "center"); - tileset->center = { array[0], array[1] }; - tileset->zoom = array[2]; - parseTileJSONMember(value, array, "bounds"); - tileset->bounds = LatLngBounds::hull({ array[0], array[1] }, { array[2], array[3] }); - - return tileset; -} - void Parser::parseLayers(const JSValue& value) { std::vector ids; -- cgit v1.2.1