PostGIS  2.5.0dev-r@@SVN_REVISION@@

◆ gserialized_gist_distance_2d()

Datum gserialized_gist_distance_2d ( PG_FUNCTION_ARGS  )

Definition at line 1258 of file gserialized_gist_2d.c.

References box2df_distance(), box2df_distance_leaf_centroid(), distance(), gserialized_datum_get_box2df_p(), and LW_FAILURE.

Referenced by gserialized_gist_consistent_2d().

1259 {
1260  GISTENTRY *entry = (GISTENTRY*) PG_GETARG_POINTER(0);
1261  BOX2DF query_box;
1262  BOX2DF *entry_box;
1263  StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
1264  double distance;
1265 #if POSTGIS_PGSQL_VERSION >= 95
1266  bool *recheck = (bool *) PG_GETARG_POINTER(4);
1267 #endif
1268 
1269  POSTGIS_DEBUG(4, "[GIST] 'distance' function called");
1270 
1271  /* We are using '13' as the gist true-distance <-> strategy number
1272  * and '14' as the gist distance-between-boxes <#> strategy number */
1273  if ( strategy != 13 && strategy != 14 ) {
1274  elog(ERROR, "unrecognized strategy number: %d", strategy);
1275  PG_RETURN_FLOAT8(FLT_MAX);
1276  }
1277 
1278  /* Null box should never make this far. */
1279  if ( gserialized_datum_get_box2df_p(PG_GETARG_DATUM(1), &query_box) == LW_FAILURE )
1280  {
1281  POSTGIS_DEBUG(4, "[GIST] null query_gbox_index!");
1282  PG_RETURN_FLOAT8(FLT_MAX);
1283  }
1284 
1285  /* Get the entry box */
1286  entry_box = (BOX2DF*)DatumGetPointer(entry->key);
1287 
1288 #if POSTGIS_PGSQL_VERSION >= 95
1289 
1290  /* Box-style distance test */
1291  if ( strategy == 14 ) /* operator <#> */
1292  {
1293  distance = box2df_distance(entry_box, &query_box);
1294  }
1295  /* True distance test (formerly centroid distance) */
1296  else if ( strategy == 13 ) /* operator <-> */
1297  {
1298  /* In all cases, since we only have keys (boxes) we'll return */
1299  /* the minimum possible distance, which is the box2df_distance */
1300  /* and let the recheck sort things out in the case of leaves */
1301  distance = box2df_distance(entry_box, &query_box);
1302 
1303  if (GIST_LEAF(entry))
1304  *recheck = true;
1305  }
1306  else
1307  {
1308  elog(ERROR, "%s: reached unreachable code", __func__);
1309  PG_RETURN_NULL();
1310  }
1311 #else
1312  /* Box-style distance test */
1313  if ( strategy == 14 )
1314  {
1315  distance = (double)box2df_distance(entry_box, &query_box);
1316  PG_RETURN_FLOAT8(distance);
1317  }
1318 
1319  /* Treat leaf node tests different from internal nodes */
1320  if (GIST_LEAF(entry))
1321  {
1322  /* Calculate distance to leaves */
1323  distance = (double)box2df_distance_leaf_centroid(entry_box, &query_box);
1324  }
1325  else
1326  {
1327  /* Calculate distance for internal nodes */
1328  distance = (double)box2df_distance_node_centroid(entry_box, &query_box);
1329  }
1330 #endif
1331 
1332  PG_RETURN_FLOAT8(distance);
1333 }
#define LW_FAILURE
Definition: liblwgeom.h:78
static double box2df_distance(const BOX2DF *a, const BOX2DF *b)
Calculate the box->box distance.
static double box2df_distance_leaf_centroid(const BOX2DF *a, const BOX2DF *b)
Calculate the centroid->centroid distance between the boxes.
int gserialized_datum_get_box2df_p(Datum gsdatum, BOX2DF *box2df)
Peak into a GSERIALIZED datum to find the bounding box.
Datum distance(PG_FUNCTION_ARGS)
Here is the call graph for this function:
Here is the caller graph for this function: