Skip to content

Commit 2409c7c

Browse files
authored
Merge pull request #11819 from rouault/fix_11817
Make all Transform methods of OGRCoordinateTransformation and GDALTransformerFunc return FALSE as soon as one point fails to transform
2 parents 6884b62 + f80739a commit 2409c7c

13 files changed

+300
-262
lines changed

MIGRATION_GUIDE.TXT

+15
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,21 @@ 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. When
21+
FALSE is returned the pabSuccess[] or panErrorCodes[] arrays indicate which
22+
point succeeded or failed to transform.
23+
24+
The GDALTransformerFunc callback and its implementations (GenImgProjTransformer,
25+
RPCTransformer, etc.) are also modified to return FALSE as soon as at least
26+
one point fails to transform.
27+
1328
MIGRATION GUIDE FROM GDAL 3.9 to GDAL 3.10
1429
------------------------------------------
1530

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)