]> granicus.if.org Git - postgis/commitdiff
Added NumInteriorRings() and InteriorRingN()
authorSandro Santilli <strk@keybit.net>
Tue, 24 Aug 2004 15:05:34 +0000 (15:05 +0000)
committerSandro Santilli <strk@keybit.net>
Tue, 24 Aug 2004 15:05:34 +0000 (15:05 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@737 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/MISSING_OBJECTS
lwgeom/lwgeom_ogc.c
lwgeom/lwpostgis.sql.in

index fb8b8679f1e394f79dc56824bf90ace7cb3eb2d3..661a298f24bf813ce33128f69d99550b0c206ee1 100644 (file)
@@ -29,8 +29,6 @@ FUNC: KEEPING FUNCTION: [x(geometry)]
 FUNC: KEEPING FUNCTION: [y(geometry)]
 FUNC: KEEPING FUNCTION: [z(geometry)]
 FUNC: KEEPING FUNCTION: [pointn(geometry, integer)]
-FUNC: KEEPING FUNCTION: [numinteriorrings(geometry)]
-FUNC: KEEPING FUNCTION: [interiorringn(geometry, integer)]
 FUNC: KEEPING FUNCTION: [max_distance(geometry, geometry)]
 FUNC: KEEPING FUNCTION: [optimistic_overlap(geometry, geometry, double precision)]
 FUNC: KEEPING FUNCTION: [segmentize(geometry, double precision)]
index 9fb27adc76ad12ec7e7e7082c1ad0194af3b929b..fd0d3c2a54e7e6d9fee6b429a4528a72eb94eba2 100644 (file)
@@ -37,6 +37,10 @@ Datum LWGEOM_geometryn_collection(PG_FUNCTION_ARGS);
 Datum LWGEOM_dimension(PG_FUNCTION_ARGS);
 // ---- ExteriorRing(geometry)
 Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS);
+// ---- InteriorRingN(geometry, integer)
+Datum LWGEOM_interiorringn_polygon(PG_FUNCTION_ARGS);
+// ---- NumInteriorRings(geometry)
+Datum LWGEOM_numinteriorrings_polygon(PG_FUNCTION_ARGS);
 
 
 // internal
@@ -279,8 +283,8 @@ Datum LWGEOM_dimension(PG_FUNCTION_ARGS)
 
 
 // exteriorRing(GEOMETRY) -- find the first polygon in GEOMETRY, return
-// its exterior ring (as a linestring).  Return NULL if there is no
-// POLYGON(..) in GEOMETRY.
+// its exterior ring (as a linestring).
+// Return NULL if there is no POLYGON(..) in (first level of) GEOMETRY.
 PG_FUNCTION_INFO_V1(LWGEOM_exteriorring_polygon);
 Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS)
 {
@@ -320,3 +324,85 @@ Datum LWGEOM_exteriorring_polygon(PG_FUNCTION_ARGS)
        PG_RETURN_POINTER(result);
 }
 
+// NumInteriorRings(GEOMETRY) -- find the first polygon in GEOMETRY, return
+// the number of its interior rings (holes).
+// Return NULL if there is no POLYGON(..) in (first level of) GEOMETRY.
+PG_FUNCTION_INFO_V1(LWGEOM_numinteriorrings_polygon);
+Datum LWGEOM_numinteriorrings_polygon(PG_FUNCTION_ARGS)
+{
+       LWGEOM *geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       LWGEOM_INSPECTED *inspected = lwgeom_inspect(SERIALIZED_FORM(geom));
+       LWPOLY *poly = NULL;
+       int32 result;
+       int i;
+
+       for (i=0; i<inspected->ngeometries; i++)
+       {
+               poly = lwgeom_getpoly_inspected(inspected, i);
+               if ( poly ) break;
+       }
+
+       if ( poly == NULL ) PG_RETURN_NULL();
+
+       // Ok, now we have a polygon. Here is its number of holes
+       result = poly->nrings-1;
+
+       PG_RETURN_INT32(result);
+}
+
+// InteriorRingN(GEOMETRY) -- find the first polygon in GEOMETRY, return
+// its Nth interior ring (as a linestring).
+// Return NULL if there is no POLYGON(..) in (first level of) GEOMETRY.
+PG_FUNCTION_INFO_V1(LWGEOM_interiorringn_polygon);
+Datum LWGEOM_interiorringn_polygon(PG_FUNCTION_ARGS)
+{
+       LWGEOM *geom;
+       int32 wanted_index;
+       LWGEOM_INSPECTED *inspected;
+       LWPOLY *poly = NULL;
+       POINTARRAY *ring;
+       LWLINE *line;
+       char *serializedline;
+       LWGEOM *result;
+       int i;
+
+       wanted_index = PG_GETARG_INT32(1);
+       if ( wanted_index < 0 )
+               PG_RETURN_NULL(); // index out of range
+
+       geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       inspected = lwgeom_inspect(SERIALIZED_FORM(geom));
+
+       for (i=0; i<inspected->ngeometries; i++)
+       {
+               poly = lwgeom_getpoly_inspected(inspected, i);
+               if ( poly ) break;
+       }
+
+       if ( poly == NULL ) PG_RETURN_NULL();
+
+       // Ok, now we have a polygon. Let's see if it has enough holes
+       if ( wanted_index > poly->nrings-2 )
+       {
+               pfree_inspected(inspected);
+               PG_RETURN_NULL();
+       }
+
+       ring = poly->rings[wanted_index+1];
+
+       // This is a LWLINE constructed by exterior ring POINTARRAY
+       line = lwline_construct(poly->ndims, poly->SRID, ring);
+
+       // Now we serialized it (copying data)
+       serializedline = lwline_serialize(line);
+
+       // And we construct the line (copy again)
+       result = LWGEOM_construct(serializedline, poly->SRID,
+               lwgeom_hasBBOX(geom->type));
+
+       pfree(serializedline);
+       pfree(line);
+
+       PG_RETURN_POINTER(result);
+}
+
index 40202ac3b028b90b0b22839cfe8ea728b4fd0f8c..a72e77e765be4a1236ac89d8391271261d9d24c6 100644 (file)
@@ -11,6 +11,9 @@
 --  
 -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 -- $Log$
+-- Revision 1.12  2004/08/24 15:05:34  strk
+-- Added NumInteriorRings() and InteriorRingN()
+--
 -- Revision 1.11  2004/08/24 14:48:58  strk
 -- Added dimension() and exteriorring()
 --
@@ -847,31 +850,42 @@ CREATEFUNCTION npoints(geometry)
 
 ------------------------------------------------------------------------
 
-CREATEFUNCTION numpoints(geometry)
+CREATEFUNCTION NumPoints(geometry)
        RETURNS int4
        AS '@MODULE_FILENAME@', 'LWGEOM_numpoints_linestring'
        LANGUAGE 'C' WITH (isstrict);
 
-CREATEFUNCTION numgeometries(geometry)
+CREATEFUNCTION NumGeometries(geometry)
        RETURNS int4
        AS '@MODULE_FILENAME@', 'LWGEOM_numgeometries_collection'
        LANGUAGE 'C' WITH (isstrict);
 
-CREATEFUNCTION geometryn(geometry,integer)
+CREATEFUNCTION GeometryN(geometry,integer)
        RETURNS geometry
        AS '@MODULE_FILENAME@', 'LWGEOM_geometryn_collection'
        LANGUAGE 'C' WITH (isstrict);
 
-CREATEFUNCTION dimension(geometry)
+CREATEFUNCTION Dimension(geometry)
        RETURNS int4
        AS '@MODULE_FILENAME@', 'LWGEOM_dimension'
        LANGUAGE 'C' WITH (isstrict);
 
-CREATEFUNCTION exteriorring(geometry)
+CREATEFUNCTION ExterioRring(geometry)
        RETURNS geometry
        AS '@MODULE_FILENAME@','LWGEOM_exteriorring_polygon'
        LANGUAGE 'C' WITH (isstrict);
 
+CREATEFUNCTION NumInteriorRings(geometry)
+       RETURNS integer
+       AS '@MODULE_FILENAME@','LWGEOM_numinteriorrings_polygon'
+       LANGUAGE 'C' WITH (isstrict);
+
+CREATEFUNCTION InteriorRingN(geometry,integer)
+       RETURNS geometry
+       AS '@MODULE_FILENAME@','LWGEOM_interiorringn_polygon'
+       LANGUAGE 'C' WITH (isstrict);
+
+
 ------------------------------------------------------------------------
 
 CREATEFUNCTION geometrytype(geometry)