21 #include "CUnit/Basic.h" 79 CU_ASSERT_DOUBLE_EQUAL(dir, M_PI_2, 1e-14);
80 CU_ASSERT_DOUBLE_EQUAL(dist, 0.0174532925199433, 1e-14);
87 CU_ASSERT_DOUBLE_EQUAL(dir, 0.0, 1e-14);
88 CU_ASSERT_DOUBLE_EQUAL(dist, 0.0174532925199433, 1e-14);
95 double dir1, dist1, dir2, dist2;
103 CU_ASSERT_DOUBLE_EQUAL(e.
lon, 0.1, 1e-14);
104 CU_ASSERT_DOUBLE_EQUAL(e.
lat, 0.0, 1e-14);
110 CU_ASSERT_DOUBLE_EQUAL(dist1, dist2, 1e-14);
111 CU_ASSERT_DOUBLE_EQUAL(dir1, dir2, 1e-14);
117 CU_ASSERT_DOUBLE_EQUAL(s.
lon, 0.0, 1e-14);
118 CU_ASSERT_DOUBLE_EQUAL(s.
lat, 0.0, 1e-14);
125 CU_ASSERT_DOUBLE_EQUAL(dir1, 0.0, 1e-14);
126 CU_ASSERT_DOUBLE_EQUAL(dist1, 0.0034906585039887, 1e-14);
133 CU_ASSERT_DOUBLE_EQUAL(dir2, 0.0, 1e-14);
134 CU_ASSERT_DOUBLE_EQUAL(dist2, 0.0174532925199433, 1e-14);
140 CU_ASSERT_DOUBLE_EQUAL(dir2, 89.991273575329292895136 * M_PI / 180.0, 1e-14);
141 CU_ASSERT_DOUBLE_EQUAL(dist2, 0.0174506342314906, 1e-14);
147 CU_ASSERT_DOUBLE_EQUAL(dir2, M_PI, 1e-14);
148 CU_ASSERT_DOUBLE_EQUAL(dist2, 0.0174532925199433, 1e-14);
154 CU_ASSERT_DOUBLE_EQUAL(dir2, -89.991273575329292895136 * M_PI / 180.0, 1e-14);
155 CU_ASSERT_DOUBLE_EQUAL(dist2, 0.0174506342314906, 1e-14);
161 CU_ASSERT_DOUBLE_EQUAL(dir2, 44.978182941465044354783 * M_PI / 180.0, 1e-14);
162 CU_ASSERT_DOUBLE_EQUAL(dist2, 0.0246782972905467, 1e-14);
168 CU_ASSERT_DOUBLE_EQUAL(dir2, -134.995636455344851488216 * M_PI / 180.0, 1e-14);
169 CU_ASSERT_DOUBLE_EQUAL(dist2, 0.0246820563917664, 1e-14);
177 static void cross_product_stability(
void)
194 for ( i = 0; i < 40; i++ )
208 printf(
"\n- %d -------------------- %.24g ------------------------\n", i, p2.
y);
209 printf(
"Skea: %.24g,%.24g,%.24g\n", Nr.
x, Nr.
y, Nr.
z);
210 printf(
"Skea Diff: %.24g,%.24g,%.24g\n", Or.
x-Nr.
x, Or.
y-Nr.
y, Or.
z-Nr.
z);
211 printf(
"Ramsey: %.24g,%.24g,%.24g\n", Nc.
x, Nc.
y, Nc.
z);
212 printf(
"Ramsey Diff: %.24g,%.24g,%.24g\n", Oc.
x-Nc.
x, Oc.
y-Nc.
y, Oc.
z-Nc.
z);
213 printf(
"Diff: %.24g,%.24g,%.24g\n", Nr.
x-Nc.
x, Nr.
y-Nc.
y, Nr.
z-Nc.
z);
219 p2.
y += (p1.
y - p2.
y)/2.0;
227 const double gtolerance = 0.000001;
239 ll[0] = -3.083333333333333333333333333333333;
240 ll[1] = 9.83333333333333333333333333333333;
251 for ( i = 0; i < loops; i++ )
253 rndlat = (int)(90.0 - 180.0 * (
double)random() / pow(2.0, 31.0));
254 rndlon = (int)(180.0 - 360.0 * (
double)random() / pow(2.0, 31.0));
255 ll[0] = (double)rndlon;
256 ll[1] = (double)rndlat;
258 rndlat = (int)(90.0 - 180.0 * (
double)random() / pow(2.0, 31.0));
259 rndlon = (int)(180.0 - 360.0 * (
double)random() / pow(2.0, 31.0));
260 ll[2] = (double)rndlon;
261 ll[3] = (double)rndlat;
270 ( fabs( gbox.
xmin - gbox_slow.
xmin ) > gtolerance ) ||
271 ( fabs( gbox.
xmax - gbox_slow.
xmax ) > gtolerance ) ||
272 ( fabs( gbox.
ymin - gbox_slow.
ymin ) > gtolerance ) ||
273 ( fabs( gbox.
ymax - gbox_slow.
ymax ) > gtolerance ) ||
274 ( fabs( gbox.
zmin - gbox_slow.
zmin ) > gtolerance ) ||
275 ( fabs( gbox.
zmax - gbox_slow.
zmax ) > gtolerance ) )
277 printf(
"\n-------\n");
278 printf(
"If you are seeing this, cut and paste it, it is a randomly generated test case!\n");
279 printf(
"LOOP: %d\n", i);
280 printf(
"SEGMENT (Lon Lat): (%.9g %.9g) (%.9g %.9g)\n", ll[0], ll[1], ll[2], ll[3]);
283 printf(
"-------\n\n");
284 CU_FAIL_FATAL(Slow (GOOD) and fast (CALC) box calculations returned different values!!);
298 GBOX gbox, gbox_slow;
305 printf(
"\n\n------------\n");
319 printf(
"line %d: diff %.9g\n", i, fabs(gbox.
xmin - gbox_slow.
xmin)+fabs(gbox.
ymin - gbox_slow.
ymin)+fabs(gbox.
zmin - gbox_slow.
zmin));
320 printf(
"------------\n");
322 CU_ASSERT_DOUBLE_EQUAL(gbox.
xmin, gbox_slow.
xmin, 0.00000001);
323 CU_ASSERT_DOUBLE_EQUAL(gbox.
ymin, gbox_slow.
ymin, 0.00000001);
324 CU_ASSERT_DOUBLE_EQUAL(gbox.
zmin, gbox_slow.
zmin, 0.00000001);
325 CU_ASSERT_DOUBLE_EQUAL(gbox.
xmax, gbox_slow.
xmax, 0.00000001);
326 CU_ASSERT_DOUBLE_EQUAL(gbox.
ymax, gbox_slow.
ymax, 0.00000001);
327 CU_ASSERT_DOUBLE_EQUAL(gbox.
zmax, gbox_slow.
zmax, 0.00000001);
379 CU_ASSERT_DOUBLE_EQUAL(v_out_top.
lat, g_out_top.
lat, 0.000001);
380 CU_ASSERT_DOUBLE_EQUAL(v_out_top.
lon, g_out_top.
lon, 0.000001);
381 CU_ASSERT_DOUBLE_EQUAL(v_out_bottom.
lat, g_out_bottom.
lat, 0.000001);
382 CU_ASSERT_DOUBLE_EQUAL(v_out_bottom.
lon, g_out_bottom.
lon, 0.000001);
384 gs.
lat = 1.3021240033804449;
385 ge.
lat = 1.3021240033804449;
386 gs.
lon = -1.3387392931438733;
387 ge.
lon = 1.80285336044592;
395 CU_ASSERT_DOUBLE_EQUAL(v_out_top.
lat, g_out_top.
lat, 0.000001);
396 CU_ASSERT_DOUBLE_EQUAL(v_out_top.
lon, g_out_top.
lon, 0.000001);
397 CU_ASSERT_DOUBLE_EQUAL(v_out_bottom.
lat, g_out_bottom.
lat, 0.000001);
398 CU_ASSERT_DOUBLE_EQUAL(v_out_bottom.
lon, g_out_bottom.
lon, 0.000001);
408 edge_set(50, -10.999999999999998224, -10.0, 50.0, &e1);
409 edge_set(-10.0, 50.0, -10.272779983831613393, -16.937003313332997578, &e2);
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;
426 edge_set(-123.165031277506, 42.4696787216231, -123.165031605021, 42.4697127292275, &e1);
448 CU_ASSERT_DOUBLE_EQUAL(g.
lat, 0.0, 0.00001);
449 CU_ASSERT_DOUBLE_EQUAL(g.
lon, 0.0, 0.00001);
454 edge_set(0.0, -1.0, 0.0, -2.0, &e2);
467 printf(
"g = (%.15g %.15g)\n", g.
lon, g.
lat);
468 printf(
"rv = %d\n", rv);
470 CU_ASSERT_DOUBLE_EQUAL(g.
lon, 0.0, 0.00001);
482 printf(
"g = (%.15g %.15g)\n", g.
lon, g.
lat);
483 printf(
"rv = %d\n", rv);
485 CU_ASSERT_DOUBLE_EQUAL(g.
lat, 0.0, 0.00001);
486 CU_ASSERT_DOUBLE_EQUAL(g.
lon, 0.0, 0.00001);
490 edge_set(-179.0, -1.0, 179.0, 1.0, &e1);
491 edge_set(-179.0, 1.0, 179.0, -1.0, &e2);
494 CU_ASSERT_DOUBLE_EQUAL(g.
lat, 0.0, 0.00001);
495 CU_ASSERT_DOUBLE_EQUAL(fabs(g.
lon), 180.0, 0.00001);
499 edge_set(-170.0, 0.0, 170.0, 0.0, &e1);
500 edge_set(180.0, -10.0, 180.0, 10.0, &e2);
503 CU_ASSERT_DOUBLE_EQUAL(g.
lat, 0.0, 0.00001);
504 CU_ASSERT_DOUBLE_EQUAL(fabs(g.
lon), 180.0, 0.00001);
508 edge_set(-180.0, 80.0, 0.0, 80.0, &e1);
509 edge_set(90.0, 80.0, -90.0, 80.0, &e2);
512 CU_ASSERT_DOUBLE_EQUAL(g.
lat, 90.0, 0.00001);
516 edge_set(45.0, 10.0, 50.0, 20.0, &e1);
517 edge_set(45.0, 10.0, 50.0, 20.0, &e2);
523 edge_set(40.0, 0.0, 70.0, 0.0, &e1);
524 edge_set(60.0, 0.0, 50.0, 0.0, &e2);
527 CU_ASSERT_EQUAL(rv, 2);
530 edge_set(-180.0, 80.0, 0.0, 80.0, &e1);
531 edge_set(90.0, 80.0, -90.0, 90.0, &e2);
538 printf(
"g = (%.15g %.15g)\n", g.
lon, g.
lat);
539 printf(
"rv = %d\n", rv);
541 CU_ASSERT_DOUBLE_EQUAL(g.
lat, 90.0, 0.00001);
545 edge_set(-180.0, 80.0, 0.0, 90.0, &e1);
546 edge_set(90.0, 80.0, -90.0, 90.0, &e2);
553 printf(
"g = (%.15g %.15g)\n", g.
lon, g.
lat);
554 printf(
"rv = %d\n", rv);
556 CU_ASSERT_DOUBLE_EQUAL(g.
lat, 90.0, 0.00001);
569 printf(
"BAD WKT FOUND in test_edge_intersects:\n %s\n\n", wkt);
590 line2pts(
"LINESTRING(58.5112113206308 0, 58.511211320077201 0.00090193752520337797)", &A1, &A2);
591 line2pts(
"LINESTRING(58.511166525601702 0.00027058124084120699, 58.511166525562899 0.00036077498778824899)", &B1, &B2);
596 line2pts(
"LINESTRING(50 -10.999999999999998224, -10.0 50.0)", &A1, &A2);
597 line2pts(
"LINESTRING(-10.0 50.0, -10.272779983831613393 -16.937003313332997578)", &B1, &B2);
602 g.
lat = 0.74123572595649878103;
603 g.
lon = -2.1496353191142714145;
605 g.
lat = 0.74123631950116664058;
606 g.
lon = -2.1496353248304860273;
608 g.
lat = 0.73856343764436815924;
609 g.
lon = -2.1461493501950630325;
611 g.
lat = 0.70971354024834598651;
612 g.
lon = 2.1082194552519770703;
618 g.
lat = 0.73826546728290887156;
619 g.
lon = -2.14426380171833042;
621 g.
lat = 0.73826545883786642843;
622 g.
lon = -2.1442638997530165668;
624 g.
lat = 0.73775469118192538165;
625 g.
lon = -2.1436035534281718817;
627 g.
lat = 0.71021099548296817705;
628 g.
lon = 2.1065275171200439353;
631 CU_ASSERT(rv == PIR_INTERSECTS);
634 line2pts(
"LINESTRING(-123.165031277506 42.4696787216231, -123.165031605021 42.4697127292275)", &A1, &A2);
639 line2pts(
"LINESTRING(-1.0 0.0, 1.0 0.0)", &A1, &A2);
640 line2pts(
"LINESTRING(0.0 -1.0, 0.0 1.0)", &B1, &B2);
642 CU_ASSERT(rv == PIR_INTERSECTS);
645 line2pts(
"LINESTRING(-1.0 0.0, 1.0 0.0)", &A1, &A2);
646 line2pts(
"LINESTRING(0.0 -1.0, 0.0 -2.0)", &B1, &B2);
651 line2pts(
"LINESTRING(-1.0 0.0, 1.0 0.0)", &A1, &A2);
652 line2pts(
"LINESTRING(0.0 -1.0, 0.0 0.0)", &B1, &B2);
657 line2pts(
"LINESTRING(0.0 0.0, 1.0 0.0)", &A1, &A2);
658 line2pts(
"LINESTRING(0.0 -1.0, 0.0 0.0)", &B1, &B2);
663 line2pts(
"LINESTRING(-179.0 -1.0, 179.0 1.0)", &A1, &A2);
664 line2pts(
"LINESTRING(-179.0 1.0, 179.0 -1.0)", &B1, &B2);
666 CU_ASSERT(rv == PIR_INTERSECTS);
669 line2pts(
"LINESTRING(-170.0 0.0, 170.0 0.0)", &A1, &A2);
670 line2pts(
"LINESTRING(180.0 -10.0, 180.0 10.0)", &B1, &B2);
672 CU_ASSERT(rv == PIR_INTERSECTS);
675 line2pts(
"LINESTRING(-180.0 80.0, 0.0 80.0)", &A1, &A2);
676 line2pts(
"LINESTRING(90.0 80.0, -90.0 80.0)", &B1, &B2);
678 CU_ASSERT(rv == PIR_INTERSECTS);
681 line2pts(
"LINESTRING(45.0 10.0, 50.0 20.0)", &A1, &A2);
682 line2pts(
"LINESTRING(45.0 10.0, 50.0 20.0)", &B1, &B2);
684 CU_ASSERT(rv & PIR_INTERSECTS);
687 line2pts(
"LINESTRING(40.0 0.0, 70.0 0.0)", &A1, &A2);
688 line2pts(
"LINESTRING(60.0 0.0, 50.0 0.0)", &B1, &B2);
693 line2pts(
"LINESTRING(-180.0 80.0, 0.0 80.0)", &A1, &A2);
694 line2pts(
"LINESTRING(90.0 80.0, -90.0 90.0)", &B1, &B2);
699 line2pts(
"LINESTRING(-180.0 80.0, 0.0 90.0)", &A1, &A2);
700 line2pts(
"LINESTRING(90.0 80.0, -90.0 90.0)", &B1, &B2);
708 line2pts(
"LINESTRING(90.0 60.0, 90.0 -20.0)", &A1, &A2);
709 line2pts(
"LINESTRING(0.0 0.0, -90.04868865037885 -57.44011727050777)", &B1, &B2);
713 line2pts(
"LINESTRING(-5 0, 5 0)", &A1, &A2);
714 line2pts(
"LINESTRING(179 -5, 179 5)", &B1, &B2);
718 line2pts(
"LINESTRING(175 -85, 175 85)", &A1, &A2);
719 line2pts(
"LINESTRING(65 0, -105 0)", &B1, &B2);
723 line2pts(
"LINESTRING(175 -85, 175 85)", &A1, &A2);
724 line2pts(
"LINESTRING(45 0, -125 0)", &B1, &B2);
738 edge_set(-50.0, 0.0, 50.0, 0.0, &e);
741 CU_ASSERT_DOUBLE_EQUAL(d, M_PI / 180.0, 0.00001);
744 edge_set(-50.0, 0.0, 50.0, 0.0, &e);
749 printf(
"POINT(%.9g %.9g)\n", g.
lon, g.
lat);
750 printf(
"\nDISTANCE == %.8g\n", d);
752 CU_ASSERT_DOUBLE_EQUAL(d, M_PI / 90.0, 0.00001);
753 CU_ASSERT_DOUBLE_EQUAL(closest.
lat, 0.0, 0.00001);
754 CU_ASSERT_DOUBLE_EQUAL(closest.
lon, 0.0, 0.00001);
757 edge_set(149.386990599235, -26.3567415843982, 149.386990599247, -26.3567415843965, &e);
758 point_set(149.386990599235, -26.3567415843982, &g);
760 CU_ASSERT_DOUBLE_EQUAL(d, 0.0, 0.00001);
763 CU_ASSERT_DOUBLE_EQUAL(g.
lat, closest.
lat, 0.00001);
764 CU_ASSERT_DOUBLE_EQUAL(g.
lon, closest.
lon, 0.00001);
774 edge_set(-50.0, 0.0, 50.0, 0.0, &e1);
775 edge_set(-5.0, 20.0, 0.0, 1.0, &e2);
780 printf(
"\nDISTANCE == %.8g\n", d);
782 CU_ASSERT_DOUBLE_EQUAL(d, M_PI / 180.0, 0.00001);
783 CU_ASSERT_DOUBLE_EQUAL(c1.
lat, 0.0, 0.00001);
784 CU_ASSERT_DOUBLE_EQUAL(c2.
lat, M_PI / 180.0, 0.00001);
785 CU_ASSERT_DOUBLE_EQUAL(c1.
lon, 0.0, 0.00001);
786 CU_ASSERT_DOUBLE_EQUAL(c2.
lon, 0.0, 0.00001);
814 "LINESTRING(-1 -1,-1 2.5,2 2,2 -1)",
815 "SRID=1;MULTILINESTRING((-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1))",
816 "POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0))",
817 "SRID=4326;MULTIPOLYGON(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)),((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)))",
818 "SRID=4326;GEOMETRYCOLLECTION(POINT(0 1),POLYGON((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0)),MULTIPOLYGON(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5))))",
820 "LINESTRING(-1 -1,-1231 2.5,2 2,2 -1)",
821 "SRID=1;MULTILINESTRING((-1 -131,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1),(-1 -1,-1 2.5,2 2,2 -1))",
822 "POLYGON((-1 -1,-1 2.5,2 2,2 -133,-1 -1),(0 0,0 1,1 1,1 0,0 0))",
823 "SRID=4326;MULTIPOLYGON(((-1 -1,-1 2.5,211 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)),((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5)))",
824 "SRID=4326;GEOMETRYCOLLECTION(POINT(0 1),POLYGON((-1 -1,-1111 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0)),MULTIPOLYGON(((-1 -1,-1 2.5,2 2,2 -1,-1 -1),(0 0,0 1,1 1,1 0,0 0),(-0.5 -0.5,-0.5 -0.4,-0.4 -0.4,-0.4 -0.5,-0.5 -0.5))))",
827 for ( i = 0; i < 6; i++ )
836 for ( i = 6; i < 12; i++ )
906 inspect = (
double*)g;
907 CU_ASSERT_EQUAL(inspect[3], 0.2);
911 geom =
lwgeom_from_wkt(
"POLYGON((-1 -1, -1 2.5, 2 2, 2 -1, -1 -1), (0 0, 0 1, 1 1, 1 0, 0 0))",
LW_PARSER_CHECK_NONE);
916 inspect = (
double*)g;
917 CU_ASSERT_EQUAL(inspect[9], 2.5);
926 inspect = (
double*)g;
927 CU_ASSERT_EQUAL(inspect[12], 0.1);
942 lwg =
lwgeom_from_hexwkb(
"0103000020E61000000100000025000000ACAD6F91DDB65EC03F84A86D57264540CCABC279DDB65EC0FCE6926B57264540B6DEAA62DDB65EC0A79F6B63572645402E0BE84CDDB65EC065677155572645405D0B1D39DDB65EC0316310425726454082B5DB27DDB65EC060A4E12957264540798BB619DDB65EC0C393A10D57264540D4BC160FDDB65EC0BD0320EE56264540D7AC4E08DDB65EC096C862CC56264540AFD29205DDB65EC02A1F68A956264540363AFA06DDB65EC0722E418656264540B63A780CDDB65EC06E9B0064562645409614E215DDB65EC0E09DA84356264540FF71EF22DDB65EC0B48145265626454036033F33DDB65EC081B8A60C5626454066FB4546DDB65EC08A47A6F7552645409061785BDDB65EC0F05AE0E755264540D4B63772DDB65EC05C86CEDD55264540D2E4C689DDB65EC09B6EBFD95526454082E573A1DDB65EC0C90BD5DB552645401ABE85B8DDB65EC06692FCE35526454039844ECEDDB65EC04D8AF6F155264540928319E2DDB65EC0AD8D570556264540D31055F3DDB65EC02D618F1D56264540343B7A01DEB65EC0EB70CF3956264540920A1A0CDEB65EC03B00515956264540911BE212DEB65EC0E43A0E7B56264540E3F69D15DEB65EC017E4089E562645408D903614DEB65EC0F0D42FC1562645402191B80EDEB65EC0586870E35626454012B84E05DEB65EC09166C80357264540215B41F8DDB65EC08F832B21572645408392F7E7DDB65EC01138C13A57264540F999F0D4DDB65EC0E4A9C14F57264540AC3FB8BFDDB65EC0EED6875F57264540D3DCFEA8DDB65EC04F6C996957264540ACAD6F91DDB65EC03F84A86D57264540",
LW_PARSER_CHECK_NONE);
944 pt_to_test.
x = -122.819436560680316;
945 pt_to_test.
y = 42.2702301207017328;
946 pt_outside.
x = 120.695136159150778;
947 pt_outside.
y = 40.6920926049588516;
960 CU_ASSERT_EQUAL(result,
LW_TRUE);
971 CU_ASSERT_EQUAL(result,
LW_TRUE);
985 CU_ASSERT_EQUAL(result,
LW_TRUE);
1002 pt_to_test.
x = 1.05;
1005 pt_outside.
y = 1.05;
1011 lwg =
lwgeom_from_wkt(
"POLYGON((0 0, 0 2, 1 2, 0 3, 2 3, 0 4, 3 5, 0 6, 6 10, 6 1, 0 0))",
LW_PARSER_CHECK_NONE);
1016 pt_outside.
y = 10.0;
1018 CU_ASSERT_EQUAL(result,
LW_TRUE);
1027 pt_outside.
y = 1.05;
1029 CU_ASSERT_EQUAL(result,
LW_TRUE);
1038 pt_outside.
y = 1.05;
1040 CU_ASSERT_EQUAL(result,
LW_TRUE);
1047 pt_to_test.
y = 1.05;
1051 CU_ASSERT_EQUAL(result,
LW_TRUE);
1090 pt_to_test.
x = 0.99;
1091 pt_to_test.
y = 0.99;
1092 pt_outside.
x = 1.21;
1093 pt_outside.
y = 1.21;
1101 pt_to_test.
x = 1.11;
1102 pt_to_test.
y = 1.11;
1103 pt_outside.
x = 1.21;
1104 pt_outside.
y = 1.21;
1106 CU_ASSERT_EQUAL(result,
LW_TRUE);
1112 pt_to_test.
x = -10.0;
1113 pt_to_test.
y = 50.0;
1114 pt_outside.
x = -10.2727799838316134;
1115 pt_outside.
y = -16.9370033133329976;
1117 CU_ASSERT_EQUAL(result,
LW_TRUE);
1131 pt_to_test.
x = -10.0;
1132 pt_to_test.
y = 50.0;
1134 CU_ASSERT_EQUAL(result,
LW_TRUE);
1141 pt_to_test.
y = 11.0;
1143 CU_ASSERT_EQUAL(result,
LW_TRUE);
1149 pt_to_test.
x = -172.0;
1150 pt_to_test.
y = -13.0;
1152 CU_ASSERT_EQUAL(result,
LW_TRUE);
1162 POINT2D pt_outside, pt_to_test;
1165 pt_to_test.
x = -95.900000000000006;
1166 pt_to_test.
y = 42.899999999999999;
1167 pt_outside.
x = -96.381873780830645;
1168 pt_outside.
y = 40.185394449416371;
1191 CU_ASSERT_DOUBLE_EQUAL(d, s.
radius * M_PI / 180.0, 0.00001);
1199 CU_ASSERT_DOUBLE_EQUAL(d, 0.0, 0.00001);
1207 CU_ASSERT_DOUBLE_EQUAL(d, s.
radius * M_PI / 180.0, 0.00001);
1214 CU_ASSERT_DOUBLE_EQUAL(d, s.
radius * M_PI / 90.0, 0.00001);
1222 CU_ASSERT_DOUBLE_EQUAL(d, 0.0, 0.00001);
1227 lwg1 =
lwgeom_from_wkt(
"POLYGON((-4 -4, -4 4, 4 4, 4 -4, -4 -4), (-2 -2, -2 2, 2 2, 2 -2, -2 -2))",
LW_PARSER_CHECK_NONE);
1230 CU_ASSERT_DOUBLE_EQUAL(d, 111178.142466, 0.1);
1235 lwg1 =
lwgeom_from_wkt(
"POLYGON((-4 -4, -4 4, 4 4, 4 -4, -4 -4), (-2 -2, -2 2, 2 2, 2 -2, -2 -2))",
LW_PARSER_CHECK_NONE);
1238 CU_ASSERT_DOUBLE_EQUAL(d, 0.0, 0.00001);
1244 lwg2 =
lwgeom_from_hexwkb(
"0106000020E61000000100000001030000000100000007000000280EC3FB8CCA5EC0A5CDC747233C45402787C8F58CCA5EC0659EA2761E3C45400CED58DF8FCA5EC0C37FAE6E1E3C4540AE97B8E08FCA5EC00346F58B1F3C4540250359FD8ECA5EC05460628E1F3C45403738F4018FCA5EC05DC84042233C4540280EC3FB8CCA5EC0A5CDC747233C4540",
LW_PARSER_CHECK_NONE);
1246 CU_ASSERT_DOUBLE_EQUAL(d, 23630.8003, 0.1);
1254 CU_ASSERT_DOUBLE_EQUAL(d, 0.0, 0.00001);
1260 lwg2 =
lwgeom_from_wkt(
"POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7,5 5))",
LW_PARSER_CHECK_NONE);
1262 CU_ASSERT_DOUBLE_EQUAL(d, 0.0, 0.00001);
1268 lwg2 =
lwgeom_from_wkt(
"POLYGON M ((0 0 2,10 0 1,10 10 -2,0 10 -5,0 0 -5),(5 5 6,7 5 6,7 7 6,5 7 10,5 5 -2))",
LW_PARSER_CHECK_NONE);
1270 CU_ASSERT_DOUBLE_EQUAL(d, 0.0, 0.00001);
1282 const double epsilon = 1e-8;
1297 CU_ASSERT_DOUBLE_EQUAL(d, 110574.3885577987957342, epsilon);
1307 CU_ASSERT_DOUBLE_EQUAL(d, 1113194.9079327357264771, epsilon);
1317 CU_ASSERT_DOUBLE_EQUAL(d, 111319.4907932735726477, epsilon);
1327 CU_ASSERT_DOUBLE_EQUAL(d, 19893357.0700676468277450, epsilon);
1337 CU_ASSERT_DOUBLE_EQUAL(d, 10001965.7293127228117396, epsilon);
1354 lwg =
lwgeom_from_wkt(
"POLYGON((-122.848227067007 42.5007249610493,-122.848309475585 42.5007179884263,-122.848327688675 42.500835880696,-122.848245279942 42.5008428533324,-122.848227067007 42.5007249610493))",
LW_PARSER_CHECK_NONE);
1360 CU_ASSERT_DOUBLE_EQUAL(a1, 89.721147136698008, 0.1);
1365 CU_ASSERT_DOUBLE_EQUAL(a2, 89.868413479309585, 0.1);
1373 CU_ASSERT_DOUBLE_EQUAL(a1, 12341436880.106982993974659, 0.1);
1378 CU_ASSERT_DOUBLE_EQUAL(a2, 12286884908.946891319597874, 0.1);
1387 CU_ASSERT_DOUBLE_EQUAL(a1, 12360265021.368023059138681, 0.1);
1391 CU_ASSERT_DOUBLE_EQUAL(a2, 12305128751.042900673161556, 0.1);
1400 CU_ASSERT_DOUBLE_EQUAL(a1, 12360265021.368023059138681, 0.1);
1404 CU_ASSERT_DOUBLE_EQUAL(a2, 12305128751.042900673161556, 0.1);
1413 CU_ASSERT_DOUBLE_EQUAL(a1, 12360265021.368023059138681, 0.1);
1417 CU_ASSERT_DOUBLE_EQUAL(a2, 12305128751.042900673161556, 0.1);
1440 CU_ASSERT_DOUBLE_EQUAL(a1, 0.0177951, 0.0000001);
1441 CU_ASSERT_DOUBLE_EQUAL(a2, 0.017764, 0.0000001);
1450 CU_ASSERT_DOUBLE_EQUAL(a1, 0.0174613, 0.0000001);
1451 CU_ASSERT_DOUBLE_EQUAL(a2, 0.0174553, 0.0000001);
1459 CU_ASSERT_DOUBLE_EQUAL(pt.
x, 179.5, 0.0001);
1460 CU_ASSERT_DOUBLE_EQUAL(pt.
y, 1.50024, 0.0001);
1470 memset(&p1, 0,
sizeof(
POINT3D));
1471 memset(&p2, 0,
sizeof(
POINT3D));
1476 CU_ASSERT_DOUBLE_EQUAL(angle, M_PI_2, 0.00001);
1482 CU_ASSERT_DOUBLE_EQUAL(angle, M_PI_2, 0.00001);
1487 CU_ASSERT_DOUBLE_EQUAL(angle, M_PI_4, 0.00001);
1489 p2.
x = p2.
y = p2.
z = 1.0;
1492 CU_ASSERT_DOUBLE_EQUAL(angle, 0.955317, 0.00001);
1501 memset(&p1, 0,
sizeof(
POINT3D));
1502 memset(&p2, 0,
sizeof(
POINT3D));
1503 memset(&n, 0,
sizeof(
POINT3D));
1510 CU_ASSERT_DOUBLE_EQUAL(n.
x, 0.707107, 0.00001);
1512 angle = 2*M_PI/400000000;
1515 CU_ASSERT_DOUBLE_EQUAL(n.
x, 0.999999999999999888978, 0.0000000000000001);
1516 CU_ASSERT_DOUBLE_EQUAL(n.
y, 1.57079632679489654446e-08, 0.0000000000000001);
1521 CU_ASSERT_DOUBLE_EQUAL(n.
x, 1.0, 0.00000001);
1557 CU_ASSERT_DOUBLE_EQUAL(area, 12360265021.3561, 1.0);
1563 CU_ASSERT_DOUBLE_EQUAL(area, 127516467322130, 1.0);
1568 CU_ASSERT_DOUBLE_EQUAL(area, 127516467322130, 1.0);
1573 CU_ASSERT_DOUBLE_EQUAL(area, 127516467322130, 1.0);
1595 ASSERT_STRING_EQUAL(c,
"GBOX((-1.7976931e+308,-1.7976931e+308,-1.7976931e+308,-1.7976931e+308),(-1.7976931e+308,-1.7976931e+308,-1.7976931e+308,-1.7976931e+308))");
1606 CU_pSuite suite = CU_add_suite(
"geodetic", NULL, NULL);
uint32_t gserialized_get_type(const GSERIALIZED *s)
Extract the geometry type from the serialized form (it hides in the anonymous data area...
int lwgeom_calculate_gbox_geodetic(const LWGEOM *geom, GBOX *gbox)
Calculate the geodetic bounding box for an LWGEOM.
void robust_cross_product(const GEOGRAPHIC_POINT *p, const GEOGRAPHIC_POINT *q, POINT3D *a)
Computes the cross product of two vectors using their lat, lng representations.
static void edge_deg2rad(GEOGRAPHIC_EDGE *e)
Convert an edge from degrees to radians.
double sphere_distance(const GEOGRAPHIC_POINT *s, const GEOGRAPHIC_POINT *e)
Given two points on a unit sphere, calculate their distance apart in radians.
static void test_ptarray_contains_point_sphere(void)
double longitude_radians_normalize(double lon)
Convert a longitude to the range of -PI,PI.
int sphere_project(const GEOGRAPHIC_POINT *r, double distance, double azimuth, GEOGRAPHIC_POINT *n)
Given a starting location r, a distance and an azimuth to the new point, compute the location of the ...
void spheroid_init(SPHEROID *s, double a, double b)
Initialize a spheroid object for use in geodetic functions.
double edge_distance_to_edge(const GEOGRAPHIC_EDGE *e1, const GEOGRAPHIC_EDGE *e2, GEOGRAPHIC_POINT *closest1, GEOGRAPHIC_POINT *closest2)
Calculate the distance between two edges.
Two-point great circle segment from a to b.
#define PIR_B_TOUCH_RIGHT
void normalize(POINT3D *p)
Normalize to a unit vector.
static void test_sphere_direction(void)
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
char * gbox_to_string(const GBOX *gbox)
Allocate a string representation of the GBOX, based on dimensionality of flags.
static void test_lwgeom_segmentize_sphere(void)
#define PIR_A_TOUCH_RIGHT
#define ASSERT_STRING_EQUAL(o, e)
Datum area(PG_FUNCTION_ARGS)
static void line2pts(const char *wkt, POINT3D *A1, POINT3D *A2)
int lwgeom_check_geodetic(const LWGEOM *geom)
Check that coordinates of LWGEOM are all within the geodetic range (-180, -90, 180, 90)
void lwgeom_free(LWGEOM *geom)
void lwline_free(LWLINE *line)
static void point_deg2rad(GEOGRAPHIC_POINT *p)
Convert an edge from radians to degrees.
static void edge_set(double lon1, double lat1, double lon2, double lat2, GEOGRAPHIC_EDGE *e)
int gbox_centroid(const GBOX *gbox, POINT2D *out)
Computes the average(ish) center of the box and returns success.
static void test_lwgeom_area_sphere(void)
static void test_sphere_project(void)
static void test_clairaut(void)
LWGEOM * lwgeom_from_wkt(const char *wkt, const char check)
#define FLAGS_SET_GEODETIC(flags, value)
Point in spherical coordinates on the world.
static void test_edge_distance_to_edge(void)
static void test_lwgeom_check_geodetic(void)
static void test_ptarray_contains_point_sphere_iowa(void)
static void test_gbox_utils(void)
static void test_vector_angle(void)
void geodetic_suite_setup(void)
int lwgeom_calculate_gbox(const LWGEOM *lwgeom, GBOX *gbox)
Calculate bounding box of a geometry, automatically taking into account whether it is cartesian or ge...
#define LW_PARSER_CHECK_NONE
int clairaut_geographic(const GEOGRAPHIC_POINT *start, const GEOGRAPHIC_POINT *end, GEOGRAPHIC_POINT *g_top, GEOGRAPHIC_POINT *g_bottom)
Computes the pole of the great circle disk which is the intersection of the great circle with the lin...
void unit_normal(const POINT3D *P1, const POINT3D *P2, POINT3D *normal)
Calculates the unit normal to two vectors, trying to avoid problems with over-narrow or over-wide cas...
#define FLAGS_SET_Z(flags, value)
int ptarray_contains_point_sphere(const POINTARRAY *pa, const POINT2D *pt_outside, const POINT2D *pt_to_test)
This routine returns LW_TRUE if the stabline joining the pt_outside and pt_to_test crosses the ring a...
LWGEOM * lwline_as_lwgeom(const LWLINE *obj)
#define LW_TRUE
Return types for functions with status returns.
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
double edge_distance_to_point(const GEOGRAPHIC_EDGE *e, const GEOGRAPHIC_POINT *gp, GEOGRAPHIC_POINT *closest)
static void point_rad2deg(GEOGRAPHIC_POINT *p)
Convert a point from radians to degrees.
void ll2cart(const POINT2D *g, POINT3D *p)
Convert lon/lat coordinates to cartesion coordinates on unit sphere.
int clairaut_cartesian(const POINT3D *start, const POINT3D *end, GEOGRAPHIC_POINT *g_top, GEOGRAPHIC_POINT *g_bottom)
Computes the pole of the great circle disk which is the intersection of the great circle with the lin...
#define SRID_UNKNOWN
Unknown SRID value.
#define PG_ADD_TEST(suite, testfunc)
void vector_rotate(const POINT3D *v1, const POINT3D *v2, double angle, POINT3D *n)
Rotates v1 through an angle (in radians) within the plane defined by v1/v2, returns the rotated vecto...
POINTARRAY * ptarray_construct_reference_data(char hasz, char hasm, uint32_t npoints, uint8_t *ptlist)
Construct a new POINTARRAY, referencing to the data from ptlist.
static void test_lwpoly_covers_point2d(void)
static void test_gbox_from_spherical_coordinates(void)
int getPoint2d_p(const POINTARRAY *pa, int n, POINT2D *point)
static void point_set(double lon, double lat, GEOGRAPHIC_POINT *p)
double lwgeom_area_sphere(const LWGEOM *lwgeom, const SPHEROID *spheroid)
Calculate the geodetic area of a lwgeom on the sphere.
uint8_t gflags(int hasz, int hasm, int geodetic)
Construct a new flags char.
LWGEOM * lwgeom_from_hexwkb(const char *hexwkb, const char check)
void geog2cart(const GEOGRAPHIC_POINT *g, POINT3D *p)
Convert spherical coordinates to cartesion coordinates on unit sphere.
int gbox_geocentric_slow
For testing geodetic bounding box, we have a magic global variable.
double latitude_radians_normalize(double lat)
Convert a latitude to the range of -PI/2,PI/2.
static void test_gserialized_from_lwgeom(void)
int edge_intersects(const POINT3D *A1, const POINT3D *A2, const POINT3D *B1, const POINT3D *B2)
Returns non-zero if edges A and B interact.
static void test_spheroid_distance(void)
static void test_edge_intersects(void)
LWGEOM * lwgeom_segmentize_sphere(const LWGEOM *lwg_in, double max_seg_length)
Derive a new geometry with vertices added to ensure no vertex is more than max_seg_length (in radians...
static void test_edge_distance_to_point(void)
double gbox_angular_height(const GBOX *gbox)
GBOX utility functions to figure out coverage/location on the globe.
void geographic_point_init(double lon, double lat, GEOGRAPHIC_POINT *g)
Initialize a geographic point.
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
static void test_gbox_to_string_truncated(void)
#define deg2rad(d)
Conversion functions.
double lwgeom_area_spheroid(const LWGEOM *lwgeom, const SPHEROID *spheroid)
Calculate the geodetic area of a lwgeom on the spheroid.
double spheroid_distance(const GEOGRAPHIC_POINT *a, const GEOGRAPHIC_POINT *b, const SPHEROID *spheroid)
Computes the shortest distance along the surface of the spheroid between two points.
double lwgeom_distance_spheroid(const LWGEOM *lwgeom1, const LWGEOM *lwgeom2, const SPHEROID *spheroid, double tolerance)
Calculate the geodetic distance from lwgeom1 to lwgeom2 on the spheroid.
static void test_edge_intersection(void)
static void test_gserialized_get_gbox_geocentric(void)
int lwpoly_covers_point2d(const LWPOLY *poly, const POINT2D *pt_to_test)
Given a polygon (lon/lat decimal degrees) and point (lon/lat decimal degrees) and a guaranteed outsid...
GSERIALIZED * gserialized_from_lwgeom(LWGEOM *geom, size_t *size)
Allocate a new GSERIALIZED from an LWGEOM.
static LWGEOM * lwgeom_over_gserialized(char *wkt, GSERIALIZED **g)
static void test_vector_rotate(void)
double vector_angle(const POINT3D *v1, const POINT3D *v2)
Angle between two unit vectors.
static void test_spheroid_area(void)
static void test_lwgeom_distance_sphere(void)
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.
#define FLAGS_SET_M(flags, value)
double gbox_angular_width(const GBOX *gbox)
Returns the angular width (longitudinal span) of the box in radians.
double sphere_direction(const GEOGRAPHIC_POINT *s, const GEOGRAPHIC_POINT *e, double d)
Given two points on a unit sphere, calculate the direction from s to e.