[postgis-users] Z Interpolation of Point in Triangle
Steffen Macke
sdteffen at gmail.com
Wed Feb 1 21:39:14 PST 2006
Hello All,
the PL/SQL function below allows a "poor man's" TIN implemenation,
with a triangle represented by a polygon (3 dimensions). The function
returns the interpolated z value
if it is fed with such a triangle polygon and a point that lies inside
the polygon.
It would be nice to have it included in the PostGIS distribution.
An example how to use the function is included at the end.
Regards,
Steffen
create or replace function interpolate_from_tin(location geometry, tin
geometry) returns float as
$body$
declare
az float8;
bz float8;
cz float8;
a1 float8;
a2 float8;
b1 float8;
b2 float8;
c1 float8;
c2 float8;
result float8;
ring geometry;
tinpoint geometry;
a geometry;
b geometry;
c geometry;
begin
if numgeometries(tin) <> 1 then
raise exception 'Expecting 1 geometry in TIN polygon, got %.',
numgeometries(tin);
end if;
ring := exteriorring(geometryn(tin,1));
if numpoints(ring) <> 4 then
raise exception 'Expecting 3 points in TIN polygon, got %.',
numpoints(ring);
end if;
if ndims(ring) < 3 then
raise exception 'Expecting 3 dimensions in TIN polygon, got %.',
ndims(ring);
end if;
a := pointn(ring, 1);
b := pointn(ring, 2);
c := pointn(ring, 3);
a1 := x(location)-x(a);
a2 := y(location)-y(a);
b1 := x(location)-x(b);
b2 := y(location)-y(b);
c1 := x(location)-x(c);
c2 := y(location)-y(c);
az := z(a);
bz := z(b);
cz := z(c);
result := ((a1*b2*cz)-(a1*bz*c2)+(a2*bz*c1)-(a2*b1*cz)+(az*b1*c2)-(az*b2*c1))/((a1*b2)-(a1*c2)+(a2*c1)-(a2*b1)+(b1*c2)-(b2*c1));
return result;
end;
$body$
language plpgsql immutable;
comment on function interpolate_from_tin(geometry, geometry) is
'Linear interpolation of a given points z value from a triangle polygon
@param location is the point geometry.
@param tin is the triangle polygon (3D).
@returns the interpolated z value at point location.';
select interpolate_from_tin('POINT(1 1)', 'MULTIPOLYGON(((0 0 0,1 2
1,2 0 0,0 0 0)))'),
interpolate_from_tin('POINT(1 2)', 'MULTIPOLYGON(((0 0 0,1 2 1,2 0
0,0 0 0)))'),
interpolate_from_tin('POINT(2 0)', 'MULTIPOLYGON(((0 0 0,1 2 1,2 0
0,0 0 0)))');
More information about the postgis-users
mailing list