From ea7216641b25c8a2168ab970ae16efc1320cb04c Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Mon, 27 Oct 2014 16:00:16 -0700 Subject: [PATCH] If the requested tile doesn't exist, try climbing up to a lower zoom --- decode.cc | 50 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/decode.cc b/decode.cc index 5fc539d..5a57d90 100644 --- a/decode.cc +++ b/decode.cc @@ -105,32 +105,46 @@ void handle(std::string message, int z, unsigned x, unsigned y) { void decode(char *fname, int z, unsigned x, unsigned y) { sqlite3 *db; + int oz = z; + unsigned ox = x, oy = y; if (sqlite3_open(fname, &db) != SQLITE_OK) { fprintf(stderr, "%s: %s\n", fname, sqlite3_errmsg(db)); exit(EXIT_FAILURE); } - const char *sql = "SELECT tile_data from tiles where zoom_level = ? and tile_column = ? and tile_row = ?;"; - sqlite3_stmt *stmt; - if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) { - fprintf(stderr, "%s: select failed: %s\n", fname, sqlite3_errmsg(db)); - exit(EXIT_FAILURE); + int handled = 0; + while (z >= 0 && !handled) { + const char *sql = "SELECT tile_data from tiles where zoom_level = ? and tile_column = ? and tile_row = ?;"; + sqlite3_stmt *stmt; + if (sqlite3_prepare_v2(db, sql, -1, &stmt, NULL) != SQLITE_OK) { + fprintf(stderr, "%s: select failed: %s\n", fname, sqlite3_errmsg(db)); + exit(EXIT_FAILURE); + } + + sqlite3_bind_int(stmt, 1, z); + sqlite3_bind_int(stmt, 2, x); + sqlite3_bind_int(stmt, 3, (1LL << z) - 1 - y); + + while (sqlite3_step(stmt) == SQLITE_ROW) { + int len = sqlite3_column_bytes(stmt, 0); + const char *s = (const char *) sqlite3_column_blob(stmt, 0); + + if (z != oz) { + fprintf(stderr, "%s: Warning: using tile %d/%u/%u instead of %d/%u/%u\n", fname, z, x, y, oz, ox, oy); + } + + handle(std::string(s, len), z, x, y); + handled = 1; + } + + sqlite3_finalize(stmt); + + z--; + x /= 2; + y /= 2; } - sqlite3_bind_int(stmt, 1, z); - sqlite3_bind_int(stmt, 2, x); - sqlite3_bind_int(stmt, 3, (1LL << z) - 1 - y); - - while (sqlite3_step(stmt) == SQLITE_ROW) { - int len = sqlite3_column_bytes(stmt, 0); - const char *s = (const char *) sqlite3_column_blob(stmt, 0); - - handle(std::string(s, len), z, x, y); - } - - sqlite3_finalize(stmt); - if (sqlite3_close(db) != SQLITE_OK) { fprintf(stderr, "%s: could not close database: %s\n", fname, sqlite3_errmsg(db)); exit(EXIT_FAILURE);