aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2018-11-26 15:47:57 +0100
committerEven Rouault <even.rouault@spatialys.com>2018-11-29 00:35:25 +0100
commit67758b2c67ea329116b59818c038797667c4e1d1 (patch)
tree7e6b4ead6cbe9251ea5ef64d6c45179287597b2e /src
parent7e05bd0ff52fe3ba78dfd75f9ebebe3dfe715bca (diff)
downloadPROJ-67758b2c67ea329116b59818c038797667c4e1d1.tar.gz
PROJ-67758b2c67ea329116b59818c038797667c4e1d1.zip
Redirect epsg:XXXX and IGNF:XXXX CRS expansions to the database, and remove the data/epsg and data/IGNF files
Diffstat (limited to 'src')
-rw-r--r--src/c_api.cpp22
-rw-r--r--src/cs2cs.cpp4
-rw-r--r--src/factory.cpp19
-rw-r--r--src/gie.c14
-rw-r--r--src/io.cpp85
-rw-r--r--src/pj_ctx.c5
-rw-r--r--src/pj_init.c102
-rw-r--r--src/proj.h5
-rw-r--r--src/proj_4D_api.c50
-rw-r--r--src/projects.h5
10 files changed, 248 insertions, 63 deletions
diff --git a/src/c_api.cpp b/src/c_api.cpp
index 3b51d905..e74f4347 100644
--- a/src/c_api.cpp
+++ b/src/c_api.cpp
@@ -252,6 +252,28 @@ const char *proj_context_get_database_path(PJ_CONTEXT *ctx) {
// ---------------------------------------------------------------------------
+/** \brief Return a metadata from the database.
+ *
+ * The returned pointer remains valid while ctx is valid, and until
+ * proj_context_get_database_metadata() is called.
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param key Metadata key. Must not be NULL
+ * @return value, or nullptr
+ */
+const char *proj_context_get_database_metadata(PJ_CONTEXT *ctx,
+ const char *key) {
+ SANITIZE_CTX(ctx);
+ try {
+ return getDBcontext(ctx)->getMetadata(key);
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ return nullptr;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
/** \brief Guess the "dialect" of the WKT string.
*
* @param ctx PROJ context, or NULL for default context
diff --git a/src/cs2cs.cpp b/src/cs2cs.cpp
index 6f4c4a55..8dc23ac5 100644
--- a/src/cs2cs.cpp
+++ b/src/cs2cs.cpp
@@ -534,8 +534,8 @@ int main(int argc, char **argv) {
const char *const optionsProj4Mode[] = {"USE_PROJ4_INIT_RULES=YES",
nullptr};
const char *const *optionsImportCRS =
- proj_context_get_use_proj4_init_rules(nullptr) ? optionsProj4Mode
- : nullptr;
+ proj_context_get_use_proj4_init_rules(nullptr, TRUE) ? optionsProj4Mode
+ : nullptr;
PJ_OBJ *src = nullptr;
if (!fromStr.empty()) {
diff --git a/src/factory.cpp b/src/factory.cpp
index 3c360d13..f58b66a0 100644
--- a/src/factory.cpp
+++ b/src/factory.cpp
@@ -157,6 +157,8 @@ struct DatabaseContext::Private {
};
private:
+ friend class DatabaseContext;
+
std::string databasePath_{};
bool close_handle_ = true;
sqlite3 *sqlite_handle_{};
@@ -164,6 +166,7 @@ struct DatabaseContext::Private {
PJ_CONTEXT *pjCtxt_ = nullptr;
int recLevel_ = 0;
bool detach_ = false;
+ std::string lastMetadataValue_{};
void closeDB();
@@ -704,6 +707,22 @@ const std::string &DatabaseContext::getPath() const { return d->getPath(); }
// ---------------------------------------------------------------------------
+/** \brief Return a metadata item.
+ *
+ * Value remains valid while this is alive and to the next call to getMetadata
+ */
+const char *DatabaseContext::getMetadata(const char *key) const {
+ auto res =
+ d->run("SELECT value FROM metadata WHERE key = ?", {std::string(key)});
+ if (res.empty()) {
+ return nullptr;
+ }
+ d->lastMetadataValue_ = res[0][0];
+ return d->lastMetadataValue_.c_str();
+}
+
+// ---------------------------------------------------------------------------
+
//! @cond Doxygen_Suppress
DatabaseContextNNPtr DatabaseContext::create(void *sqlite_handle) {
diff --git a/src/gie.c b/src/gie.c
index d71a3e75..4bb79f1f 100644
--- a/src/gie.c
+++ b/src/gie.c
@@ -148,7 +148,8 @@ static ffio *ffio_destroy (ffio *G);
static ffio *ffio_create (const char **tags, size_t n_tags, size_t max_record_size);
static const char *gie_tags[] = {
- "<gie>", "operation", "accept", "expect", "roundtrip", "banner", "verbose",
+ "<gie>", "operation", "use_proj4_init_rules",
+ "accept", "expect", "roundtrip", "banner", "verbose",
"direction", "tolerance", "ignore", "require_grid", "echo", "skip", "</gie>"
};
@@ -186,6 +187,7 @@ typedef struct {
size_t operation_lineno;
size_t dimensions_given, dimensions_given_at_last_accept;
double tolerance;
+ int use_proj4_init_rules;
int ignore;
int skip_test;
const char *curr_file;
@@ -243,6 +245,7 @@ int main (int argc, char **argv) {
T.verbosity = 1;
T.tolerance = 5e-4;
T.ignore = 5555; /* Error code that will not be issued by proj_create() */
+ T.use_proj4_init_rules = FALSE;
o = opt_parse (argc, argv, "hlvq", "o", longflags, longkeys);
if (0==o)
@@ -498,6 +501,12 @@ static int tolerance (const char *args) {
return 0;
}
+
+static int use_proj4_init_rules (const char *args) {
+ T.use_proj4_init_rules = strcmp(args, "true") == 0;
+ return 0;
+}
+
static int ignore (const char *args) {
T.ignore = errno_from_err_const (column (args, 1));
return 0;
@@ -583,6 +592,7 @@ either a conversion or a transformation)
if (T.P)
proj_destroy (T.P);
proj_errno_reset (0);
+ proj_context_use_proj4_init_rules(0, T.use_proj4_init_rules);
T.P = proj_create (0, F->args);
@@ -1001,6 +1011,8 @@ static int dispatch (const char *cmnd, const char *args) {
if (0==strcmp (cmnd, "require_grid")) return require_grid (args);
if (0==strcmp (cmnd, "echo")) return echo (args);
if (0==strcmp (cmnd, "skip")) return skip (args);
+ if (0==strcmp (cmnd, "use_proj4_init_rules"))
+ return use_proj4_init_rules (args);
return 0;
}
diff --git a/src/io.cpp b/src/io.cpp
index 15df312b..7a0a7435 100644
--- a/src/io.cpp
+++ b/src/io.cpp
@@ -7009,14 +7009,15 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
// Those used to come from a text init file
// We only support them in compatibility mode
- if (ci_starts_with(d->steps_[0].name, "epsg:") ||
- ci_starts_with(d->steps_[0].name, "IGNF:")) {
+ const std::string &stepName = d->steps_[0].name;
+ if (ci_starts_with(stepName, "epsg:") ||
+ ci_starts_with(stepName, "IGNF:")) {
bool usePROJ4InitRules = d->usePROJ4InitRules_;
if (!usePROJ4InitRules) {
PJ_CONTEXT *ctx = proj_context_create();
if (ctx) {
- usePROJ4InitRules =
- proj_context_get_use_proj4_init_rules(ctx) == TRUE;
+ usePROJ4InitRules = proj_context_get_use_proj4_init_rules(
+ ctx, FALSE) == TRUE;
proj_context_destroy(ctx);
}
}
@@ -7024,41 +7025,52 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
throw ParsingException("init=epsg:/init=IGNF: syntax not "
"supported in non-PROJ4 emulation mode");
}
- auto obj =
- createFromUserInput(d->steps_[0].name, d->dbContext_, true);
- auto crs = dynamic_cast<CRS *>(obj.get());
- if (crs) {
- PropertyMap properties;
- properties.set(IdentifiedObject::NAME_KEY, crs->nameStr());
- const auto &extent = getExtent(crs);
- if (extent) {
- properties.set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY,
- NN_NO_CHECK(extent));
- }
- auto geogCRS = dynamic_cast<GeographicCRS *>(crs);
- if (geogCRS) {
- // Override with longitude latitude in radian
- return GeographicCRS::create(
- properties, geogCRS->datum(), geogCRS->datumEnsemble(),
- EllipsoidalCS::createLongitudeLatitude(
- UnitOfMeasure::RADIAN));
- }
- auto projCRS = dynamic_cast<ProjectedCRS *>(crs);
- if (projCRS) {
- // Override with easting northing order
- const auto &conv = projCRS->derivingConversionRef();
- if (conv->method()->getEPSGCode() !=
- EPSG_CODE_METHOD_TRANSVERSE_MERCATOR_SOUTH_ORIENTATED) {
- return ProjectedCRS::create(
- properties, projCRS->baseCRS(), conv,
- CartesianCS::createEastingNorthing(
- projCRS->coordinateSystem()
- ->axisList()[0]
- ->unit()));
+
+ PJ_CONTEXT *ctx = proj_context_create();
+ char unused[256];
+ std::string initname(stepName);
+ initname.resize(initname.find(':'));
+ int file_found =
+ pj_find_file(ctx, initname.c_str(), unused, sizeof(unused));
+ proj_context_destroy(ctx);
+ if (!file_found) {
+ auto obj = createFromUserInput(stepName, d->dbContext_, true);
+ auto crs = dynamic_cast<CRS *>(obj.get());
+ if (crs) {
+ PropertyMap properties;
+ properties.set(IdentifiedObject::NAME_KEY, crs->nameStr());
+ const auto &extent = getExtent(crs);
+ if (extent) {
+ properties.set(
+ common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY,
+ NN_NO_CHECK(extent));
+ }
+ auto geogCRS = dynamic_cast<GeographicCRS *>(crs);
+ if (geogCRS) {
+ // Override with longitude latitude in radian
+ return GeographicCRS::create(
+ properties, geogCRS->datum(),
+ geogCRS->datumEnsemble(),
+ EllipsoidalCS::createLongitudeLatitude(
+ UnitOfMeasure::RADIAN));
+ }
+ auto projCRS = dynamic_cast<ProjectedCRS *>(crs);
+ if (projCRS) {
+ // Override with easting northing order
+ const auto &conv = projCRS->derivingConversionRef();
+ if (conv->method()->getEPSGCode() !=
+ EPSG_CODE_METHOD_TRANSVERSE_MERCATOR_SOUTH_ORIENTATED) {
+ return ProjectedCRS::create(
+ properties, projCRS->baseCRS(), conv,
+ CartesianCS::createEastingNorthing(
+ projCRS->coordinateSystem()
+ ->axisList()[0]
+ ->unit()));
+ }
}
}
+ return obj;
}
- return obj;
}
paralist *init = pj_mkparam(("init=" + d->steps_[0].name).c_str());
@@ -7284,6 +7296,7 @@ PROJStringParser::createFromPROJString(const std::string &projString) {
throw ParsingException("out of memory");
}
proj_log_func(pj_context, &logger, Logger::log);
+ proj_context_use_proj4_init_rules(pj_context, d->usePROJ4InitRules_);
auto pj = proj_create(pj_context, projString.c_str());
bool valid = pj != nullptr;
proj_destroy(pj);
diff --git a/src/pj_ctx.c b/src/pj_ctx.c
index 54e2cfb7..1c99e921 100644
--- a/src/pj_ctx.c
+++ b/src/pj_ctx.c
@@ -85,7 +85,8 @@ projCtx pj_get_default_ctx()
default_context.app_data = NULL;
default_context.fileapi = pj_get_default_fileapi();
default_context.cpp_context = NULL;
- default_context.use_proj4_init_rules = FALSE;
+ default_context.use_proj4_init_rules = -1;
+ default_context.epsg_file_exists = -1;
if( getenv("PROJ_DEBUG") != NULL )
{
@@ -115,7 +116,7 @@ projCtx pj_ctx_alloc()
memcpy( ctx, pj_get_default_ctx(), sizeof(projCtx_t) );
ctx->last_errno = 0;
ctx->cpp_context = NULL;
- ctx->use_proj4_init_rules = FALSE;
+ ctx->use_proj4_init_rules = -1;
return ctx;
}
diff --git a/src/pj_init.c b/src/pj_init.c
index fcc03537..0440cf59 100644
--- a/src/pj_init.c
+++ b/src/pj_init.c
@@ -43,7 +43,6 @@
#include "projects.h"
-
/**************************************************************************************/
static paralist *string_to_paralist (PJ_CONTEXT *ctx, char *definition) {
/***************************************************************************************
@@ -81,14 +80,15 @@ static paralist *string_to_paralist (PJ_CONTEXT *ctx, char *definition) {
/**************************************************************************************/
-static char *get_init_string (PJ_CONTEXT *ctx, char *name) {
+static char *get_init_string (PJ_CONTEXT *ctx, const char *name) {
/***************************************************************************************
Read a section of an init file. Return its contents as a plain character string.
It is the duty of the caller to free the memory allocated for the string.
***************************************************************************************/
#define MAX_LINE_LENGTH 1000
size_t current_buffer_size = 5 * (MAX_LINE_LENGTH + 1);
- char *fname, *section, *key;
+ char *fname, *section;
+ const char *key;
char *buffer = 0;
char *line = 0;
PAFile fid;
@@ -228,11 +228,12 @@ static char *get_init_string (PJ_CONTEXT *ctx, char *name) {
/************************************************************************/
-static paralist *get_init(PJ_CONTEXT *ctx, char *key) {
+static paralist *get_init(PJ_CONTEXT *ctx, const char *key, int allow_init_epsg) {
/*************************************************************************
Expand key from buffer or (if not in buffer) from init file
*************************************************************************/
- char *xkey, *definition;
+ const char *xkey;
+ char *definition = 0;
paralist *init_items = 0;
/* support "init=file:section", "+init=file:section", and "file:section" format */
@@ -248,10 +249,68 @@ Expand key from buffer or (if not in buffer) from init file
if (init_items)
return init_items;
- /* If not, we must read it from file */
- pj_log (ctx, PJ_LOG_TRACE,
- "get_init: searching on in init files for [%s]", xkey);
- definition = get_init_string (ctx, xkey);
+ if( (strncmp(xkey, "epsg:", 5) == 0 || strncmp(xkey, "IGNF:", 5) == 0) ) {
+ char unused[256];
+ char initname[5];
+ int exists;
+
+ memcpy(initname, xkey, 4);
+ initname[4] = 0;
+
+ if( strncmp(xkey, "epsg:", 5) == 0 ) {
+ exists = ctx->epsg_file_exists;
+ if( exists < 0 ) {
+ exists = pj_find_file(ctx, initname, unused, sizeof(unused));
+ ctx->epsg_file_exists = exists;
+ }
+ } else {
+ exists = pj_find_file(ctx, initname, unused, sizeof(unused));
+ }
+
+ if( !exists ) {
+ const char* const optionsProj4Mode[] = { "USE_PROJ4_INIT_RULES=YES", NULL };
+ char szInitStr[7 + 64];
+ PJ_OBJ* src;
+ const char* proj_string;
+
+ pj_ctx_set_errno( ctx, 0 );
+
+ if( !allow_init_epsg ) {
+ pj_log (ctx, PJ_LOG_TRACE, "%s expansion disallowed", xkey);
+ return 0;
+ }
+ if( strlen(xkey) > 64 ) {
+ return 0;
+ }
+ strcpy(szInitStr, "+init=");
+ strcat(szInitStr, xkey);
+
+ src = proj_obj_create_from_user_input(ctx, szInitStr, optionsProj4Mode);
+ if( !src ) {
+ return 0;
+ }
+
+ proj_string = proj_obj_as_proj_string(src, PJ_PROJ_4, NULL);
+ if( !proj_string ) {
+ proj_obj_unref(src);
+ return 0;
+ }
+ definition = (char*)calloc(1, strlen(proj_string)+1);
+ if( definition ) {
+ strcpy(definition, proj_string);
+ }
+
+ proj_obj_unref(src);
+ }
+ }
+
+ if( !definition ) {
+ /* If not, we must read it from file */
+ pj_log (ctx, PJ_LOG_TRACE,
+ "get_init: searching on in init files for [%s]", xkey);
+ definition = get_init_string (ctx, xkey);
+ }
+
if (0==definition)
return 0;
init_items = string_to_paralist (ctx, definition);
@@ -271,7 +330,7 @@ Expand key from buffer or (if not in buffer) from init file
-static paralist *append_defaults_to_paralist (PJ_CONTEXT *ctx, paralist *start, char *key) {
+static paralist *append_defaults_to_paralist (PJ_CONTEXT *ctx, paralist *start, const char *key, int allow_init_epsg) {
paralist *defaults, *last = 0;
char keystring[ID_TAG_MAX + 20];
paralist *next, *proj;
@@ -303,7 +362,7 @@ static paralist *append_defaults_to_paralist (PJ_CONTEXT *ctx, paralist *start,
strcpy (keystring, "proj_def.dat:");
strcat (keystring, key);
- defaults = get_init (ctx, keystring);
+ defaults = get_init (ctx, keystring, allow_init_epsg);
/* Defaults are optional - so we don't care if we cannot open the file */
pj_ctx_set_errno (ctx, err);
@@ -340,7 +399,7 @@ static paralist *append_defaults_to_paralist (PJ_CONTEXT *ctx, paralist *start,
}
/*****************************************************************************/
-paralist *pj_expand_init(PJ_CONTEXT *ctx, paralist *init) {
+static paralist *pj_expand_init_internal(PJ_CONTEXT *ctx, paralist *init, int allow_init_epsg) {
/******************************************************************************
Append expansion of <key> to the paralist <init>. The expansion is appended,
rather than inserted at <init>'s place, since <init> may contain
@@ -367,7 +426,7 @@ Note that 'init=foo:bar' stays in the list. It is ignored after expansion.
if (0==init)
return 0;
- expn = get_init(ctx, init->param);
+ expn = get_init(ctx, init->param, allow_init_epsg);
/* Nothing in expansion? */
if (0==expn)
@@ -381,6 +440,9 @@ Note that 'init=foo:bar' stays in the list. It is ignored after expansion.
return init;
}
+paralist *pj_expand_init(PJ_CONTEXT *ctx, paralist *init) {
+ return pj_expand_init_internal(ctx, init, TRUE);
+}
/************************************************************************/
@@ -496,6 +558,14 @@ static PJ_CONSTRUCTOR locate_constructor (const char *name) {
PJ *
pj_init_ctx(projCtx ctx, int argc, char **argv) {
+ /* Legacy interface: allow init=epsg:XXXX syntax by default */
+ int allow_init_epsg = proj_context_get_use_proj4_init_rules(ctx, TRUE);
+ return pj_init_ctx_with_allow_init_epsg(ctx, argc, argv, allow_init_epsg);
+}
+
+
+PJ *
+pj_init_ctx_with_allow_init_epsg(projCtx ctx, int argc, char **argv, int allow_init_epsg) {
const char *s;
char *name;
PJ_CONSTRUCTOR proj;
@@ -558,7 +628,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) {
/* problem when '+init's are expanded as late as possible. */
init = pj_param_exists (start, "init");
if (init && n_pipelines == 0) {
- init = pj_expand_init (ctx, init);
+ init = pj_expand_init_internal (ctx, init, allow_init_epsg);
if (!init)
return pj_dealloc_params (ctx, start, PJD_ERR_NO_ARGS);
}
@@ -580,8 +650,8 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) {
/* Append general and projection specific defaults to the definition list */
- append_defaults_to_paralist (ctx, start, "general");
- append_defaults_to_paralist (ctx, start, name);
+ append_defaults_to_paralist (ctx, start, "general", allow_init_epsg);
+ append_defaults_to_paralist (ctx, start, name, allow_init_epsg);
/* Allocate projection structure */
diff --git a/src/proj.h b/src/proj.h
index 31cd730c..711f8f66 100644
--- a/src/proj.h
+++ b/src/proj.h
@@ -336,7 +336,7 @@ PJ_CONTEXT PROJ_DLL *proj_context_create (void);
PJ_CONTEXT PROJ_DLL *proj_context_destroy (PJ_CONTEXT *ctx);
void PROJ_DLL proj_context_use_proj4_init_rules(PJ_CONTEXT *ctx, int enable);
-int PROJ_DLL proj_context_get_use_proj4_init_rules(PJ_CONTEXT *ctx);
+int PROJ_DLL proj_context_get_use_proj4_init_rules(PJ_CONTEXT *ctx, int from_legacy_code_path);
/* Manage the transformation definition object PJ */
PJ PROJ_DLL *proj_create (PJ_CONTEXT *ctx, const char *definition);
@@ -458,6 +458,9 @@ int PROJ_DLL proj_context_set_database_path(PJ_CONTEXT *ctx,
const char PROJ_DLL *proj_context_get_database_path(PJ_CONTEXT *ctx);
+const char PROJ_DLL *proj_context_get_database_metadata(PJ_CONTEXT* ctx,
+ const char* key);
+
/** \brief Guessed WKT "dialect". */
typedef enum
{
diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c
index b7b500a7..4d05530e 100644
--- a/src/proj_4D_api.c
+++ b/src/proj_4D_api.c
@@ -567,6 +567,7 @@ PJ *proj_create (PJ_CONTEXT *ctx, const char *definition) {
char *args, **argv;
size_t argc, n;
int ret;
+ int allow_init_epsg;
if (0==ctx)
ctx = pj_get_default_ctx ();
@@ -590,7 +591,9 @@ PJ *proj_create (PJ_CONTEXT *ctx, const char *definition) {
argv = pj_trim_argv (argc, args);
/* ...and let pj_init_ctx do the hard work */
- P = pj_init_ctx (ctx, (int) argc, argv);
+ /* New interface: forbid init=epsg:XXXX syntax by default */
+ allow_init_epsg = proj_context_get_use_proj4_init_rules(ctx, FALSE);
+ P = pj_init_ctx_with_allow_init_epsg (ctx, (int) argc, argv, allow_init_epsg);
pj_dealloc (argv);
pj_dealloc (args);
@@ -687,7 +690,7 @@ static int EQUAL(const char* a, const char* b) {
/* proj_context_get_use_proj4_init_rules() */
/************************************************************************/
-int proj_context_get_use_proj4_init_rules(PJ_CONTEXT *ctx) {
+int proj_context_get_use_proj4_init_rules(PJ_CONTEXT *ctx, int from_legacy_code_path) {
const char* val = getenv("PROJ_USE_PROJ4_INIT_RULES");
if( ctx == NULL ) {
@@ -704,7 +707,10 @@ int proj_context_get_use_proj4_init_rules(PJ_CONTEXT *ctx) {
pj_log(ctx, PJ_LOG_ERROR, "Invalid value for PROJ_USE_PROJ4_INIT_RULES");
}
- return ctx->use_proj4_init_rules;
+ if( ctx->use_proj4_init_rules >= 0 ) {
+ return ctx->use_proj4_init_rules;
+ }
+ return from_legacy_code_path;
}
@@ -735,7 +741,7 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *srid_from, const char
const char* proj_string;
const char* const optionsProj4Mode[] = { "USE_PROJ4_INIT_RULES=YES", NULL };
const char* const* optionsImportCRS =
- proj_context_get_use_proj4_init_rules(ctx) ? optionsProj4Mode : NULL;
+ proj_context_get_use_proj4_init_rules(ctx, FALSE) ? optionsProj4Mode : NULL;
src = proj_obj_create_from_user_input(ctx, srid_from, optionsImportCRS);
if( !src ) {
@@ -1151,6 +1157,42 @@ PJ_INIT_INFO proj_init_info(const char *initname){
file_found = pj_find_file(ctx, initname, ininfo.filename, sizeof(ininfo.filename));
if (!file_found || strlen(initname) > 64) {
+ if( strcmp(initname, "epsg") == 0 || strcmp(initname, "EPSG") == 0 ) {
+ const char* val;
+
+ pj_ctx_set_errno( ctx, 0 );
+
+ strncpy (ininfo.name, initname, sizeof(ininfo.name) - 1);
+ strcpy(ininfo.origin, "EPSG");
+ val = proj_context_get_database_metadata(ctx, "EPSG.VERSION");
+ if( val ) {
+ strncpy(ininfo.version, val, sizeof(ininfo.version) - 1);
+ }
+ val = proj_context_get_database_metadata(ctx, "EPSG.DATE");
+ if( val ) {
+ strncpy(ininfo.lastupdate, val, sizeof(ininfo.lastupdate) - 1);
+ }
+ return ininfo;
+ }
+
+ if( strcmp(initname, "IGNF") == 0 ) {
+ const char* val;
+
+ pj_ctx_set_errno( ctx, 0 );
+
+ strncpy (ininfo.name, initname, sizeof(ininfo.name) - 1);
+ strcpy(ininfo.origin, "IGNF");
+ val = proj_context_get_database_metadata(ctx, "IGNF.VERSION");
+ if( val ) {
+ strncpy(ininfo.version, val, sizeof(ininfo.version) - 1);
+ }
+ val = proj_context_get_database_metadata(ctx, "IGNF.DATE");
+ if( val ) {
+ strncpy(ininfo.lastupdate, val, sizeof(ininfo.lastupdate) - 1);
+ }
+ return ininfo;
+ }
+
return ininfo;
}
diff --git a/src/projects.h b/src/projects.h
index 8ab6f478..11467d56 100644
--- a/src/projects.h
+++ b/src/projects.h
@@ -597,7 +597,8 @@ struct projCtx_t {
void *app_data;
struct projFileAPI_t *fileapi;
struct projCppContext* cpp_context; /* internal context for C++ code */
- int use_proj4_init_rules;
+ int use_proj4_init_rules; /* -1 = unknown, 0 = no, 1 = yes */
+ int epsg_file_exists; /* -1 = unknown, 0 = no, 1 = yes */
};
/* classic public API */
@@ -833,6 +834,8 @@ double PROJ_DLL pj_atof( const char* nptr );
double pj_strtod( const char *nptr, char **endptr );
void pj_freeup_plain (PJ *P);
+projPJ pj_init_ctx_with_allow_init_epsg( projCtx ctx, int argc, char **argv, int allow_init_epsg );
+
#ifdef __cplusplus
}
#endif