PostGIS  2.3.7dev-r@@SVN_REVISION@@
Datum gserialized_gist_distance_2d ( PG_FUNCTION_ARGS  )

Definition at line 1168 of file gserialized_gist_2d.c.

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

1169 {
1170  GISTENTRY *entry = (GISTENTRY*) PG_GETARG_POINTER(0);
1171  BOX2DF query_box;
1172  BOX2DF *entry_box;
1173  StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2);
1174  double distance;
1175 #if POSTGIS_PGSQL_VERSION >= 95
1176  bool *recheck = (bool *) PG_GETARG_POINTER(4);
1177 #endif
1178 
1179  POSTGIS_DEBUG(4, "[GIST] 'distance' function called");
1180 
1181  /* We are using '13' as the gist true-distance <-> strategy number
1182  * and '14' as the gist distance-between-boxes <#> strategy number */
1183  if ( strategy != 13 && strategy != 14 ) {
1184  elog(ERROR, "unrecognized strategy number: %d", strategy);
1185  PG_RETURN_FLOAT8(FLT_MAX);
1186  }
1187 
1188  /* Null box should never make this far. */
1189  if ( gserialized_datum_get_box2df_p(PG_GETARG_DATUM(1), &query_box) == LW_FAILURE )
1190  {
1191  POSTGIS_DEBUG(4, "[GIST] null query_gbox_index!");
1192  PG_RETURN_FLOAT8(FLT_MAX);
1193  }
1194 
1195  /* Get the entry box */
1196  entry_box = (BOX2DF*)DatumGetPointer(entry->key);
1197 
1198 #if POSTGIS_PGSQL_VERSION >= 95
1199 
1200  /* Box-style distance test */
1201  if ( strategy == 14 ) /* operator <#> */
1202  {
1203  distance = box2df_distance(entry_box, &query_box);
1204  }
1205  /* True distance test (formerly centroid distance) */
1206  else if ( strategy == 13 ) /* operator <-> */
1207  {
1208  /* In all cases, since we only have keys (boxes) we'll return */
1209  /* the minimum possible distance, which is the box2df_distance */
1210  /* and let the recheck sort things out in the case of leaves */
1211  distance = box2df_distance(entry_box, &query_box);
1212 
1213  if (GIST_LEAF(entry))
1214  *recheck = true;
1215  }
1216  else
1217  {
1218  elog(ERROR, "%s: reached unreachable code", __func__);
1219  PG_RETURN_NULL();
1220  }
1221 #else
1222  /* Box-style distance test */
1223  if ( strategy == 14 )
1224  {
1225  distance = (double)box2df_distance(entry_box, &query_box);
1226  PG_RETURN_FLOAT8(distance);
1227  }
1228 
1229  /* Treat leaf node tests different from internal nodes */
1230  if (GIST_LEAF(entry))
1231  {
1232  /* Calculate distance to leaves */
1233  distance = (double)box2df_distance_leaf_centroid(entry_box, &query_box);
1234  }
1235  else
1236  {
1237  /* Calculate distance for internal nodes */
1238  distance = (double)box2df_distance_node_centroid(entry_box, &query_box);
1239  }
1240 #endif
1241 
1242  PG_RETURN_FLOAT8(distance);
1243 }
static double box2df_distance_node_centroid(const BOX2DF *node, const BOX2DF *query)
Calculate the The node_box_edge->query_centroid distance between the boxes.
#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: