| 2970 | #define TOL 1e-12 |
| 2971 | |
| 2972 | static PJ_LP pj_hgrid_apply_internal(PJ_CONTEXT *ctx, PJ_LP in, |
| 2973 | PJ_DIRECTION direction, |
| 2974 | const HorizontalShiftGrid *grid, |
| 2975 | HorizontalShiftGridSet *gridset, |
| 2976 | const ListOfHGrids &grids, |
| 2977 | bool &shouldRetry) { |
| 2978 | PJ_LP t, tb, del, dif; |
| 2979 | int i = MAX_ITERATIONS; |
| 2980 | const double toltol = TOL * TOL; |
| 2981 | |
| 2982 | shouldRetry = false; |
| 2983 | if (in.lam == HUGE_VAL) |
| 2984 | return in; |
| 2985 | |
| 2986 | /* normalize input to ll origin */ |
| 2987 | tb = in; |
| 2988 | const auto *extent = &(grid->extentAndRes()); |
| 2989 | const double epsilon = |
| 2990 | (extent->resX + extent->resY) * REL_TOLERANCE_HGRIDSHIFT; |
| 2991 | tb.lam -= extent->west; |
| 2992 | if (tb.lam + epsilon < 0) |
| 2993 | tb.lam += 2 * M_PI; |
| 2994 | else if (tb.lam - epsilon > extent->east - extent->west) |
| 2995 | tb.lam -= 2 * M_PI; |
| 2996 | tb.phi -= extent->south; |
| 2997 | |
| 2998 | t = pj_hgrid_interpolate(tb, grid, true); |
| 2999 | if (grid->hasChanged()) { |
| 3000 | shouldRetry = gridset->reopen(ctx); |
| 3001 | return t; |
| 3002 | } |
| 3003 | if (t.lam == HUGE_VAL) |
| 3004 | return t; |
| 3005 | |
| 3006 | if (direction == PJ_FWD) { |
| 3007 | in.lam += t.lam; |
| 3008 | in.phi += t.phi; |
| 3009 | return in; |
| 3010 | } |
| 3011 | |
| 3012 | t.lam = tb.lam - t.lam; |
| 3013 | t.phi = tb.phi - t.phi; |
| 3014 | |
| 3015 | do { |
| 3016 | del = pj_hgrid_interpolate(t, grid, true); |
| 3017 | if (grid->hasChanged()) { |
| 3018 | shouldRetry = gridset->reopen(ctx); |
| 3019 | return t; |
| 3020 | } |
| 3021 | |
| 3022 | /* We can possibly go outside of the initial guessed grid, so try */ |
| 3023 | /* to fetch a new grid into which iterate... */ |
| 3024 | if (del.lam == HUGE_VAL) { |
| 3025 | PJ_LP lp; |
| 3026 | lp.lam = t.lam + extent->west; |
| 3027 | lp.phi = t.phi + extent->south; |
| 3028 | auto newGrid = findGrid(grids, lp, gridset); |
| 3029 | if (newGrid == nullptr || newGrid == grid || newGrid->isNullGrid()) |
no test coverage detected