Schema
public
Owner
albenard
Descriptions
There is no description for function _st_hillshade4ma
Options
Option | Value |
---|---|
Returns |
double precision |
Language |
plpgsql |
Parameters |
value double precision [] pos integer [] variadic userargs text [] = NULL::text[] |
Definition
CREATE OR REPLACE FUNCTION public._st_hillshade4ma (
value double precision [],
pos integer [],
variadic userargs text [] = NULL::text[]
)
RETURNS double precision AS
$span$
DECLARE
_pixwidth double precision;
_pixheight double precision;
_width double precision;
_height double precision;
_azimuth double precision;
_altitude double precision;
_bright double precision;
_scale double precision;
dz_dx double precision;
dz_dy double precision;
azimuth double precision;
zenith double precision;
slope double precision;
aspect double precision;
shade double precision;
_value double precision[][][];
ndims int;
z int;
BEGIN
ndims := array_ndims(value);
-- add a third dimension if 2-dimension
IF ndims = 2 THEN
_value := public._ST_convertarray4ma(value);
ELSEIF ndims != 3 THEN
RAISE EXCEPTION 'First parameter of function must be a 3-dimension array';
ELSE
_value := value;
END IF;
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;
IF array_length(userargs, 1) < 8 THEN
RAISE EXCEPTION 'At least eight elements must be provided for the third parameter';
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);
_pixwidth := userargs[1]::double precision;
_pixheight := userargs[2]::double precision;
_width := userargs[3]::double precision;
_height := userargs[4]::double precision;
_azimuth := userargs[5]::double precision;
_altitude := userargs[6]::double precision;
_bright := userargs[7]::double precision;
_scale := userargs[8]::double precision;
-- check that pixel is not edge pixel
IF (pos[1][1] = 1 OR pos[1][2] = 1) OR (pos[1][1] = _width OR pos[1][2] = _height) THEN
RETURN NULL;
END IF;
-- clamp azimuth
IF _azimuth < 0. THEN
RAISE NOTICE 'Clamping provided azimuth value % to 0', _azimuth;
_azimuth := 0.;
ELSEIF _azimuth >= 360. THEN
RAISE NOTICE 'Converting provided azimuth value % to be between 0 and 360', _azimuth;
_azimuth := _azimuth - (360. * floor(_azimuth / 360.));
END IF;
azimuth := 360. - _azimuth + 90.;
IF azimuth >= 360. THEN
azimuth := azimuth - 360.;
END IF;
azimuth := radians(azimuth);
--RAISE NOTICE 'azimuth = %', azimuth;
-- clamp altitude
IF _altitude < 0. THEN
RAISE NOTICE 'Clamping provided altitude value % to 0', _altitude;
_altitude := 0.;
ELSEIF _altitude > 90. THEN
RAISE NOTICE 'Clamping provided altitude value % to 90', _altitude;
_altitude := 90.;
END IF;
zenith := radians(90. - _altitude);
--RAISE NOTICE 'zenith = %', zenith;
-- clamp bright
IF _bright < 0. THEN
RAISE NOTICE 'Clamping provided bright value % to 0', _bright;
_bright := 0.;
ELSEIF _bright > 255. THEN
RAISE NOTICE 'Clamping provided bright value % to 255', _bright;
_bright := 255.;
END IF;
dz_dy := ((_value[z][3][1] + _value[z][3][2] + _value[z][3][2] + _value[z][3][3]) -
(_value[z][1][1] + _value[z][1][2] + _value[z][1][2] + _value[z][1][3])) / (8 * _pixheight);
dz_dx := ((_value[z][1][3] + _value[z][2][3] + _value[z][2][3] + _value[z][3][3]) -
(_value[z][1][1] + _value[z][2][1] + _value[z][2][1] + _value[z][3][1])) / (8 * _pixwidth);
slope := atan(sqrt(dz_dx * dz_dx + dz_dy * dz_dy) / _scale);
IF dz_dx != 0. THEN
aspect := atan2(dz_dy, -dz_dx);
IF aspect < 0. THEN
aspect := aspect + (2.0 * pi());
END IF;
ELSE
IF dz_dy > 0. THEN
aspect := pi() / 2.;
ELSEIF dz_dy < 0. THEN
aspect := (2. * pi()) - (pi() / 2.);
-- set to pi as that is the expected PostgreSQL answer in Linux
ELSE
aspect := pi();
END IF;
END IF;
shade := _bright * ((cos(zenith) * cos(slope)) + (sin(zenith) * sin(slope) * cos(azimuth - aspect)));
IF shade < 0. THEN
shade := 0;
END IF;
RETURN shade;
END;
$span$
LANGUAGE 'plpgsql'
IMMUTABLE
CALLED ON NULL INPUT
SECURITY INVOKER
COST 100;
This file was generated with SQL Manager for PostgreSQL (www.pgsqlmanager.com) at 26/02/2014 11:51 |