PostGIS  2.4.9dev-r@@SVN_REVISION@@

◆ gserialized_gist_distance_2d()

Datum gserialized_gist_distance_2d ( PG_FUNCTION_ARGS  )

Definition at line 1203 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().

1204 {
1205  GISTENTRY *entry = (GISTENTRY*) PG_GETARG_POINTER(0);
1206  BOX2DF query_box;
1207  BOX2DF *entry_box;
1208  StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
1209  double distance;
1210 #if POSTGIS_PGSQL_VERSION >= 95
1211  bool *recheck = (bool *) PG_GETARG_POINTER(4);
1212 #endif
1213 
1214  POSTGIS_DEBUG(4, "[GIST] 'distance' function called");
1215 
1216  /* We are using '13' as the gist true-distance <-> strategy number
1217  * and '14' as the gist distance-between-boxes <#> strategy number */
1218  if ( strategy != 13 && strategy != 14 ) {
1219  elog(ERROR, "unrecognized strategy number: %d", strategy);
1220  PG_RETURN_FLOAT8(FLT_MAX);
1221  }
1222 
1223  /* Null box should never make this far. */
1224  if ( gserialized_datum_get_box2df_p(PG_GETARG_DATUM(1), &query_box) == LW_FAILURE )
1225  {
1226  POSTGIS_DEBUG(4, "[GIST] null query_gbox_index!");
1227  PG_RETURN_FLOAT8(FLT_MAX);
1228  }
1229 
1230  /* Get the entry box */
1231  entry_box = (BOX2DF*)DatumGetPointer(entry->key);
1232 
1233 #if POSTGIS_PGSQL_VERSION >= 95
1234 
1235  /* Box-style distance test */
1236  if ( strategy == 14 ) /* operator <#> */
1237  {
1238  distance = box2df_distance(entry_box, &query_box);
1239  }
1240  /* True distance test (formerly centroid distance) */
1241  else if ( strategy == 13 ) /* operator <-> */
1242  {
1243  /* In all cases, since we only have keys (boxes) we'll return */
1244  /* the minimum possible distance, which is the box2df_distance */
1245  /* and let the recheck sort things out in the case of leaves */
1246  distance = box2df_distance(entry_box, &query_box);
1247 
1248  if (GIST_LEAF(entry))
1249  *recheck = true;
1250  }
1251  else
1252  {
1253  elog(ERROR, "%s: reached unreachable code", __func__);
1254  PG_RETURN_NULL();
1255  }
1256 #else
1257  /* Box-style distance test */
1258  if ( strategy == 14 )
1259  {
1260  distance = (double)box2df_distance(entry_box, &query_box);
1261  PG_RETURN_FLOAT8(distance);
1262  }
1263 
1264  /* Treat leaf node tests different from internal nodes */
1265  if (GIST_LEAF(entry))
1266  {
1267  /* Calculate distance to leaves */
1268  distance = (double)box2df_distance_leaf_centroid(entry_box, &query_box);
1269  }
1270  else
1271  {
1272  /* Calculate distance for internal nodes */
1273  distance = (double)box2df_distance_node_centroid(entry_box, &query_box);
1274  }
1275 #endif
1276 
1277  PG_RETURN_FLOAT8(distance);
1278 }
#define LW_FAILURE
Definition: liblwgeom.h:79
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: