Smathermather's Weblog

Remote Sensing, GIS, Ecology, and Oddball Techniques

2.5D TINs in PostGIS

Posted by smathermather on December 18, 2013

(edited: changed TIN to TIN Z)
(edited again — function already exists as a flag in ST_DelaunayTriangles… .)

Uh, I wrote a function for nothin’…
As Regina points out in the commments, this functionality was rolled into 2.1 with a flag. Her example:

       'POLYGON((175 150, 20 40, 50 60, 125 100, 175 150))'), 
       ST_Buffer(ST_GeomFromText(‘POINT(110 170)’), 20) ),0.001,2) )
    AS dtriag;

For the record, my code is about 2% slower on a dataset that takes ~50minutes to triangulate .

Original Post

Ever since ST_Delaunay made its way into PostGIS with GEOS 3.4, there’s been the promise of TINs from geometries in PostGIS. The promise is for 2.5D TINs.  What are these, and why aren’t they 3D? It’s all about overhangs– imagine the edge of a building.  A 3D TIN can handle that building edge with a true vertical wall, or even overhang.  A 2.5D TIN is like a 2.5D raster– no overlaps allowed.

With those limitations in mind, you can have TINs today if you want:

-- A small function to convert ST_Delaunay (requires GEOS 3.4) to a 2.5D Tin
-- Uses the hackerish approach of converting to text, and doing string replacement
--- for format conversion.

-- A Delaunay triangulation does not by itself formally make a TIN.  To do this,
-- we will require some modification to the output format.  If we perform an ST_AsText
-- on our new geometries we will see that they are POLYGON Z's wrapped in a

-- Thus there are two ways in which this is not a TIN-- the internal POLYGON Z are
-- implicitly triangles, but explicitly POLYGON Zs.  In addition, the external wrapper
-- for the collection of triangles is a GEOMETRYCOLLECTION, not a TIN.
-- Once that we have this geometry in text form, the easiest way to fix this is
-- with string replacement to fix these two things, then convert back to binary

-- We'll go from e.g. this:
-- GEOMETRYCOLLECTION Z (POLYGON Z ((-1.14864 0.61002 -2.00108,-0.433998 -0.0288903 -2.13766, ...
-- to this:
-- TIN ( ((-1.14864 0.61002 -2.00108,-0.433998 -0.0288903 -2.13766, ...

  RETURNS geometry AS

SELECT ST_AsText(ST_DelaunayTriangles(ST_Collect($1))) AS atext
replacedt AS
-- Remove polygon z designation, as TINs don't require it.
SELECT replace(atext, 'POLYGON Z', '') as ttext
  FROM dt
replacegc AS
-- change leading declaration to TIN
SELECT replace(ttext, 'GEOMETRYCOLLECTION Z', 'TIN Z') AS tintext
  from replacedt
tingeom AS
-- Aaaand convert back to binary.  Voila!
SELECT ST_GeomFromEWKT(tintext) AS the_geom FROM replacegc

SELECT the_geom FROM tingeom

  COST 100;

Here’s an example TIN derived from UAS (non-weaponized drone) imagery:
Image showing UAS derived TIN

6 Responses to “2.5D TINs in PostGIS”

  1. Regina Obe said

    I didn’t add an example because it was added late 2.1 release, but you can get TINS directly using the optional flag arg setting to 2

    ST_Union(ST_GeomFromText(‘POLYGON((175 150, 20 40,
    50 60, 125 100, 175 150))’),
    ST_Buffer(ST_GeomFromText(‘POINT(110 170)’), 20)
    ),0.001,2) )
    As dtriag;

  2. […] 2.5D TINs in PostGIS […]

  3. […] ramsey slides)   – TIN Support and – create TINs […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: