static void process(FILE *fid) { char line[MAX_LINE], *s, t, pline[100]; projUV val; double tmp; for (;;) { if (input.bin) fread(&val, sizeof(projUV), 1, fid); else if (s = fgets(line, MAX_LINE, fid)) { if (*s == tag) { fputs(line, stdout); continue; } else if (input.ll) { val.u = dmstor(s, &s); val.v = dmstor(s, &s); } else { val.u = strtod(s, &s); val.v = strtod(s, &s); } } if (feof(fid)) break; if (input.rev) { tmp = val.u; val.u = val.v; val.v = tmp; } /* data in, manupulate */ if (input.cnv) val = pj_inv(val, input.cnv); if (input.hp) val = nad_cvt(val, 1, htab); /* nad conversion */ if (ctab) val = nad_cvt(val, input.t83 ? 1 : 0, ctab); if (output.hp) val = nad_cvt(val, 0, htab); if (output.cnv) val = pj_fwd(val, output.cnv); /* output data */ if (output.rev) { tmp = val.u; val.u = val.v; val.v = tmp; } if (output.bin) (void)fwrite(&val, sizeof(projUV), 1, stdout); else { if (echoin) { t = *s; *s = '\0'; (void)fputs(line, stdout); (void)putchar('\t'); *s = t; } if (val.u == HUGE_VAL) (void)fputs(oterr, stdout); else if (output.ll) if (oform) { (void)printf(oform, val.u * RAD_TO_DEG); (void)putchar('\t'); (void)printf(oform, val.v * RAD_TO_DEG); } else if (output.rev) { (void)fputs(rtodms(pline, val.u, 'N', 'S'), stdout); (void)putchar('\t'); (void)fputs(rtodms(pline, val.v, 'E', 'W'), stdout); } else { (void)fputs(rtodms(pline, val.u, 'E', 'W'), stdout); (void)putchar('\t'); (void)fputs(rtodms(pline, val.v, 'N', 'S'), stdout); } else { (void)printf(oform ? oform : "%.2f", val.u); (void)putchar('\t'); (void)printf(oform ? oform : "%.2f", val.v); } if (input.bin) putchar('\n'); else (void)fputs(s, stdout); } } }
int pj_gc_apply_gridshift( PJ *defn, int inverse, long point_count, int point_offset, double *x, double *y, double *z ) { int i; if( defn->catalog == NULL ) { defn->catalog = pj_gc_findcatalog( defn->ctx, defn->catalog_name ); if( defn->catalog == NULL ) return defn->ctx->last_errno; } defn->ctx->last_errno = 0; for( i = 0; i < point_count; i++ ) { long io = i * point_offset; LP input, output_after, output_before; double mix_ratio; PJ_GRIDINFO *gi; input.phi = y[io]; input.lam = x[io]; /* make sure we have appropriate "after" shift file available */ if( defn->last_after_grid == NULL || input.lam < defn->last_after_region.ll_long || input.lam > defn->last_after_region.ur_long || input.phi < defn->last_after_region.ll_lat || input.phi > defn->last_after_region.ll_lat ) { defn->last_after_grid = pj_gc_findgrid( defn->ctx, defn->catalog, 1, input, defn->datum_date, &(defn->last_after_region), &(defn->last_after_date)); } gi = defn->last_after_grid; assert( gi->child == NULL ); /* load the grid shift info if we don't have it. */ if( gi->ct->cvs == NULL && !pj_gridinfo_load( defn->ctx, gi ) ) { pj_ctx_set_errno( defn->ctx, -38 ); return -38; } output_after = nad_cvt( input, inverse, gi->ct ); if( output_after.lam == HUGE_VAL ) { if( defn->ctx->debug_level >= PJ_LOG_DEBUG_MAJOR ) { pj_log( defn->ctx, PJ_LOG_DEBUG_MAJOR, "pj_apply_gridshift(): failed to find a grid shift table for\n" " location (%.7fdW,%.7fdN)", x[io] * RAD_TO_DEG, y[io] * RAD_TO_DEG ); } continue; } if( defn->datum_date == 0.0 ) { y[io] = output_after.phi; x[io] = output_after.lam; continue; } /* make sure we have appropriate "before" shift file available */ if( defn->last_before_grid == NULL || input.lam < defn->last_before_region.ll_long || input.lam > defn->last_before_region.ur_long || input.phi < defn->last_before_region.ll_lat || input.phi > defn->last_before_region.ll_lat ) { defn->last_before_grid = pj_gc_findgrid( defn->ctx, defn->catalog, 0, input, defn->datum_date, &(defn->last_before_region), &(defn->last_before_date)); } gi = defn->last_before_grid; assert( gi->child == NULL ); /* load the grid shift info if we don't have it. */ if( gi->ct->cvs == NULL && !pj_gridinfo_load( defn->ctx, gi ) ) { pj_ctx_set_errno( defn->ctx, -38 ); return -38; } output_before = nad_cvt( input, inverse, gi->ct ); if( output_before.lam == HUGE_VAL ) { if( defn->ctx->debug_level >= PJ_LOG_DEBUG_MAJOR ) { pj_log( defn->ctx, PJ_LOG_DEBUG_MAJOR, "pj_apply_gridshift(): failed to find a grid shift table for\n" " location (%.7fdW,%.7fdN)", x[io] * RAD_TO_DEG, y[io] * RAD_TO_DEG ); } continue; } mix_ratio = (defn->datum_date - defn->last_before_date) / (defn->last_after_date - defn->last_before_date); y[io] = mix_ratio * output_after.phi + (1.0-mix_ratio) * output_before.phi; x[io] = mix_ratio * output_after.lam + (1.0-mix_ratio) * output_before.lam; } return 0; }
int pj_apply_gridshift( const char *nadgrids, int inverse, long point_count, int point_offset, double *x, double *y, double *z ) { int grid_count = 0; PJ_GRIDINFO **tables; int i; int debug_flag = getenv( "PROJ_DEBUG" ) != NULL; static int debug_count = 0; pj_errno = 0; tables = pj_gridlist_from_nadgrids( nadgrids, &grid_count); if( tables == NULL || grid_count == 0 ) return pj_errno; for( i = 0; i < point_count; i++ ) { long io = i * point_offset; LP input, output; int itable; input.phi = y[io]; input.lam = x[io]; output.phi = HUGE_VAL; output.lam = HUGE_VAL; /* keep trying till we find a table that works */ for( itable = 0; itable < grid_count; itable++ ) { PJ_GRIDINFO *gi = tables[itable]; struct CTABLE *ct = gi->ct; /* skip tables that don't match our point at all. */ if( ct->ll.phi > input.phi || ct->ll.lam > input.lam || ct->ll.phi + (ct->lim.phi-1) * ct->del.phi < input.phi || ct->ll.lam + (ct->lim.lam-1) * ct->del.lam < input.lam ) continue; /* If we have child nodes, check to see if any of them apply. */ if( gi->child != NULL ) { PJ_GRIDINFO *child; for( child = gi->child; child != NULL; child = child->next ) { struct CTABLE *ct1 = child->ct; if( ct1->ll.phi > input.phi || ct1->ll.lam > input.lam || ct1->ll.phi+(ct1->lim.phi-1)*ct1->del.phi < input.phi || ct1->ll.lam+(ct1->lim.lam-1)*ct1->del.lam < input.lam) continue; break; } /* we found a more refined child node to use */ if( child != NULL ) { gi = child; ct = child->ct; } } /* load the grid shift info if we don't have it. */ if( ct->cvs == NULL && !pj_gridinfo_load( gi ) ) { pj_errno = -38; return pj_errno; } output = nad_cvt( input, inverse, ct ); if( output.lam != HUGE_VAL ) { if( debug_flag && debug_count++ < 20 ) fprintf( stderr, "pj_apply_gridshift(): used %s\n", ct->id ); break; } } if( output.lam == HUGE_VAL ) { if( debug_flag ) { fprintf( stderr, "pj_apply_gridshift(): failed to find a grid shift table for\n" " location (%.7fdW,%.7fdN)\n", x[io] * RAD_TO_DEG, y[io] * RAD_TO_DEG ); fprintf( stderr, " tried: %s\n", nadgrids ); } pj_errno = -38; return pj_errno; } else { y[io] = output.phi; x[io] = output.lam; } } return 0; }
int pj_apply_gridshift_3( projCtx ctx, PJ_GRIDINFO **tables, int grid_count, int inverse, long point_count, int point_offset, double *x, double *y, double *z ) { int i; static int debug_count = 0; if( tables == NULL || grid_count == 0 ) { pj_ctx_set_errno( ctx, -38); return -38; } ctx->last_errno = 0; for( i = 0; i < point_count; i++ ) { long io = i * point_offset; LP input, output; int itable; input.phi = y[io]; input.lam = x[io]; output.phi = HUGE_VAL; output.lam = HUGE_VAL; /* keep trying till we find a table that works */ for( itable = 0; itable < grid_count; itable++ ) { PJ_GRIDINFO *gi = tables[itable]; struct CTABLE *ct = gi->ct; double epsilon = (fabs(ct->del.phi)+fabs(ct->del.lam))/10000.0; /* skip tables that don't match our point at all. */ if( ct->ll.phi - epsilon > input.phi || ct->ll.lam - epsilon > input.lam || (ct->ll.phi + (ct->lim.phi-1) * ct->del.phi + epsilon < input.phi) || (ct->ll.lam + (ct->lim.lam-1) * ct->del.lam + epsilon < input.lam) ) continue; /* If we have child nodes, check to see if any of them apply. */ if( gi->child != NULL ) { PJ_GRIDINFO *child; for( child = gi->child; child != NULL; child = child->next ) { struct CTABLE *ct1 = child->ct; double epsilon = (fabs(ct1->del.phi)+fabs(ct1->del.lam))/10000.0; if( ct1->ll.phi - epsilon > input.phi || ct1->ll.lam - epsilon > input.lam || (ct1->ll.phi+(ct1->lim.phi-1)*ct1->del.phi + epsilon < input.phi) || (ct1->ll.lam+(ct1->lim.lam-1)*ct1->del.lam + epsilon < input.lam) ) continue; break; } /* we found a more refined child node to use */ if( child != NULL ) { gi = child; ct = child->ct; } } /* load the grid shift info if we don't have it. */ if( ct->cvs == NULL && !pj_gridinfo_load( ctx, gi ) ) { pj_ctx_set_errno( ctx, -38 ); return -38; } output = nad_cvt( input, inverse, ct ); if( output.lam != HUGE_VAL ) { if( debug_count++ < 20 ) pj_log( ctx, PJ_LOG_DEBUG_MINOR, "pj_apply_gridshift(): used %s", ct->id ); break; } } if( output.lam == HUGE_VAL ) { if( ctx->debug_level >= PJ_LOG_DEBUG_MAJOR ) { pj_log( ctx, PJ_LOG_DEBUG_MAJOR, "pj_apply_gridshift(): failed to find a grid shift table for\n" " location (%.7fdW,%.7fdN)", x[io] * RAD_TO_DEG, y[io] * RAD_TO_DEG ); for( itable = 0; itable < grid_count; itable++ ) { PJ_GRIDINFO *gi = tables[itable]; if( itable == 0 ) pj_log( ctx, PJ_LOG_DEBUG_MAJOR, " tried: %s", gi->gridname ); else pj_log( ctx, PJ_LOG_DEBUG_MAJOR, ",%s", gi->gridname ); } } /* * We don't actually have any machinery currently to set the * following macro, so this is mostly kept here to make it clear * how we ought to operate if we wanted to make it super clear * that an error has occured when points are outside our available * datum shift areas. But if this is on, we will find that "low * value" points on the fringes of some datasets will completely * fail causing lots of problems when it is more or less ok to * just not apply a datum shift. So rather than deal with * that we just fallback to no shift. (see also bug #45). */ #ifdef ERR_GRID_AREA_TRANSIENT_SEVERE y[io] = HUGE_VAL; x[io] = HUGE_VAL; #else /* leave x/y unshifted. */ #endif } else { y[io] = output.phi; x[io] = output.lam; } } return 0; }