I was wondering how to implement a directed (or one-sided) Hausdorff distance function in PostGIS?
I looked into the PostGIS 2.3.3 source code, and it seems that ST_HausdorffDistance is implemented as a simple C wrapper function that calls the corresponding GEOS function as follows:
PG_FUNCTION_INFO_V1(hausdorffdistance);
Datum hausdorffdistance(PG_FUNCTION_ARGS)
{
GSERIALIZED *geom1;
GSERIALIZED *geom2;
GEOSGeometry *g1;
GEOSGeometry *g2;
double result;
int retcode;
POSTGIS_DEBUG(2, "hausdorff_distance called");
geom1 = PG_GETARG_GSERIALIZED_P(0);
geom2 = PG_GETARG_GSERIALIZED_P(1);
if ( gserialized_is_empty(geom1) || gserialized_is_empty(geom2) )
PG_RETURN_NULL();
initGEOS(lwpgnotice, lwgeom_geos_error);
g1 = (GEOSGeometry *)POSTGIS2GEOS(geom1);
if ( 0 == g1 ) /* exception thrown at construction */
{
HANDLE_GEOS_ERROR("First argument geometry could not be converted to GEOS");
PG_RETURN_NULL();
}
g2 = (GEOSGeometry *)POSTGIS2GEOS(geom2);
if ( 0 == g2 ) /* exception thrown */
{
HANDLE_GEOS_ERROR("Second argument geometry could not be converted to GEOS");
GEOSGeom_destroy(g1);
PG_RETURN_NULL();
}
retcode = GEOSHausdorffDistance(g1, g2, &result);
GEOSGeom_destroy(g1);
GEOSGeom_destroy(g2);
if (retcode == 0)
{
HANDLE_GEOS_ERROR("GEOSHausdorffDistance");
PG_RETURN_NULL(); /*never get here */
}
PG_FREE_IF_COPY(geom1, 0);
PG_FREE_IF_COPY(geom2, 1);
PG_RETURN_FLOAT8(result);
}
I don't have much experience with GEOS or interfacing it with PostGIS. The only thing I found in GEOS is that in that in geos::algorithm::distance::DiscreteHausdorffDistance, it is said that there is an double orientedDistance ()
member function. I am not sure if the documentation is even current.
Can some with the knowledge suggest how to adapt the above code to obtain the directed (or one-sided) Hausdorff distance from GEOS?