From 8302bf9db2d5bfa3a84a0f9ddf31a90698cccc84 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Mon, 7 Aug 2017 10:37:40 +0200 Subject: Adding info functions to proj.h API. (#551) * Adding info functions to proj.h API. Four new functions are added with this commit: proj_info(), proj_pj_info(), proj_grid_info() and proj_init_info(). Additionally four new data types are added: PJ_INFO, PJ_PROJ_INFO, PJ_GRID_INFO and PJ_INIT_INFO. The functions return the corresponding data types. These functions allows users of the PROJ.4 library to get information about various PROJ.4 entities and the library itself. The new data types are structs that contain specific information about either the library instance, a PJ instance, a grid or an init file. Together the four new functions cover a big part of the functionality in the semi-public projects.h API and should hopefully make it easier for user to migrate their code to the proj.h API in the future. Besides covering already existing functionality in the old API, this commit introduces the ability to add metadata to init-files. This is primarily added to give users a way of knowing which version of the EPSG database they are using, but it also comes in handy for other init-files. The init-file metadata is added directly to the init-file as a special "projection" called "metadata". The info projection of the epsg init-file is thus described as: +version=9.0.0 +origin=EPSG +lastupdate=2017-01-10 The proj_init_info() function uses the internal pj_param() to read the metadata. As a consequence, "metadata" will not be available as a the name of a projection in the future. This is a reasonable price to pay considering the ease of the implementation of adding metadata to init-files this way, and of course that "metadata" is a very unlikely name for a projection in any case. A metadata tag has been added to all init-files in the nad-directory. For most only a subset of the possible parameters has been added. * Replaced calls to sprintf and strncpy with safer options. Added pj_strlcpy for internal use. * Fail gracefully when getting non-initialized PJ in proj_pj_info() * Change length of filename member in PJ_INIT_INFO and PJ_GRID_INFO to 260 (MAX_PATH) --- src/PJ_cart.c | 65 +++++++++++---- src/pj_init.c | 13 +-- src/pj_internal.c | 47 +++++++++++ src/pj_obs_api.c | 234 ++++++++++++++++++++++++++++++++++++++++++++++++---- src/pj_open_lib.c | 12 ++- src/proj.def | 80 +++++++++--------- src/proj.h | 72 +++++++++++++--- src/proj_internal.h | 4 + src/projects.h | 1 + 9 files changed, 439 insertions(+), 89 deletions(-) (limited to 'src') diff --git a/src/PJ_cart.c b/src/PJ_cart.c index 169002ba..1373e870 100644 --- a/src/PJ_cart.c +++ b/src/PJ_cart.c @@ -236,14 +236,20 @@ int pj_cart_selftest (void) { PJ *P; PJ_OBS a, b, obs[2]; PJ_COORD coord[2]; + + PJ_INFO info; + PJ_PROJ_INFO pj_info; + PJ_GRID_INFO grid_info; + PJ_INIT_INFO init_info; + PJ_DERIVS derivs; PJ_FACTORS factors; + int err; size_t n, sz; double dist, h, t; char *args[3] = {"proj=utm", "zone=32", "ellps=GRS80"}; - char *arg = {" +proj=utm +zone=32 +ellps=GRS80"}; - char *arg_def; + char *arg = {"+proj=utm +zone=32 +ellps=GRS80"}; char buf[40]; /* An utm projection on the GRS80 ellipsoid */ @@ -251,11 +257,6 @@ int pj_cart_selftest (void) { if (0==P) return 1; - /* note arg is handcrafted to go undisturbed through get def reconstruction */ - arg_def = proj_definition_retrieve (P); - if (0!=strcmp(arg, arg_def)) - return 44; - proj_release (arg_def); /* Clean up */ proj_destroy (P); @@ -478,21 +479,50 @@ int pj_cart_selftest (void) { } proj_destroy(P); - /* Test proj_has_inverse() */ - P = proj_create(0, "+proj=august"); /* august has no inverse */ - if (proj_has_inverse(P)) { - proj_destroy(P); - return 60; + /* ********************************************************************** */ + /* Test info functions */ + /* ********************************************************************** */ + + /* proj_info() */ + /* this one is difficult to test, since the output changes with the setup */ + info = proj_info(); + if (info.version) { + char tmpstr[64]; + sprintf(tmpstr, "%d.%d.%d", info.major, info.minor, info.patch); + if (strcmp(info.version, tmpstr)) return 55; } + if (!info.release) return 56; + if (!info.searchpath) return 57; + + /* proj_pj_info() */ + P = proj_create(0, "+proj=august"); /* august has no inverse */ + if (proj_pj_info(P).has_inverse) { proj_destroy(P); return 60; } proj_destroy(P); - P = proj_create(0, "+proj=merc"); /* merc has an inverse */ - if (!proj_has_inverse(P)) { - proj_destroy(P); - return 61; - } + P = proj_create(0, arg); + pj_info = proj_pj_info(P); + if ( !pj_info.has_inverse ) { proj_destroy(P); return 61; } + if ( strcmp(pj_info.definition, arg) ) { proj_destroy(P); return 62; } + if ( strcmp(pj_info.id, "utm") ) { proj_destroy(P); return 63; } proj_destroy(P); + /* proj_grid_info() */ + grid_info = proj_grid_info("egm96_15.gtx"); + if ( strlen(grid_info.filename) == 0 ) return 64; + if ( strcmp(grid_info.gridname, "egm96_15.gtx") ) return 65; + grid_info = proj_grid_info("nonexistinggrid"); + if ( strlen(grid_info.filename) > 0 ) return 66; + + /* proj_init_info() */ + init_info = proj_init_info("unknowninit"); + if ( strlen(init_info.filename) != 0 ) return 67; + + init_info = proj_init_info("epsg"); + if ( strcmp(init_info.origin, "EPSG") ) return 69; + if ( strcmp(init_info.name, "epsg") ) return 68; + + + /* test proj_rtodms() and proj_dmstor() */ if (strcmp("180dN", proj_rtodms(buf, M_PI, 'N', 'S'))) return 70; @@ -536,6 +566,7 @@ int pj_cart_selftest (void) { proj_destroy(P); + return 0; } diff --git a/src/pj_init.c b/src/pj_init.c index 243174e1..7448fdb6 100644 --- a/src/pj_init.c +++ b/src/pj_init.c @@ -243,8 +243,9 @@ get_opt(projCtx ctx, paralist **start, PAFile fid, char *name, paralist *next, else { /* skip past word */ - while( *next_char && !isspace(*next_char) ) + while( *next_char && !isspace(*next_char) ) { next_char++; + } } } @@ -253,7 +254,6 @@ get_opt(projCtx ctx, paralist **start, PAFile fid, char *name, paralist *next, errno = 0; free(state); - return next; } @@ -280,8 +280,7 @@ get_defaults(projCtx ctx, paralist **start, paralist *next, char *name) { /************************************************************************/ /* get_init() */ /************************************************************************/ -static paralist * -get_init(projCtx ctx, paralist **start, paralist *next, char *name, int *found_def) { +static paralist *get_init(projCtx ctx, paralist **start, paralist *next, char *name, int *found_def) { char fname[MAX_PATH_FILENAME+ID_TAG_MAX+3], *opt; PAFile fid; paralist *init_items = NULL; @@ -330,6 +329,10 @@ get_init(projCtx ctx, paralist **start, paralist *next, char *name, int *found_d return next; } +paralist * pj_get_init(projCtx ctx, paralist **start, paralist *next, char *name, int *found_def) { + return get_init(ctx, start, next, name, found_def); +} + /************************************************************************/ /* pj_init_plus() */ /* */ @@ -466,7 +469,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { } } - /* in cae the parameter list only consist of a +init parameter + /* in case the parameter list only consist of a +init parameter it is expanded here (will not be handled in the above loop). */ if (pj_param(ctx, start, "tinit").i && argc == 1) { found_def = 0; diff --git a/src/pj_internal.c b/src/pj_internal.c index f3ca3566..31c299ac 100644 --- a/src/pj_internal.c +++ b/src/pj_internal.c @@ -167,6 +167,53 @@ void proj_context_inherit (PJ *parent, PJ *child) { +size_t pj_strlcpy(char *dst, const char *src, size_t siz) { +/******************************************************************* + Copy src to string dst of size siz. At most siz-1 characters + will be copied. Always NUL terminates (unless siz == 0). + Returns strlen(src); if retval >= siz, truncation occurred. + + + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Source: http://www.i-pi.com/Training/EthicalHacking/Solutions/strlcpy.c + +********************************************************************/ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + /* stuff below is *not* considered API, and will be moved to an "internal plumbing toolset" */ diff --git a/src/pj_obs_api.c b/src/pj_obs_api.c index b06f0823..b2929a07 100644 --- a/src/pj_obs_api.c +++ b/src/pj_obs_api.c @@ -390,9 +390,13 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *srid_from, const char ******************************************************************************/ PJ *P; - char buffer[256]; + char buffer[512]; + + strcpy(buffer, "+proj=pipeline +step +init="); + strncat(buffer, srid_from, 512-strlen(buffer)); + strncat(buffer, " +inv +step +init=", 512-strlen(buffer)); + strncat(buffer, srid_to, 512-strlen(buffer)); - sprintf(buffer, "+proj=pipeline +step +init=%s +inv +step +init=%s", srid_from, srid_to); P = proj_create(ctx, buffer); return P; @@ -509,11 +513,218 @@ void proj_context_destroy (PJ_CONTEXT *ctx) { } -/* Build a fully expanded proj_create() compatible representation of P */ -char *proj_definition_retrieve (PJ *P) { - if (0==P) - return 0; - return pj_get_def(P, 0); +/*****************************************************************************/ +PJ_INFO proj_info(void) { +/****************************************************************************** + Basic info about the current instance of the PROJ.4 library. + + Returns PJ_INFO struct. Searchpath member of the struct is truncated to 512 + characters. + +******************************************************************************/ + PJ_INFO info; + const char **paths; + char *tmpstr; + int i, n; + size_t len = 0; + + memset(&info, 0, sizeof(PJ_INFO)); + + info.major = PROJ_VERSION_MAJOR; + info.minor = PROJ_VERSION_MINOR; + info.patch = PROJ_VERSION_PATCH; + + /* This is a controlled environment, so no risk of sprintf buffer + overflow. A normal version string is xx.yy.zz which is 8 characters + long and there is room for 64 bytes in the version string. */ + sprintf(info.version, "%d.%d.%d", info.major, info.minor, info.patch); + + pj_strlcpy(info.release, pj_get_release(), sizeof(info.release)); + + + /* build search path string */ + tmpstr = getenv("HOME"); + if (tmpstr != NULL) { + pj_strlcpy(info.searchpath, tmpstr, sizeof(info.searchpath)); + } + + tmpstr = getenv("PROJ_LIB"); + if (tmpstr != NULL) { + if (strlen(info.searchpath) != 0) { + /* $HOME already in path */ + strcat(info.searchpath, ";"); + len = strlen(tmpstr); + strncat(info.searchpath, tmpstr, sizeof(info.searchpath)-len-1); + } else { + /* path is empty */ + pj_strlcpy(info.searchpath, tmpstr, sizeof(info.searchpath)); + } + } + + paths = proj_get_searchpath(); + n = proj_get_path_count(); + + for (i=0; i= 511) + continue; + + if (strlen(info.searchpath) != 0) { + strcat(info.searchpath, ";"); + len = strlen(paths[i]); + strncat(info.searchpath, paths[i], sizeof(info.searchpath)-len-1); + } else { + pj_strlcpy(info.searchpath, paths[i], sizeof(info.searchpath)); + } + } + + return info; +} + + +/*****************************************************************************/ +PJ_PROJ_INFO proj_pj_info(const PJ *P) { +/****************************************************************************** + Basic info about a particular instance of a projection object. + + Returns PJ_PROJ_INFO struct. + +******************************************************************************/ + PJ_PROJ_INFO info; + char *def; + + memset(&info, 0, sizeof(PJ_PROJ_INFO)); + + if (!P) { + return info; + } + + /* projection id */ + if (pj_param(P->ctx, P->params, "tproj").i) + pj_strlcpy(info.id, pj_param(P->ctx, P->params, "sproj").s, sizeof(info.id)); + + /* projection description */ + pj_strlcpy(info.description, P->descr, sizeof(info.description)); + + /* projection definition */ + def = pj_get_def((PJ *)P, 0); /* pj_get_def takes a non-const PJ pointer */ + pj_strlcpy(info.definition, &def[1], sizeof(info.definition)); /* def includes a leading space */ + pj_dealloc(def); + + /* this does not take into account that a pipeline potentially does not */ + /* have an inverse. */ + info.has_inverse = (P->inv != 0 || P->inv3d != 0 || P->invobs != 0); + + return info; +} + + +/*****************************************************************************/ +PJ_GRID_INFO proj_grid_info(const char *gridname) { +/****************************************************************************** + Information about a named datum grid. + + Returns PJ_GRID_INFO struct. + +******************************************************************************/ + PJ_GRID_INFO info; + + /*PJ_CONTEXT *ctx = proj_context_create(); */ + PJ_CONTEXT *ctx = pj_get_default_ctx(); + PJ_GRIDINFO *gridinfo = pj_gridinfo_init(ctx, gridname); + memset(&info, 0, sizeof(PJ_GRID_INFO)); + + /* in case the grid wasn't found */ + if (gridinfo->filename == NULL) { + pj_gridinfo_free(ctx, gridinfo); + strcpy(info.format, "missing"); + return info; + } + + /* name of grid */ + pj_strlcpy(info.gridname, gridname, sizeof(info.gridname)); + + /* full path of grid */ + pj_find_file(ctx, gridname, info.filename, sizeof(info.filename)); + + /* grid format */ + pj_strlcpy(info.format, gridinfo->format, sizeof(info.format)); + + /* grid size */ + info.n_lon = gridinfo->ct->lim.lam; + info.n_lat = gridinfo->ct->lim.phi; + + /* cell size */ + info.cs_lon = gridinfo->ct->del.lam; + info.cs_lat = gridinfo->ct->del.phi; + + /* bounds of grid */ + info.lowerleft = gridinfo->ct->ll; + info.upperright.lam = info.lowerleft.lam + info.n_lon*info.cs_lon; + info.upperright.phi = info.lowerleft.phi + info.n_lat*info.cs_lat; + + pj_gridinfo_free(ctx, gridinfo); + + return info; +} + +/*****************************************************************************/ +PJ_INIT_INFO proj_init_info(const char *initname){ +/****************************************************************************** + Information about a named init file. + + Maximum length of initname is 64. + + Returns PJ_INIT_INFO struct. + + If the init file is not found all members of + the return struct are set to 0. If the init file is found, but it the + metadata is missing, the value is set to "Unknown". + +******************************************************************************/ + int file_found, def_found=0; + char param[80], key[74]; + paralist *start, *next; + PJ_INIT_INFO info; + PJ_CONTEXT *ctx = pj_get_default_ctx(); + + memset(&info, 0, sizeof(PJ_INIT_INFO)); + + file_found = pj_find_file(ctx, initname, info.filename, sizeof(info.filename)); + if (!file_found || strlen(initname) > 64) { + return info; + } + + pj_strlcpy(info.name, initname, sizeof(info.name)); + strcpy(info.origin, "Unknown"); + strcpy(info.version, "Unknown"); + strcpy(info.lastupdate, "Unknown"); + + pj_strlcpy(key, initname, 64); /* make room for ":metadata\0" at the end */ + strncat(key, ":metadata", 9); + strcpy(param, "+init="); + strncat(param, key, 73); + + start = pj_mkparam(param); + next = pj_get_init(ctx, &start, start, key, &def_found); + + if (pj_param(ctx, start, "tversion").i) { + pj_strlcpy(info.version, pj_param(ctx, start, "sversion").s, sizeof(info.version)); + } + + if (pj_param(ctx, start, "torigin").i) { + pj_strlcpy(info.origin, pj_param(ctx, start, "sorigin").s, sizeof(info.origin)); + } + + if (pj_param(ctx, start, "tlastupdate").i) { + pj_strlcpy(info.lastupdate, pj_param(ctx, start, "slastupdate").s, sizeof(info.lastupdate)); + } + + for ( ; start; start = next) { + next = start->next; + pj_dalloc(start); + } + + return info; } @@ -565,18 +776,9 @@ PJ_FACTORS proj_factors(const PJ *P, const LP lp) { } -/* Release, or free, memory that was retrieved by the above functions */ -void *proj_release (void *buffer) { - return pj_dealloc (buffer); -} - - double proj_torad (double angle_in_degrees) { return PJ_TORAD (angle_in_degrees);} double proj_todeg (double angle_in_radians) { return PJ_TODEG (angle_in_radians);} -int proj_has_inverse(PJ *P) { - return (P->inv != 0 || P->inv3d != 0 || P->invobs != 0); -} double proj_dmstor(const char *is, char **rs) { return dmstor(is, rs); diff --git a/src/pj_open_lib.c b/src/pj_open_lib.c index 859adede..08532beb 100644 --- a/src/pj_open_lib.c +++ b/src/pj_open_lib.c @@ -29,6 +29,7 @@ *****************************************************************************/ #define PJ_LIB__ +#include "proj_internal.h" #include #include #include @@ -86,10 +87,19 @@ void pj_set_searchpath ( int count, const char **path ) strcpy(search_path[i], path[i]); } } - + path_count = count; } +/* just a couple of helper functions that lets other functions + access the otherwise private search path */ +const char **proj_get_searchpath(void) { + return (const char **)search_path; +} + +int proj_get_path_count(void) { + return path_count; +} /************************************************************************/ /* pj_open_lib_ex() */ /************************************************************************/ diff --git a/src/proj.def b/src/proj.def index 835391ac..12816f1c 100644 --- a/src/proj.def +++ b/src/proj.def @@ -90,54 +90,56 @@ EXPORTS geod_polygon_clear @88 pj_run_selftests @89 - proj_create @90 - proj_create_argv @91 - proj_create_crs_to_crs @92 - proj_destroy @93 + pj_find_file @90 - proj_trans_obs @94 - proj_trans_coord @95 - proj_transform @96 - proj_transform_obs @97 - proj_transform_coord @98 - proj_roundtrip @99 + proj_create @91 + proj_create_argv @92 + proj_create_crs_to_crs @93 + proj_destroy @94 - proj_coord @100 - proj_obs @101 - proj_coord_error @102 - proj_obs_error @103 + proj_trans_obs @95 + proj_trans_coord @96 + proj_transform @97 + proj_transform_obs @98 + proj_transform_coord @99 + proj_roundtrip @100 - proj_errno @104 - proj_errno_set @105 - proj_errno_reset @106 - proj_errno_restore @107 - proj_context_errno_set @108 + proj_coord @101 + proj_obs @102 + proj_coord_error @103 + proj_obs_error @104 - proj_context_create @109 - proj_context_set @110 - proj_context_inherit @111 - proj_context_destroy @112 + proj_errno @105 + proj_errno_set @106 + proj_errno_reset @107 + proj_errno_restore @108 + proj_context_errno_set @109 - proj_lp_dist @113 - proj_xy_dist @114 - proj_xyz_dist @115 + proj_context_create @110 + proj_context_set @111 + proj_context_inherit @112 + proj_context_destroy @113 - proj_log_level @116 - proj_log_func @117 - proj_log_error @118 - proj_log_debug @119 - proj_log_trace @120 + proj_lp_dist @114 + proj_xy_dist @115 + proj_xyz_dist @116 - proj_definition_retrieve @121 - proj_derivatives @122 - proj_factors @123 - proj_release @124 + proj_log_level @117 + proj_log_func @118 + proj_log_error @119 + proj_log_debug @120 + proj_log_trace @121 - proj_torad @125 - proj_todeg @126 - proj_has_inverse @127 + proj_info @122 + proj_pj_info @123 + proj_grid_info @124 + proj_init_info @125 + + proj_torad @126 + proj_todeg @127 proj_rtodms @128 proj_dmstor @129 + proj_derivatives @130 + proj_factors @131 - pj_find_file @130 diff --git a/src/proj.h b/src/proj.h index 5f165dc5..1d6191fd 100644 --- a/src/proj.h +++ b/src/proj.h @@ -156,7 +156,7 @@ extern "C" { ************************************************************************/ #define PROJ_VERSION_MAJOR 10 #define PROJ_VERSION_MINOR 0 -#define PROJ_VERSION_MICRO 0 +#define PROJ_VERSION_PATCH 0 #ifndef PJ_VERSION #define PJ_VERSION 10##000##00 @@ -192,6 +192,19 @@ typedef struct PJ_FACTORS PJ_FACTORS; struct PJconsts; typedef struct PJconsts PJ; /* the PJ object herself */ +/* Data type for library level information */ +struct PJ_INFO; +typedef struct PJ_INFO PJ_INFO; + +struct PJ_PROJ_INFO; +typedef struct PJ_PROJ_INFO PJ_PROJ_INFO; + +struct PJ_GRID_INFO; +typedef struct PJ_GRID_INFO PJ_GRID_INFO; + +struct PJ_INIT_INFO; +typedef struct PJ_INIT_INFO PJ_INIT_INFO; + /* Omega, Phi, Kappa: Rotations */ typedef struct {double o, p, k;} PJ_OPK; @@ -275,6 +288,7 @@ struct PJ_OBS { unsigned int flags; /* additional data, intended for flags */ }; + struct PJ_DERIVS { double x_l, x_p; /* derivatives of x for lambda-phi */ double y_l, y_p; /* derivatives of y for lambda-phi */ @@ -291,6 +305,44 @@ struct PJ_FACTORS { }; +struct PJ_INFO { + char release[64]; /* Release info. Version + date */ + char version[64]; /* Full version number */ + int major; /* Major release number */ + int minor; /* Minor release number */ + int patch; /* Patch level */ + char searchpath[512]; /* Paths where init and grid files are */ + /* looked for. Paths are separated by */ + /* semi-colons. */ +}; + +struct PJ_PROJ_INFO { + char id[16]; /* Name of the projection in question */ + char description[128]; /* Description of the projection */ + char definition[512]; /* Projection definition */ + int has_inverse; /* 1 if an inverse mapping exists, 0 otherwise */ +}; + +struct PJ_GRID_INFO { + char gridname[32]; /* name of grid */ + char filename[260]; /* full path to grid */ + char format[8]; /* file format of grid */ + LP lowerleft; /* Coordinates of lower left corner */ + LP upperright; /* Coordinates of upper right corner */ + int n_lon, n_lat; /* Grid size */ + double cs_lon, cs_lat; /* Cell size of grid */ +}; + +struct PJ_INIT_INFO { + char name[32]; /* name of init file */ + char filename[260]; /* full path to the init file. */ + char version[32]; /* version of the init file */ + char origin[32]; /* origin of the file, e.g. EPSG */ + char lastupdate[16]; /* Date of last update in YYYY-MM-DD format */ +}; + + + /* The context type - properly namespaced synonym for projCtx */ struct projCtx_t; typedef struct projCtx_t PJ_CONTEXT; @@ -358,10 +410,14 @@ int proj_errno_reset (PJ *P); void proj_errno_restore (PJ *P, int err); -/* Build a fully expanded proj_create() compatible representation of P */ -char *proj_definition_retrieve (PJ *P); -/* ...and get rid of it safely */ -void *proj_release (void *buffer); +PJ_DERIVS proj_derivatives(const PJ *P, const LP lp); +PJ_FACTORS proj_factors(const PJ *P, const LP lp); + +/* Info functions - get information about various PROJ.4 entities */ +PJ_INFO proj_info(void); +PJ_PROJ_INFO proj_pj_info(const PJ *P); +PJ_GRID_INFO proj_grid_info(const char *gridname); +PJ_INIT_INFO proj_init_info(const char *initname); /* These are trivial, and while occasionaly useful in real code, primarily here to */ @@ -370,15 +426,9 @@ void *proj_release (void *buffer); double proj_torad (double angle_in_degrees); double proj_todeg (double angle_in_radians); -/* Check if a projection has an inverse mapping */ -int proj_has_inverse(PJ *P); - double proj_dmstor(const char *is, char **rs); char* proj_rtodms(char *s, double r, int pos, int neg); -PJ_DERIVS proj_derivatives(const PJ *P, const LP lp); -PJ_FACTORS proj_factors(const PJ *P, const LP lp); - #ifdef __cplusplus } #endif diff --git a/src/proj_internal.h b/src/proj_internal.h index da457077..0b74b563 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -107,6 +107,10 @@ void proj_log_func (PJ_CONTEXT *ctx, void *app_data, PJ_LOG_FUNCTION log); /* Lowest level: Minimum support for fileapi */ void proj_fileapi_set (PJ *P, void *fileapi); +const char **proj_get_searchpath(void); +int proj_get_path_count(void); + +size_t pj_strlcpy(char *dst, const char *src, size_t siz); #ifdef __cplusplus } diff --git a/src/projects.h b/src/projects.h index 710d5022..872bf816 100644 --- a/src/projects.h +++ b/src/projects.h @@ -712,6 +712,7 @@ void pj_prepare (PJ *P, const char *description, void (*freeup)(struct PJconsts paralist *pj_clone_paralist( const paralist* ); paralist *pj_search_initcache( const char *filekey ); void pj_insert_initcache( const char *filekey, const paralist *list); +paralist *pj_get_init(projCtx ctx, paralist **start, paralist *next, char *name, int *found_def); double *pj_enfn(double); double pj_mlfn(double, double, double, double *); -- cgit v1.2.3