/* ** GiST support function. Called from gserialized_gist_consistent below. */ static inline bool gserialized_gist_consistent_internal_2d(BOX2DF *key, BOX2DF *query, StrategyNumber strategy) { bool retval; POSTGIS_DEBUGF(4, "[GIST] internal consistent, strategy [%d], count[%i], query[%s], key[%s]", strategy, g2d_counter_internal++, box2df_to_string(query), box2df_to_string(key) ); switch (strategy) { case RTOverlapStrategyNumber: retval = (bool) box2df_overlaps(key, query); break; case RTSameStrategyNumber: case RTContainsStrategyNumber: case RTOldContainsStrategyNumber: retval = (bool) box2df_contains(key, query); break; case RTContainedByStrategyNumber: case RTOldContainedByStrategyNumber: retval = (bool) box2df_overlaps(key, query); break; default: retval = FALSE; } return (retval); }
static inline bool gserialized_gist_consistent_internal_2d(BOX2DF *key, BOX2DF *query, StrategyNumber strategy) { bool retval; switch (strategy) { /* Basic overlaps */ case RTOverlapStrategyNumber: retval = (bool) box2df_overlaps(key, query); break; case RTSameStrategyNumber: case RTContainsStrategyNumber: case RTOldContainsStrategyNumber: retval = (bool) box2df_contains(key, query); break; case RTContainedByStrategyNumber: case RTOldContainedByStrategyNumber: retval = (bool) box2df_overlaps(key, query); break; /* To one side */ case RTAboveStrategyNumber: retval = (bool)(!box2df_overbelow(key, query)); break; case RTBelowStrategyNumber: retval = (bool)(!box2df_overabove(key, query)); break; case RTRightStrategyNumber: retval = (bool)(!box2df_overleft(key, query)); break; case RTLeftStrategyNumber: retval = (bool)(!box2df_overright(key, query)); break; /* Overlapping to one side */ case RTOverAboveStrategyNumber: retval = (bool)(!box2df_below(key, query)); break; case RTOverBelowStrategyNumber: retval = (bool)(!box2df_above(key, query)); break; case RTOverRightStrategyNumber: retval = (bool)(!box2df_left(key, query)); break; case RTOverLeftStrategyNumber: retval = (bool)(!box2df_right(key, query)); break; default: retval = FALSE; } return (retval); }
/* ** GiST support function. Called from gserialized_gist_consistent below. */ static inline bool gserialized_gist_consistent_leaf_2d(BOX2DF *key, BOX2DF *query, StrategyNumber strategy) { bool retval; POSTGIS_DEBUGF(4, "[GIST] leaf consistent, strategy [%d], count[%i]", strategy, g2d_counter_leaf++); switch (strategy) { case RTOverlapStrategyNumber: retval = (bool) box2df_overlaps(key, query); break; case RTSameStrategyNumber: retval = (bool) box2df_equals(key, query); break; case RTContainsStrategyNumber: case RTOldContainsStrategyNumber: retval = (bool) box2df_contains(key, query); break; case RTContainedByStrategyNumber: case RTOldContainedByStrategyNumber: retval = (bool) box2df_contains(query, key); break; default: retval = FALSE; } return (retval); }
/** * Calculate the box->box distance. */ static double box2df_distance(const BOX2DF *a, const BOX2DF *b) { /* Check for overlap */ if ( box2df_overlaps(a, b) ) return 0.0; if ( box2df_left(a, b) ) { if ( box2df_above(a, b) ) return pt_distance(a->xmax, a->ymin, b->xmin, b->ymax); if ( box2df_below(a, b) ) return pt_distance(a->xmax, a->ymax, b->xmin, b->ymin); else return b->xmin - a->xmax; } if ( box2df_right(a, b) ) { if ( box2df_above(a, b) ) return pt_distance(a->xmin, a->ymin, b->xmax, b->ymax); if ( box2df_below(a, b) ) return pt_distance(a->xmin, a->ymax, b->xmax, b->ymin); else return a->xmin - b->xmax; } if ( box2df_above(a, b) ) { if ( box2df_left(a, b) ) return pt_distance(a->xmax, a->ymin, b->xmin, b->ymax); if ( box2df_right(a, b) ) return pt_distance(a->xmin, a->ymin, b->xmax, b->ymax); else return a->ymin - b->ymax; } if ( box2df_below(a, b) ) { if ( box2df_left(a, b) ) return pt_distance(a->xmax, a->ymax, b->xmin, b->ymin); if ( box2df_right(a, b) ) return pt_distance(a->xmin, a->ymax, b->xmax, b->ymin); else return b->ymin - a->ymax; } return MAXFLOAT; }
/** * Calculate the The node_box_edge->query_centroid distance * between the boxes. */ static double box2df_distance_node_centroid(const BOX2DF *node, const BOX2DF *query) { BOX2DF q; double qx, qy; double d = 0.0; /* Turn query into point */ q.xmin = q.xmax = (query->xmin + query->xmax) / 2.0; q.ymin = q.ymax = (query->ymin + query->ymax) / 2.0; qx = q.xmin; qy = q.ymin; /* Check for overlap */ if ( box2df_overlaps(node, &q) == LW_TRUE ) return 0.0; /* Above or below */ if ( qx >= node->xmin && qx <= node->xmax ) { if( qy > node->ymax ) d = qy - node->ymax; else if ( qy < node->ymin ) d = node->ymin - qy; return d; } /* Left or right */ else if ( qy >= node->ymin && qy <= node->ymax ) { if ( qx > node->xmax ) d = qx - node->xmax; else if ( qx < node->xmin ) d = node->xmin - qx; return d; } /* Corner quadrants */ else { /* below/left of xmin/ymin */ if ( qx < node->xmin && qy < node->ymin ) { d = (node->xmin - qx) * (node->xmin - qx) + (node->ymin - qy) * (node->ymin - qy); } /* above/left of xmin/ymax */ else if ( qx < node->xmin && qy > node->ymax ) { d = (node->xmin - qx) * (node->xmin - qx) + (node->ymax - qy) * (node->ymax - qy); } /* above/right of xmax/ymax */ else if ( qx > node->xmax && qy > node->ymax ) { d = (node->xmax - qx) * (node->xmax - qx) + (node->ymax - qy) * (node->ymax - qy); } /* below/right of xmax/ymin */ else if ( qx > node->xmin && qy < node->ymin ) { d = (node->xmax - qx) * (node->xmax - qx) + (node->ymin - qy) * (node->ymin - qy); } else { /*ERROR*/ } } return sqrt(d); }