- #2276, ST_AddBand(raster) variant for out-db bands
- #2280, ST_Summary(raster)
- #2163, ST_TPI for raster (Nathaniel Clay)
+ - #2302, ST_Roughness for raster (Nathaniel Clay)
* Enhancements *
<title>See Also</title>
<para>
<xref linkend="RT_ST_MapAlgebra" />,
+ <xref linkend="RT_ST_TRI" />,
+ <xref linkend="RT_ST_TPI" />,
+ <xref linkend="RT_ST_Roughness" />,
<xref linkend="RT_ST_Aspect" />,
<xref linkend="RT_ST_Slope" />
</para>
<title>See Also</title>
<para>
<xref linkend="RT_ST_MapAlgebra" />,
+ <xref linkend="RT_ST_TRI" />,
+ <xref linkend="RT_ST_TPI" />,
+ <xref linkend="RT_ST_Roughness" />,
<xref linkend="RT_ST_HillShade" />,
<xref linkend="RT_ST_Slope" />
</para>
<title>See Also</title>
<para>
<xref linkend="RT_ST_MapAlgebra" />,
+ <xref linkend="RT_ST_TRI" />,
+ <xref linkend="RT_ST_TPI" />,
+ <xref linkend="RT_ST_Roughness" />,
<xref linkend="RT_ST_HillShade" />,
<xref linkend="RT_ST_Aspect" />
</para>
<funcdef>raster <function>ST_TPI</function></funcdef>
<paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
<paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
- <paramdef choice="opt"><type>raster </type> <parameter>customextent</parameter></paramdef>
+ <paramdef><type>raster </type> <parameter>customextent</parameter></paramdef>
<paramdef choice="opt"><type>text </type> <parameter>pixeltype="32BF"</parameter> </paramdef>
<paramdef choice="opt"><type>boolean </type> <parameter> interpolate_nodata=FALSE </parameter> </paramdef>
</funcprototype>
<para>
<xref linkend="RT_ST_MapAlgebra" />,
<xref linkend="RT_ST_TRI" />,
+ <xref linkend="RT_ST_Roughness" />,
+ <xref linkend="RT_ST_Slope" />,
+ <xref linkend="RT_ST_HillShade" />,
+ <xref linkend="RT_ST_Aspect" />
+ </para>
+ </refsection>
+ </refentry>
+
+ <refentry id="RT_ST_Roughness">
+ <refnamediv>
+ <refname>ST_Roughness</refname>
+ <refpurpose>Returns a raster with the calculated "roughness" of a DEM.</refpurpose>
+ </refnamediv>
+
+ <refsynopsisdiv>
+ <funcsynopsis>
+ <funcprototype>
+ <funcdef>raster <function>ST_Roughness</function></funcdef>
+ <paramdef><type>raster </type> <parameter>rast</parameter></paramdef>
+ <paramdef><type>integer </type> <parameter>nband</parameter></paramdef>
+ <paramdef><type>raster </type> <parameter>customextent</parameter></paramdef>
+ <paramdef choice="opt"><type>text </type> <parameter>pixeltype="32BF"</parameter> </paramdef>
+ <paramdef choice="opt"><type>boolean </type> <parameter> interpolate_nodata=FALSE </parameter> </paramdef>
+ </funcprototype>
+ </funcsynopsis>
+ </refsynopsisdiv>
+
+ <refsection>
+ <title>Description</title>
+ <para>Calculates the "roughness" of a DEM, by subtracting the maximum from the minimum for a given area.</para>
+ <para>Availability: 2.1</para>
+ </refsection>
+
+ <refsection>
+ <title>Examples</title>
+ <programlisting>
+-- needs examples
+ </programlisting>
+ </refsection>
+
+ <refsection>
+ <title>See Also</title>
+ <para>
+ <xref linkend="RT_ST_MapAlgebra" />,
+ <xref linkend="RT_ST_TRI" />,
+ <xref linkend="RT_ST_TPI" />,
+ <xref linkend="RT_ST_Slope" />,
<xref linkend="RT_ST_HillShade" />,
<xref linkend="RT_ST_Aspect" />
</para>
END;
$$ LANGUAGE 'plpgsql' IMMUTABLE;
+-----------------------------------------------------------------------
+-- ST_Roughness
+-----------------------------------------------------------------------
+
+CREATE OR REPLACE FUNCTION _st_roughness4ma(value double precision[][][], pos integer[][], VARIADIC userargs text[] DEFAULT NULL)
+ RETURNS double precision
+ AS $$
+ DECLARE
+ x integer;
+ y integer;
+ z integer;
+
+ minimum double precision;
+ maximum double precision;
+
+ _value double precision[][][];
+ ndims int;
+ BEGIN
+
+ ndims := array_ndims(value);
+ -- add a third dimension if 2-dimension
+ IF ndims = 2 THEN
+ _value := _st_convertarray4ma(value);
+ ELSEIF ndims != 3 THEN
+ RAISE EXCEPTION 'First parameter of function must be a 3-dimension array';
+ ELSE
+ _value := value;
+ END IF;
+
+ -- only use the first raster passed to this function
+ IF array_length(_value, 1) > 1 THEN
+ RAISE NOTICE 'Only using the values from the first raster';
+ END IF;
+ z := array_lower(_value, 1);
+
+ IF (
+ array_lower(_value, 2) != 1 OR array_upper(_value, 2) != 3 OR
+ array_lower(_value, 3) != 1 OR array_upper(_value, 3) != 3
+ ) THEN
+ RAISE EXCEPTION 'First parameter of function must be a 1x3x3 array with each of the lower bounds starting from 1';
+ END IF;
+
+ -- check that center pixel isn't NODATA
+ IF _value[z][2][2] IS NULL THEN
+ RETURN NULL;
+ -- substitute center pixel for any neighbor pixels that are NODATA
+ ELSE
+ FOR y IN 1..3 LOOP
+ FOR x IN 1..3 LOOP
+ IF _value[z][y][x] IS NULL THEN
+ _value[z][y][x] = _value[z][2][2];
+ END IF;
+ END LOOP;
+ END LOOP;
+ END IF;
+
+ minimum := _value[z][1][1];
+ maximum := _value[z][1][1];
+
+ FOR Y IN 1..3 LOOP
+ FOR X IN 1..3 LOOP
+ IF _value[z][y][x] < minimum THEN
+ minimum := _value[z][y][x];
+ ELSIF _value[z][y][x] > maximum THEN
+ maximum := _value[z][y][x];
+ END IF;
+ END LOOP;
+ END LOOP;
+
+ RETURN maximum - minimum;
+ END;
+ $$ LANGUAGE 'plpgsql' IMMUTABLE;
+
+CREATE OR REPLACE FUNCTION st_roughness(
+ rast raster, nband integer,
+ customextent raster,
+ pixeltype text DEFAULT '32BF', interpolate_nodata boolean DEFAULT FALSE
+)
+ RETURNS raster
+ AS $$
+ DECLARE
+ _rast raster;
+ _nband integer;
+ _pixtype text;
+ _pixwidth double precision;
+ _pixheight double precision;
+ _width integer;
+ _height integer;
+ _customextent raster;
+ _extenttype text;
+ BEGIN
+ _customextent := customextent;
+ IF _customextent IS NULL THEN
+ _extenttype := 'FIRST';
+ ELSE
+ _extenttype := 'CUSTOM';
+ END IF;
+
+ IF interpolate_nodata IS TRUE THEN
+ _rast := ST_MapAlgebra(
+ ARRAY[ROW(rast, nband)]::rastbandarg[],
+ 'st_invdistweight4ma(double precision[][][], integer[][], text[])'::regprocedure,
+ pixeltype,
+ 'FIRST', NULL,
+ 1, 1
+ );
+ _nband := 1;
+ _pixtype := NULL;
+ ELSE
+ _rast := rast;
+ _nband := nband;
+ _pixtype := pixeltype;
+ END IF;
+
+ RETURN ST_MapAlgebra(
+ ARRAY[ROW(_rast, _nband)]::rastbandarg[],
+ '_st_roughness4ma(double precision[][][], integer[][], text[])'::regprocedure,
+ _pixtype,
+ _extenttype, _customextent,
+ 1, 1);
+ END;
+ $$ LANGUAGE 'plpgsql' IMMUTABLE;
+
-----------------------------------------------------------------------
-- Get information about the raster
-----------------------------------------------------------------------
SELECT
id,
val,
- _st_tpi4ma(val,NULL,NULL)::numeric(16, 10) as tpi
+ round(_st_tpi4ma(val,NULL,NULL)::numeric, 6) as tpi
+FROM raster_value_arrays
+ORDER BY id;
+
+SELECT
+ id,
+ val,
+ round(_st_roughness4ma(val,NULL,NULL)::numeric, 6) as roughness
FROM raster_value_arrays
ORDER BY id;
9|slope|1|3|26.565052
9|slope|2|3|21.568129
9|slope|3|3|10.024988
-1|{{{1,2,3},{4,5,6},{7,8,9}}}|0.0000000000
-2|{{{15,14,13},{12,11,10},{9,8,7}}}|0.0000000000
-3|{{{1,3,5},{7,9,11},{13,15,17}}}|0.0000000000
+1|{{{1,2,3},{4,5,6},{7,8,9}}}|0.000000
+2|{{{15,14,13},{12,11,10},{9,8,7}}}|0.000000
+3|{{{1,3,5},{7,9,11},{13,15,17}}}|0.000000
4|{{{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}}|
-5|{{{1,NULL,3},{NULL,5,NULL},{7,NULL,9}}}|0.0000000000
+5|{{{1,NULL,3},{NULL,5,NULL},{7,NULL,9}}}|0.000000
6|{{{NULL,2,NULL},{4,NULL,6},{NULL,8,NULL}}}|
7|{{{1,3.1,5.2},{NULL,NULL,11.5},{13.6,NULL,NULL}}}|
-8|{{{NULL,3.14,NULL},{NULL,12.56,NULL},{NULL,NULL,25.12}}}|-0.3925000000
+8|{{{NULL,3.14,NULL},{NULL,12.56,NULL},{NULL,NULL,25.12}}}|-0.392500
9|{{{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,9}}}|
-10|{{{3.14,15.14,27.14},{39.14,51.14,63.14},{75.14,87.14,99.14}}}|0.0000000000
-11|{{{2.11,13.11,24.11},{35.11,46.11,57.11},{68.11,79.11,90.11}}}|0.0000000000
+10|{{{3.14,15.14,27.14},{39.14,51.14,63.14},{75.14,87.14,99.14}}}|0.000000
+11|{{{2.11,13.11,24.11},{35.11,46.11,57.11},{68.11,79.11,90.11}}}|0.000000
+1|{{{1,2,3},{4,5,6},{7,8,9}}}|8.000000
+2|{{{15,14,13},{12,11,10},{9,8,7}}}|8.000000
+3|{{{1,3,5},{7,9,11},{13,15,17}}}|16.000000
+4|{{{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,NULL}}}|
+5|{{{1,NULL,3},{NULL,5,NULL},{7,NULL,9}}}|8.000000
+6|{{{NULL,2,NULL},{4,NULL,6},{NULL,8,NULL}}}|
+7|{{{1,3.1,5.2},{NULL,NULL,11.5},{13.6,NULL,NULL}}}|
+8|{{{NULL,3.14,NULL},{NULL,12.56,NULL},{NULL,NULL,25.12}}}|21.980000
+9|{{{NULL,NULL,NULL},{NULL,NULL,NULL},{NULL,NULL,9}}}|
+10|{{{3.14,15.14,27.14},{39.14,51.14,63.14},{75.14,87.14,99.14}}}|96.000000
+11|{{{2.11,13.11,24.11},{35.11,46.11,57.11},{68.11,79.11,90.11}}}|88.000000