PostGIS  2.1.10dev-r@@SVN_REVISION@@
int lwline_crossing_direction ( const LWLINE l1,
const LWLINE l2 
)

lwline_crossing_direction: returns the kind of CG_LINE_CROSS_TYPE behavior of 2 linestrings

Given two lines, characterize how (and if) they cross each other.

Parameters
l1first line string
l2second line string
Returns
a CG_LINE_CROSS_TYPE LINE_NO_CROSS = 0 LINE_CROSS_LEFT = -1 LINE_CROSS_RIGHT = 1 LINE_MULTICROSS_END_LEFT = -2 LINE_MULTICROSS_END_RIGHT = 2 LINE_MULTICROSS_END_SAME_FIRST_LEFT = -3 LINE_MULTICROSS_END_SAME_FIRST_RIGHT = 3

Definition at line 461 of file lwalgorithm.c.

References getPoint2d_p(), LINE_CROSS_LEFT, LINE_CROSS_RIGHT, LINE_MULTICROSS_END_LEFT, LINE_MULTICROSS_END_RIGHT, LINE_MULTICROSS_END_SAME_FIRST_LEFT, LINE_MULTICROSS_END_SAME_FIRST_RIGHT, LINE_NO_CROSS, lw_segment_intersects(), LWDEBUG, LWDEBUGF, lwgeom_to_ewkt(), POINTARRAY::npoints, LWLINE::points, SEG_COLINEAR, SEG_CROSS_LEFT, SEG_CROSS_RIGHT, POINT2D::x, and POINT2D::y.

Referenced by ST_LineCrossingDirection(), test_lwline_crossing_bugs(), test_lwline_crossing_long_lines(), and test_lwline_crossing_short_lines().

462 {
463  int i = 0, j = 0;
464  POINT2D p1, p2, q1, q2;
465  POINTARRAY *pa1 = NULL, *pa2 = NULL;
466  int cross_left = 0;
467  int cross_right = 0;
468  int first_cross = 0;
469  int this_cross = 0;
470 
471  pa1 = (POINTARRAY*)l1->points;
472  pa2 = (POINTARRAY*)l2->points;
473 
474  /* One-point lines can't intersect (and shouldn't exist). */
475  if ( pa1->npoints < 2 || pa2->npoints < 2 )
476  return LINE_NO_CROSS;
477 
478  LWDEBUGF(4, "l1 = %s", lwgeom_to_ewkt((LWGEOM*)l1));
479  LWDEBUGF(4, "l2 = %s", lwgeom_to_ewkt((LWGEOM*)l2));
480 
481  /* Initialize first point of q */
482  getPoint2d_p(pa2, 0, &q1);
483 
484  for ( i = 1; i < pa2->npoints; i++ )
485  {
486 
487  /* Update second point of q to next value */
488  getPoint2d_p(pa2, i, &q2);
489 
490  /* Initialize first point of p */
491  getPoint2d_p(pa1, 0, &p1);
492 
493  for ( j = 1; j < pa1->npoints; j++ )
494  {
495 
496  /* Update second point of p to next value */
497  getPoint2d_p(pa1, j, &p2);
498 
499  this_cross = lw_segment_intersects(&p1, &p2, &q1, &q2);
500 
501  LWDEBUGF(4, "i=%d, j=%d (%.8g %.8g, %.8g %.8g)", this_cross, i, j, p1.x, p1.y, p2.x, p2.y);
502 
503  if ( this_cross == SEG_CROSS_LEFT )
504  {
505  LWDEBUG(4,"this_cross == SEG_CROSS_LEFT");
506  cross_left++;
507  if ( ! first_cross )
508  first_cross = SEG_CROSS_LEFT;
509  }
510 
511  if ( this_cross == SEG_CROSS_RIGHT )
512  {
513  LWDEBUG(4,"this_cross == SEG_CROSS_RIGHT");
514  cross_right++;
515  if ( ! first_cross )
516  first_cross = SEG_CROSS_LEFT;
517  }
518 
519  /*
520  ** Crossing at a co-linearity can be turned handled by extending
521  ** segment to next vertext and seeing if the end points straddle
522  ** the co-linear segment.
523  */
524  if ( this_cross == SEG_COLINEAR )
525  {
526  LWDEBUG(4,"this_cross == SEG_COLINEAR");
527  /* TODO: Add logic here and in segment_intersects()
528  continue;
529  */
530  }
531 
532  LWDEBUG(4,"this_cross == SEG_NO_INTERSECTION");
533 
534  /* Turn second point of p into first point */
535  p1 = p2;
536 
537  }
538 
539  /* Turn second point of q into first point */
540  q1 = q2;
541 
542  }
543 
544  LWDEBUGF(4, "first_cross=%d, cross_left=%d, cross_right=%d", first_cross, cross_left, cross_right);
545 
546  if ( !cross_left && !cross_right )
547  return LINE_NO_CROSS;
548 
549  if ( !cross_left && cross_right == 1 )
550  return LINE_CROSS_RIGHT;
551 
552  if ( !cross_right && cross_left == 1 )
553  return LINE_CROSS_LEFT;
554 
555  if ( cross_left - cross_right == 1 )
557 
558  if ( cross_left - cross_right == -1 )
560 
561  if ( cross_left - cross_right == 0 && first_cross == SEG_CROSS_LEFT )
563 
564  if ( cross_left - cross_right == 0 && first_cross == SEG_CROSS_RIGHT )
566 
567  return LINE_NO_CROSS;
568 
569 }
int npoints
Definition: liblwgeom.h:327
char * lwgeom_to_ewkt(const LWGEOM *lwgeom)
Return an alloced string.
Definition: lwgeom.c:425
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:50
int lw_segment_intersects(const POINT2D *p1, const POINT2D *p2, const POINT2D *q1, const POINT2D *q2)
returns the kind of CG_SEGMENT_INTERSECTION_TYPE behavior of lineseg 1 (constructed from p1 and p2) a...
Definition: lwalgorithm.c:372
double x
Definition: liblwgeom.h:284
double y
Definition: liblwgeom.h:284
int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
Definition: lwgeom_api.c:434
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:55
POINTARRAY * points
Definition: liblwgeom.h:378

Here is the call graph for this function:

Here is the caller graph for this function: