Ticket #76: my_st_dump_points.sql

File my_st_dump_points.sql, 2.0 KB (added by kneufeld, 3 years ago)

A proprosed implemenation of ST_DumpPoints by Maxime van Noppen (maxime@…)

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