@@ -95,6 +95,42 @@ def _itrf_transformation_step(source_itrf: str, target_itrf: str) -> str:
9595 raise RuntimeError (err_msg )
9696
9797
98+ def _get_pmm_transform_step (
99+ data : IceflowDataFrame ,
100+ target_itrf : str ,
101+ target_epoch : str | None ,
102+ plate : str | None ,
103+ ):
104+ """Perform coordinate propagation to the target epoch using a proj-provided plate
105+ motion model (PMM).
106+
107+ This step uses the target_itrf's init file to lookup the associated plate's
108+ PMM parameters. For example, ITRF2014 parameters are defined here:
109+ https://github.com/OSGeo/PROJ/blob/8b65d5b14e2a8fbb8198335019488a2b2968df5c/data/ITRF2014.
110+ The step is inverted because proj defined `t_epoch` as the "central epoch" -
111+ not the "target epoch". The transformation uses a delta defined by
112+ `t_observed - t_epoch` that are applied to the PMM's rate of change to
113+ propagate the point into the past/future. See
114+ https://proj.org/en/9.5/operations/transformations/helmert.html#mathematical-description
115+ for more information. For example, if a point's observation date
116+ (`t_observed`) is 1993.0 (1993-01-01T00:00:00) and the t_epoch is 2011.0
117+ (2011-01-01T00:00:00), then the delta is 1993 - 2011: -18. We need to invert
118+ the step so that the point is propagated forward in time, from 1993 to 2011.
119+ """
120+ plate_model_step = ""
121+ if target_epoch :
122+ if not plate :
123+ plate = plate_name (Point (data .longitude .mean (), data .latitude .mean ()))
124+ plate_model_step = (
125+ f"+step +inv +init={ target_itrf } :{ plate } +t_epoch={ target_epoch } "
126+ )
127+ if not _check_valid_proj_step (plate_model_step ):
128+ err_msg = f"Failed to find pre-defined plate-model parameters for { target_itrf } :{ plate } "
129+ raise RuntimeError (err_msg )
130+
131+ return plate_model_step
132+
133+
98134@pa .check_types ()
99135def transform_itrf (
100136 data : IceflowDataFrame ,
@@ -152,34 +188,13 @@ def transform_itrf(
152188 transformed_chunks .append (chunk )
153189 continue
154190
155- plate_model_step = ""
156- if target_epoch :
157- if not plate :
158- plate = plate_name (Point (chunk .longitude .mean (), chunk .latitude .mean ()))
159- plate_model_step = (
160- # Perform coordinate propagation to the target epoch using the
161- # provided plate motion model (PMM).
162- # This step uses the target_itrf's init file to lookup the
163- # associated plate's PMM parameters. For example, ITRF2014
164- # parameters are defined here:
165- # https://github.com/OSGeo/PROJ/blob/8b65d5b14e2a8fbb8198335019488a2b2968df5c/data/ITRF2014.
166- # The step is inverted because proj defined `t_epoch` as the
167- # "central epoch" - not the "target epoch. The transformation
168- # uses a delta defined by `t_observed - t_epoch` that are
169- # applied to the PMM's rate of change to propagate the point
170- # into the past/future. See
171- # https://proj.org/en/9.5/operations/transformations/helmert.html#mathematical-description
172- # for more information.
173- # For example, if a point's observation date
174- # (`t_observed`) is 1993.0 (1993-01-01T00:00:00) and the t_epoch
175- # is 2011.0 (2011-01-01T00:00:00), then the delta is 1993 -
176- # 2011: -18. We need to invert the step so that the point is
177- # propagated forward in time, from 1993 to 2011.
178- f"+step +inv +init={ target_itrf } :{ plate } +t_epoch={ target_epoch } "
179- )
180- if not _check_valid_proj_step (plate_model_step ):
181- err_msg = f"Failed to find pre-defined plate-model parameters for { target_itrf } :{ plate } "
182- raise RuntimeError (err_msg )
191+ chunk = cast (IceflowDataFrame , chunk )
192+ plate_model_step = _get_pmm_transform_step (
193+ chunk ,
194+ target_itrf ,
195+ target_epoch ,
196+ plate ,
197+ )
183198
184199 itrf_transformation_step = _itrf_transformation_step (source_itrf , target_itrf )
185200
0 commit comments