Opened 11 years ago

Closed 11 years ago

#549 closed enhancement (fixed)

ST_isCollection

Reported by: strk Owned by: strk
Priority: medium Milestone: PostGIS 2.0.0
Component: postgis Version: master
Keywords: Cc:

Description

ST_isCollection(geometry)

A function returning TRUE if the argument geometry is of any COLLECTION type (MULTI*, GEOMETRYCOLLECTION).

This will be useful now that ST_NumGeometries returns 1 rather than NULL for non-collections.

Attachments (1)

iscollection_doc.patch (2.6 KB) - added by yabo 11 years ago.
Documentation for ST_IsCollection.

Download all attachments as: .zip

Change History (15)

comment:1 Changed 11 years ago by yabo

I don't know all the internals so this might be wrong but here's a first try :

$ svn diff
Index: postgis/lwgeom_functions_basic.c
===================================================================
--- postgis/lwgeom_functions_basic.c    (revision 5717)
+++ postgis/lwgeom_functions_basic.c    (working copy)
@@ -2977,6 +2977,15 @@
        PG_RETURN_POINTER(result);
 }
 
+PG_FUNCTION_INFO_V1(LWGEOM_st_IsCollection)
+int ST_IsCollection(PG_FUNCTION_ARGS)
+{
+  PG_LWGEOM* geom;
+  geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+
+  return lwgeom_is_collection(geom->type);
+}
+
 PG_FUNCTION_INFO_V1(LWGEOM_makepoint);
 Datum LWGEOM_makepoint(PG_FUNCTION_ARGS)
 {

comment:2 Changed 11 years ago by yabo

Without the typos :

+PG_FUNCTION_INFO_V1(LWGEOM_ST_IsCollection);
+int ST_IsCollection(PG_FUNCTION_ARGS)
+{
+  PG_LWGEOM* geom;
+  geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+
+  return lwgeom_is_collection(geom->type);
+}

I don't have a setup to test this from PostGIS svn right now, so I can't tell if it works or not though it compiles fine with this patch.

comment:3 Changed 11 years ago by strk

a test for regress/ dir and we're done

comment:4 Changed 11 years ago by yabo

Something like this ?

There should also be a test on 'GEOMETRYCOLLECTION EMPTY' but I don't know what it should return. Is an empty geometry a collection ? Maybe could the C function be patched to catch that case.

$ svn diff
Index: iscollection_expected
===================================================================
--- iscollection_expected       (revision 0)
+++ iscollection_expected       (revision 0)
@@ -0,0 +1,11 @@
+f
+f
+f
+t
+t
+t
+t
+t
+t
+t
+t
Index: iscollection.sql
===================================================================
--- iscollection.sql    (revision 0)
+++ iscollection.sql    (revision 0)
@@ -0,0 +1,17 @@
+-- Ensure there are no false-positives
+SELECT ST_IsCollection('POINT(42 42)');
+SELECT ST_IsCollection('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))');
+SELECT ST_IsCollection('LINESTRING(0 0, 10 10)');
+
+--Ensure that all collections return true (even if they contain a single geometry).
+SELECT ST_IsCollection('MULTIPOINT((0 0))');
+SELECT ST_IsCollection('MULTIPOINT((0 0), (42 42))');
+
+SELECT ST_IsCollection('MULTILINE((0 0, 10 10))');
+SELECT ST_IsCollection('MULTILINE((0 0, 10 10), (100 100, 142 142))');
+
+SELECT ST_IsCollection('MULTIPOLYGON(((0 0, 10 0, 10 10, 10 0, 0 0)))');
+SELECT ST_IsCollection('MULTIPOLYGON(((0 0, 10 0, 10 10, 10 0, 0 0), (100 100, 110 100, 110 110, 100 110, 100 100)))');
+
+SELECT ST_IsCollection('GEOMETRYCOLLECTION(POINT(0 0))');
+SELECT ST_IsCollection('GEOMETRYCOLLECTION(POINT(0 0), POINT(42 42))');

comment:5 Changed 11 years ago by strk

Is an empty geometry a collection ?

Well, a POINT EMPTY isn't, a GEOMETRYCOLLECTION EMPTY is, a MULTILINESTRING EMPTY is. But this is my POV, not necessarely what you're looking for. It was you proposing the function :)

Anyway, my suggestion should pretty much match the NULL result from ST_GetNumGeometries, which was the whole reason to suggest this new function, right ? It used to return 0 for GEOMETRYCOLLECTION EMPTY and NULL for POINT EMPTY.

comment:6 in reply to:  5 Changed 11 years ago by yabo

Replying to strk:

Well, a POINT EMPTY isn't, a GEOMETRYCOLLECTION EMPTY is, a MULTILINESTRING EMPTY is. But this is my POV, not necessarely what you're looking for. It was you proposing the function :)

Anyway, my suggestion should pretty much match the NULL result from ST_GetNumGeometries, which was the whole reason to suggest this new function, right ? It used to return 0 for GEOMETRYCOLLECTION EMPTY and NULL for POINT EMPTY.

That seems coherent. The C function should be ok. So here we go for the tests :

$ svn diff
Index: iscollection_expected
===================================================================
--- iscollection_expected       (revision 0)
+++ iscollection_expected       (revision 0)
@@ -0,0 +1,18 @@
+f
+f
+f
+f
+f
+f
+t
+t
+t
+t
+t
+t
+t
+t
+t
+t
+t
+t
Index: iscollection.sql
===================================================================
--- iscollection.sql    (revision 0)
+++ iscollection.sql    (revision 0)
@@ -0,0 +1,27 @@
+-- Ensure there are no false-positives
+SELECT ST_IsCollection('POINT(42 42)');
+SELECT ST_IsCollection('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))');
+SELECT ST_IsCollection('LINESTRING(0 0, 10 10)');
+SELECT ST_IsCollection('POINT EMPTY');
+SELECT ST_IsCollection('POLYGON EMPTY');
+SELECT ST_IsCollection('LINESTRING EMPTY');
+
+--Ensure that all collections return true (even if they contain a single geometry).
+SELECT ST_IsCollection('MULTIPOINT EMPTY');
+SELECT ST_IsCollection('MULTIPOINT((0 0))');
+SELECT ST_IsCollection('MULTIPOINT((0 0), (42 42))');
+
+SELECT ST_IsCollection('MULTILINESTRING EMPTY');
+SELECT ST_IsCollection('MULTILINESTRING((0 0, 10 10))');
+SELECT ST_IsCollection('MULTILINESTRING((0 0, 10 10), (100 100, 142 142))');
+
+SELECT ST_IsCollection('MULTIPOLYGON EMPTY');
+SELECT ST_IsCollection('MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0)))');
+SELECT ST_IsCollection('MULTIPOLYGON(((0 0, 10 0, 10 10, 0 10, 0 0)), ((100 100, 110 100, 110 110, 100 110, 100 100)))');
+
+SELECT ST_IsCollection('GEOMETRYCOLLECTION EMPTY');
+SELECT ST_IsCollection('GEOMETRYCOLLECTION(POINT(0 0))');
+SELECT ST_IsCollection('GEOMETRYCOLLECTION(POINT(0 0), POINT(42 42))');
+

comment:7 Changed 11 years ago by strk

Owner: changed from pramsey to strk
Status: newassigned

Your name for the ChangeLog? ?

comment:8 Changed 11 years ago by strk

Oh, also the patch for postgis/postgis.sql.in.c is missing, and doc/reference_accessor.xml

comment:9 Changed 11 years ago by strk

I'm rewriting the code myself, and doing the sql part too. Note that postgis doesn't currently really support typed empty geometries, so I'll drop those tests from the regression

comment:10 Changed 11 years ago by strk

So, r5718 contains the code and tests. I took the chance to use sliced detoasting which would be nice to do for a few more functions too.

Documentation in reference_accessor.xml is still missing

comment:11 in reply to:  9 Changed 11 years ago by yabo

Replying to strk:

I'm rewriting the code myself, and doing the sql part too.

Ok great.

Note that postgis doesn't currently really support typed empty geometries, so I'll drop those tests from the regression

That was what I thought but as we talked about them here I included them just in case.

This is quite a minor patch, like the ST_DumpPoints I did before, but however if you want to include me in the ChangeLog? my name is Maxime van Noppen (maxime@…).

Great work, thanks!

comment:12 Changed 11 years ago by strk

Maxime, do you feel like providing a patch for the documentation ?

Changed 11 years ago by yabo

Attachment: iscollection_doc.patch added

Documentation for ST_IsCollection.

comment:13 Changed 11 years ago by yabo

Of course, see attached patch.

comment:14 Changed 11 years ago by strk

Resolution: fixed
Status: assignedclosed

All done in r5723 It's been a pleasure :)

Note: See TracTickets for help on using tickets.