@@ -1470,24 +1470,35 @@ int OGRProjCT::Initialize(const OGRSpatialReference *poSourceIn,
1470
1470
bSourceLatLong = CPL_TO_BOOL (poSRSSource->IsGeographic ());
1471
1471
bSourceIsDynamicCRS = poSRSSource->IsDynamic ();
1472
1472
dfSourceCoordinateEpoch = poSRSSource->GetCoordinateEpoch ();
1473
+ if (!bSourceIsDynamicCRS && dfSourceCoordinateEpoch > 0 )
1474
+ {
1475
+ bSourceIsDynamicCRS = poSRSSource->HasPointMotionOperation ();
1476
+ }
1473
1477
poSRSSource->GetAxis (nullptr , 0 , &m_eSourceFirstAxisOrient);
1474
1478
}
1475
1479
if (poSRSTarget)
1476
1480
{
1477
1481
bTargetLatLong = CPL_TO_BOOL (poSRSTarget->IsGeographic ());
1478
1482
bTargetIsDynamicCRS = poSRSTarget->IsDynamic ();
1479
1483
dfTargetCoordinateEpoch = poSRSTarget->GetCoordinateEpoch ();
1484
+ if (!bTargetIsDynamicCRS && dfTargetCoordinateEpoch > 0 )
1485
+ {
1486
+ bTargetIsDynamicCRS = poSRSTarget->HasPointMotionOperation ();
1487
+ }
1480
1488
poSRSTarget->GetAxis (nullptr , 0 , &m_eTargetFirstAxisOrient);
1481
1489
}
1482
1490
1491
+ #if PROJ_VERSION_MAJOR < 9 || \
1492
+ (PROJ_VERSION_MAJOR == 9 && PROJ_VERSION_MINOR < 4 )
1483
1493
if (bSourceIsDynamicCRS && bTargetIsDynamicCRS &&
1484
1494
dfSourceCoordinateEpoch > 0 && dfTargetCoordinateEpoch > 0 &&
1485
1495
dfSourceCoordinateEpoch != dfTargetCoordinateEpoch)
1486
1496
{
1487
1497
CPLError (CE_Warning, CPLE_AppDefined,
1488
- " Coordinate transformation between different epochs are "
1489
- " not currently supported " );
1498
+ " Coordinate transformation between different epochs only "
1499
+ " supported since PROJ 9.4 " );
1490
1500
}
1501
+ #endif
1491
1502
1492
1503
/* -------------------------------------------------------------------- */
1493
1504
/* Setup source and target translations to radians for lat/long */
@@ -1659,6 +1670,24 @@ int OGRProjCT::Initialize(const OGRSpatialReference *poSourceIn,
1659
1670
options.d ->bOnlyBest ? " YES" : " NO" );
1660
1671
}
1661
1672
#endif
1673
+
1674
+ #if PROJ_VERSION_MAJOR > 9 || \
1675
+ (PROJ_VERSION_MAJOR == 9 && PROJ_VERSION_MINOR >= 4 )
1676
+ if (bSourceIsDynamicCRS && dfSourceCoordinateEpoch > 0 &&
1677
+ bTargetIsDynamicCRS && dfTargetCoordinateEpoch > 0 )
1678
+ {
1679
+ auto srcCM = proj_coordinate_metadata_create (
1680
+ ctx, srcCRS, dfSourceCoordinateEpoch);
1681
+ proj_destroy (srcCRS);
1682
+ srcCRS = srcCM;
1683
+
1684
+ auto targetCM = proj_coordinate_metadata_create (
1685
+ ctx, targetCRS, dfTargetCoordinateEpoch);
1686
+ proj_destroy (targetCRS);
1687
+ targetCRS = targetCM;
1688
+ }
1689
+ #endif
1690
+
1662
1691
m_pj = proj_create_crs_to_crs_from_pj (ctx, srcCRS, targetCRS, area,
1663
1692
aosOptions.List ());
1664
1693
proj_destroy (srcCRS);
@@ -1694,7 +1723,9 @@ int OGRProjCT::Initialize(const OGRSpatialReference *poSourceIn,
1694
1723
#endif
1695
1724
}
1696
1725
1697
- if (options.d ->osCoordOperation .empty () && poSRSSource && poSRSTarget)
1726
+ if (options.d ->osCoordOperation .empty () && poSRSSource && poSRSTarget &&
1727
+ (dfSourceCoordinateEpoch == 0 || dfTargetCoordinateEpoch == 0 ||
1728
+ dfSourceCoordinateEpoch == dfTargetCoordinateEpoch))
1698
1729
{
1699
1730
// Determine if we can skip the transformation completely.
1700
1731
const char *const apszOptionsIsSame[] = {" CRITERION=EQUIVALENT" ,
0 commit comments