Changeset 5204


Ignore:
Timestamp:
Feb 5, 2010, 9:26:23 AM (15 years ago)
Author:
strk
Message:

Add ST_isValidDetail(geom) returns valid_detail (new type!)

Location:
trunk/postgis
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/postgis/lwgeom_geos.c

    r5181 r5204  
    1717#include "lwgeom_rtree.h"
    1818#include "lwgeom_geos_prepared.h"
     19#include "funcapi.h"
    1920
    2021#include <string.h>
     
    4344Datum isvalid(PG_FUNCTION_ARGS);
    4445Datum isvalidreason(PG_FUNCTION_ARGS);
     46Datum isvaliddetail(PG_FUNCTION_ARGS);
    4547Datum buffer(PG_FUNCTION_ARGS);
    4648Datum intersection(PG_FUNCTION_ARGS);
     
    14501452}
    14511453
     1454/*
     1455** IsValidDetail is only available in the GEOS
     1456** C API >= version 3.3
     1457*/
     1458PG_FUNCTION_INFO_V1(isvaliddetail);
     1459Datum isvaliddetail(PG_FUNCTION_ARGS)
     1460{
     1461#if POSTGIS_GEOS_VERSION < 33
     1462        lwerror("The GEOS version this postgis binary "
     1463                "was compiled against (%d) doesn't support "
     1464                "'isValidDetail' function (3.3.0+ required)",
     1465                POSTGIS_GEOS_VERSION);
     1466        PG_RETURN_NULL();
     1467#else /* POSTGIS_GEOS_VERSION >= 33 */
     1468
     1469        PG_LWGEOM *geom = NULL;
     1470        const GEOSGeometry *g1 = NULL;
     1471        char *values[3]; /* valid bool, reason text, location geometry */
     1472        char *geos_reason = NULL;
     1473        char *reason = NULL;
     1474        const GEOSGeometry *geos_location = NULL;
     1475        LWGEOM *location = NULL;
     1476        char valid;
     1477        Datum result;
     1478        TupleDesc tupdesc;
     1479        HeapTuple tuple;
     1480        AttInMetadata *attinmeta;
     1481
     1482        /*
     1483         * Build a tuple description for a
     1484         * valid_detail tuple
     1485         */
     1486        tupdesc = RelationNameGetTupleDesc("valid_detail");
     1487        if ( ! tupdesc )
     1488        {
     1489                lwerror("TYPE valid_detail not found");
     1490                PG_RETURN_NULL();
     1491        }
     1492
     1493        /*
     1494         * generate attribute metadata needed later to produce
     1495         * tuples from raw C strings
     1496         */
     1497        attinmeta = TupleDescGetAttInMetadata(tupdesc);
     1498
     1499        geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
     1500
     1501        initGEOS(lwnotice, lwnotice);
     1502
     1503        g1 = (GEOSGeometry *)POSTGIS2GEOS(geom);
     1504        if ( ! g1 )
     1505        {       /* TODO: take as invalid */
     1506                PG_RETURN_NULL();
     1507        }
     1508
     1509        valid = GEOSisValidDetail(g1, &geos_reason, &geos_location);
     1510        GEOSGeom_destroy((GEOSGeometry *)g1);
     1511        if ( geos_reason )
     1512        {
     1513                reason = pstrdup(geos_reason);
     1514                GEOSFree(geos_reason);
     1515        }
     1516        if ( geos_location )
     1517        {
     1518                location = GEOS2LWGEOM(geos_location, GEOSHasZ(geos_location));
     1519                GEOSGeom_destroy((GEOSGeometry *)geos_location);
     1520        }
     1521
     1522        if (valid == 2)
     1523        {
     1524                /* NOTE: should only happen on OOM or similar */
     1525                lwerror("GEOS isvaliddetail() threw an exception!");
     1526                PG_RETURN_NULL(); /* never gets here */
     1527        }
     1528
     1529        /* the boolean validity */
     1530        values[0] =  valid ? "t" : "f";
     1531
     1532        /* the reason */
     1533        values[1] =  reason;
     1534
     1535        /* the location */
     1536        values[2] =  location ?
     1537                     lwgeom_to_hexwkb(location, PARSER_CHECK_NONE, -1) : 0;
     1538
     1539        tuple = BuildTupleFromCStrings(attinmeta, values);
     1540        result = HeapTupleGetDatum(tuple);
     1541
     1542        PG_RETURN_HEAPTUPLEHEADER(result);
     1543
     1544#endif /* POSTGIS_GEOS_VERSION >= 33 */
     1545}
     1546
    14521547/**
    14531548 * overlaps(PG_LWGEOM g1,PG_LWGEOM g2)
  • trunk/postgis/postgis.sql.in.c

    r5166 r5204  
    39243924        COST 100;
    39253925
     3926-- Availability: 2.0.0
     3927CREATE TYPE valid_detail AS (valid bool, reason varchar, location geometry);
     3928
     3929-- Requires GEOS >= 3.3.0
     3930-- Availability: 2.0.0
     3931CREATE OR REPLACE FUNCTION ST_IsValidDetail(geometry)
     3932        RETURNS valid_detail
     3933        AS 'MODULE_PATHNAME', 'isvaliddetail'
     3934        LANGUAGE 'C' IMMUTABLE STRICT
     3935        COST 100;
     3936
    39263937#if POSTGIS_GEOS_VERSION >= 32
    39273938-- Requires GEOS >= 3.2.0
Note: See TracChangeset for help on using the changeset viewer.