Skip to main content
Tweeted twitter.com/StackGIS/status/910363299581177856
added 506 characters in body
Source Link
tinlyx
  • 11.2k
  • 18
  • 76
  • 127

--EDIT--

The PostGIS info from SELECT postgis_full_version();' is as below (Ubuntu 16.04).

POSTGIS="2.3.3 r15473" GEOS="3.5.1-CAPI-1.9.1 r4246" SFCGAL="1.2.2" PROJ="Rel. 4.9.2, 08 September 2015" GDAL="GDAL 1.11.3, released 2015/09/16" LIBXML="2.9.3" LIBJSON="0.11.99" (core procs from "2.3.2 r15302" need upgrade) TOPOLOGY (topology procs from "2.3.2 r15302" need upgrade) RASTER (raster procs from "2.3.2 r15302" need upgrade) (sfcgal procs from "2.3.2 r15302" need upgrade)

--EDIT--

The PostGIS info from SELECT postgis_full_version();' is as below (Ubuntu 16.04).

POSTGIS="2.3.3 r15473" GEOS="3.5.1-CAPI-1.9.1 r4246" SFCGAL="1.2.2" PROJ="Rel. 4.9.2, 08 September 2015" GDAL="GDAL 1.11.3, released 2015/09/16" LIBXML="2.9.3" LIBJSON="0.11.99" (core procs from "2.3.2 r15302" need upgrade) TOPOLOGY (topology procs from "2.3.2 r15302" need upgrade) RASTER (raster procs from "2.3.2 r15302" need upgrade) (sfcgal procs from "2.3.2 r15302" need upgrade)

added 111 characters in body
Source Link
Evan Carroll
  • 7.1k
  • 2
  • 33
  • 62

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 codePostGIS 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?

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?

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?

Source Link
tinlyx
  • 11.2k
  • 18
  • 76
  • 127

Directed Hausdorff distance in PostGIS?

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?