Changeset 10060

Show
Ignore:
Timestamp:
07/13/12 16:44:29 (10 months ago)
Author:
dustymugs
Message:

Updated TODO and refactored ST_Intersects(geometry, raster) to use
ST_BandSurface()

Location:
trunk/raster
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/raster/rt_pg/rtpostgis.sql.in.c

    r10058 r10060  
    31913191        RETURNS boolean AS $$ 
    31923192        DECLARE 
     3193                convexhull geometry; 
    31933194                hasnodata boolean := TRUE; 
    3194                 nodata float8 := 0.0; 
    3195                 convexhull geometry; 
    3196                 geomintersect geometry; 
    3197                 x1w double precision := 0.0; 
    3198                 x2w double precision := 0.0; 
    3199                 y1w double precision := 0.0; 
    3200                 y2w double precision := 0.0; 
    3201                 x1 integer := 0; 
    3202                 x2 integer := 0; 
    3203                 x3 integer := 0; 
    3204                 x4 integer := 0; 
    3205                 y1 integer := 0; 
    3206                 y2 integer := 0; 
    3207                 y3 integer := 0; 
    3208                 y4 integer := 0; 
    3209                 x integer := 0; 
    3210                 y integer := 0; 
    3211                 xinc integer := 0; 
    3212                 yinc integer := 0; 
    3213                 pixelval double precision; 
    3214                 bintersect boolean := FALSE; 
    3215                 gtype text; 
    3216                 scale float8; 
    3217                 w int; 
    3218                 h int; 
     3195                surface geometry; 
    32193196        BEGIN 
    32203197                convexhull := ST_ConvexHull(rast); 
     
    32293206                END IF; 
    32303207 
    3231                 -- Get the intersection between with the geometry. 
    3232                 -- We will search for withvalue pixel only in this area. 
    3233                 geomintersect := st_intersection(geom, convexhull); 
    3234  
    3235 --RAISE NOTICE 'geomintersect=%', st_astext(geomintersect); 
    3236  
    3237                 -- If the intersection is empty, return false 
    3238                 IF st_isempty(geomintersect) THEN 
    3239                         RETURN FALSE; 
    3240                 END IF; 
    3241  
    3242                 -- We create a minimalistic buffer around the intersection in order to scan every pixels 
    3243                 -- that would touch the edge or intersect with the geometry 
    3244                 SELECT sqrt(scalex * scalex + skewy * skewy), width, height INTO scale, w, h FROM ST_Metadata(rast); 
    3245                 IF scale != 0 THEN 
    3246                         geomintersect := st_buffer(geomintersect, scale / 1000000); 
    3247                 END IF; 
    3248  
    3249 --RAISE NOTICE 'geomintersect2=%', st_astext(geomintersect); 
    3250  
    3251                 -- Find the world coordinates of the bounding box of the intersecting area 
    3252                 x1w := st_xmin(geomintersect); 
    3253                 y1w := st_ymin(geomintersect); 
    3254                 x2w := st_xmax(geomintersect); 
    3255                 y2w := st_ymax(geomintersect); 
    3256                 nodata := st_bandnodatavalue(rast, nband); 
    3257  
    3258 --RAISE NOTICE 'x1w=%, y1w=%, x2w=%, y2w=%', x1w, y1w, x2w, y2w; 
    3259  
    3260                 -- Convert world coordinates to raster coordinates 
    3261                 x1 := st_world2rastercoordx(rast, x1w, y1w); 
    3262                 y1 := st_world2rastercoordy(rast, x1w, y1w); 
    3263                 x2 := st_world2rastercoordx(rast, x2w, y1w); 
    3264                 y2 := st_world2rastercoordy(rast, x2w, y1w); 
    3265                 x3 := st_world2rastercoordx(rast, x1w, y2w); 
    3266                 y3 := st_world2rastercoordy(rast, x1w, y2w); 
    3267                 x4 := st_world2rastercoordx(rast, x2w, y2w); 
    3268                 y4 := st_world2rastercoordy(rast, x2w, y2w); 
    3269  
    3270 --RAISE NOTICE 'x1=%, y1=%, x2=%, y2=%, x3=%, y3=%, x4=%, y4=%', x1, y1, x2, y2, x3, y3, x4, y4; 
    3271  
    3272                 -- Order the raster coordinates for the upcoming FOR loop. 
    3273                 x1 := int4smaller(int4smaller(int4smaller(x1, x2), x3), x4); 
    3274                 y1 := int4smaller(int4smaller(int4smaller(y1, y2), y3), y4); 
    3275                 x2 := int4larger(int4larger(int4larger(x1, x2), x3), x4); 
    3276                 y2 := int4larger(int4larger(int4larger(y1, y2), y3), y4); 
    3277  
    3278                 -- Make sure the range is not lower than 1. 
    3279                 -- This can happen when world coordinate are exactly on the left border 
    3280                 -- of the raster and that they do not span on more than one pixel. 
    3281                 x1 := int4smaller(int4larger(x1, 1), w); 
    3282                 y1 := int4smaller(int4larger(y1, 1), h); 
    3283  
    3284                 -- Also make sure the range does not exceed the width and height of the raster. 
    3285                 -- This can happen when world coordinate are exactly on the lower right border 
    3286                 -- of the raster. 
    3287                 x2 := int4smaller(x2, w); 
    3288                 y2 := int4smaller(y2, h); 
    3289  
    3290 --RAISE NOTICE 'x1=%, y1=%, x2=%, y2=%', x1, y1, x2, y2; 
    3291  
    3292                 -- Search exhaustively for withvalue pixel on a moving 3x3 grid 
    3293                 -- (very often more efficient than searching on a mere 1x1 grid) 
    3294                 FOR xinc in 0..2 LOOP 
    3295                         FOR yinc in 0..2 LOOP 
    3296                                 FOR x IN x1+xinc..x2 BY 3 LOOP 
    3297                                         FOR y IN y1+yinc..y2 BY 3 LOOP 
    3298                                                 -- Check first if the pixel intersects with the geometry. Often many won't. 
    3299                                                 bintersect := NOT st_isempty(st_intersection(st_pixelaspolygon(rast, x, y), geom)); 
    3300  
    3301                                                 IF bintersect THEN 
    3302                                                         -- If the pixel really intersects, check its value. Return TRUE if with value. 
    3303                                                         pixelval := st_value(rast, nband, x, y); 
    3304                                                         IF pixelval != nodata THEN 
    3305                                                                 RETURN TRUE; 
    3306                                                         END IF; 
    3307                                                 END IF; 
    3308                                         END LOOP; 
    3309                                 END LOOP; 
    3310                         END LOOP; 
    3311                 END LOOP; 
     3208                -- get band surface 
     3209                surface := ST_BandSurface(rast, nband); 
     3210 
     3211                IF surface IS NOT NULL THEN 
     3212                        RETURN ST_Intersects(geom, surface); 
     3213                END IF; 
    33123214 
    33133215                RETURN FALSE; 
  • trunk/raster/TODO

    r10002 r10060  
    66 
    77== Simple Projects == 
    8  
    9 -- C version of ST_Intersects() in vector-space -- 
    10  
    11 A C version of this function should be faster than the current plpgsql 
    12 version. 
    138 
    149== Larger Projects ==