aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-01-13 22:17:08 +0100
committerEven Rouault <even.rouault@spatialys.com>2020-01-14 22:42:18 +0100
commit034238e5014ae965a7dbd1e2bf26f7227196e987 (patch)
tree6e98016cddec4ac673ae03064491ff69b37e3516
parent0961d15ac13620beef2f7600974afe8e4d011972 (diff)
downloadPROJ-034238e5014ae965a7dbd1e2bf26f7227196e987.tar.gz
PROJ-034238e5014ae965a7dbd1e2bf26f7227196e987.zip
Fix reading resources from user-writable directory & test it
-rw-r--r--src/filemanager.cpp30
-rw-r--r--test/unit/test_network.cpp48
2 files changed, 63 insertions, 15 deletions
diff --git a/src/filemanager.cpp b/src/filemanager.cpp
index 277578d1..d2fce822 100644
--- a/src/filemanager.cpp
+++ b/src/filemanager.cpp
@@ -3294,9 +3294,39 @@ static void *pj_open_file_with_manager(projCtx ctx, const char *name,
std::unique_ptr<NS_PROJ::File>
NS_PROJ::FileManager::open_resource_file(projCtx ctx, const char *name) {
+
+ if (ctx == nullptr) {
+ ctx = pj_get_default_ctx();
+ }
+
auto file = std::unique_ptr<NS_PROJ::File>(
reinterpret_cast<NS_PROJ::File *>(pj_open_lib_internal(
ctx, name, "rb", pj_open_file_with_manager, nullptr, 0)));
+
+ // Retry with a .tif extension if the file name doesn't end with .tif
+ if (file == nullptr && !is_tilde_slash(name) &&
+ !is_rel_or_absolute_filename(name) && !starts_with(name, "http://") &&
+ !starts_with(name, "https://") && strcmp(name, "proj.db") != 0 &&
+ strstr(name, ".tif") == nullptr) {
+ std::string filename(name);
+ auto pos = filename.rfind('.');
+ if (pos + 4 == filename.size()) {
+ filename = filename.substr(0, pos) + ".tif";
+ file.reset(reinterpret_cast<NS_PROJ::File *>(
+ pj_open_lib_internal(ctx, filename.c_str(), "rb",
+ pj_open_file_with_manager, nullptr, 0)));
+ } else {
+ // For example for resource files like 'alaska'
+ filename += ".tif";
+ file.reset(reinterpret_cast<NS_PROJ::File *>(
+ pj_open_lib_internal(ctx, filename.c_str(), "rb",
+ pj_open_file_with_manager, nullptr, 0)));
+ }
+ if (file) {
+ pj_ctx_set_errno(ctx, 0);
+ }
+ }
+
if (file == nullptr && !is_tilde_slash(name) &&
!is_rel_or_absolute_filename(name) && !starts_with(name, "http://") &&
!starts_with(name, "https://") && pj_context_is_network_enabled(ctx)) {
diff --git a/test/unit/test_network.cpp b/test/unit/test_network.cpp
index 4e66d8c5..e959fd54 100644
--- a/test/unit/test_network.cpp
+++ b/test/unit/test_network.cpp
@@ -1574,27 +1574,45 @@ TEST(networking, download_whole_files) {
proj_cleanup();
unlink("proj_test_tmp/cache.db");
- unlink("proj_test_tmp/ntf_r93.tif");
+ unlink("proj_test_tmp/dvr90.tif");
rmdir("proj_test_tmp");
putenv(const_cast<char *>("PROJ_IGNORE_USER_WRITABLE_DIRECTORY="));
putenv(const_cast<char *>("PROJ_USER_WRITABLE_DIRECTORY=./proj_test_tmp"));
- putenv(const_cast<char *>("PROJ_FULL_FILE_CHUNK_SIZE=30000"));
+ putenv(const_cast<char *>("PROJ_FULL_FILE_CHUNK_SIZE=100000"));
auto ctx = proj_context_create();
proj_context_set_enable_network(ctx, true);
- ASSERT_TRUE(proj_is_download_needed(ctx, "ntf_r93.gsb", false));
+ ASSERT_TRUE(proj_is_download_needed(ctx, "dvr90.gtx", false));
- ASSERT_TRUE(
- proj_download_file(ctx, "ntf_r93.gsb", false, nullptr, nullptr));
+ ASSERT_TRUE(proj_download_file(ctx, "dvr90.gtx", false, nullptr, nullptr));
- FILE *f = fopen("proj_test_tmp/ntf_r93.tif", "rb");
+ FILE *f = fopen("proj_test_tmp/dvr90.tif", "rb");
ASSERT_NE(f, nullptr);
- fseek(f, 0, SEEK_END);
- ASSERT_EQ(ftell(f), 93581);
fclose(f);
- ASSERT_FALSE(proj_is_download_needed(ctx, "ntf_r93.gsb", false));
+ proj_context_set_enable_network(ctx, false);
+
+ const char *pipeline =
+ "+proj=pipeline "
+ "+step +proj=unitconvert +xy_in=deg +xy_out=rad "
+ "+step +proj=vgridshift +grids=dvr90.gtx +multiplier=1 "
+ "+step +proj=unitconvert +xy_in=rad +xy_out=deg";
+
+ auto P = proj_create(ctx, pipeline);
+ ASSERT_NE(P, nullptr);
+
+ double lon = 12;
+ double lat = 56;
+ double z = 0;
+ proj_trans_generic(P, PJ_FWD, &lon, sizeof(double), 1, &lat, sizeof(double),
+ 1, &z, sizeof(double), 1, nullptr, 0, 0);
+ EXPECT_NEAR(z, 36.5909996032715, 1e-10);
+ proj_destroy(P);
+
+ proj_context_set_enable_network(ctx, true);
+
+ ASSERT_FALSE(proj_is_download_needed(ctx, "dvr90.gtx", false));
{
sqlite3 *hDB = nullptr;
@@ -1613,7 +1631,7 @@ TEST(networking, download_whole_files) {
}
// If we ignore TTL settings, then no network access will be done
- ASSERT_FALSE(proj_is_download_needed(ctx, "ntf_r93.gsb", true));
+ ASSERT_FALSE(proj_is_download_needed(ctx, "dvr90.gtx", true));
{
sqlite3 *hDB = nullptr;
@@ -1633,7 +1651,7 @@ TEST(networking, download_whole_files) {
}
// Should recheck from the CDN, update last_checked and do nothing
- ASSERT_FALSE(proj_is_download_needed(ctx, "ntf_r93.gsb", false));
+ ASSERT_FALSE(proj_is_download_needed(ctx, "dvr90.gtx", false));
{
sqlite3 *hDB = nullptr;
@@ -1662,10 +1680,10 @@ TEST(networking, download_whole_files) {
sqlite3_close(hDB);
}
- ASSERT_TRUE(proj_is_download_needed(ctx, "ntf_r93.gsb", false));
+ ASSERT_TRUE(proj_is_download_needed(ctx, "dvr90.gtx", false));
// Redo download with a progress callback this time.
- unlink("proj_test_tmp/ntf_r93.tif");
+ unlink("proj_test_tmp/dvr90.tif");
const auto cbk = [](PJ_CONTEXT *l_ctx, double pct, void *user_data) -> int {
auto vect = static_cast<std::vector<std::pair<PJ_CONTEXT *, double>> *>(
@@ -1675,7 +1693,7 @@ TEST(networking, download_whole_files) {
};
std::vector<std::pair<PJ_CONTEXT *, double>> vectPct;
- ASSERT_TRUE(proj_download_file(ctx, "ntf_r93.gsb", false, cbk, &vectPct));
+ ASSERT_TRUE(proj_download_file(ctx, "dvr90.gtx", false, cbk, &vectPct));
ASSERT_EQ(vectPct.size(), 3U);
ASSERT_EQ(vectPct.back().first, ctx);
ASSERT_EQ(vectPct.back().second, 1.0);
@@ -1685,7 +1703,7 @@ TEST(networking, download_whole_files) {
putenv(const_cast<char *>("PROJ_USER_WRITABLE_DIRECTORY="));
putenv(const_cast<char *>("PROJ_FULL_FILE_CHUNK_SIZE="));
unlink("proj_test_tmp/cache.db");
- unlink("proj_test_tmp/ntf_r93.tif");
+ unlink("proj_test_tmp/dvr90.tif");
rmdir("proj_test_tmp");
}