Digamos que tienes una función como ST_Distance
y quiero saber cómo funciona. Los documentos no dicen mucho en absoluto, ¿cómo puedo ir sobre la depuración de este o averiguar cómo funciona.
Respuestas
¿Demasiados anuncios?No estoy seguro de que esto sea útil, vamos a bajar a la madriguera del conejo. Primero necesitamos saber qué ocurre cuando se llama a la función en SQL. Para ello hacemos referencia a la salida de \dS+
. \dS+
muestra la tabla de anulación con una entrada para cada función y prototipo, así como la función a la que se envía.
- Estás llamando
ST_Distance($1::geog,$2::geog)
. ST_Distance($1::geog,$2::geog)
está llamando_st_distance($1::geog, $2::geog, 0.0, true)
_st_distance($1::geog, $2::geog, 0.0, true)
está llamando a una función C llamadageography_distance
A partir de ahí tenemos que empezar a buscar en las funciones C,
geography_distance
es una función con nombre propio sobre :201 enpostgis/postgis/geography_measurement.c
geography_distance
entonces llama alwgeom_distance_spheroid(lwgeom1, lwgeom2, &s, tolerance);
lwgeom_distance_spheroid
se define en la liblwgeom utilizada por PostGIS en :2091 de lwgeodetic.c .- Porque le estás dando dos puntos, que llama
ptarray_distance_spheroid
que se define aquí pt_array_distance_spheroid
llama internamente liblwgeom'sspheroid_distance
y finalmente
tenemos un código
/**
* Computes the shortest distance along the surface of the spheroid
* between two points, using the inverse geodesic problem from
* GeographicLib (Karney 2013).
*
* @param a - location of first point
* @param b - location of second point
* @param s - spheroid to calculate on
* @return spheroidal distance between a and b in spheroid units
*/
double spheroid_distance(const GEOGRAPHIC_POINT *a, const GEOGRAPHIC_POINT *b, const SPHEROID *spheroid)
{
struct geod_geodesic gd;
geod_init(&gd, spheroid->a, spheroid->f);
double lat1 = a->lat * 180.0 / M_PI;
double lon1 = a->lon * 180.0 / M_PI;
double lat2 = b->lat * 180.0 / M_PI;
double lon2 = b->lon * 180.0 / M_PI;
double s12; /* return distance */
geod_inverse(&gd, lat1, lon1, lat2, lon2, &s12, 0, 0);
return s12;
}
Así que eso es lo que eventualmente se llama y hace el levantamiento cuando se llama ST_Distance
. La carne de eso es geod_inverse
. No ver que en lwspheroid.c
, he buscado en Google y parece que viene de GeographicLib . Mirando hacia atrás lwspheroid.c
puede ver que se incluye aquí,
/* GeographicLib */
#if PROJ_GEODESIC
#include <geodesic.h>
#endif
Y GeographicLib proporciona una implementación en C de los algoritmos geodésicos descritos en C. F. F. Karney, Algorithms for geodesics, J. Geodesy 87, 43-55 (2013); DOI: 10.1007/s00190-012-0578-z puedes ver geod_inverse
documentado aquí . Puede encontrar el aplicación aquí en la línea :1054
Esto también coincide con un parche aceptado hace sólo 17 meses, aquí para pasar a utilizar a GeographicLib.
Así es como se ve la depuración de PostGIS y Postgres de arriba a abajo.
También puedes descargar y depurar el código fuente desde el repositorio Git. Yo personalmente busqué las definiciones de las funciones depurando el código fuente en Visual Studio y viendo los diagramas de colaboración disponibles en http://postgis.net/docs/doxygen/2.1/annotated.html