ST_Aspect — Returns the aspect (in degrees by default) of an elevation raster band. Useful for analyzing terrain.
raster ST_Aspect(raster  rast, integer  band=1, text  pixeltype=32BF, text  units=DEGREES, boolean  interpolate_nodata=FALSE);
raster ST_Aspect(raster  rast, integer  band, raster  customextent, text  pixeltype=32BF, text  units=DEGREES, boolean  interpolate_nodata=FALSE);
Returns the aspect (in degrees by default) of an elevation raster band. Utilizes map algebra and applies the aspect equation to neighboring pixels.
                        units indicates the units of the aspect. Possible values are: RADIANS, DEGREES (default).
                    
                        When units = RADIANS, values are between 0 and 2 * pi radians measured clockwise from North.
                    
                        When units = DEGREES, values are between 0 and 360 degrees measured clockwise from North.
                    
If slope of pixel is zero, aspect of pixel is -1.
                 
               | 
              |
| 
                 For more information about Slope, Aspect and Hillshade, please refer to ESRI - How hillshade works and ERDAS Field Guide - Aspect Images.  | 
            
Availability: 2.0.0
Enhanced: 2.1.0 Uses ST_MapAlgebra() and added optional interpolate_nodata function parameter
Changed: 2.1.0 In prior versions, return values were in radians. Now, return values default to degrees
WITH foo AS (
    SELECT ST_SetValues(
        ST_AddBand(ST_MakeEmptyRaster(5, 5, 0, 0, 1, -1, 0, 0, 0), 1, '32BF', 0, -9999),
        1, 1, 1, ARRAY[
            [1, 1, 1, 1, 1],
            [1, 2, 2, 2, 1],
            [1, 2, 3, 2, 1],
            [1, 2, 2, 2, 1],
            [1, 1, 1, 1, 1]
        ]::double precision[][]
    ) AS rast
)
SELECT
    ST_DumpValues(ST_Aspect(rast, 1, '32BF'))
FROM foo
                                                                                                    st_dumpvalues
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------
 (1,"{{315,341.565063476562,0,18.4349479675293,45},{288.434936523438,315,0,45,71.5650482177734},{270,270,-1,90,90},{251.565048217773,225,180,135,108.434951782227},{225,198.43495178
2227,180,161.565048217773,135}}")
(1 row)
                    
      Complete example of tiles of a coverage. This query only works with PostgreSQL 9.1 or higher.
WITH foo AS (
    SELECT ST_Tile(
        ST_SetValues(
            ST_AddBand(
                ST_MakeEmptyRaster(6, 6, 0, 0, 1, -1, 0, 0, 0),
                1, '32BF', 0, -9999
            ),
            1, 1, 1, ARRAY[
                [1, 1, 1, 1, 1, 1],
                [1, 1, 1, 1, 2, 1],
                [1, 2, 2, 3, 3, 1],
                [1, 1, 3, 2, 1, 1],
                [1, 2, 2, 1, 2, 1],
                [1, 1, 1, 1, 1, 1]
            ]::double precision[]
        ),
        2, 2
    ) AS rast
)
SELECT
    t1.rast,
    ST_Aspect(ST_Union(t2.rast), 1, t1.rast)
FROM foo t1
CROSS JOIN foo t2
WHERE ST_Intersects(t1.rast, t2.rast)
GROUP BY t1.rast;