int proj_context_errno (PJ_CONTEXT *ctx) { /****************************************************************************** Read an error directly from a context, without going through a PJ belonging to that context. ******************************************************************************/ if (0==ctx) ctx = pj_get_default_ctx(); return pj_ctx_get_errno (ctx); }
static paralist *append_defaults_to_paralist (PJ_CONTEXT *ctx, paralist *start, char *key) { paralist *defaults, *last = 0; char keystring[ID_TAG_MAX + 20]; paralist *next, *proj; int err; if (0==start) return 0; if (strlen(key) > ID_TAG_MAX) return 0; /* Set defaults, unless inhibited (either explicitly through a "no_defs" token */ /* or implicitly, because we are initializing a pipeline) */ if (pj_param_exists (start, "no_defs")) return start; proj = pj_param_exists (start, "proj"); if (0==proj) return start; if (strlen (proj->param) < 6) return start; if (0==strcmp ("pipeline", proj->param + 5)) return start; err = pj_ctx_get_errno (ctx); pj_ctx_set_errno (ctx, 0); /* Locate end of start-list */ for (last = start; last->next; last = last->next); strcpy (keystring, "proj_def.dat:"); strcat (keystring, key); defaults = get_init (ctx, keystring); /* Defaults are optional - so we don't care if we cannot open the file */ pj_ctx_set_errno (ctx, err); if (!defaults) return last; /* Loop over all default items */ for (next = defaults; next; next = next->next) { /* Don't override existing parameter value of same name */ if (pj_param_exists (start, next->param)) continue; /* Don't default ellipse if datum, ellps or any ellipsoid information is set */ if (0==strncmp(next->param,"ellps=", 6)) { if (pj_param_exists (start, "datum")) continue; if (pj_param_exists (start, "ellps")) continue; if (pj_param_exists (start, "a")) continue; if (pj_param_exists (start, "b")) continue; if (pj_param_exists (start, "rf")) continue; if (pj_param_exists (start, "f")) continue; if (pj_param_exists (start, "e")) continue; if (pj_param_exists (start, "es")) continue; } /* If we're here, it's OK to append the current default item */ last = last->next = pj_mkparam(next->param); } last->next = 0; pj_dealloc_params (ctx, defaults, 0); return last; }
int proj_errno (const PJ *P) { /****************************************************************************** Read an error level from the context of a PJ. ******************************************************************************/ return pj_ctx_get_errno (pj_get_ctx ((PJ *) P)); }
int pj_transform( PJ *srcdefn, PJ *dstdefn, long point_count, int point_offset, double *x, double *y, double *z ) { long i; int err; srcdefn->ctx->last_errno = 0; dstdefn->ctx->last_errno = 0; if( point_offset == 0 ) point_offset = 1; /* -------------------------------------------------------------------- */ /* Transform unusual input coordinate axis orientation to */ /* standard form if needed. */ /* -------------------------------------------------------------------- */ if( strcmp(srcdefn->axis,"enu") != 0 ) { int err; err = pj_adjust_axis( srcdefn->ctx, srcdefn->axis, 0, point_count, point_offset, x, y, z ); if( err != 0 ) return err; } /* -------------------------------------------------------------------- */ /* Transform Z to meters if it isn't already. */ /* -------------------------------------------------------------------- */ if( srcdefn->vto_meter != 1.0 && z != NULL ) { for( i = 0; i < point_count; i++ ) z[point_offset*i] *= srcdefn->vto_meter; } /* -------------------------------------------------------------------- */ /* Transform geocentric source coordinates to lat/long. */ /* -------------------------------------------------------------------- */ if( srcdefn->is_geocent ) { if( z == NULL ) { pj_ctx_set_errno( pj_get_ctx(srcdefn), PJD_ERR_GEOCENTRIC); return PJD_ERR_GEOCENTRIC; } if( srcdefn->to_meter != 1.0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] != HUGE_VAL ) { x[point_offset*i] *= srcdefn->to_meter; y[point_offset*i] *= srcdefn->to_meter; } } } err = pj_geocentric_to_geodetic( srcdefn->a_orig, srcdefn->es_orig, point_count, point_offset, x, y, z ); if( err != 0 ) return err; } /* -------------------------------------------------------------------- */ /* Transform source points to lat/long, if they aren't */ /* already. */ /* -------------------------------------------------------------------- */ else if( !srcdefn->is_latlong ) { if( srcdefn->inv == NULL ) { pj_ctx_set_errno( pj_get_ctx(srcdefn), -17 ); pj_log( pj_get_ctx(srcdefn), PJ_LOG_ERROR, "pj_transform(): source projection not invertable" ); return -17; } for( i = 0; i < point_count; i++ ) { XY projected_loc; LP geodetic_loc; projected_loc.u = x[point_offset*i]; projected_loc.v = y[point_offset*i]; if( projected_loc.u == HUGE_VAL ) continue; geodetic_loc = pj_inv( projected_loc, srcdefn ); if( srcdefn->ctx->last_errno != 0 ) { if( (srcdefn->ctx->last_errno != 33 /*EDOM*/ && srcdefn->ctx->last_errno != 34 /*ERANGE*/ ) && (srcdefn->ctx->last_errno > 0 || srcdefn->ctx->last_errno < -44 || point_count == 1 || transient_error[-srcdefn->ctx->last_errno] == 0 ) ) return srcdefn->ctx->last_errno; else { geodetic_loc.u = HUGE_VAL; geodetic_loc.v = HUGE_VAL; } } x[point_offset*i] = geodetic_loc.u; y[point_offset*i] = geodetic_loc.v; } } /* -------------------------------------------------------------------- */ /* But if they are already lat long, adjust for the prime */ /* meridian if there is one in effect. */ /* -------------------------------------------------------------------- */ if( srcdefn->from_greenwich != 0.0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] != HUGE_VAL ) x[point_offset*i] += srcdefn->from_greenwich; } } /* -------------------------------------------------------------------- */ /* Do we need to translate from geoid to ellipsoidal vertical */ /* datum? */ /* -------------------------------------------------------------------- */ if( srcdefn->has_geoid_vgrids ) { if( pj_apply_vgridshift( srcdefn, "sgeoidgrids", &(srcdefn->vgridlist_geoid), &(srcdefn->vgridlist_geoid_count), 0, point_count, point_offset, x, y, z ) != 0 ) return pj_ctx_get_errno(srcdefn->ctx); } /* -------------------------------------------------------------------- */ /* Convert datums if needed, and possible. */ /* -------------------------------------------------------------------- */ if( pj_datum_transform( srcdefn, dstdefn, point_count, point_offset, x, y, z ) != 0 ) { if( srcdefn->ctx->last_errno != 0 ) return srcdefn->ctx->last_errno; else return dstdefn->ctx->last_errno; } /* -------------------------------------------------------------------- */ /* Do we need to translate from geoid to ellipsoidal vertical */ /* datum? */ /* -------------------------------------------------------------------- */ if( dstdefn->has_geoid_vgrids ) { if( pj_apply_vgridshift( dstdefn, "sgeoidgrids", &(dstdefn->vgridlist_geoid), &(dstdefn->vgridlist_geoid_count), 1, point_count, point_offset, x, y, z ) != 0 ) return dstdefn->ctx->last_errno; } /* -------------------------------------------------------------------- */ /* But if they are staying lat long, adjust for the prime */ /* meridian if there is one in effect. */ /* -------------------------------------------------------------------- */ if( dstdefn->from_greenwich != 0.0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] != HUGE_VAL ) x[point_offset*i] -= dstdefn->from_greenwich; } } /* -------------------------------------------------------------------- */ /* Transform destination latlong to geocentric if required. */ /* -------------------------------------------------------------------- */ if( dstdefn->is_geocent ) { if( z == NULL ) { pj_ctx_set_errno( dstdefn->ctx, PJD_ERR_GEOCENTRIC ); return PJD_ERR_GEOCENTRIC; } pj_geodetic_to_geocentric( dstdefn->a_orig, dstdefn->es_orig, point_count, point_offset, x, y, z ); if( dstdefn->fr_meter != 1.0 ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] != HUGE_VAL ) { x[point_offset*i] *= dstdefn->fr_meter; y[point_offset*i] *= dstdefn->fr_meter; } } } } /* -------------------------------------------------------------------- */ /* Transform destination points to projection coordinates, if */ /* desired. */ /* -------------------------------------------------------------------- */ else if( !dstdefn->is_latlong ) { for( i = 0; i < point_count; i++ ) { XY projected_loc; LP geodetic_loc; geodetic_loc.u = x[point_offset*i]; geodetic_loc.v = y[point_offset*i]; if( geodetic_loc.u == HUGE_VAL ) continue; projected_loc = pj_fwd( geodetic_loc, dstdefn ); if( dstdefn->ctx->last_errno != 0 ) { if( (dstdefn->ctx->last_errno != 33 /*EDOM*/ && dstdefn->ctx->last_errno != 34 /*ERANGE*/ ) && (dstdefn->ctx->last_errno > 0 || dstdefn->ctx->last_errno < -44 || point_count == 1 || transient_error[-dstdefn->ctx->last_errno] == 0 ) ) return dstdefn->ctx->last_errno; else { projected_loc.u = HUGE_VAL; projected_loc.v = HUGE_VAL; } } x[point_offset*i] = projected_loc.u; y[point_offset*i] = projected_loc.v; } } /* -------------------------------------------------------------------- */ /* If a wrapping center other than 0 is provided, rewrap around */ /* the suggested center (for latlong coordinate systems only). */ /* -------------------------------------------------------------------- */ else if( dstdefn->is_latlong && dstdefn->is_long_wrap_set ) { for( i = 0; i < point_count; i++ ) { if( x[point_offset*i] == HUGE_VAL ) continue; while( x[point_offset*i] < dstdefn->long_wrap_center - PI ) x[point_offset*i] += TWOPI; while( x[point_offset*i] > dstdefn->long_wrap_center + PI ) x[point_offset*i] -= TWOPI; } } /* -------------------------------------------------------------------- */ /* Transform Z from meters if needed. */ /* -------------------------------------------------------------------- */ if( dstdefn->vto_meter != 1.0 && z != NULL ) { for( i = 0; i < point_count; i++ ) z[point_offset*i] *= dstdefn->vfr_meter; } /* -------------------------------------------------------------------- */ /* Transform normalized axes into unusual output coordinate axis */ /* orientation if needed. */ /* -------------------------------------------------------------------- */ if( strcmp(dstdefn->axis,"enu") != 0 ) { int err; err = pj_adjust_axis( dstdefn->ctx, dstdefn->axis, 1, point_count, point_offset, x, y, z ); if( err != 0 ) return err; } return 0; }