Skip to content

Commit

Permalink
Merge pull request #4334 from rouault/createFromPROJString_optims
Browse files Browse the repository at this point in the history
createFromPROJString: avoid repeated openings of proj.db and proj.ini and lookup of 'epsg'
  • Loading branch information
rouault authored Dec 2, 2024
2 parents 7fbd2ce + 9ab0f64 commit 2dc4914
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/ctx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ projCppContext *pj_ctx::get_cpp_context() {
/************************************************************************/

void pj_ctx::set_search_paths(const std::vector<std::string> &search_paths_in) {
lookupedFiles.clear();
search_paths = search_paths_in;
delete[] c_compat_paths;
c_compat_paths = nullptr;
Expand Down
15 changes: 15 additions & 0 deletions src/filemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1779,6 +1779,16 @@ NS_PROJ::FileManager::open_resource_file(PJ_CONTEXT *ctx, const char *name,
*/
int pj_find_file(PJ_CONTEXT *ctx, const char *short_filename,
char *out_full_filename, size_t out_full_filename_size) {
const auto iter = ctx->lookupedFiles.find(short_filename);
if (iter != ctx->lookupedFiles.end()) {
if (iter->second.empty()) {
out_full_filename[0] = 0;
return 0;
}
snprintf(out_full_filename, out_full_filename_size, "%s",
iter->second.c_str());
return 1;
}
const bool old_network_enabled =
proj_context_is_network_enabled(ctx) != FALSE;
if (old_network_enabled)
Expand All @@ -1787,6 +1797,11 @@ int pj_find_file(PJ_CONTEXT *ctx, const char *short_filename,
ctx, short_filename, out_full_filename, out_full_filename_size);
if (old_network_enabled)
proj_context_set_enable_network(ctx, true);
if (file) {
ctx->lookupedFiles[short_filename] = out_full_filename;
} else {
ctx->lookupedFiles[short_filename] = std::string();
}
return file != nullptr;
}

Expand Down
42 changes: 23 additions & 19 deletions src/iso19111/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12244,25 +12244,35 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
if (d->steps_.size() == 1 && d->steps_[0].isInit &&
!d->steps_[0].inverted) {

auto ctx = d->ctx_ ? d->ctx_ : proj_context_create();
if (!ctx) {
throw ParsingException("out of memory");
}
PJContextHolder contextHolder(ctx, ctx != d->ctx_);

// Those used to come from a text init file
// We only support them in compatibility mode
const std::string &stepName = d->steps_[0].name;
if (ci_starts_with(stepName, "epsg:") ||
ci_starts_with(stepName, "IGNF:")) {

/* We create a new context so as to avoid messing up with the */
/* errorno of the main context, when trying to find the likely */
/* missing epsg file */
auto ctx = proj_context_create();
if (!ctx) {
throw ParsingException("out of memory");
}
PJContextHolder contextHolder(ctx, true);
if (d->ctx_) {
ctx->set_search_paths(d->ctx_->search_paths);
ctx->file_finder = d->ctx_->file_finder;
ctx->file_finder_user_data = d->ctx_->file_finder_user_data;
}
struct BackupContextErrno {
PJ_CONTEXT *m_ctxt = nullptr;
int m_last_errno = 0;

explicit BackupContextErrno(PJ_CONTEXT *ctxtIn)
: m_ctxt(ctxtIn), m_last_errno(m_ctxt->last_errno) {
m_ctxt->debug_level = PJ_LOG_ERROR;
}

~BackupContextErrno() { m_ctxt->last_errno = m_last_errno; }

BackupContextErrno(const BackupContextErrno &) = delete;
BackupContextErrno &
operator=(const BackupContextErrno &) = delete;
};

BackupContextErrno backupContextErrno(ctx);

bool usePROJ4InitRules = d->usePROJ4InitRules_;
if (!usePROJ4InitRules) {
Expand Down Expand Up @@ -12369,12 +12379,6 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
}
}

auto ctx = d->ctx_ ? d->ctx_ : proj_context_create();
if (!ctx) {
throw ParsingException("out of memory");
}
PJContextHolder contextHolder(ctx, ctx != d->ctx_);

paralist *init = pj_mkparam(("init=" + d->steps_[0].name).c_str());
if (!init) {
throw ParsingException("out of memory");
Expand Down
3 changes: 3 additions & 0 deletions src/proj_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,9 @@ struct pj_ctx {
void *user_data) = nullptr;
void *file_finder_user_data = nullptr;

// Cache result of pj_find_file()
std::map<std::string, std::string> lookupedFiles{};

bool defer_grid_opening = false; // set transiently by pj_obj_create()

projFileApiCallbackAndData fileApi{};
Expand Down

0 comments on commit 2dc4914

Please sign in to comment.