159
159
static int gbox_check_poles(GBOX *gbox)
162
LWDEBUG(4, "checking poles");
163
LWDEBUGF(4, "gbox %s", gbox_to_string(gbox));
162
165
if ( gbox->xmin < 0.0 && gbox->xmax > 0.0 &&
163
gbox->ymin < 0.0 && gbox->ymax > 0.0 )
166
gbox->ymin < 0.0 && gbox->ymax > 0.0 )
165
if ( (gbox->zmin+gbox->zmin)/2 > 0.0 )
168
if ( (gbox->zmin + gbox->zmax) > 0.0 )
170
LWDEBUG(4, "enclosed positive z axis");
166
171
gbox->zmax = 1.0;
175
LWDEBUG(4, "enclosed negative z axis");
168
176
gbox->zmin = -1.0;
173
182
if ( gbox->xmin < 0.0 && gbox->xmax > 0.0 &&
174
gbox->zmin < 0.0 && gbox->zmax > 0.0 )
183
gbox->zmin < 0.0 && gbox->zmax > 0.0 )
176
if ( (gbox->ymin+gbox->ymin)/2 > 0.0 )
185
if ( (gbox->ymin + gbox->ymax) > 0.0 )
187
LWDEBUG(4, "enclosed positive y axis");
177
188
gbox->ymax = 1.0;
192
LWDEBUG(4, "enclosed negative y axis");
179
193
gbox->ymin = -1.0;
184
199
if ( gbox->ymin < 0.0 && gbox->ymax > 0.0 &&
185
gbox->zmin < 0.0 && gbox->zmax > 0.0 )
200
gbox->zmin < 0.0 && gbox->zmax > 0.0 )
187
if ( (gbox->xmin+gbox->xmin)/2 > 0.0 )
202
if ( (gbox->xmin + gbox->xmax) > 0.0 )
204
LWDEBUG(4, "enclosed positive x axis");
188
205
gbox->xmax = 1.0;
209
LWDEBUG(4, "enclosed negative x axis");
190
210
gbox->xmin = -1.0;
786
807
LWDEBUG(4, "flipping point to other side of sphere");
787
808
g->lat = -1.0 * g->lat;
788
809
g->lon = g->lon + M_PI;
810
LWDEBUGF(4, "g == GPOINT(%.12g %.12g)", g->lat, g->lon);
811
LWDEBUGF(4, "g == POINT(%.12g %.12g)", rad2deg(g->lon), rad2deg(g->lat));
789
812
if ( g->lon > M_PI )
791
814
g->lon = -1.0 * (2.0 * M_PI - g->lon);
1249
1272
void gbox_pt_outside(const GBOX *gbox, POINT2D *pt_outside)
1251
static double grow = M_PI / 180.0 / 60.0; /* one arc-minute */
1274
double grow = M_PI / 180.0 / 60.0; /* one arc-minute */
1255
1277
POINT3D corners[8];
1257
1279
GEOGRAPHIC_POINT g;
1259
/* Assign our box and expand it slightly. */
1268
/* Build our eight corner points */
1269
corners[0].x = ge.xmin;
1270
corners[0].y = ge.ymin;
1271
corners[0].z = ge.zmin;
1273
corners[1].x = ge.xmin;
1274
corners[1].y = ge.ymax;
1275
corners[1].z = ge.zmin;
1277
corners[2].x = ge.xmin;
1278
corners[2].y = ge.ymin;
1279
corners[2].z = ge.zmax;
1281
corners[3].x = ge.xmax;
1282
corners[3].y = ge.ymin;
1283
corners[3].z = ge.zmin;
1285
corners[4].x = ge.xmax;
1286
corners[4].y = ge.ymax;
1287
corners[4].z = ge.zmin;
1289
corners[5].x = ge.xmax;
1290
corners[5].y = ge.ymin;
1291
corners[5].z = ge.zmax;
1293
corners[6].x = ge.xmin;
1294
corners[6].y = ge.ymax;
1295
corners[6].z = ge.zmax;
1297
corners[7].x = ge.xmax;
1298
corners[7].y = ge.ymax;
1299
corners[7].z = ge.zmax;
1301
for ( i = 0; i < 8; i++ )
1281
while( grow < M_PI )
1303
normalize(&(corners[i]));
1304
if ( ! gbox_contains_point3d(gbox, &(corners[i])) )
1283
/* Assign our box and expand it slightly. */
1285
if ( ge.xmin > -1 ) ge.xmin -= grow;
1286
if ( ge.ymin > -1 ) ge.ymin -= grow;
1287
if ( ge.zmin > -1 ) ge.zmin -= grow;
1288
if ( ge.xmax < 1 ) ge.xmax += grow;
1289
if ( ge.ymax < 1 ) ge.ymax += grow;
1290
if ( ge.zmax < 1 ) ge.zmax += grow;
1292
/* Build our eight corner points */
1293
corners[0].x = ge.xmin;
1294
corners[0].y = ge.ymin;
1295
corners[0].z = ge.zmin;
1297
corners[1].x = ge.xmin;
1298
corners[1].y = ge.ymax;
1299
corners[1].z = ge.zmin;
1301
corners[2].x = ge.xmin;
1302
corners[2].y = ge.ymin;
1303
corners[2].z = ge.zmax;
1305
corners[3].x = ge.xmax;
1306
corners[3].y = ge.ymin;
1307
corners[3].z = ge.zmin;
1309
corners[4].x = ge.xmax;
1310
corners[4].y = ge.ymax;
1311
corners[4].z = ge.zmin;
1313
corners[5].x = ge.xmax;
1314
corners[5].y = ge.ymin;
1315
corners[5].z = ge.zmax;
1317
corners[6].x = ge.xmin;
1318
corners[6].y = ge.ymax;
1319
corners[6].z = ge.zmax;
1321
corners[7].x = ge.xmax;
1322
corners[7].y = ge.ymax;
1323
corners[7].z = ge.zmax;
1325
LWDEBUG(4, "trying to use a box corner point...");
1326
for ( i = 0; i < 8; i++ )
1309
pt_outside->x = rad2deg(g.lon);
1310
pt_outside->y = rad2deg(g.lat);
1328
normalize(&(corners[i]));
1329
LWDEBUGF(4, "testing corner %d: POINT(%.8g %.8g %.8g)", i, corners[i].x, corners[i].y, corners[i].z);
1330
if ( ! gbox_contains_point3d(gbox, &(corners[i])) )
1332
LWDEBUGF(4, "corner %d is outside our gbox", i);
1336
pt_outside->x = rad2deg(g.lon);
1337
pt_outside->y = rad2deg(g.lat);
1338
LWDEBUGF(4, "returning POINT(%.8g %.8g) as outside point", pt_outside->x, pt_outside->y);
1319
if ((1.0 - gbox->xmax) > 0.1)
1321
pt.x = gbox->xmax + (1.0 - gbox->xmax) * 0.01;
1322
d = sqrt((1.0 - POW2(pt.x))/2.0);
1326
else if ((1.0 - gbox->ymax) > 0.1)
1328
pt.y = gbox->ymax + (1.0 - gbox->ymax) * 0.01;
1329
d = sqrt((1.0 - POW2(pt.y))/2.0);
1333
else if ((1.0 - gbox->zmax) > 0.1)
1335
pt.z = gbox->zmax + (1.0 - gbox->zmax) * 0.01;
1336
d = sqrt((1.0 - POW2(pt.z))/2.0);
1342
pt_outside->x = rad2deg(g.lon);
1343
pt_outside->y = rad2deg(g.lat);
1343
/* Try a wider growth to push the corners outside the original box. */
1347
/* This should never happen! */
1348
lwerror("BOOM! Could not generate outside point!");
1424
* This routine returns LW_TRUE if the point is inside the ring or on the boundary, LW_FALSE otherwise.
1429
* This routine returns LW_TRUE if the stabline joining the pt_outside and pt_to_test
1430
* crosses the ring an odd number of times, or if the pt_to_test is on the ring boundary itself,
1431
* returning LW_FALSE otherwise.
1425
1432
* The pt_outside must be guaranteed to be outside the ring (use the geography_pt_outside() function
1426
1433
* to derive one in postgis, or the gbox_pt_outside() function if you don't mind burning CPU cycles
1427
1434
* building a gbox first).
2067
2074
return LW_FALSE;
2077
LWDEBUGF(4, "pt_to_test POINT(%.18g %.18g)", pt_to_test->x, pt_to_test->y);
2078
LWDEBUGF(4, "gbox %s", gbox_to_string(gbox));
2070
2080
/* Point not in box? Done! */
2071
2081
geographic_point_init(pt_to_test->x, pt_to_test->y, &gpt_to_test);
2072
2082
geog2cart(&gpt_to_test, &p);
2073
if ( ! gbox_contains_point3d(gbox, &p) )
2083
LWDEBUGF(4, "p POINT(%.18g %.18g %.18g)", p.x, p.y, p.z);
2084
if ( ! gbox_contains_point3d(gbox, &p) )
2086
LWDEBUG(4, "the point is not in the box!");
2074
2087
return LW_FALSE;
2076
2090
/* Calculate our outside point from the gbox */
2077
2091
gbox_pt_outside(gbox, &pt_outside);
2079
2093
LWDEBUGF(4, "pt_outside POINT(%.18g %.18g)", pt_outside.x, pt_outside.y);
2080
LWDEBUGF(4, "pt_to_test POINT(%.18g %.18g)", pt_to_test->x, pt_to_test->y);
2081
2094
LWDEBUGF(4, "polygon %s", lwgeom_to_ewkt((LWGEOM*)poly, PARSER_CHECK_NONE));
2082
LWDEBUGF(4, "gbox %s", gbox_to_string(gbox));
2084
2096
/* Not in outer ring? We're done! */
2085
2097
if ( ! ptarray_point_in_ring(poly->rings[0], &pt_outside, pt_to_test) )