PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ lwline_crossing_direction()

int lwline_crossing_direction ( const LWLINE l1,
const LWLINE l2 
)

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

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 460 of file lwalgorithm.c.

References getPoint2d_cp(), 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().

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