| 1 | CREATE FUNCTION _my_ST_DumpPoints(the_geom geometry, cur_path integer[]) RETURNS SETOF geometry_dump AS $$ |
|---|
| 2 | DECLARE |
|---|
| 3 | tmp geometry_dump; |
|---|
| 4 | nb_points integer; |
|---|
| 5 | nb_geom integer; |
|---|
| 6 | i integer; |
|---|
| 7 | g geometry; |
|---|
| 8 | BEGIN |
|---|
| 9 | |
|---|
| 10 | -- Special case (POLYGON) : return the points of the exterior ring of a polygon |
|---|
| 11 | IF (ST_GeometryType(the_geom) = 'ST_Polygon') THEN |
|---|
| 12 | |
|---|
| 13 | -- Support PostgreSQL < 8.4 |
|---|
| 14 | FOR tmp IN SELECT * FROM _my_ST_DumpPoints(ST_ExteriorRing(the_geom), cur_path) LOOP |
|---|
| 15 | RETURN NEXT tmp; |
|---|
| 16 | END LOOP; |
|---|
| 17 | |
|---|
| 18 | -- PostgreSQL 8.4 required |
|---|
| 19 | -- RETURN QUERY (SELECT * FROM _my_ST_DumpPoints(ST_ExteriorRing(the_geom), NULL)); |
|---|
| 20 | |
|---|
| 21 | RETURN; |
|---|
| 22 | END IF; |
|---|
| 23 | |
|---|
| 24 | -- Special case (MULTI* OR GEOMETRYCOLLECTION) : iterate and return the DumpPoints of the geometries |
|---|
| 25 | SELECT ST_NumGeometries(the_geom) INTO nb_geom; |
|---|
| 26 | |
|---|
| 27 | IF (nb_geom IS NOT NULL) THEN |
|---|
| 28 | |
|---|
| 29 | i = 0; |
|---|
| 30 | FOR g IN SELECT (ST_Dump(the_geom)).geom LOOP |
|---|
| 31 | |
|---|
| 32 | -- Support PostgreSQL < 8.4 |
|---|
| 33 | FOR tmp IN SELECT * FROM _my_ST_DumpPoints(g, cur_path || ARRAY[i]) LOOP |
|---|
| 34 | RETURN NEXT tmp; |
|---|
| 35 | i = i + 1; |
|---|
| 36 | END LOOP; |
|---|
| 37 | |
|---|
| 38 | -- PostgreSQL 8.4 required |
|---|
| 39 | -- RETURN QUERY (SELECT * FROM _my_ST_DumpPoints(ST_GeometryN(the_geom, i), cur_path || ARRAY(i))); |
|---|
| 40 | END LOOP; |
|---|
| 41 | |
|---|
| 42 | RETURN; |
|---|
| 43 | END IF; |
|---|
| 44 | |
|---|
| 45 | -- Special case (POINT) : return the point |
|---|
| 46 | IF (ST_GeometryType(the_geom) = 'ST_Point') THEN |
|---|
| 47 | |
|---|
| 48 | tmp.path = cur_path || ARRAY[1]; |
|---|
| 49 | tmp.geom = the_geom; |
|---|
| 50 | |
|---|
| 51 | RETURN NEXT tmp; |
|---|
| 52 | RETURN; |
|---|
| 53 | |
|---|
| 54 | END IF; |
|---|
| 55 | |
|---|
| 56 | -- Use ST_NumPoints rather than ST_NPoints to have a NULL value if the_geom isn't |
|---|
| 57 | -- a LINESTRING or CIRCULARSTRING. |
|---|
| 58 | SELECT ST_NumPoints(the_geom) INTO nb_points; |
|---|
| 59 | |
|---|
| 60 | -- This should never happen |
|---|
| 61 | IF (nb_points IS NULL) THEN |
|---|
| 62 | RAISE EXCEPTION 'Unexpected error while dumping geometry %', ST_AsText(the_geom); |
|---|
| 63 | END IF; |
|---|
| 64 | |
|---|
| 65 | FOR i IN 1..nb_points LOOP |
|---|
| 66 | tmp.path = cur_path || i; |
|---|
| 67 | tmp.geom := ST_PointN(the_geom, i); |
|---|
| 68 | RETURN NEXT tmp; |
|---|
| 69 | END LOOP; |
|---|
| 70 | END |
|---|
| 71 | $$ LANGUAGE plpgsql; |
|---|
| 72 | |
|---|
| 73 | CREATE FUNCTION my_ST_DumpPoints(geometry) RETURNS SETOF geometry_dump AS $$ |
|---|
| 74 | SELECT * FROM _my_ST_DumpPoints($1, NULL); |
|---|
| 75 | $$ LANGUAGE SQL; |
|---|