Skip to content

Commit 063e2a8

Browse files
committed
Make all Transform methods of OGRCoordinateTransformation and GDALTransformerFunc return FALSE as soon as one point fails to transform
Fixes OSGeo#11817 Kind of a breaking change, but the current behavior was highly inconsistent and hard to reason about. New paragraph in MIGRATION_GUIDE.TXT: - The following methods OGRCoordinateTransformation::Transform(size_t nCount, double *x, double *y, double *z, double *t, int *pabSuccess) and OGRCoordinateTransformation::TransformWithErrorCodes(size_t nCount, double *x, double *y, double *z, double *t, int *panErrorCodes) are modified to return FALSE as soon as at least one point fails to transform (to be consistent with the other form of Transform() that doesn't take a "t" argument), whereas previously they would return FALSE only if no transformation was found. The GDALTransformerFunc callback and its implementations (GenImgProjTransformer, RPCTransformer, etc.) are also modified to return FALSE as soon as at least one point fails to transform.
1 parent b2068ed commit 063e2a8

12 files changed

+288
-262
lines changed

MIGRATION_GUIDE.TXT

+13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,19 @@ MIGRATION GUIDE FROM GDAL 3.10 to GDAL 3.11
1010
- If only a specific GDAL Minor version is to be supported, this must now be
1111
specified in the find_package call in CMake via a version range specification.
1212

13+
- The following methods
14+
OGRCoordinateTransformation::Transform(size_t nCount, double *x, double *y,
15+
double *z, double *t, int *pabSuccess) and
16+
OGRCoordinateTransformation::TransformWithErrorCodes(size_t nCount, double *x,
17+
double *y, double *z, double *t, int *panErrorCodes) are modified to return
18+
FALSE as soon as at least one point fails to transform (to be consistent with
19+
the other form of Transform() that doesn't take a "t" argument), whereas
20+
previously they would return FALSE only if no transformation was found.
21+
22+
The GDALTransformerFunc callback and its implementations (GenImgProjTransformer,
23+
RPCTransformer, etc.) are also modified to return FALSE as soon as at least
24+
one point fails to transform.
25+
1326
MIGRATION GUIDE FROM GDAL 3.9 to GDAL 3.10
1427
------------------------------------------
1528

alg/gdal_alg.h

+16
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,22 @@ CPLErr CPL_DLL CPL_STDCALL GDALSieveFilter(
7676
* Warp Related.
7777
*/
7878

79+
/**
80+
* Callback to transforms points.
81+
*
82+
* @param pTransformerArg return value from a GDALCreateXXXXTransformer() function
83+
* @param bDstToSrc TRUE if transformation is from the destination
84+
* (georeferenced) coordinates to pixel/line or FALSE when transforming
85+
* from pixel/line to georeferenced coordinates.
86+
* @param nPointCount the number of values in the x, y and z arrays.
87+
* @param[in,out] x array containing the X values to be transformed. Must not be NULL.
88+
* @param[in,out] y array containing the Y values to be transformed. Must not be NULL.
89+
* @param[in,out] z array containing the Z values to be transformed. Must not be NULL.
90+
* @param[out] panSuccess array in which a flag indicating success (TRUE) or
91+
* failure (FALSE) of the transformation are placed. Must not be NULL.
92+
*
93+
* @return TRUE if all points have been successfully transformed.
94+
*/
7995
typedef int (*GDALTransformerFunc)(void *pTransformerArg, int bDstToSrc,
8096
int nPointCount, double *x, double *y,
8197
double *z, int *panSuccess);

alg/gdal_crs.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ void GDALDestroyGCPTransformer(void *pTransformArg)
422422
* @param panSuccess array in which a flag indicating success (TRUE) or
423423
* failure (FALSE) of the transformation are placed.
424424
*
425-
* @return TRUE.
425+
* @return TRUE if all points have been successfully transformed.
426426
*/
427427

428428
int GDALGCPTransform(void *pTransformArg, int bDstToSrc, int nPointCount,
@@ -436,10 +436,12 @@ int GDALGCPTransform(void *pTransformArg, int bDstToSrc, int nPointCount,
436436
if (psInfo->bReversed)
437437
bDstToSrc = !bDstToSrc;
438438

439+
int bRet = TRUE;
439440
for (i = 0; i < nPointCount; i++)
440441
{
441442
if (x[i] == HUGE_VAL || y[i] == HUGE_VAL)
442443
{
444+
bRet = FALSE;
443445
panSuccess[i] = FALSE;
444446
continue;
445447
}
@@ -459,7 +461,7 @@ int GDALGCPTransform(void *pTransformArg, int bDstToSrc, int nPointCount,
459461
panSuccess[i] = TRUE;
460462
}
461463

462-
return TRUE;
464+
return bRet;
463465
}
464466

465467
/************************************************************************/

alg/gdal_rpc.cpp

+22-3
Original file line numberDiff line numberDiff line change
@@ -1449,10 +1449,15 @@ GDALRPCTransformWholeLineWithDEM(const GDALRPCTransformInfo *psTransform,
14491449
const int nY = static_cast<int>(dfY);
14501450
const double dfDeltaY = dfY - nY;
14511451

1452+
int bRet = TRUE;
14521453
for (int i = 0; i < nPointCount; i++)
14531454
{
14541455
if (padfX[i] == HUGE_VAL)
1456+
{
1457+
bRet = FALSE;
1458+
panSuccess[i] = FALSE;
14551459
continue;
1460+
}
14561461

14571462
double dfDEMH = 0.0;
14581463
const double dfZ_i = padfZ ? padfZ[i] : 0.0;
@@ -1502,6 +1507,7 @@ GDALRPCTransformWholeLineWithDEM(const GDALRPCTransformInfo *psTransform,
15021507
dfDEMH = psTransform->dfDEMMissingValue;
15031508
else
15041509
{
1510+
bRet = FALSE;
15051511
panSuccess[i] = FALSE;
15061512
continue;
15071513
}
@@ -1546,6 +1552,7 @@ GDALRPCTransformWholeLineWithDEM(const GDALRPCTransformInfo *psTransform,
15461552
{
15471553
if (!RPCIsValidLongLat(psTransform, padfX[i], padfY[i]))
15481554
{
1555+
bRet = FALSE;
15491556
panSuccess[i] = FALSE;
15501557
padfX[i] = HUGE_VAL;
15511558
padfY[i] = HUGE_VAL;
@@ -1565,6 +1572,7 @@ GDALRPCTransformWholeLineWithDEM(const GDALRPCTransformInfo *psTransform,
15651572
{
15661573
if (!RPCIsValidLongLat(psTransform, padfX[i], padfY[i]))
15671574
{
1575+
bRet = FALSE;
15681576
panSuccess[i] = FALSE;
15691577
padfX[i] = HUGE_VAL;
15701578
padfY[i] = HUGE_VAL;
@@ -1582,6 +1590,7 @@ GDALRPCTransformWholeLineWithDEM(const GDALRPCTransformInfo *psTransform,
15821590
}
15831591
else
15841592
{
1593+
bRet = FALSE;
15851594
panSuccess[i] = FALSE;
15861595
padfX[i] = HUGE_VAL;
15871596
padfY[i] = HUGE_VAL;
@@ -1613,6 +1622,7 @@ GDALRPCTransformWholeLineWithDEM(const GDALRPCTransformInfo *psTransform,
16131622
dfDEMH = psTransform->dfDEMMissingValue;
16141623
else
16151624
{
1625+
bRet = FALSE;
16161626
panSuccess[i] = FALSE;
16171627
padfX[i] = HUGE_VAL;
16181628
padfY[i] = HUGE_VAL;
@@ -1623,6 +1633,7 @@ GDALRPCTransformWholeLineWithDEM(const GDALRPCTransformInfo *psTransform,
16231633

16241634
if (!RPCIsValidLongLat(psTransform, padfX[i], padfY[i]))
16251635
{
1636+
bRet = FALSE;
16261637
panSuccess[i] = FALSE;
16271638
padfX[i] = HUGE_VAL;
16281639
padfY[i] = HUGE_VAL;
@@ -1638,7 +1649,7 @@ GDALRPCTransformWholeLineWithDEM(const GDALRPCTransformInfo *psTransform,
16381649

16391650
VSIFree(padfDEMBuffer);
16401651

1641-
return TRUE;
1652+
return bRet;
16421653
}
16431654

16441655
/************************************************************************/
@@ -1900,10 +1911,12 @@ int GDALRPCTransform(void *pTransformArg, int bDstToSrc, int nPointCount,
19001911
}
19011912
}
19021913

1914+
int bRet = TRUE;
19031915
for (int i = 0; i < nPointCount; i++)
19041916
{
19051917
if (!RPCIsValidLongLat(psTransform, padfX[i], padfY[i]))
19061918
{
1919+
bRet = FALSE;
19071920
panSuccess[i] = FALSE;
19081921
padfX[i] = HUGE_VAL;
19091922
padfY[i] = HUGE_VAL;
@@ -1913,6 +1926,7 @@ int GDALRPCTransform(void *pTransformArg, int bDstToSrc, int nPointCount,
19131926
if (!GDALRPCGetHeightAtLongLat(psTransform, padfX[i], padfY[i],
19141927
&dfHeight))
19151928
{
1929+
bRet = FALSE;
19161930
panSuccess[i] = FALSE;
19171931
padfX[i] = HUGE_VAL;
19181932
padfY[i] = HUGE_VAL;
@@ -1925,13 +1939,15 @@ int GDALRPCTransform(void *pTransformArg, int bDstToSrc, int nPointCount,
19251939
panSuccess[i] = TRUE;
19261940
}
19271941

1928-
return TRUE;
1942+
return bRet;
19291943
}
19301944

19311945
if (padfZ == nullptr)
19321946
{
19331947
CPLError(CE_Failure, CPLE_NotSupported,
19341948
"Z array should be provided for reverse RPC computation");
1949+
for (int i = 0; i < nPointCount; i++)
1950+
panSuccess[i] = FALSE;
19351951
return FALSE;
19361952
}
19371953

@@ -1940,6 +1956,7 @@ int GDALRPCTransform(void *pTransformArg, int bDstToSrc, int nPointCount,
19401956
/* function uses an iterative method from an initial linear */
19411957
/* approximation. */
19421958
/* -------------------------------------------------------------------- */
1959+
int bRet = TRUE;
19431960
for (int i = 0; i < nPointCount; i++)
19441961
{
19451962
double dfResultX = 0.0;
@@ -1948,13 +1965,15 @@ int GDALRPCTransform(void *pTransformArg, int bDstToSrc, int nPointCount,
19481965
if (!RPCInverseTransformPoint(psTransform, padfX[i], padfY[i], padfZ[i],
19491966
&dfResultX, &dfResultY))
19501967
{
1968+
bRet = FALSE;
19511969
panSuccess[i] = FALSE;
19521970
padfX[i] = HUGE_VAL;
19531971
padfY[i] = HUGE_VAL;
19541972
continue;
19551973
}
19561974
if (!RPCIsValidLongLat(psTransform, padfX[i], padfY[i]))
19571975
{
1976+
bRet = FALSE;
19581977
panSuccess[i] = FALSE;
19591978
padfX[i] = HUGE_VAL;
19601979
padfY[i] = HUGE_VAL;
@@ -1967,7 +1986,7 @@ int GDALRPCTransform(void *pTransformArg, int bDstToSrc, int nPointCount,
19671986
panSuccess[i] = TRUE;
19681987
}
19691988

1970-
return TRUE;
1989+
return bRet;
19711990
}
19721991

19731992
/************************************************************************/

alg/gdal_tps.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ void GDALDestroyTPSTransformer(void *pTransformArg)
324324
* @param panSuccess array in which a flag indicating success (TRUE) or
325325
* failure (FALSE) of the transformation are placed.
326326
*
327-
* @return TRUE.
327+
* @return TRUE if all points have been successfully transformed.
328328
*/
329329

330330
int GDALTPSTransform(void *pTransformArg, int bDstToSrc, int nPointCount,

alg/gdalgeoloc.cpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ int GDALGeoLoc<Accessors>::Transform(void *pTransformArg, int bDstToSrc,
589589
double *padfY, double * /* padfZ */,
590590
int *panSuccess)
591591
{
592+
int bSuccess = TRUE;
592593
GDALGeoLocTransformInfo *psTransform =
593594
static_cast<GDALGeoLocTransformInfo *>(pTransformArg);
594595

@@ -607,6 +608,7 @@ int GDALGeoLoc<Accessors>::Transform(void *pTransformArg, int bDstToSrc,
607608
{
608609
if (padfX[i] == HUGE_VAL || padfY[i] == HUGE_VAL)
609610
{
611+
bSuccess = FALSE;
610612
panSuccess[i] = FALSE;
611613
continue;
612614
}
@@ -623,6 +625,7 @@ int GDALGeoLoc<Accessors>::Transform(void *pTransformArg, int bDstToSrc,
623625
if (!PixelLineToXY(psTransform, dfGeoLocPixel, dfGeoLocLine,
624626
padfX[i], padfY[i]))
625627
{
628+
bSuccess = FALSE;
626629
panSuccess[i] = FALSE;
627630
padfX[i] = HUGE_VAL;
628631
padfY[i] = HUGE_VAL;
@@ -665,6 +668,7 @@ int GDALGeoLoc<Accessors>::Transform(void *pTransformArg, int bDstToSrc,
665668
{
666669
if (padfX[i] == HUGE_VAL || padfY[i] == HUGE_VAL)
667670
{
671+
bSuccess = FALSE;
668672
panSuccess[i] = FALSE;
669673
continue;
670674
}
@@ -688,6 +692,7 @@ int GDALGeoLoc<Accessors>::Transform(void *pTransformArg, int bDstToSrc,
688692
dfBMX + 1 < psTransform->nBackMapWidth &&
689693
dfBMY + 1 < psTransform->nBackMapHeight))
690694
{
695+
bSuccess = FALSE;
691696
panSuccess[i] = FALSE;
692697
padfX[i] = HUGE_VAL;
693698
padfY[i] = HUGE_VAL;
@@ -701,6 +706,7 @@ int GDALGeoLoc<Accessors>::Transform(void *pTransformArg, int bDstToSrc,
701706
const auto fBMY_0_0 = pAccessors->backMapYAccessor.Get(iBMX, iBMY);
702707
if (fBMX_0_0 == INVALID_BMXY)
703708
{
709+
bSuccess = FALSE;
704710
panSuccess[i] = FALSE;
705711
padfX[i] = HUGE_VAL;
706712
padfY[i] = HUGE_VAL;
@@ -914,6 +920,7 @@ int GDALGeoLoc<Accessors>::Transform(void *pTransformArg, int bDstToSrc,
914920
}
915921
if (!bDone)
916922
{
923+
bSuccess = FALSE;
917924
panSuccess[i] = FALSE;
918925
padfX[i] = HUGE_VAL;
919926
padfY[i] = HUGE_VAL;
@@ -924,7 +931,7 @@ int GDALGeoLoc<Accessors>::Transform(void *pTransformArg, int bDstToSrc,
924931
}
925932
}
926933

927-
return TRUE;
934+
return bSuccess;
928935
}
929936

930937
/*! @endcond */

0 commit comments

Comments
 (0)