| 750 | static const std::string sHORIZONTAL_OFFSET("HORIZONTAL_OFFSET"); |
| 751 | |
| 752 | PJ_XYZ gridshiftData::apply(PJ *P, PJ_DIRECTION direction, PJ_XYZ xyz) { |
| 753 | PJ_XYZ out; |
| 754 | |
| 755 | out.x = HUGE_VAL; |
| 756 | out.y = HUGE_VAL; |
| 757 | out.z = HUGE_VAL; |
| 758 | |
| 759 | std::string &type = m_mainGridType; |
| 760 | bool bFoundGeog3DOffset = false; |
| 761 | while (true) { |
| 762 | GenericShiftGridSet *gridset = nullptr; |
| 763 | const GenericShiftGrid *grid = findGrid(type, xyz, gridset); |
| 764 | if (!grid) { |
| 765 | if (m_mainGridTypeIsGeographic3DOffset && m_bHasHorizontalOffset) { |
| 766 | // If we have a mix of grids with GEOGRAPHIC_3D_OFFSET |
| 767 | // and HORIZONTAL_OFFSET+ELLIPSOIDAL_HEIGHT_OFFSET |
| 768 | type = sHORIZONTAL_OFFSET; |
| 769 | grid = findGrid(type, xyz, gridset); |
| 770 | } |
| 771 | if (!grid) { |
| 772 | proj_context_errno_set(P->ctx, |
| 773 | PROJ_ERR_COORD_TRANSFM_OUTSIDE_GRID); |
| 774 | return out; |
| 775 | } |
| 776 | } else { |
| 777 | if (m_mainGridTypeIsGeographic3DOffset) |
| 778 | bFoundGeog3DOffset = true; |
| 779 | } |
| 780 | |
| 781 | if (grid->isNullGrid()) { |
| 782 | out = xyz; |
| 783 | break; |
| 784 | } |
| 785 | bool shouldRetry = false; |
| 786 | out = grid_apply_internal( |
| 787 | P->ctx, type, !(m_bHasGeographic3DOffset || m_bHasHorizontalOffset), |
| 788 | xyz, direction, grid, gridset, shouldRetry); |
| 789 | if (!shouldRetry) { |
| 790 | break; |
| 791 | } |
| 792 | } |
| 793 | |
| 794 | if (out.x == HUGE_VAL || out.y == HUGE_VAL) { |
| 795 | if (proj_context_errno(P->ctx) == 0) { |
| 796 | proj_context_errno_set(P->ctx, PROJ_ERR_COORD_TRANSFM_OUTSIDE_GRID); |
| 797 | } |
| 798 | return out; |
| 799 | } |
| 800 | |
| 801 | // Second pass to apply vertical transformation, if it is in a |
| 802 | // separate grid than lat-lon offsets. |
| 803 | if (!bFoundGeog3DOffset && !m_auxGridType.empty()) { |
| 804 | xyz = out; |
| 805 | while (true) { |
| 806 | GenericShiftGridSet *gridset = nullptr; |
| 807 | const auto grid = findGrid(m_auxGridType, xyz, gridset); |
| 808 | if (!grid) { |
| 809 | proj_context_errno_set(P->ctx, |
no test coverage detected