Ticket #76: my_st_dump_points.2.sql

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

ST_DumpPoints implementation in plpgsql using ST_Dump

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;
6  i integer;
7  g geometry;
8BEGIN
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;
70END
71$$ LANGUAGE plpgsql;
72
73CREATE FUNCTION my_ST_DumpPoints(geometry) RETURNS SETOF geometry_dump AS $$
74  SELECT * FROM _my_ST_DumpPoints($1, NULL);
75$$ LANGUAGE SQL;