From 26abfb555e592d3cdc75b0184f645a9563d81934 Mon Sep 17 00:00:00 2001 From: rosecodym Date: Fri, 15 Jul 2016 16:41:54 -0700 Subject: [core] create offline polygon region definition There is now a way to create and persist offline storage regions other than the old tile pyramids. The region type is now a variant, and the two options are the old tile pyramids, and a new type for polygons. Each type is an instantiation of a class template for offline regions with fixed geometry. --- include/mbgl/storage/offline.hpp | 130 ++++++++++++++++--- platform/default/mbgl/storage/offline.cpp | 142 ++++++++++----------- platform/default/mbgl/storage/offline_download.cpp | 12 +- platform/macos/platform.gyp | 1 + test/storage/offline.cpp | 57 ++++++--- test/storage/offline_database.cpp | 49 +++---- test/storage/offline_download.cpp | 34 ++--- 7 files changed, 273 insertions(+), 152 deletions(-) diff --git a/include/mbgl/storage/offline.hpp b/include/mbgl/storage/offline.hpp index 818cfe2ba5..af12744f0d 100644 --- a/include/mbgl/storage/offline.hpp +++ b/include/mbgl/storage/offline.hpp @@ -3,9 +3,16 @@ #include #include #include +#include +#include +#include #include #include +#include +#include +#include + #include #include #include @@ -15,7 +22,7 @@ namespace mbgl { class TileID; /* - * An offline region defined by a style URL, geographic bounding box, zoom range, and + * An offline region defined by a style URL, geometry, zoom range, and * device pixel ratio. * * Both minZoom and maxZoom must be ≥ 0, and maxZoom must be ≥ minZoom. @@ -25,29 +32,118 @@ class TileID; * * pixelRatio must be ≥ 0 and should typically be 1.0 or 2.0. */ -class OfflineTilePyramidRegionDefinition { + +template +struct OfflineFixedGeometryTraits { }; + +template <> +struct OfflineFixedGeometryTraits { + static const char typeName[]; + constexpr static const size_t typeNameLength = sizeof("PYRAMID") - 1; + + void encode(rapidjson::GenericDocument, rapidjson::CrtAllocator>& doc, LatLngBounds bounds); + LatLngBounds decode(const rapidjson::GenericDocument, rapidjson::CrtAllocator>& doc); +}; + +template <> +struct OfflineFixedGeometryTraits> { + static const char typeName[]; + constexpr static const size_t typeNameLength = sizeof("POLYGON") - 1; + + void encode(rapidjson::GenericDocument, rapidjson::CrtAllocator>&, const Polygon&); + Polygon decode(const rapidjson::GenericDocument, rapidjson::CrtAllocator>&); +}; + +template +class OfflineFixedGeometryRegionDefinition { public: - OfflineTilePyramidRegionDefinition(std::string, LatLngBounds, double, double, float); - + OfflineFixedGeometryRegionDefinition(std::string styleURL_, TGeometry geometry_, Range zoomRange_, float pixelRatio_) + : styleURL(std::move(styleURL_)), + geometry(std::move(geometry_)), + minZoom(zoomRange_.min), + maxZoom(zoomRange_.max), + pixelRatio(pixelRatio_) { } + /* Private */ - std::vector tileCover(SourceType, uint16_t tileSize, const Range& zoomRange) const; - + std::vector tileCover(SourceType type, uint16_t tileSize, Range sourceZoomRange) const { + double minZ = std::max(util::coveringZoomLevel(minZoom, type, tileSize), sourceZoomRange.min); + double maxZ = std::min(util::coveringZoomLevel(maxZoom, type, tileSize), sourceZoomRange.max); + + assert(minZ >= 0); + assert(maxZ >= 0); + assert(minZ < std::numeric_limits::max()); + assert(maxZ < std::numeric_limits::max()); + + std::vector result; + for (uint8_t z = minZ; z <= maxZ; ++z) { + for (const auto& tile : util::tileCover(geometry, z)) { + result.emplace_back(tile.canonical); + } + } + + return result; + } + + std::string encode() const { + OfflineFixedGeometryTraits geometryTraits; + + rapidjson::GenericDocument, rapidjson::CrtAllocator> doc; + doc.SetObject(); + + doc.AddMember("type", rapidjson::StringRef(geometryTraits.typeName, geometryTraits.typeNameLength), doc.GetAllocator()); + doc.AddMember("style_url", rapidjson::StringRef(styleURL.data(), styleURL.length()), doc.GetAllocator()); + + geometryTraits.encode(doc, geometry); + + doc.AddMember("min_zoom", minZoom, doc.GetAllocator()); + if (std::isfinite(maxZoom)) { + doc.AddMember("max_zoom", maxZoom, doc.GetAllocator()); + } + + doc.AddMember("pixel_ratio", pixelRatio, doc.GetAllocator()); + + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + doc.Accept(writer); + + return buffer.GetString(); + } + + static OfflineFixedGeometryRegionDefinition decode(const rapidjson::GenericDocument, rapidjson::CrtAllocator>& doc) { + OfflineFixedGeometryTraits geometryTraits; + + if (doc.HasParseError() || + !doc.HasMember("style_url") || !doc["style_url"].IsString() || + !doc.HasMember("min_zoom") || !doc["min_zoom"].IsDouble() || + (doc.HasMember("max_zoom") && !doc["max_zoom"].IsDouble()) || + !doc.HasMember("pixel_ratio") || !doc["pixel_ratio"].IsDouble()) { + throw std::runtime_error("Malformed offline fixed geometry region definition"); + } + + std::string styleURL { doc["style_url"].GetString(), doc["style_url"].GetStringLength() }; + double minZoom = doc["min_zoom"].GetDouble(); + double maxZoom = doc.HasMember("max_zoom") ? doc["max_zoom"].GetDouble() : INFINITY; + Range zoomRange{ minZoom, maxZoom }; + float pixelRatio = doc["pixel_ratio"].GetDouble(); + + auto geometry = geometryTraits.decode(doc); + + return { styleURL, geometry, zoomRange, pixelRatio }; + } + const std::string styleURL; - const LatLngBounds bounds; + const TGeometry geometry; const double minZoom; const double maxZoom; const float pixelRatio; }; - -/* - * For the present, a tile pyramid is the only type of offline region. In the future, - * other definition types will be available and this will be a variant type. - */ -using OfflineRegionDefinition = OfflineTilePyramidRegionDefinition; - -/* - * The encoded format is private. - */ + +using OfflineRegionDefinition = variant, OfflineFixedGeometryRegionDefinition>>; + +float pixelRatio(const OfflineRegionDefinition&); +const std::string& styleURL(const OfflineRegionDefinition&); +std::vector tileCover(const OfflineRegionDefinition&, SourceType, uint16_t, Range); + std::string encodeOfflineRegionDefinition(const OfflineRegionDefinition&); OfflineRegionDefinition decodeOfflineRegionDefinition(const std::string&); diff --git a/platform/default/mbgl/storage/offline.cpp b/platform/default/mbgl/storage/offline.cpp index fd2d47819b..6a2777a520 100644 --- a/platform/default/mbgl/storage/offline.cpp +++ b/platform/default/mbgl/storage/offline.cpp @@ -1,6 +1,9 @@ +#include + #include #include #include +#include #include #include @@ -9,91 +12,86 @@ #include namespace mbgl { + +const char OfflineFixedGeometryTraits::typeName[] = "PYRAMID"; +const char OfflineFixedGeometryTraits>::typeName[] = "POLYGON"; + +void OfflineFixedGeometryTraits::encode(rapidjson::GenericDocument, rapidjson::CrtAllocator>& doc, LatLngBounds bounds) { + rapidjson::GenericValue, rapidjson::CrtAllocator> encodedBounds(rapidjson::kArrayType); + encodedBounds.PushBack(bounds.south(), doc.GetAllocator()); + encodedBounds.PushBack(bounds.west(), doc.GetAllocator()); + encodedBounds.PushBack(bounds.north(), doc.GetAllocator()); + encodedBounds.PushBack(bounds.east(), doc.GetAllocator()); + doc.AddMember("bounds", encodedBounds, doc.GetAllocator()); +} -OfflineTilePyramidRegionDefinition::OfflineTilePyramidRegionDefinition( - std::string styleURL_, LatLngBounds bounds_, double minZoom_, double maxZoom_, float pixelRatio_) - : styleURL(std::move(styleURL_)), - bounds(std::move(bounds_)), - minZoom(minZoom_), - maxZoom(maxZoom_), - pixelRatio(pixelRatio_) { - if (minZoom < 0 || maxZoom < 0 || maxZoom < minZoom || pixelRatio < 0 || - !std::isfinite(minZoom) || std::isnan(maxZoom) || !std::isfinite(pixelRatio)) { - throw std::invalid_argument("Invalid offline region definition"); +LatLngBounds OfflineFixedGeometryTraits::decode(const rapidjson::GenericDocument, rapidjson::CrtAllocator>& doc) { + if (!doc.HasMember("bounds") || !doc["bounds"].IsArray() || doc["bounds"].Size() != 4) { + throw std::runtime_error("Malformed pyramid offline region definition"); } + return LatLngBounds::hull(LatLng(doc["bounds"][0].GetDouble(), doc["bounds"][1].GetDouble()), + LatLng(doc["bounds"][2].GetDouble(), doc["bounds"][3].GetDouble())); } - -std::vector OfflineTilePyramidRegionDefinition::tileCover(SourceType type, uint16_t tileSize, const Range& zoomRange) const { - double minZ = std::max(util::coveringZoomLevel(minZoom, type, tileSize), zoomRange.min); - double maxZ = std::min(util::coveringZoomLevel(maxZoom, type, tileSize), zoomRange.max); - - assert(minZ >= 0); - assert(maxZ >= 0); - assert(minZ < std::numeric_limits::max()); - assert(maxZ < std::numeric_limits::max()); - - std::vector result; - - for (uint8_t z = minZ; z <= maxZ; z++) { - for (const auto& tile : util::tileCover(bounds, z)) { - result.emplace_back(tile.canonical); - } + +void OfflineFixedGeometryTraits>::encode(rapidjson::GenericDocument, rapidjson::CrtAllocator>& doc, const Polygon& polygon) { + auto encodedGeom = mapbox::geojson::convert>({ polygon }, doc.GetAllocator()); + doc.AddMember("polygon", encodedGeom, doc.GetAllocator()); +} + +Polygon OfflineFixedGeometryTraits>::decode(const rapidjson::GenericDocument, rapidjson::CrtAllocator>& doc) { + if (!doc.HasMember("polygon")) { + throw std::runtime_error("Malformed polygon offline region definition"); } + return mapbox::geojson::convert>(doc["polygon"]).get>(); +} + +float pixelRatio(const OfflineRegionDefinition& region) { + return OfflineRegionDefinition::visit(region, [](const auto& r) { return r.pixelRatio; }); +} + +const std::string& styleURL(const OfflineRegionDefinition& region) { + return OfflineRegionDefinition::visit(region, [](const auto& r) -> const std::string& { return r.styleURL; }); +} - return result; +std::vector tileCover(const OfflineRegionDefinition& region, SourceType type, uint16_t tileSize, Range zoomRange) { + return OfflineRegionDefinition::visit(region, [type, tileSize, zoomRange](const auto& r) { return r.tileCover(type, tileSize, zoomRange); }); +} + +std::string encodeOfflineRegionDefinition(const OfflineRegionDefinition& region) { + return OfflineRegionDefinition::visit(region, [](const auto& r) { return r.encode(); }); } OfflineRegionDefinition decodeOfflineRegionDefinition(const std::string& region) { + rapidjson::GenericDocument, rapidjson::CrtAllocator> doc; doc.Parse<0>(region.c_str()); - - if (doc.HasParseError() || - !doc.HasMember("style_url") || !doc["style_url"].IsString() || - !doc.HasMember("bounds") || !doc["bounds"].IsArray() || doc["bounds"].Size() != 4 || - !doc["bounds"][0].IsDouble() || !doc["bounds"][1].IsDouble() || - !doc["bounds"][2].IsDouble() || !doc["bounds"][3].IsDouble() || - !doc.HasMember("min_zoom") || !doc["min_zoom"].IsDouble() || - (doc.HasMember("max_zoom") && !doc["max_zoom"].IsDouble()) || - !doc.HasMember("pixel_ratio") || !doc["pixel_ratio"].IsDouble()) { + + if (doc.HasParseError()) { throw std::runtime_error("Malformed offline region definition"); } - - std::string styleURL { doc["style_url"].GetString(), doc["style_url"].GetStringLength() }; - LatLngBounds bounds = LatLngBounds::hull( - LatLng(doc["bounds"][0].GetDouble(), doc["bounds"][1].GetDouble()), - LatLng(doc["bounds"][2].GetDouble(), doc["bounds"][3].GetDouble())); - double minZoom = doc["min_zoom"].GetDouble(); - double maxZoom = doc.HasMember("max_zoom") ? doc["max_zoom"].GetDouble() : INFINITY; - float pixelRatio = doc["pixel_ratio"].GetDouble(); - - return { styleURL, bounds, minZoom, maxZoom, pixelRatio }; -} - -std::string encodeOfflineRegionDefinition(const OfflineRegionDefinition& region) { - rapidjson::GenericDocument, rapidjson::CrtAllocator> doc; - doc.SetObject(); - - doc.AddMember("style_url", rapidjson::StringRef(region.styleURL.data(), region.styleURL.length()), doc.GetAllocator()); - - rapidjson::GenericValue, rapidjson::CrtAllocator> bounds(rapidjson::kArrayType); - bounds.PushBack(region.bounds.south(), doc.GetAllocator()); - bounds.PushBack(region.bounds.west(), doc.GetAllocator()); - bounds.PushBack(region.bounds.north(), doc.GetAllocator()); - bounds.PushBack(region.bounds.east(), doc.GetAllocator()); - doc.AddMember("bounds", bounds, doc.GetAllocator()); - - doc.AddMember("min_zoom", region.minZoom, doc.GetAllocator()); - if (std::isfinite(region.maxZoom)) { - doc.AddMember("max_zoom", region.maxZoom, doc.GetAllocator()); + + std::string type; + if (!doc.HasMember("type")) { + // Might be an old database format; assume it's a tile pyramid + type = OfflineFixedGeometryTraits::typeName; + } + else if (!doc["type"].IsString()) { + throw std::runtime_error("Malformed offline region definition"); + } + else { + type = doc["type"].GetString(); + } + + if (type == OfflineFixedGeometryTraits::typeName) { + return OfflineFixedGeometryRegionDefinition::decode(doc); + } + else if (type == OfflineFixedGeometryTraits>::typeName) { + return OfflineFixedGeometryRegionDefinition>::decode(doc); + } + else { + std::string msg("Unknown offline region type: "); + throw std::runtime_error(msg + type); } - - doc.AddMember("pixel_ratio", region.pixelRatio, doc.GetAllocator()); - - rapidjson::StringBuffer buffer; - rapidjson::Writer writer(buffer); - doc.Accept(writer); - - return buffer.GetString(); } OfflineRegion::OfflineRegion(int64_t id_, diff --git a/platform/default/mbgl/storage/offline_download.cpp b/platform/default/mbgl/storage/offline_download.cpp index 6ff605167a..58551bca11 100644 --- a/platform/default/mbgl/storage/offline_download.cpp +++ b/platform/default/mbgl/storage/offline_download.cpp @@ -53,8 +53,8 @@ std::vector OfflineDownload::spriteResources(const style::Parser& pars std::vector result; if (!parser.spriteURL.empty()) { - result.push_back(Resource::spriteImage(parser.spriteURL, definition.pixelRatio)); - result.push_back(Resource::spriteJSON(parser.spriteURL, definition.pixelRatio)); + result.push_back(Resource::spriteImage(parser.spriteURL, pixelRatio(definition))); + result.push_back(Resource::spriteJSON(parser.spriteURL, pixelRatio(definition))); } return result; @@ -77,8 +77,8 @@ std::vector OfflineDownload::glyphResources(const style::Parser& parse std::vector OfflineDownload::tileResources(SourceType type, uint16_t tileSize, const Tileset& tileset) const { std::vector result; - for (const auto& tile : definition.tileCover(type, tileSize, tileset.zoomRange)) { - result.push_back(Resource::tile(tileset.tiles[0], definition.pixelRatio, tile.x, tile.y, tile.z)); + for (const auto& tile : tileCover(definition, type, tileSize, tileset.zoomRange)) { + result.push_back(Resource::tile(tileset.tiles[0], pixelRatio(definition), tile.x, tile.y, tile.z)); } return result; @@ -92,7 +92,7 @@ OfflineRegionStatus OfflineDownload::getStatus() const { OfflineRegionStatus result = offlineDatabase.getRegionCompletedStatus(id); result.requiredResourceCount++; - optional styleResponse = offlineDatabase.get(Resource::style(definition.styleURL)); + optional styleResponse = offlineDatabase.get(Resource::style(styleURL(definition))); if (!styleResponse) { return result; } @@ -153,7 +153,7 @@ void OfflineDownload::activateDownload() { requiredSourceURLs.clear(); - ensureResource(Resource::style(definition.styleURL), [&] (Response styleResponse) { + ensureResource(Resource::style(styleURL(definition)), [&] (Response styleResponse) { status.requiredResourceCountIsPrecise = true; style::Parser parser; diff --git a/platform/macos/platform.gyp b/platform/macos/platform.gyp index 68ab4ce467..2462765cc5 100644 --- a/platform/macos/platform.gyp +++ b/platform/macos/platform.gyp @@ -84,6 +84,7 @@ '<@(sqlite_cflags)', '<@(zlib_cflags)', '<@(rapidjson_cflags)', + '<@(geojson_cflags)', ], 'CLANG_ENABLE_OBJC_ARC': 'YES', 'CLANG_ENABLE_MODULES': 'YES', diff --git a/test/storage/offline.cpp b/test/storage/offline.cpp index 0faaabc298..c65e6eef42 100644 --- a/test/storage/offline.cpp +++ b/test/storage/offline.cpp @@ -5,50 +5,71 @@ using namespace mbgl; +using OfflineTilePyramidRegionDefinition = OfflineFixedGeometryRegionDefinition; + static const LatLngBounds sanFrancisco = LatLngBounds::hull({ 37.6609, -122.5744 }, { 37.8271, -122.3204 }); static const LatLngBounds sanFranciscoWrapped = LatLngBounds::hull({ 37.6609, 238.5744 }, { 37.8271, 238.3204 }); -TEST(OfflineTilePyramidRegionDefinition, TileCoverEmpty) { - OfflineTilePyramidRegionDefinition region("", LatLngBounds::empty(), 0, 20, 1.0); +TEST(OfflineRegionDefinition, TileCoverEmpty) { + OfflineTilePyramidRegionDefinition region("", LatLngBounds::empty(), {0, 20}, 1.0); - EXPECT_EQ((std::vector{}), region.tileCover(SourceType::Vector, 512, { 0, 22 })); + EXPECT_EQ((std::vector{}), tileCover(region, SourceType::Vector, 512, { 0, 22 })); } -TEST(OfflineTilePyramidRegionDefinition, TileCoverZoomIntersection) { - OfflineTilePyramidRegionDefinition region("", sanFrancisco, 2, 2, 1.0); +TEST(OfflineRegionDefinition, TileCoverZoomIntersection) { + OfflineTilePyramidRegionDefinition region("", sanFrancisco, {2, 2}, 1.0); EXPECT_EQ((std::vector{ { 2, 0, 1 } }), - region.tileCover(SourceType::Vector, 512, { 0, 22 })); + tileCover(region, SourceType::Vector, 512, { 0, 22 })); - EXPECT_EQ((std::vector{}), region.tileCover(SourceType::Vector, 512, { 3, 22 })); + EXPECT_EQ((std::vector{}), tileCover(region, SourceType::Vector, 512, { 3, 22 })); } -TEST(OfflineTilePyramidRegionDefinition, TileCoverTileSize) { - OfflineTilePyramidRegionDefinition region("", LatLngBounds::world(), 0, 0, 1.0); +TEST(OfflineRegionDefinition, TileCoverTileSize) { + OfflineTilePyramidRegionDefinition region("", LatLngBounds::world(), {0, 0}, 1.0); EXPECT_EQ((std::vector{ { 0, 0, 0 } }), - region.tileCover(SourceType::Vector, 512, { 0, 22 })); + tileCover(region, SourceType::Vector, 512, { 0, 22 })); EXPECT_EQ((std::vector{ { 1, 0, 0 }, { 1, 0, 1 }, { 1, 1, 0 }, { 1, 1, 1 } }), - region.tileCover(SourceType::Vector, 256, { 0, 22 })); + tileCover(region, SourceType::Vector, 256, { 0, 22 })); } -TEST(OfflineTilePyramidRegionDefinition, TileCoverZoomRounding) { - OfflineTilePyramidRegionDefinition region("", sanFrancisco, 0.6, 0.7, 1.0); +TEST(OfflineRegionDefinition, TileCoverZoomRounding) { + OfflineTilePyramidRegionDefinition region("", sanFrancisco, {0.6, 0.7}, 1.0); EXPECT_EQ((std::vector{ { 0, 0, 0 } }), - region.tileCover(SourceType::Vector, 512, { 0, 22 })); + tileCover(region, SourceType::Vector, 512, { 0, 22 })); EXPECT_EQ((std::vector{ { 1, 0, 0 } }), - region.tileCover(SourceType::Raster, 512, { 0, 22 })); + tileCover(region, SourceType::Raster, 512, { 0, 22 })); } -TEST(OfflineTilePyramidRegionDefinition, TileCoverWrapped) { - OfflineTilePyramidRegionDefinition region("", sanFranciscoWrapped, 0, 0, 1.0); +TEST(OfflineRegionDefinition, TileCoverWrapped) { + OfflineTilePyramidRegionDefinition region("", sanFranciscoWrapped, {0, 0}, 1.0); EXPECT_EQ((std::vector{ { 0, 0, 0 } }), - region.tileCover(SourceType::Vector, 512, { 0, 22 })); + tileCover(region, SourceType::Vector, 512, { 0, 22 })); +} + +TEST(OfflinePolygonRegionDefinition, EncodeDecode) { + Polygon polygon { { + { 1, 1, }, + { 2, 2, }, + { 1.5, 2.5 } + } }; + OfflineFixedGeometryRegionDefinition> region("", polygon, { 2, 2 }, 1.0); + + auto encoded = encodeOfflineRegionDefinition(region); + auto decoded = decodeOfflineRegionDefinition(encoded).get>>(); + + EXPECT_EQ(region.maxZoom, decoded.maxZoom); + EXPECT_EQ(region.minZoom, decoded.minZoom); + EXPECT_EQ(region.pixelRatio, decoded.pixelRatio); + EXPECT_EQ(region.styleURL, decoded.styleURL); + EXPECT_EQ(region.geometry, decoded.geometry); } + diff --git a/test/storage/offline_database.cpp b/test/storage/offline_database.cpp index 6a3262abf6..23f310769c 100644 --- a/test/storage/offline_database.cpp +++ b/test/storage/offline_database.cpp @@ -262,15 +262,16 @@ TEST(OfflineDatabase, CreateRegion) { using namespace mbgl; OfflineDatabase db(":memory:"); - OfflineRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), 5, 6, 2.0 }; + OfflineFixedGeometryRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), {5, 6}, 2.0 }; OfflineRegionMetadata metadata {{ 1, 2, 3 }}; OfflineRegion region = db.createRegion(definition, metadata); - - EXPECT_EQ(definition.styleURL, region.getDefinition().styleURL); - EXPECT_EQ(definition.bounds, region.getDefinition().bounds); - EXPECT_EQ(definition.minZoom, region.getDefinition().minZoom); - EXPECT_EQ(definition.maxZoom, region.getDefinition().maxZoom); - EXPECT_EQ(definition.pixelRatio, region.getDefinition().pixelRatio); + + auto retrieved = region.getDefinition().get>(); + EXPECT_EQ(definition.styleURL, retrieved.styleURL); + EXPECT_EQ(definition.geometry, retrieved.geometry); + EXPECT_EQ(definition.minZoom, retrieved.minZoom); + EXPECT_EQ(definition.maxZoom, retrieved.maxZoom); + EXPECT_EQ(definition.pixelRatio, retrieved.pixelRatio); EXPECT_EQ(metadata, region.getMetadata()); } @@ -278,7 +279,7 @@ TEST(OfflineDatabase, ListRegions) { using namespace mbgl; OfflineDatabase db(":memory:"); - OfflineRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), 5, 6, 2.0 }; + OfflineFixedGeometryRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), {5, 6}, 2.0 }; OfflineRegionMetadata metadata {{ 1, 2, 3 }}; OfflineRegion region = db.createRegion(definition, metadata); @@ -286,11 +287,12 @@ TEST(OfflineDatabase, ListRegions) { ASSERT_EQ(1u, regions.size()); EXPECT_EQ(region.getID(), regions.at(0).getID()); - EXPECT_EQ(definition.styleURL, regions.at(0).getDefinition().styleURL); - EXPECT_EQ(definition.bounds, regions.at(0).getDefinition().bounds); - EXPECT_EQ(definition.minZoom, regions.at(0).getDefinition().minZoom); - EXPECT_EQ(definition.maxZoom, regions.at(0).getDefinition().maxZoom); - EXPECT_EQ(definition.pixelRatio, regions.at(0).getDefinition().pixelRatio); + auto retrievedDefinition = regions.at(0).getDefinition().get>(); + EXPECT_EQ(definition.styleURL, retrievedDefinition.styleURL); + EXPECT_EQ(definition.geometry, retrievedDefinition.geometry); + EXPECT_EQ(definition.minZoom, retrievedDefinition.minZoom); + EXPECT_EQ(definition.maxZoom, retrievedDefinition.maxZoom); + EXPECT_EQ(definition.pixelRatio, retrievedDefinition.pixelRatio); EXPECT_EQ(metadata, regions.at(0).getMetadata()); } @@ -298,24 +300,25 @@ TEST(OfflineDatabase, GetRegionDefinition) { using namespace mbgl; OfflineDatabase db(":memory:"); - OfflineRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), 5, 6, 2.0 }; + OfflineFixedGeometryRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), {5, 6}, 2.0 }; OfflineRegionMetadata metadata {{ 1, 2, 3 }}; OfflineRegion region = db.createRegion(definition, metadata); - OfflineRegionDefinition result = db.getRegionDefinition(region.getID()); + OfflineFixedGeometryRegionDefinition result = db.getRegionDefinition(region.getID()).get>(); EXPECT_EQ(definition.styleURL, result.styleURL); - EXPECT_EQ(definition.bounds, result.bounds); + EXPECT_EQ(definition.geometry, result.geometry); EXPECT_EQ(definition.minZoom, result.minZoom); EXPECT_EQ(definition.maxZoom, result.maxZoom); EXPECT_EQ(definition.pixelRatio, result.pixelRatio); + EXPECT_EQ(metadata, region.getMetadata()); } TEST(OfflineDatabase, DeleteRegion) { using namespace mbgl; OfflineDatabase db(":memory:"); - OfflineRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), 5, 6, 2.0 }; + OfflineFixedGeometryRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), {5, 6}, 2.0 }; OfflineRegionMetadata metadata {{ 1, 2, 3 }}; OfflineRegion region = db.createRegion(definition, metadata); @@ -334,12 +337,12 @@ TEST(OfflineDatabase, CreateRegionInfiniteMaxZoom) { using namespace mbgl; OfflineDatabase db(":memory:"); - OfflineRegionDefinition definition { "", LatLngBounds::world(), 0, INFINITY, 1.0 }; + OfflineFixedGeometryRegionDefinition definition { "", LatLngBounds::world(), {0, INFINITY}, 1.0 }; OfflineRegionMetadata metadata; OfflineRegion region = db.createRegion(definition, metadata); - EXPECT_EQ(0, region.getDefinition().minZoom); - EXPECT_EQ(INFINITY, region.getDefinition().maxZoom); + EXPECT_EQ(0, region.getDefinition().get>().minZoom); + EXPECT_EQ(INFINITY, region.getDefinition().get>().maxZoom); } TEST(OfflineDatabase, TEST_REQUIRES_WRITE(ConcurrentUse)) { @@ -423,7 +426,7 @@ TEST(OfflineDatabase, PutRegionResourceDoesNotEvict) { using namespace mbgl; OfflineDatabase db(":memory:", 1024 * 100); - OfflineRegionDefinition definition { "", LatLngBounds::world(), 0, INFINITY, 1.0 }; + OfflineFixedGeometryRegionDefinition definition { "", LatLngBounds::world(), {0, INFINITY }, 1.0 }; OfflineRegion region = db.createRegion(definition, OfflineRegionMetadata()); Response response; @@ -453,7 +456,7 @@ TEST(OfflineDatabase, GetRegionCompletedStatus) { using namespace mbgl; OfflineDatabase db(":memory:"); - OfflineRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), 5, 6, 2.0 }; + OfflineFixedGeometryRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), {5, 6}, 2.0 }; OfflineRegionMetadata metadata; OfflineRegion region = db.createRegion(definition, metadata); @@ -487,7 +490,7 @@ TEST(OfflineDatabase, OfflineMapboxTileCount) { using namespace mbgl; OfflineDatabase db(":memory:"); - OfflineRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), 5, 6, 2.0 }; + OfflineFixedGeometryRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), {5, 6}, 2.0 }; OfflineRegionMetadata metadata; OfflineRegion region1 = db.createRegion(definition, metadata); diff --git a/test/storage/offline_download.cpp b/test/storage/offline_download.cpp index eb676e3b8d..43eb1db9b6 100644 --- a/test/storage/offline_download.cpp +++ b/test/storage/offline_download.cpp @@ -14,6 +14,8 @@ using namespace mbgl; using namespace std::literals::string_literals; +using OfflineTilePyramidRegionDefinition = OfflineFixedGeometryRegionDefinition; + class MockObserver : public OfflineRegionObserver { public: void statusChanged(OfflineRegionStatus status) override { @@ -41,7 +43,7 @@ public: std::size_t size = 0; OfflineRegion createRegion() { - OfflineRegionDefinition definition { "", LatLngBounds::hull({1, 2}, {3, 4}), 5, 6, 1.0 }; + OfflineTilePyramidRegionDefinition definition { "", LatLngBounds::hull({1, 2}, {3, 4}), {5, 6}, 1.0 }; OfflineRegionMetadata metadata; return db.createRegion(definition, metadata); } @@ -61,7 +63,7 @@ TEST(OfflineDownload, NoSubresources) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); test.fileSource.styleResponse = [&] (const Resource& resource) { @@ -101,7 +103,7 @@ TEST(OfflineDownload, InlineSource) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); test.fileSource.styleResponse = [&] (const Resource& resource) { @@ -141,7 +143,7 @@ TEST(OfflineDownload, GeoJSONSource) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); test.fileSource.styleResponse = [&] (const Resource& resource) { @@ -176,7 +178,7 @@ TEST(OfflineDownload, Activate) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); test.fileSource.styleResponse = [&] (const Resource& resource) { @@ -245,7 +247,7 @@ TEST(OfflineDownload, GetStatusNoResources) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); OfflineRegionStatus status = download.getStatus(); @@ -262,7 +264,7 @@ TEST(OfflineDownload, GetStatusStyleComplete) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); test.db.putRegionResource(1, @@ -284,7 +286,7 @@ TEST(OfflineDownload, GetStatusStyleAndSourceComplete) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); test.db.putRegionResource(1, @@ -310,7 +312,7 @@ TEST(OfflineDownload, RequestError) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); test.fileSource.styleResponse = [&] (const Resource&) { @@ -338,7 +340,7 @@ TEST(OfflineDownload, RequestErrorsAreRetried) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); test.fileSource.styleResponse = [&] (const Resource&) { @@ -371,7 +373,7 @@ TEST(OfflineDownload, TileCountLimitExceededNoTileResponse) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); uint64_t tileLimit = 0; @@ -413,7 +415,7 @@ TEST(OfflineDownload, TileCountLimitExceededWithTileResponse) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); uint64_t tileLimit = 1; @@ -467,7 +469,7 @@ TEST(OfflineDownload, WithPreviouslyExistingTile) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); test.fileSource.styleResponse = [&] (const Resource& resource) { @@ -501,7 +503,7 @@ TEST(OfflineDownload, ReactivatePreviouslyCompletedDownload) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); test.fileSource.styleResponse = [&] (const Resource& resource) { @@ -527,7 +529,7 @@ TEST(OfflineDownload, ReactivatePreviouslyCompletedDownload) { OfflineDownload redownload( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); std::vector statusesAfterReactivate; @@ -568,7 +570,7 @@ TEST(OfflineDownload, Deactivate) { OfflineRegion region = test.createRegion(); OfflineDownload download( region.getID(), - OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), 0.0, 0.0, 1.0), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/style.json", LatLngBounds::world(), {0.0, 0.0}, 1.0), test.db, test.fileSource); test.fileSource.styleResponse = [&] (const Resource& resource) { -- cgit v1.2.1