PostGIS  2.2.7dev-r@@SVN_REVISION@@
int point_interpolate ( const POINT4D p1,
const POINT4D p2,
POINT4D p,
int  hasz,
int  hasm,
char  ordinate,
double  interpolation_value 
)

Given two points, a dimensionality, an ordinate, and an interpolation value generate a new point that is proportionally between the input points, using the values in the provided dimension as the scaling factors.

Definition at line 308 of file lwlinearreferencing.c.

References FP_MAX, FP_MIN, LWDEBUGF, lwerror(), lwpoint_get_ordinate(), and lwpoint_set_ordinate().

Referenced by lwline_clip_to_ordinate_range(), and test_point_interpolate().

309 {
310  static char* dims = "XYZM";
311  double p1_value = lwpoint_get_ordinate(p1, ordinate);
312  double p2_value = lwpoint_get_ordinate(p2, ordinate);
313  double proportion;
314  int i = 0;
315 
316  if ( ! ( ordinate == 'X' || ordinate == 'Y' || ordinate == 'Z' || ordinate == 'M' ) )
317  {
318  lwerror("Cannot set %c ordinate.", ordinate);
319  return 0;
320  }
321 
322  if ( FP_MIN(p1_value, p2_value) > interpolation_value ||
323  FP_MAX(p1_value, p2_value) < interpolation_value )
324  {
325  lwerror("Cannot interpolate to a value (%g) not between the input points (%g, %g).", interpolation_value, p1_value, p2_value);
326  return 0;
327  }
328 
329  proportion = fabs((interpolation_value - p1_value) / (p2_value - p1_value));
330 
331  for ( i = 0; i < 4; i++ )
332  {
333  double newordinate = 0.0;
334  if ( dims[i] == 'Z' && ! hasz ) continue;
335  if ( dims[i] == 'M' && ! hasm ) continue;
336  p1_value = lwpoint_get_ordinate(p1, dims[i]);
337  p2_value = lwpoint_get_ordinate(p2, dims[i]);
338  newordinate = p1_value + proportion * (p2_value - p1_value);
339  lwpoint_set_ordinate(p, dims[i], newordinate);
340  LWDEBUGF(4, " clip ordinate(%c) p1_value(%g) p2_value(%g) proportion(%g) newordinate(%g) ", dims[i], p1_value, p2_value, proportion, newordinate );
341  }
342 
343  return 1;
344 }
double lwpoint_get_ordinate(const POINT4D *p, char ordinate)
Given a POINT4D and an ordinate number, return the value of the ordinate.
#define FP_MIN(A, B)
void lwpoint_set_ordinate(POINT4D *p, char ordinate, double value)
Given a point, ordinate number and value, set that ordinate on the point.
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:55
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:74
#define FP_MAX(A, B)

Here is the call graph for this function:

Here is the caller graph for this function: