aboutsummaryrefslogtreecommitdiff
path: root/src/pj_obs_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pj_obs_api.c')
-rw-r--r--src/pj_obs_api.c234
1 files changed, 218 insertions, 16 deletions
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);