File: st_geomextent2rastercoord.sql

package info (click to toggle)
postgis 2.3.1%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 58,660 kB
  • ctags: 10,181
  • sloc: ansic: 132,858; sql: 131,148; xml: 46,460; sh: 4,832; perl: 4,476; makefile: 2,749; python: 1,198; yacc: 442; lex: 131
file content (102 lines) | stat: -rw-r--r-- 3,903 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
DROP FUNCTION ST_GeomExtent2RasterCoord(rast raster, geomin geometry);
CREATE OR REPLACE FUNCTION ST_GeomExtent2RasterCoord(rast raster,
							geomin geometry)
    RETURNS int[] AS
    $$
    DECLARE
        geomintersect geometry;
        x1w double precision := 0.0;
        x2w double precision := 0.0;
        y1w double precision := 0.0;
        y2w double precision := 0.0;
        x1 integer := 0;
        x2 integer := 0;
        x3 integer := 0;
        x4 integer := 0;
        y1 integer := 0;
        y2 integer := 0;
        y3 integer := 0;
        y4 integer := 0;
        psize float8;
    BEGIN

        -- Get the intersection between with the geometry.
        -- We will search for withvalue pixel only in this area.
        geomintersect := st_intersection(geomin, st_convexhull(rast));
--RAISE NOTICE 'geomintersect1=%', astext(geomintersect);

        -- If the intersection is empty, return false
        IF st_isempty(geomintersect) THEN
            RETURN ARRAY[NULL, NULL, NULL, NULL];
        END IF;

        -- We create a minimalistic buffer around the intersection in order to scan every pixels
        -- that would touch the edge or intersect with the geometry
        psize := st_scalex(rast) + st_skewy(rast);
        geomintersect := st_buffer(geomintersect, psize / 1000000);

--RAISE NOTICE 'geomintersect2=%', astext(geomintersect);

        -- Find the world coordinates of the bounding box of the intersecting area
        x1w := st_xmin(geomintersect);
        y1w := st_ymin(geomintersect);
        x2w := st_xmax(geomintersect);
        y2w := st_ymax(geomintersect);

--RAISE NOTICE 'x1w=%, y1w=%, x2w=%, y2w=%', x1w, y1w, x2w, y2w;

        -- Convert world coordinates to raster coordinates
        x1 := st_world2rastercoordx(rast, x1w, y1w);
        y1 := st_world2rastercoordy(rast, x1w, y1w);
        x2 := st_world2rastercoordx(rast, x2w, y1w);
        y2 := st_world2rastercoordy(rast, x2w, y1w);
        x3 := st_world2rastercoordx(rast, x1w, y2w);
        y3 := st_world2rastercoordy(rast, x1w, y2w);
        x4 := st_world2rastercoordx(rast, x2w, y2w);
        y4 := st_world2rastercoordy(rast, x2w, y2w);

--RAISE NOTICE 'x1=%, y1=%, x2=%, y2=%, x3=%, y3=%, x4=%, y4=%', x1, y1, x2, y2, x3, y3, x4, y4;

        -- Order the raster coordinates for the upcoming FOR loop.
        x1 := int4smaller(int4smaller(int4smaller(x1, x2), x3), x4);
        y1 := int4smaller(int4smaller(int4smaller(y1, y2), y3), y4);
        x2 := int4larger(int4larger(int4larger(x1, x2), x3), x4);
        y2 := int4larger(int4larger(int4larger(y1, y2), y3), y4);

        -- Make sure the range is not lower than 1.
        -- This can happen when world coordinate are exactly on the left border
        -- of the raster and that they do not span on more than one pixel.
        x1 := int4smaller(int4larger(x1, 1), st_width(rast));
        y1 := int4smaller(int4larger(y1, 1), st_height(rast));

        -- Also make sure the range does not exceed the width and height of the raster.
        -- This can happen when world coordinate are exactly on the lower right border
        -- of the raster.
        x2 := int4smaller(x2, st_width(rast));
        y2 := int4smaller(y2, st_height(rast));

        RETURN ARRAY[x1, y1, x2, y2];

    END;
    $$
    LANGUAGE 'plpgsql' IMMUTABLE STRICT;

--Test
SELECT (gvxy).geom, (gvxy).x::text || ',' || (gvxy).y::text
FROM (SELECT DISTINCT rid, ST_PixelAsPolygons(rast) gvxy
      FROM srtm_22_03_tiled, rect3
      WHERE st_intersects(rast, geom)
     ) foo

SELECT DISTINCT rid
FROM srtm_22_03_tiled, rect3
WHERE st_intersects(rast, geom)


SELECT rid, id, ST_GeomExtent2RasterCoord(rast, geom)
FROM srtm_22_03_tiled, rect3
WHERE st_intersects(rast, geom)


SELECT (ext).x1, (ext).y1, (ext).x2, (ext).y2 FROM (SELECT ST_GeomExtent2RasterCoord(rast, geom) ext FROM srtm_22_03_tiled, rect3
WHERE st_intersects(rast, geom)) foo