PostGIS  2.1.10dev-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 299 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().

300 {
301  static char* dims = "XYZM";
302  double p1_value = lwpoint_get_ordinate(p1, ordinate);
303  double p2_value = lwpoint_get_ordinate(p2, ordinate);
304  double proportion;
305  int i = 0;
306 
307  if ( ! ( ordinate == 'X' || ordinate == 'Y' || ordinate == 'Z' || ordinate == 'M' ) )
308  {
309  lwerror("Cannot set %c ordinate.", ordinate);
310  return 0;
311  }
312 
313  if ( FP_MIN(p1_value, p2_value) > interpolation_value ||
314  FP_MAX(p1_value, p2_value) < interpolation_value )
315  {
316  lwerror("Cannot interpolate to a value (%g) not between the input points (%g, %g).", interpolation_value, p1_value, p2_value);
317  return 0;
318  }
319 
320  proportion = fabs((interpolation_value - p1_value) / (p2_value - p1_value));
321 
322  for ( i = 0; i < 4; i++ )
323  {
324  double newordinate = 0.0;
325  if ( dims[i] == 'Z' && ! hasz ) continue;
326  if ( dims[i] == 'M' && ! hasm ) continue;
327  p1_value = lwpoint_get_ordinate(p1, dims[i]);
328  p2_value = lwpoint_get_ordinate(p2, dims[i]);
329  newordinate = p1_value + proportion * (p2_value - p1_value);
330  lwpoint_set_ordinate(p, dims[i], newordinate);
331  LWDEBUGF(4, " clip ordinate(%c) p1_value(%g) p2_value(%g) proportion(%g) newordinate(%g) ", dims[i], p1_value, p2_value, proportion, newordinate );
332  }
333 
334  return 1;
335 }
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 lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:67
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
#define FP_MAX(A, B)

Here is the call graph for this function:

Here is the caller graph for this function: