@@ -400,6 +400,40 @@ static CPLString GetSrcDSProjection(GDALDatasetH hDS, CSLConstList papszTO)
400
400
return pszProjection ? pszProjection : " " ;
401
401
}
402
402
403
+ /* ***********************************************************************/
404
+ /* CreateCTCutlineToSrc() */
405
+ /* ***********************************************************************/
406
+
407
+ static std::unique_ptr<OGRCoordinateTransformation> CreateCTCutlineToSrc (
408
+ const OGRSpatialReference *poRasterSRS, const OGRSpatialReference *poDstSRS,
409
+ const OGRSpatialReference *poCutlineSRS, CSLConstList papszTO)
410
+ {
411
+ const OGRSpatialReference *poCutlineOrTargetSRS =
412
+ poCutlineSRS ? poCutlineSRS : poDstSRS;
413
+ std::unique_ptr<OGRCoordinateTransformation> poCTCutlineToSrc;
414
+ if (poCutlineOrTargetSRS && poRasterSRS &&
415
+ !poCutlineOrTargetSRS->IsSame (poRasterSRS))
416
+ {
417
+ OGRCoordinateTransformationOptions oOptions;
418
+ // If the cutline SRS is the same as the target SRS and there is
419
+ // an explicit -ct between the source SRS and the target SRS, then
420
+ // use it in the reverse way to transform from the cutline SRS to
421
+ // the source SRS.
422
+ if (poDstSRS && poCutlineOrTargetSRS->IsSame (poDstSRS))
423
+ {
424
+ const char *pszCT =
425
+ CSLFetchNameValue (papszTO, " COORDINATE_OPERATION" );
426
+ if (pszCT)
427
+ {
428
+ oOptions.SetCoordinateOperation (pszCT, /* bInverse = */ true );
429
+ }
430
+ }
431
+ poCTCutlineToSrc.reset (OGRCreateCoordinateTransformation (
432
+ poCutlineOrTargetSRS, poRasterSRS, oOptions));
433
+ }
434
+ return poCTCutlineToSrc;
435
+ }
436
+
403
437
/* ***********************************************************************/
404
438
/* CropToCutline() */
405
439
/* ***********************************************************************/
@@ -470,16 +504,10 @@ static CPLErr CropToCutline(const OGRGeometry *poCutline, CSLConstList papszTO,
470
504
}
471
505
472
506
auto poCutlineGeom = std::unique_ptr<OGRGeometry>(poCutline->clone ());
473
- const OGRSpatialReference *poCutlineOrTargetSRS =
474
- poCutlineSRS ? poCutlineSRS : poDstSRS.get ();
475
- std::unique_ptr<OGRCoordinateTransformation> poCTCutlineToSrc;
476
- std::unique_ptr<OGRCoordinateTransformation> poCTSrcToDst;
507
+ auto poCTCutlineToSrc = CreateCTCutlineToSrc (poSrcSRS.get (), poDstSRS.get (),
508
+ poCutlineSRS, papszTO);
477
509
478
- if (!poCutlineOrTargetSRS->IsSame (poSrcSRS.get ()))
479
- {
480
- poCTCutlineToSrc.reset (OGRCreateCoordinateTransformation (
481
- poCutlineOrTargetSRS, poSrcSRS.get ()));
482
- }
510
+ std::unique_ptr<OGRCoordinateTransformation> poCTSrcToDst;
483
511
if (!poSrcSRS->IsSame (poDstSRS.get ()))
484
512
{
485
513
poCTSrcToDst.reset (
@@ -4775,15 +4803,8 @@ static CPLErr TransformCutlineToSource(GDALDataset *poSrcDS,
4775
4803
" Cutline results may be incorrect." );
4776
4804
}
4777
4805
4778
- const OGRSpatialReference *poCutlineOrTargetSRS =
4779
- poCutlineSRS ? poCutlineSRS : poDstSRS.get ();
4780
- std::unique_ptr<OGRCoordinateTransformation> poCTCutlineToSrc;
4781
- if (poCutlineOrTargetSRS && poRasterSRS &&
4782
- !poCutlineOrTargetSRS->IsSame (poRasterSRS.get ()))
4783
- {
4784
- poCTCutlineToSrc.reset (OGRCreateCoordinateTransformation (
4785
- poCutlineOrTargetSRS, poRasterSRS.get ()));
4786
- }
4806
+ auto poCTCutlineToSrc = CreateCTCutlineToSrc (
4807
+ poRasterSRS.get (), poDstSRS.get (), poCutlineSRS, papszTO_In);
4787
4808
4788
4809
CPLStringList aosTO (papszTO_In);
4789
4810
@@ -4792,6 +4813,9 @@ static CPLErr TransformCutlineToSource(GDALDataset *poSrcDS,
4792
4813
// Avoid any reprojection when using the GenImgProjTransformer
4793
4814
aosTO.SetNameValue (" DST_SRS" , osProjection.c_str ());
4794
4815
}
4816
+ aosTO.SetNameValue (" SRC_COORDINATE_EPOCH" , nullptr );
4817
+ aosTO.SetNameValue (" DST_COORDINATE_EPOCH" , nullptr );
4818
+ aosTO.SetNameValue (" COORDINATE_OPERATION" , nullptr );
4795
4819
4796
4820
/* -------------------------------------------------------------------- */
4797
4821
/* It may be unwise to let the mask geometry be re-wrapped by */
@@ -4834,7 +4858,12 @@ static CPLErr TransformCutlineToSource(GDALDataset *poSrcDS,
4834
4858
}
4835
4859
}
4836
4860
if (poMultiPolygon->transform (&oTransformer) != OGRERR_NONE)
4861
+ {
4862
+ CPLError (CE_Failure, CPLE_AppDefined,
4863
+ " poMultiPolygon->transform(&oTransformer) failed at line %d" ,
4864
+ __LINE__);
4837
4865
eErr = OGRERR_FAILURE;
4866
+ }
4838
4867
const double dfInitialMaxLengthInPixels =
4839
4868
GetMaximumSegmentLength (poMultiPolygon.get ());
4840
4869
0 commit comments