PostGIS  2.5.7dev-r@@SVN_REVISION@@

◆ test_edge_intersection()

static void test_edge_intersection ( void  )
static

Definition at line 401 of file cu_geodetic.c.

402 {
403  GEOGRAPHIC_EDGE e1, e2;
405  int rv;
406 
407  /* Covers case, end-to-end intersection */
408  edge_set(50, -10.999999999999998224, -10.0, 50.0, &e1);
409  edge_set(-10.0, 50.0, -10.272779983831613393, -16.937003313332997578, &e2);
410  rv = edge_intersection(&e1, &e2, &g);
411  CU_ASSERT_EQUAL(rv, LW_TRUE);
412 
413  /* Medford case, very short segment vs very long one */
414  e1.start.lat = 0.74123572595649878103;
415  e1.start.lon = -2.1496353191142714145;
416  e1.end.lat = 0.74123631950116664058;
417  e1.end.lon = -2.1496353248304860273;
418  e2.start.lat = 0.73856343764436815924;
419  e2.start.lon = -2.1461493501950630325;
420  e2.end.lat = 0.70971354024834598651;
421  e2.end.lon = 2.1082194552519770703;
422  rv = edge_intersection(&e1, &e2, &g);
423  CU_ASSERT_EQUAL(rv, LW_FALSE);
424 
425  /* Again, this time with a less exact input edge. */
426  edge_set(-123.165031277506, 42.4696787216231, -123.165031605021, 42.4697127292275, &e1);
427  rv = edge_intersection(&e1, &e2, &g);
428  CU_ASSERT_EQUAL(rv, LW_FALSE);
429 
430  /* Second Medford case, very short segment vs very long one
431  e1.start.lat = 0.73826546728290887156;
432  e1.start.lon = -2.14426380171833042;
433  e1.end.lat = 0.73826545883786642843;
434  e1.end.lon = -2.1442638997530165668;
435  e2.start.lat = 0.73775469118192538165;
436  e2.start.lon = -2.1436035534281718817;
437  e2.end.lat = 0.71021099548296817705;
438  e2.end.lon = 2.1065275171200439353;
439  rv = edge_intersection(e1, e2, &g);
440  CU_ASSERT_EQUAL(rv, LW_FALSE);
441  */
442 
443  /* Intersection at (0 0) */
444  edge_set(-1.0, 0.0, 1.0, 0.0, &e1);
445  edge_set(0.0, -1.0, 0.0, 1.0, &e2);
446  rv = edge_intersection(&e1, &e2, &g);
447  point_rad2deg(&g);
448  CU_ASSERT_DOUBLE_EQUAL(g.lat, 0.0, 0.00001);
449  CU_ASSERT_DOUBLE_EQUAL(g.lon, 0.0, 0.00001);
450  CU_ASSERT_EQUAL(rv, LW_TRUE);
451 
452  /* No intersection at (0 0) */
453  edge_set(-1.0, 0.0, 1.0, 0.0, &e1);
454  edge_set(0.0, -1.0, 0.0, -2.0, &e2);
455  rv = edge_intersection(&e1, &e2, &g);
456  CU_ASSERT_EQUAL(rv, LW_FALSE);
457 
458  /* End touches middle of segment at (0 0) */
459  edge_set(-1.0, 0.0, 1.0, 0.0, &e1);
460  edge_set(0.0, -1.0, 0.0, 0.0, &e2);
461  rv = edge_intersection(&e1, &e2, &g);
462  point_rad2deg(&g);
463 #if 0
464  printf("\n");
465  printf("LINESTRING(%.15g %.15g, %.15g %.15g)\n", e1.start.lon, e1.start.lat, e1.end.lon, e1.end.lat);
466  printf("LINESTRING(%.15g %.15g, %.15g %.15g)\n", e2.start.lon, e2.start.lat, e2.end.lon, e2.end.lat);
467  printf("g = (%.15g %.15g)\n", g.lon, g.lat);
468  printf("rv = %d\n", rv);
469 #endif
470  CU_ASSERT_DOUBLE_EQUAL(g.lon, 0.0, 0.00001);
471  CU_ASSERT_EQUAL(rv, LW_TRUE);
472 
473  /* End touches end of segment at (0 0) */
474  edge_set(0.0, 0.0, 1.0, 0.0, &e1);
475  edge_set(0.0, -1.0, 0.0, 0.0, &e2);
476  rv = edge_intersection(&e1, &e2, &g);
477  point_rad2deg(&g);
478 #if 0
479  printf("\n");
480  printf("LINESTRING(%.15g %.15g, %.15g %.15g)\n", e1.start.lon, e1.start.lat, e1.end.lon, e1.end.lat);
481  printf("LINESTRING(%.15g %.15g, %.15g %.15g)\n", e2.start.lon, e2.start.lat, e2.end.lon, e2.end.lat);
482  printf("g = (%.15g %.15g)\n", g.lon, g.lat);
483  printf("rv = %d\n", rv);
484 #endif
485  CU_ASSERT_DOUBLE_EQUAL(g.lat, 0.0, 0.00001);
486  CU_ASSERT_DOUBLE_EQUAL(g.lon, 0.0, 0.00001);
487  CU_ASSERT_EQUAL(rv, LW_TRUE);
488 
489  /* Intersection at (180 0) */
490  edge_set(-179.0, -1.0, 179.0, 1.0, &e1);
491  edge_set(-179.0, 1.0, 179.0, -1.0, &e2);
492  rv = edge_intersection(&e1, &e2, &g);
493  point_rad2deg(&g);
494  CU_ASSERT_DOUBLE_EQUAL(g.lat, 0.0, 0.00001);
495  CU_ASSERT_DOUBLE_EQUAL(fabs(g.lon), 180.0, 0.00001);
496  CU_ASSERT_EQUAL(rv, LW_TRUE);
497 
498  /* Intersection at (180 0) */
499  edge_set(-170.0, 0.0, 170.0, 0.0, &e1);
500  edge_set(180.0, -10.0, 180.0, 10.0, &e2);
501  rv = edge_intersection(&e1, &e2, &g);
502  point_rad2deg(&g);
503  CU_ASSERT_DOUBLE_EQUAL(g.lat, 0.0, 0.00001);
504  CU_ASSERT_DOUBLE_EQUAL(fabs(g.lon), 180.0, 0.00001);
505  CU_ASSERT_EQUAL(rv, LW_TRUE);
506 
507  /* Intersection at north pole */
508  edge_set(-180.0, 80.0, 0.0, 80.0, &e1);
509  edge_set(90.0, 80.0, -90.0, 80.0, &e2);
510  rv = edge_intersection(&e1, &e2, &g);
511  point_rad2deg(&g);
512  CU_ASSERT_DOUBLE_EQUAL(g.lat, 90.0, 0.00001);
513  CU_ASSERT_EQUAL(rv, LW_TRUE);
514 
515  /* Equal edges return true */
516  edge_set(45.0, 10.0, 50.0, 20.0, &e1);
517  edge_set(45.0, 10.0, 50.0, 20.0, &e2);
518  rv = edge_intersection(&e1, &e2, &g);
519  point_rad2deg(&g);
520  CU_ASSERT_EQUAL(rv, LW_TRUE);
521 
522  /* Parallel edges (same great circle, different end points) return true */
523  edge_set(40.0, 0.0, 70.0, 0.0, &e1);
524  edge_set(60.0, 0.0, 50.0, 0.0, &e2);
525  rv = edge_intersection(&e1, &e2, &g);
526  point_rad2deg(&g);
527  CU_ASSERT_EQUAL(rv, 2); /* Hack, returning 2 as the 'co-linear' value */
528 
529  /* End touches arc at north pole */
530  edge_set(-180.0, 80.0, 0.0, 80.0, &e1);
531  edge_set(90.0, 80.0, -90.0, 90.0, &e2);
532  rv = edge_intersection(&e1, &e2, &g);
533  point_rad2deg(&g);
534 #if 0
535  printf("\n");
536  printf("LINESTRING(%.15g %.15g, %.15g %.15g)\n", e1.start.lon, e1.start.lat, e1.end.lon, e1.end.lat);
537  printf("LINESTRING(%.15g %.15g, %.15g %.15g)\n", e2.start.lon, e2.start.lat, e2.end.lon, e2.end.lat);
538  printf("g = (%.15g %.15g)\n", g.lon, g.lat);
539  printf("rv = %d\n", rv);
540 #endif
541  CU_ASSERT_DOUBLE_EQUAL(g.lat, 90.0, 0.00001);
542  CU_ASSERT_EQUAL(rv, LW_TRUE);
543 
544  /* End touches end at north pole */
545  edge_set(-180.0, 80.0, 0.0, 90.0, &e1);
546  edge_set(90.0, 80.0, -90.0, 90.0, &e2);
547  rv = edge_intersection(&e1, &e2, &g);
548  point_rad2deg(&g);
549 #if 0
550  printf("\n");
551  printf("LINESTRING(%.15g %.15g, %.15g %.15g)\n", e1.start.lon, e1.start.lat, e1.end.lon, e1.end.lat);
552  printf("LINESTRING(%.15g %.15g, %.15g %.15g)\n", e2.start.lon, e2.start.lat, e2.end.lon, e2.end.lat);
553  printf("g = (%.15g %.15g)\n", g.lon, g.lat);
554  printf("rv = %d\n", rv);
555 #endif
556  CU_ASSERT_DOUBLE_EQUAL(g.lat, 90.0, 0.00001);
557  CU_ASSERT_EQUAL(rv, LW_TRUE);
558 
559 }
static void point_rad2deg(GEOGRAPHIC_POINT *p)
Convert a point from radians to degrees.
Definition: cu_geodetic.c:63
static void edge_set(double lon1, double lat1, double lon2, double lat2, GEOGRAPHIC_EDGE *e)
Definition: cu_geodetic.c:347
#define LW_FALSE
Definition: liblwgeom.h:77
#define LW_TRUE
Return types for functions with status returns.
Definition: liblwgeom.h:76
int edge_intersection(const GEOGRAPHIC_EDGE *e1, const GEOGRAPHIC_EDGE *e2, GEOGRAPHIC_POINT *g)
Returns true if an intersection can be calculated, and places it in *g.
Definition: lwgeodetic.c:1127
GEOGRAPHIC_POINT start
Definition: lwgeodetic.h:63
GEOGRAPHIC_POINT end
Definition: lwgeodetic.h:64
Two-point great circle segment from a to b.
Definition: lwgeodetic.h:62
Point in spherical coordinates on the world.
Definition: lwgeodetic.h:53

References edge_intersection(), edge_set(), GEOGRAPHIC_EDGE::end, GEOGRAPHIC_POINT::lat, GEOGRAPHIC_POINT::lon, LW_FALSE, LW_TRUE, point_rad2deg(), and GEOGRAPHIC_EDGE::start.

Referenced by geodetic_suite_setup().

Here is the call graph for this function:
Here is the caller graph for this function: