PostGIS  3.4.0dev-r@@SVN_REVISION@@

◆ geography_distance()

Datum geography_distance ( PG_FUNCTION_ARGS  )

Definition at line 206 of file geography_measurement.c.

207 {
208  SHARED_GSERIALIZED *shared_geom1 = ToastCacheGetGeometry(fcinfo, 0);
209  SHARED_GSERIALIZED *shared_geom2 = ToastCacheGetGeometry(fcinfo, 1);
210  const GSERIALIZED *g1 = shared_gserialized_get(shared_geom1);
211  const GSERIALIZED *g2 = shared_gserialized_get(shared_geom2);
212  double distance;
213  bool use_spheroid = true;
214  SPHEROID s;
215 
216  if (PG_NARGS() > 2)
217  use_spheroid = PG_GETARG_BOOL(2);
218 
219  gserialized_error_if_srid_mismatch(g1, g2, __func__);
220 
221  /* Initialize spheroid */
222  spheroid_init_from_srid(gserialized_get_srid(g1), &s);
223 
224  /* Set to sphere if requested */
225  if ( ! use_spheroid )
226  s.a = s.b = s.radius;
227 
228  /* Return NULL on empty arguments. */
230  {
231  PG_RETURN_NULL();
232  }
233 
234  /* Do the brute force calculation if the cached calculation doesn't tick over */
235  if (LW_FAILURE == geography_distance_cache(fcinfo, shared_geom1, shared_geom2, &s, &distance))
236  {
237  /* default to using tree-based distance calculation at all times */
238  /* in standard distance call. */
240  /*
241  LWGEOM* lwgeom1 = lwgeom_from_gserialized(g1);
242  LWGEOM* lwgeom2 = lwgeom_from_gserialized(g2);
243  distance = lwgeom_distance_spheroid(lwgeom1, lwgeom2, &s, tolerance);
244  lwgeom_free(lwgeom1);
245  lwgeom_free(lwgeom2);
246  */
247  }
248 
249  /* Knock off any funny business at the nanometer level, ticket #2168 */
250  distance = round(distance * INVMINDIST) / INVMINDIST;
251 
252  /* Something went wrong, negative return... should already be eloged, return NULL */
253  if ( distance < 0.0 )
254  {
255  elog(ERROR, "distance returned negative!");
256  PG_RETURN_NULL();
257  }
258 
259  PG_RETURN_FLOAT8(distance);
260 }
char * s
Definition: cu_in_wkt.c:23
#define INVMINDIST
int geography_tree_distance(const GSERIALIZED *g1, const GSERIALIZED *g2, const SPHEROID *s, double tolerance, double *distance)
int geography_distance_cache(FunctionCallInfo fcinfo, SHARED_GSERIALIZED *g1, SHARED_GSERIALIZED *g2, const SPHEROID *s, double *distance)
void gserialized_error_if_srid_mismatch(const GSERIALIZED *g1, const GSERIALIZED *g2, const char *funcname)
Definition: gserialized.c:403
int32_t gserialized_get_srid(const GSERIALIZED *g)
Extract the SRID from the serialized form (it is packed into three bytes so this is a handy function)...
Definition: gserialized.c:126
int gserialized_is_empty(const GSERIALIZED *g)
Check if a GSERIALIZED is empty without deserializing first.
Definition: gserialized.c:152
#define LW_FAILURE
Definition: liblwgeom.h:96
#define FP_TOLERANCE
Floating point comparators.
static double distance(double x1, double y1, double x2, double y2)
Definition: lwtree.c:1032

References distance(), FP_TOLERANCE, geography_distance_cache(), geography_tree_distance(), gserialized_error_if_srid_mismatch(), gserialized_get_srid(), gserialized_is_empty(), INVMINDIST, LW_FAILURE, and s.

Here is the call graph for this function: