aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/PJ_cart.c65
-rw-r--r--src/pj_init.c13
-rw-r--r--src/pj_internal.c47
-rw-r--r--src/pj_obs_api.c234
-rw-r--r--src/pj_open_lib.c12
-rw-r--r--src/proj.def80
-rw-r--r--src/proj.h72
-rw-r--r--src/proj_internal.h4
-rw-r--r--src/projects.h1
9 files changed, 439 insertions, 89 deletions
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 <Todd.Miller@courtesan.com>
+ *
+ * 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<n; i++) {
+ if (strlen(info.searchpath)+strlen(paths[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 <projects.h>
#include <stdio.h>
#include <string.h>
@@ -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 *);