diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/fixtures/offline_database/satellite_test.db | bin | 0 -> 114688 bytes | |||
-rw-r--r-- | test/gl/bucket.test.cpp | 3 | ||||
-rw-r--r-- | test/storage/offline_database.test.cpp | 81 | ||||
-rw-r--r-- | test/storage/sqlite.test.cpp | 47 | ||||
-rw-r--r-- | test/style/expression/expression.test.cpp | 8 | ||||
-rw-r--r-- | test/text/cross_tile_symbol_index.test.cpp | 24 | ||||
-rw-r--r-- | test/util/tile_cover.test.cpp | 232 | ||||
-rw-r--r-- | test/util/tile_range.test.cpp | 8 |
8 files changed, 328 insertions, 75 deletions
diff --git a/test/fixtures/offline_database/satellite_test.db b/test/fixtures/offline_database/satellite_test.db Binary files differnew file mode 100644 index 0000000000..95dd8617ff --- /dev/null +++ b/test/fixtures/offline_database/satellite_test.db diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index 8393fd130d..9b28b2e01a 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -110,10 +110,11 @@ TEST(Buckets, SymbolBucket) { bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; + std::string bucketLeaderID = "test"; std::vector<SymbolInstance> symbolInstances; gl::Context context; - SymbolBucket bucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, std::move(symbolInstances) }; + SymbolBucket bucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(symbolInstances) }; ASSERT_FALSE(bucket.hasIconData()); ASSERT_FALSE(bucket.hasTextData()); ASSERT_FALSE(bucket.hasCollisionBoxData()); diff --git a/test/storage/offline_database.test.cpp b/test/storage/offline_database.test.cpp index 94daf59c02..656231eebe 100644 --- a/test/storage/offline_database.test.cpp +++ b/test/storage/offline_database.test.cpp @@ -38,6 +38,10 @@ void writeFile(const char* name, const std::string& data) { mbgl::util::write_file(name, data); } +void copyFile(const char* orig, const char* dest) { + mbgl::util::write_file(dest, mbgl::util::read_file(orig)); +} + } // namespace TEST(OfflineDatabase, TEST_REQUIRES_WRITE(Create)) { @@ -62,7 +66,7 @@ TEST(OfflineDatabase, TEST_REQUIRES_WRITE(SchemaVersion)) { std::string path("test/fixtures/offline_database/offline.db"); { - mapbox::sqlite::Database db(path, mapbox::sqlite::Create | mapbox::sqlite::ReadWrite); + mapbox::sqlite::Database db = mapbox::sqlite::Database::open(path, mapbox::sqlite::Create | mapbox::sqlite::ReadWrite); db.exec("PRAGMA user_version = 1"); } @@ -143,6 +147,36 @@ TEST(OfflineDatabase, PutResource) { EXPECT_EQ("second", *updateGetResult->data); } +TEST(OfflineDatabase, TEST_REQUIRES_WRITE(GetResourceFromOfflineRegion)) { + using namespace mbgl; + + createDir("test/fixtures/offline_database"); + deleteFile("test/fixtures/offline_database/satellite.db"); + copyFile("test/fixtures/offline_database/satellite_test.db", "test/fixtures/offline_database/satellite.db"); + + OfflineDatabase db("test/fixtures/offline_database/satellite.db", mapbox::sqlite::ReadOnly); + + Resource resource = Resource::style("mapbox://styles/mapbox/satellite-v9"); + ASSERT_TRUE(db.get(resource)); +} + +TEST(OfflineDatabase, PutAndGetResource) { + using namespace mbgl; + + OfflineDatabase db(":memory:"); + + Response response1; + response1.data = std::make_shared<std::string>("foobar"); + + Resource resource = Resource::style("mapbox://example.com/style"); + + db.put(resource, response1); + + auto response2 = db.get(resource); + + ASSERT_EQ(*response1.data, *(*response2).data); +} + TEST(OfflineDatabase, PutTile) { using namespace mbgl; @@ -565,40 +599,45 @@ TEST(OfflineDatabase, OfflineMapboxTileCount) { } static int databasePageCount(const std::string& path) { - mapbox::sqlite::Database db(path, mapbox::sqlite::ReadOnly); - mapbox::sqlite::Statement stmt = db.prepare("pragma page_count"); - stmt.run(); - return stmt.get<int>(0); + mapbox::sqlite::Database db = mapbox::sqlite::Database::open(path, mapbox::sqlite::ReadOnly); + mapbox::sqlite::Statement stmt{ db, "pragma page_count" }; + mapbox::sqlite::Query query{ stmt }; + query.run(); + return query.get<int>(0); } static int databaseUserVersion(const std::string& path) { - mapbox::sqlite::Database db(path, mapbox::sqlite::ReadOnly); - mapbox::sqlite::Statement stmt = db.prepare("pragma user_version"); - stmt.run(); - return stmt.get<int>(0); + mapbox::sqlite::Database db = mapbox::sqlite::Database::open(path, mapbox::sqlite::ReadOnly); + mapbox::sqlite::Statement stmt{ db, "pragma user_version" }; + mapbox::sqlite::Query query{ stmt }; + query.run(); + return query.get<int>(0); } static std::string databaseJournalMode(const std::string& path) { - mapbox::sqlite::Database db(path, mapbox::sqlite::ReadOnly); - mapbox::sqlite::Statement stmt = db.prepare("pragma journal_mode"); - stmt.run(); - return stmt.get<std::string>(0); + mapbox::sqlite::Database db = mapbox::sqlite::Database::open(path, mapbox::sqlite::ReadOnly); + mapbox::sqlite::Statement stmt{ db, "pragma journal_mode" }; + mapbox::sqlite::Query query{ stmt }; + query.run(); + return query.get<std::string>(0); } static int databaseSyncMode(const std::string& path) { - mapbox::sqlite::Database db(path, mapbox::sqlite::ReadOnly); - mapbox::sqlite::Statement stmt = db.prepare("pragma synchronous"); - stmt.run(); - return stmt.get<int>(0); + mapbox::sqlite::Database db = mapbox::sqlite::Database::open(path, mapbox::sqlite::ReadOnly); + mapbox::sqlite::Statement stmt{ db, "pragma synchronous" }; + mapbox::sqlite::Query query{ stmt }; + query.run(); + return query.get<int>(0); } static std::vector<std::string> databaseTableColumns(const std::string& path, const std::string& name) { - mapbox::sqlite::Database db(path, mapbox::sqlite::ReadOnly); + mapbox::sqlite::Database db = mapbox::sqlite::Database::open(path, mapbox::sqlite::ReadOnly); const auto sql = std::string("pragma table_info(") + name + ")"; - mapbox::sqlite::Statement stmt = db.prepare(sql.c_str()); + mapbox::sqlite::Statement stmt{ db, sql.c_str() }; + mapbox::sqlite::Query query{ stmt }; std::vector<std::string> columns; - while (stmt.run()) { - columns.push_back(stmt.get<std::string>(1)); + while (query.run()) { + columns.push_back(query.get<std::string>(1)); } return columns; } diff --git a/test/storage/sqlite.test.cpp b/test/storage/sqlite.test.cpp index 36715a2fd0..553736a0b1 100644 --- a/test/storage/sqlite.test.cpp +++ b/test/storage/sqlite.test.cpp @@ -6,33 +6,32 @@ TEST(SQLite, Statement) { using namespace mbgl; - mapbox::sqlite::Database db(":memory:", mapbox::sqlite::Create | mapbox::sqlite::ReadWrite); + mapbox::sqlite::Database db = mapbox::sqlite::Database::open(":memory:", mapbox::sqlite::Create | mapbox::sqlite::ReadWrite); db.exec("CREATE TABLE test (id INTEGER);"); - mapbox::sqlite::Statement stmt1 = db.prepare("INSERT INTO test (id) VALUES (?1);"); - ASSERT_EQ(stmt1.lastInsertRowId(), 0); - ASSERT_EQ(stmt1.changes(), 0u); - stmt1.bind(1, 10); - stmt1.run(); - ASSERT_EQ(stmt1.lastInsertRowId(), 1); - ASSERT_EQ(stmt1.changes(), 1u); + mapbox::sqlite::Statement stmt1{ db, "INSERT INTO test (id) VALUES (?1);" }; + mapbox::sqlite::Query query1{ stmt1 }; + ASSERT_EQ(query1.lastInsertRowId(), 0); + ASSERT_EQ(query1.changes(), 0u); + query1.bind(1, 10); + query1.run(); + ASSERT_EQ(query1.lastInsertRowId(), 1); + ASSERT_EQ(query1.changes(), 1u); - mapbox::sqlite::Statement stmt2 = db.prepare("INSERT INTO test (id) VALUES (?1);"); - ASSERT_EQ(stmt2.lastInsertRowId(), 0); - ASSERT_EQ(stmt2.changes(), 0u); - stmt2.bind(1, 20); - stmt2.run(); - ASSERT_EQ(stmt2.lastInsertRowId(), 2); - ASSERT_EQ(stmt2.changes(), 1u); + mapbox::sqlite::Statement stmt2{ db, "INSERT INTO test (id) VALUES (?1);" }; + mapbox::sqlite::Query query2{ stmt2 }; + ASSERT_EQ(query2.lastInsertRowId(), 0); + ASSERT_EQ(query2.changes(), 0u); + query2.bind(1, 20); + query2.run(); + ASSERT_EQ(query2.lastInsertRowId(), 2); + ASSERT_EQ(query2.changes(), 1u); } -TEST(SQLite, TEST_REQUIRES_WRITE(CantOpenException)) { - try { - // Should throw a CANTOPEN when the database doesn't exist, - // make sure all the backends behave the same way. - mapbox::sqlite::Database("test/fixtures/offline_database/foobar123.db", mapbox::sqlite::ReadOnly); - FAIL(); - } catch (mapbox::sqlite::Exception& ex) { - ASSERT_EQ(ex.code, mapbox::sqlite::Exception::Code::CANTOPEN); - } +TEST(SQLite, TEST_REQUIRES_WRITE(TryOpen)) { + // Should return a CANTOPEN exception when the database doesn't exist, + // make sure all the backends behave the same way. + auto result = mapbox::sqlite::Database::tryOpen("test/fixtures/offline_database/foobar123.db", mapbox::sqlite::ReadOnly); + ASSERT_TRUE(result.is<mapbox::sqlite::Exception>()); + ASSERT_EQ(result.get<mapbox::sqlite::Exception>().code, mapbox::sqlite::ResultCode::CantOpen); } diff --git a/test/style/expression/expression.test.cpp b/test/style/expression/expression.test.cpp index fe5c261be1..709624a50f 100644 --- a/test/style/expression/expression.test.cpp +++ b/test/style/expression/expression.test.cpp @@ -24,11 +24,15 @@ TEST(Expression, IsExpression) { spec["expression_name"].IsObject() && spec["expression_name"].HasMember("values") && spec["expression_name"]["values"].IsObject()); - + const auto& allExpressions = spec["expression_name"]["values"]; - + for(auto& entry : allExpressions.GetObject()) { const std::string name { entry.name.GetString(), entry.name.GetStringLength() }; + if (name == "collator" || name == "line-progress" || name == "resolved-locale" || name == "feature-state") { + // Not yet implemented + continue; + } JSDocument document; document.Parse<0>(R"([")" + name + R"("])"); diff --git a/test/text/cross_tile_symbol_index.test.cpp b/test/text/cross_tile_symbol_index.test.cpp index 794c2b59a1..5d255a6105 100644 --- a/test/text/cross_tile_symbol_index.test.cpp +++ b/test/text/cross_tile_symbol_index.test.cpp @@ -25,12 +25,13 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; + std::string bucketLeaderID = "test"; OverscaledTileID mainID(6, 0, 6, 8, 8); std::vector<SymbolInstance> mainInstances; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"Detroit")); mainInstances.push_back(makeSymbolInstance(2000, 2000, u"Toronto")); - SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, std::move(mainInstances) }; + SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances) }; mainBucket.bucketInstanceId = ++maxBucketInstanceId; index.addBucket(mainID, mainBucket, maxCrossTileID); @@ -45,7 +46,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { childInstances.push_back(makeSymbolInstance(2000, 2000, u"Windsor")); childInstances.push_back(makeSymbolInstance(3000, 3000, u"Toronto")); childInstances.push_back(makeSymbolInstance(4001, 4001, u"Toronto")); - SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, std::move(childInstances) }; + SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances) }; childBucket.bucketInstanceId = ++maxBucketInstanceId; index.addBucket(childID, childBucket, maxCrossTileID); @@ -61,7 +62,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { OverscaledTileID parentID(5, 0, 5, 4, 4); std::vector<SymbolInstance> parentInstances; parentInstances.push_back(makeSymbolInstance(500, 500, u"Detroit")); - SymbolBucket parentBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, std::move(parentInstances) }; + SymbolBucket parentBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(parentInstances) }; parentBucket.bucketInstanceId = ++maxBucketInstanceId; index.addBucket(parentID, parentBucket, maxCrossTileID); @@ -77,7 +78,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { std::vector<SymbolInstance> grandchildInstances; grandchildInstances.push_back(makeSymbolInstance(4000, 4000, u"Detroit")); grandchildInstances.push_back(makeSymbolInstance(4000, 4000, u"Windsor")); - SymbolBucket grandchildBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, std::move(grandchildInstances) }; + SymbolBucket grandchildBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(grandchildInstances) }; grandchildBucket.bucketInstanceId = ++maxBucketInstanceId; index.addBucket(grandchildID, grandchildBucket, maxCrossTileID); @@ -98,17 +99,18 @@ TEST(CrossTileSymbolLayerIndex, resetIDs) { bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; + std::string bucketLeaderID = "test"; OverscaledTileID mainID(6, 0, 6, 8, 8); std::vector<SymbolInstance> mainInstances; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"Detroit")); - SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, std::move(mainInstances) }; + SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances) }; mainBucket.bucketInstanceId = ++maxBucketInstanceId; OverscaledTileID childID(7, 0, 7, 16, 16); std::vector<SymbolInstance> childInstances; childInstances.push_back(makeSymbolInstance(2000, 2000, u"Detroit")); - SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, std::move(childInstances) }; + SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances) }; childBucket.bucketInstanceId = ++maxBucketInstanceId; // assigns a new id @@ -137,12 +139,13 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) { bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; + std::string bucketLeaderID = "test"; OverscaledTileID mainID(6, 0, 6, 8, 8); std::vector<SymbolInstance> mainInstances; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // A mainInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // B - SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, std::move(mainInstances) }; + SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances) }; mainBucket.bucketInstanceId = ++maxBucketInstanceId; OverscaledTileID childID(7, 0, 7, 16, 16); @@ -150,7 +153,7 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) { childInstances.push_back(makeSymbolInstance(2000, 2000, u"")); // A' childInstances.push_back(makeSymbolInstance(2000, 2000, u"")); // B' childInstances.push_back(makeSymbolInstance(2000, 2000, u"")); // C' - SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, std::move(childInstances) }; + SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances) }; childBucket.bucketInstanceId = ++maxBucketInstanceId; // assigns new ids @@ -174,19 +177,20 @@ TEST(CrossTileSymbolLayerIndex, bucketReplacement) { bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; + std::string bucketLeaderID = "test"; OverscaledTileID tileID(6, 0, 6, 8, 8); std::vector<SymbolInstance> firstInstances; firstInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // A firstInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // B - SymbolBucket firstBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, std::move(firstInstances) }; + SymbolBucket firstBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(firstInstances) }; firstBucket.bucketInstanceId = ++maxBucketInstanceId; std::vector<SymbolInstance> secondInstances; secondInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // A' secondInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // B' secondInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // C' - SymbolBucket secondBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, std::move(secondInstances) }; + SymbolBucket secondBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(secondInstances) }; secondBucket.bucketInstanceId = ++maxBucketInstanceId; // assigns new ids diff --git a/test/util/tile_cover.test.cpp b/test/util/tile_cover.test.cpp index 933c18b5ea..7defa761af 100644 --- a/test/util/tile_cover.test.cpp +++ b/test/util/tile_cover.test.cpp @@ -2,6 +2,8 @@ #include <mbgl/util/geo.hpp> #include <mbgl/map/transform.hpp> +#include <algorithm> + #include <gtest/gtest.h> using namespace mbgl; @@ -22,8 +24,8 @@ TEST(TileCover, Antarctic) { TEST(TileCover, WorldZ0) { EXPECT_EQ((std::vector<UnwrappedTileID>{ - { 0, 0, 0 }, - }), + { 0, 0, 0 }, + }), util::tileCover(LatLngBounds::world(), 0)); } @@ -37,15 +39,15 @@ TEST(TileCover, Pitch) { transform.setPitch(40.0 * M_PI / 180.0); EXPECT_EQ((std::vector<UnwrappedTileID>{ - { 2, 1, 2 }, { 2, 1, 1 }, { 2, 2, 2 }, { 2, 2, 1 }, { 2, 3, 2 } - }), + { 2, 1, 2 }, { 2, 1, 1 }, { 2, 2, 2 }, { 2, 2, 1 }, { 2, 3, 2 } + }), util::tileCover(transform.getState(), 2)); } TEST(TileCover, WorldZ1) { EXPECT_EQ((std::vector<UnwrappedTileID>{ - { 1, 0, 0 }, { 1, 0, 1 }, { 1, 1, 0 }, { 1, 1, 1 }, - }), + { 1, 0, 0 }, { 1, 0, 1 }, { 1, 1, 0 }, { 1, 1, 1 }, + }), util::tileCover(LatLngBounds::world(), 1)); } @@ -59,21 +61,44 @@ TEST(TileCover, SingletonZ1) { util::tileCover(LatLngBounds::singleton({ 0, 0 }), 1)); } +TEST(TileCoverStream, Arctic) { + auto bounds = LatLngBounds::hull({ 84, -180 }, { 70, 180 }); + auto zoom = 3; + util::TileCover tc(bounds, zoom); + auto results = util::tileCover(bounds, zoom); + std::vector<UnwrappedTileID> t; + while(tc.hasNext()) { + t.push_back(*tc.next()); + }; + EXPECT_EQ(t.size(), results.size()); +} + +TEST(TileCoverStream, WorldZ1) { + auto zoom = 1; + util::TileCover tc(LatLngBounds::world(), zoom); + std::vector<UnwrappedTileID> t; + while(tc.hasNext()) { + t.push_back(*tc.next()); + }; + EXPECT_EQ((std::vector<UnwrappedTileID>{ + { 1, 0, 0 }, { 1, 1, 0 }, { 1, 0, 1 }, { 1, 1, 1 }, + }), t); +} + static const LatLngBounds sanFrancisco = LatLngBounds::hull({ 37.6609, -122.5744 }, { 37.8271, -122.3204 }); TEST(TileCover, SanFranciscoZ0) { EXPECT_EQ((std::vector<UnwrappedTileID>{ - { 0, 0, 0 }, - }), + { 0, 0, 0 }, + }), util::tileCover(sanFrancisco, 0)); } TEST(TileCover, SanFranciscoZ10) { EXPECT_EQ((std::vector<UnwrappedTileID>{ - { 10, 163, 395 }, { 10, 163, 396 }, { 10, 164, 395 }, { 10, 164, 396 }, - - }), + { 10, 163, 395 }, { 10, 163, 396 }, { 10, 164, 395 }, { 10, 164, 396 }, + }), util::tileCover(sanFrancisco, 10)); } @@ -85,11 +110,192 @@ TEST(TileCover, SanFranciscoZ0Wrapped) { util::tileCover(sanFranciscoWrapped, 0)); } +TEST(TileCover, GeomPoint) { + auto point = Point<double>{ -122.5744, 37.6609 }; + + EXPECT_EQ((std::vector<UnwrappedTileID>{ {2 ,0 ,1 } }), + util::tileCover(point, 2)); +} + +TEST(TileCover, GeomMultiPoint) { + auto points = MultiPoint<double>{ { -122.5, 37.76 }, { -122.4, 37.76} }; + + EXPECT_EQ((std::vector<UnwrappedTileID>{ + {20, 167480, 405351}, {20, 167772, 405351} }), + util::tileCover(points, 20)); +} + +TEST(TileCover, GeomLineZ10) { + auto lineCover = util::tileCover(LineString<double>{ + {-121.49368286132812,38.57903714667459}, + {-122.4422836303711,37.773157169570695} + }, 10); + EXPECT_EQ((std::vector<UnwrappedTileID>{ + { 10, 166, 392}, {10, 165, 393}, {10, 166, 393}, + {10, 164, 394}, {10, 165, 394}, {10,163,395}, {10, 164, 395} + }),lineCover); + +} + +TEST(TileCover, WrappedGeomLineZ10) { + auto lineCover = util::tileCover(LineString<double>{ + {-179.93342914581299,38.892101707724315}, + {-180.02394485473633,38.89203490311832} + }, 10); + EXPECT_EQ((std::vector<UnwrappedTileID>{ { 10, -1, 391 }, { 10, 0, 391 } }), + lineCover); + + lineCover = util::tileCover(LineString<double>{ + {179.93342914581299,38.892101707724315}, + {180.02394485473633,38.89203490311832} + }, 10); + EXPECT_EQ((std::vector<UnwrappedTileID>{ { 10, 1023, 391 }, { 10, 1024, 391 } }), + lineCover); +} + +TEST(TileCover, GeomMultiLineString) { + auto geom = MultiLineString<double>{ + { { -122.5, 37.76 }, { -122.4, 37.76} }, + { { -122.5, 37.72 }, { -122.4, 37.72} } }; + + EXPECT_EQ((std::vector<UnwrappedTileID>{ + {14, 2616, 6333}, {14, 2617, 6333}, {14, 2618, 6333}, + {14, 2619, 6333}, {14, 2620, 6333}, {14, 2621, 6333}, + {14, 2616, 6335}, {14, 2617, 6335}, {14, 2618, 6335}, + {14, 2619, 6335}, {14, 2620, 6335}, {14, 2621, 6335}}), + util::tileCover(geom, 14)); +} + +TEST(TileCover, GeomPolygon) { + auto polygon = Polygon<double>{ + { + {5.09765625,53.067626642387374}, + {2.373046875,43.389081939117496}, + {-4.74609375,48.45835188280866}, + {-1.494140625,37.09023980307208}, + {22.587890625,36.24427318493909}, + {31.640625,46.13417004624326}, + {17.841796875,54.7246201949245}, + {5.09765625,53.067626642387374}, + },{ + {19.6875,49.66762782262194}, + {22.8515625,43.51668853502906}, + {13.623046875,45.089035564831036}, + {16.34765625,39.095962936305476}, + {5.185546875,41.244772343082076}, + {8.701171874999998,50.233151832472245}, + {19.6875,49.66762782262194} + } + }; + + auto results = util::tileCover(polygon, 8); + + EXPECT_NE(std::find(results.begin(), results.end(), UnwrappedTileID{8, 134, 87}), results.end()); + EXPECT_NE(std::find(results.begin(), results.end(), UnwrappedTileID{8, 139, 87}), results.end()); + // Should have a hole + EXPECT_EQ(std::find(results.begin(), results.end(), UnwrappedTileID{8, 136, 87}), results.end()); +} + +TEST(TileCover, GeomMultiPolygon) { + auto multiPolygon = MultiPolygon<double>{ + {{ + {5.09765625,53.067626642387374}, + {2.373046875,43.389081939117496}, + {-4.74609375,48.45835188280866}, + {-1.494140625,37.09023980307208}, + {22.587890625,36.24427318493909}, + {31.640625,46.13417004624326}, + {17.841796875,54.7246201949245}, + {5.09765625,53.067626642387374}, + }},{{ + {59.150390625,45.460130637921004}, + {65.126953125,41.11246878918088}, + {69.169921875,47.45780853075031}, + {63.896484375,50.064191736659104}, + {59.150390625,45.460130637921004} + }} + }; + auto results = util::tileCover(multiPolygon, 8); + + EXPECT_EQ(424u, results.size()); + EXPECT_NE(std::find(results.begin(), results.end(), UnwrappedTileID{8, 139, 87}), results.end()); + EXPECT_NE(std::find(results.begin(), results.end(), UnwrappedTileID{8, 136, 87}), results.end()); + EXPECT_NE(std::find(results.begin(), results.end(), UnwrappedTileID{8, 174, 94}), results.end()); +} + +TEST(TileCover, GeomSanFranciscoPoly) { + auto sanFranciscoGeom = Polygon<double>{ + { + {-122.5143814086914,37.779127216982424}, + {-122.50811576843262,37.72721239056709}, + {-122.50313758850099,37.70820178063929}, + {-122.3938751220703,37.707454835665274}, + {-122.37567901611328,37.70663997801684}, + {-122.36297607421874,37.71343018466285}, + {-122.354736328125,37.727280276860036}, + {-122.36469268798828,37.73868429065797}, + {-122.38014221191408,37.75442980295571}, + {-122.38391876220702,37.78753873820529}, + {-122.35919952392578,37.8065289741725}, + {-122.35679626464844,37.820632846207864}, + {-122.3712158203125,37.835276322922695}, + {-122.3818588256836,37.82958198283902}, + {-122.37190246582031,37.80788523279169}, + {-122.38735198974608,37.791337175930686}, + {-122.40966796874999,37.812767557570204}, + {-122.46425628662108,37.807071480609274}, + {-122.46803283691405,37.810326435534755}, + {-122.47901916503906,37.81168262440736}, + {-122.48966217041016,37.78916666399649}, + {-122.50579833984375,37.78781006166096}, + {-122.5143814086914,37.779127216982424} + } + }; + + EXPECT_EQ((std::vector<UnwrappedTileID>{ + { 12, 654, 1582 }, { 12, 655, 1582 }, + { 12, 654, 1583 }, { 12, 655, 1583 }, + { 12, 654, 1584 }, { 12, 655, 1584 } + }), util::tileCover(sanFranciscoGeom, 12)); +} + +TEST(TileCover, GeomInvalid) { + auto point = Point<double>{ -122.5744, 97.6609 }; + EXPECT_THROW(util::tileCover(point, 2), std::domain_error); + + auto badPoly = Polygon<double> { { {1.0, 35.0} } }; + EXPECT_EQ((std::vector<UnwrappedTileID>{ }), util::tileCover(badPoly, 16)); + + //Should handle open polygons. + badPoly = Polygon<double> { { {1.0, 34.2}, {1.0, 34.4}, {0.5, 34.3} } }; + EXPECT_EQ((std::vector<UnwrappedTileID>{ + { 10, 513, 407 }, { 10, 514, 407}, + { 10, 513, 408 }, { 10, 514, 408} + }), util::tileCover(badPoly, 10)); +} + + +TEST(TileCount, World) { + EXPECT_EQ(1u, util::tileCount(LatLngBounds::world(), 0)); + EXPECT_EQ(4u, util::tileCount(LatLngBounds::world(), 1)); +} + TEST(TileCount, SanFranciscoZ10) { - EXPECT_EQ(4u, util::tileCount(sanFrancisco, 10, util::tileSize)); + EXPECT_EQ(4u, util::tileCount(sanFrancisco, 10)); +} + +TEST(TileCount, SanFranciscoWrappedZ10) { + EXPECT_EQ(4u, util::tileCount(sanFranciscoWrapped, 10)); } TEST(TileCount, SanFranciscoZ22) { - EXPECT_EQ(7254450u, util::tileCount(sanFrancisco, 22, util::tileSize)); + EXPECT_EQ(7254450u, util::tileCount(sanFrancisco, 22)); } +TEST(TileCount, BoundsCrossingAntimeridian) { + auto crossingBounds = LatLngBounds::hull({-20.9615, -214.309}, {19.477, -155.830}); + + EXPECT_EQ(1u, util::tileCount(crossingBounds, 0)); + EXPECT_EQ(4u, util::tileCount(crossingBounds, 3)); + EXPECT_EQ(8u, util::tileCount(crossingBounds, 4)); +} diff --git a/test/util/tile_range.test.cpp b/test/util/tile_range.test.cpp index c4c37c74d7..83ac5096a5 100644 --- a/test/util/tile_range.test.cpp +++ b/test/util/tile_range.test.cpp @@ -52,14 +52,14 @@ TEST(TileRange, ContainsWrappedBounds) { TEST(TileRange, ContainsBoundsCrossingAntimeridian) { { - auto cossingBounds = LatLngBounds::hull({-20.9615, -214.309}, {19.477, -155.830}); - auto range = util::TileRange::fromLatLngBounds(cossingBounds, 1); + auto crossingBounds = LatLngBounds::hull({-20.9615, -214.309}, {19.477, -155.830}); + auto range = util::TileRange::fromLatLngBounds(crossingBounds, 1); EXPECT_TRUE(range.contains(CanonicalTileID(1, 1, 1))); EXPECT_TRUE(range.contains(CanonicalTileID(1, 0, 0))); } { - auto cossingBounds = LatLngBounds::hull({-20.9615, -214.309}, {19.477, -155.830}); - auto range = util::TileRange::fromLatLngBounds(cossingBounds, 6); + auto crossingBounds = LatLngBounds::hull({-20.9615, -214.309}, {19.477, -155.830}); + auto range = util::TileRange::fromLatLngBounds(crossingBounds, 6); EXPECT_FALSE(range.contains(CanonicalTileID(6, 55, 34))); EXPECT_FALSE(range.contains(CanonicalTileID(6, 5, 28))); EXPECT_TRUE(range.contains(CanonicalTileID(6, 63, 28))); |