diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2018-11-26 15:47:57 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2018-11-29 00:35:25 +0100 |
| commit | 67758b2c67ea329116b59818c038797667c4e1d1 (patch) | |
| tree | 7e6b4ead6cbe9251ea5ef64d6c45179287597b2e /src | |
| parent | 7e05bd0ff52fe3ba78dfd75f9ebebe3dfe715bca (diff) | |
| download | PROJ-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.cpp | 22 | ||||
| -rw-r--r-- | src/cs2cs.cpp | 4 | ||||
| -rw-r--r-- | src/factory.cpp | 19 | ||||
| -rw-r--r-- | src/gie.c | 14 | ||||
| -rw-r--r-- | src/io.cpp | 85 | ||||
| -rw-r--r-- | src/pj_ctx.c | 5 | ||||
| -rw-r--r-- | src/pj_init.c | 102 | ||||
| -rw-r--r-- | src/proj.h | 5 | ||||
| -rw-r--r-- | src/proj_4D_api.c | 50 | ||||
| -rw-r--r-- | src/projects.h | 5 |
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) { @@ -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; } @@ -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 */ @@ -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 |
