Opened 14 years ago

Closed 14 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 14 years ago.
Documentation for ST_IsCollection.

Download all attachments as: .zip

Change History (15)

comment:1 by yabo, 14 years ago

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 by yabo, 14 years ago

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 by strk, 14 years ago

a test for regress/ dir and we're done

comment:4 by yabo, 14 years ago

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 by strk, 14 years ago

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.

in reply to:  5 comment:6 by yabo, 14 years ago

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 by strk, 14 years ago

Owner: changed from pramsey to strk
Status: newassigned

Your name for the ChangeLog ?

comment:8 by strk, 14 years ago

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

comment:9 by strk, 14 years ago

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 by strk, 14 years ago

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

in reply to:  9 comment:11 by yabo, 14 years ago

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 by strk, 14 years ago

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

by yabo, 14 years ago

Attachment: iscollection_doc.patch added

Documentation for ST_IsCollection.

comment:13 by yabo, 14 years ago

Of course, see attached patch.

comment:14 by strk, 14 years ago

Resolution: fixed
Status: assignedclosed

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

Note: See TracTickets for help on using tickets.