| 604 | #define TOL 1e-12 |
| 605 | |
| 606 | PJ_XYZ gridshiftData::grid_apply_internal( |
| 607 | PJ_CONTEXT *ctx, const std::string &type, bool isVerticalOnly, |
| 608 | const PJ_XYZ in, PJ_DIRECTION direction, const GenericShiftGrid *grid, |
| 609 | GenericShiftGridSet *gridset, bool &shouldRetry) { |
| 610 | |
| 611 | shouldRetry = false; |
| 612 | if (in.x == HUGE_VAL) |
| 613 | return in; |
| 614 | |
| 615 | /* normalized longitude of input */ |
| 616 | const NS_PROJ::ExtentAndRes *extent; |
| 617 | PJ_XY normalized_in = normalizeX(grid, in, extent); |
| 618 | |
| 619 | bool biquadraticInterpolationOut = false; |
| 620 | PJ_XYZ shift = grid_interpolate(ctx, type, normalized_in, grid, |
| 621 | biquadraticInterpolationOut); |
| 622 | if (grid->hasChanged()) { |
| 623 | shouldRetry = gridset->reopen(ctx); |
| 624 | PJ_XYZ out; |
| 625 | out.x = out.y = out.z = HUGE_VAL; |
| 626 | return out; |
| 627 | } |
| 628 | if (shift.x == HUGE_VAL) |
| 629 | return shift; |
| 630 | |
| 631 | if (direction == PJ_FWD) { |
| 632 | PJ_XYZ out = in; |
| 633 | out.x += shift.x; |
| 634 | out.y += shift.y; |
| 635 | out.z += shift.z; |
| 636 | return out; |
| 637 | } |
| 638 | |
| 639 | if (isVerticalOnly) { |
| 640 | PJ_XYZ out = in; |
| 641 | out.z -= shift.z; |
| 642 | return out; |
| 643 | } |
| 644 | |
| 645 | PJ_XY guess; |
| 646 | guess.x = normalized_in.x - shift.x; |
| 647 | guess.y = normalized_in.y - shift.y; |
| 648 | |
| 649 | // NOAA NCAT transformer tool doesn't do iteration in the reverse path. |
| 650 | // Do the same (only for biquadratic, although NCAT applies this logic to |
| 651 | // bilinear too) |
| 652 | // Cf |
| 653 | // https://github.com/noaa-ngs/ncat-lib/blob/77bcff1ce4a78fe06d0312102ada008aefcc2c62/src/gov/noaa/ngs/grid/Transformer.java#L374 |
| 654 | // When trying to do iterative reverse path with biquadratic, we can |
| 655 | // get convergence failures on points that are close to the boundary of |
| 656 | // cells or half-cells. For example with |
| 657 | // echo -122.4250009683 37.8286740788 0 | bin/cct -I +proj=gridshift |
| 658 | // +grids=tests/us_noaa_nadcon5_nad83_1986_nad83_harn_conus_extract_sanfrancisco.tif |
| 659 | // +interpolation=biquadratic |
| 660 | if (!biquadraticInterpolationOut) { |
| 661 | int i = MAX_ITERATIONS; |
| 662 | const double toltol = TOL * TOL; |
| 663 | PJ_XY diff; |
nothing calls this directly
no test coverage detected