5 votos

¿Distancia de Hausdorff dirigida en PostGIS?

Me preguntaba cómo implementar una dirigida (o de una cara) Hausdorff función de distancia en PostGIS?

Miré en la PostGIS 2.3.3 código fuente, y parece que ST_HausdorffDistance se implementa como un simple contenedor C de la función que llama a la correspondiente a los GEÓLOGOS una función como la siguiente:

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);
}

Yo no tengo mucha experiencia con los GEOS o interfaz con PostGIS. La única cosa que he encontrado en GEOS es que en que en geos::algoritmo::distancia::DiscreteHausdorffDistance, se dice que hay un double orientedDistance () función miembro. No estoy seguro de si la documentación es aún actual.

Puede que algunos con el conocimiento sugieren cómo adaptar el código anterior para obtener las instrucciones de uso (o de una cara) de la distancia de Hausdorff de GEOS?

--EDIT--

El PostGIS la info de la SELECT postgis_full_version();' es la siguiente (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 de septiembre de 2015" GDAL="GDAL 1.11.3, publicado 2015/09/16" LIBXML="2.9.3" LIBJSON="0.11.99" (core procs de "2.3.2 r15302" la necesidad de actualización) TOPOLOGY (topología de los procs de "2.3.2 r15302" necesidad de actualización) de TRAMA (raster procs de "2.3.2 r15302" la necesidad de actualización) (sfcgal los procs de "2.3.2 r15302" la necesidad de actualización)

2voto

user309641 Puntos 131

Necesita exponer primero la "orientada" como una nueva función CAPI, entonces se utilizaría la nueva función de postgis (dependerá de la nueva versión GEOS)

2voto

jlehenbauer Puntos 7749

No estoy seguro de lo que estás hablando, pero el SEGURO de implimentation es bastante recta hacia adelante,

int GEOS_DLL GEOSHausdorffDistance(
   const GEOSGeometry *g1,
   const GEOSGeometry *g2,
   double *dist
);  

Es decir, se toma la geometría y muta de un puntero a una doble devolver un int que representa el estado. No hay argumentos adicionales. No existen métodos de contarlo "asimétrica" o "simétrico" o "unilateral". Así fullstop, si usted está utilizando SEGURO de que usted está utilizando, DiscreteHausdorffDistance.cpp

Usted puede ver la aplicación aquí

Actualización

Creo que eres de la forma por encima de la cabeza con esto, pero aquí está el desglose de la fuente.

PostGIS Enlaces

Hay dos funciones de PostGIS, se pueden ver puestos a disposición del usuario aquí

  1. ST_HausdorffDistance(geom1 geometry, geom2 geometry)

    1. que distribuye a hausdorffdistance.
    2. hausdorffdistance referencias GEOSHausdorffDistance.
  2. ST_HausdorffDistance(geom1 geometry, geom2 geometry, float8)

    1. que distribuye a hausdorffdistancedensify.
    2. hausdorffdistancedensify de referencias de función GEOSHausdorffDistanceDensify.

LibGEOS

LibGEOS proporciona dos funciones correspondientes

  1. GEOSHausdorffDistance(const Geometry *g1, const Geometry *g2, double *dist)

    1. GEOSHausdorffDistance despacha GEOSHausdorffDistance_r
    2. GEOSHausdorffDistance_r's de la implementación en última instancia invoca DiscreteHausdorffDistance::distance(*g1, *g2)
  2. GEOSHausdorffDistanceDensify(const Geometry *g1, const Geometry *g2, double densifyFrac, double *dist)

    1. GEOSHausdorffDistanceDensify despacha GEOSHausdorffDistanceDensify_r
    2. GEOSHausdorffDistanceDensify_r's de la implementación en última instancia invoca DiscreteHausdorffDistance::distance(*g1, *g2, densifyFrac)

DiscreteHausdorffDistance::distance

Ahora se puede ver todos los caminos terminan en DiscreteHausdorffDistance::distance que está sobrecargado.

Tanto de los

  1. crear un DiscreteHausdorffDistance
  2. Llame a distance sobre el objeto de crear.
  3. distance llamadas computeOrientedDistance(g0, g1, ptDist) y computeOrientedDistance(g1, g0, ptDist) , el cual es definido aquí
  4. computeOrientedDistance muta privado ptDist llamando ptDist.setMaximum

Así que la respuesta a su pregunta: computeOrientedDistance ya es llamado por tanto ST_HausdorffDistance. Si desea una direccional versión, como computeOrientedDistance creo que voy a tener que tirar de la anterior aparte y un parche en LibGEOS a través de un nuevo DiscreteHausdorffDistance::orientedDistance y, a continuación, en PostGIS. O la elaboración de un conjunto de pruebas y pagar a un consultor. Mientras que probablemente hay un par de otros programadores de software aquí que podría hacerlo, es la manera de la experiencia de esta comunidad (Paul Ramsey ser una excepción obvia, etc).

Por lo general, no nos implementar software de sugerencias en el SIG.SE. Al menos, yo no veo que la actividad si es que sucede. Nosotros les contestamos con el software ya desarrollado. La respuesta corta es que no ha hecho.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X