[postgis-devel] new constrained delauney triangulation

Nicklas Avén nicklas.aven at jordogskog.no
Sun Mar 10 14:33:14 PDT 2019


Hello


I have been working on a delauney-triangulation code.

Link to the code in the bottom

I need it booth for packaging maps to TilelessMap, but I also need it to 
be able to implement editing in the app.

For packaging I will use it in PostGIS.


The results so far looks so promising so I might suggest that it maybe 
could go into PostGIS core. Now it is in an extension.


All core logic comes from this paper

https://www.newcastle.edu.au/__data/assets/pdf_file/0019/22519/23_A-fast-algortithm-for-generating-constrained-Delaunay-triangulations.pdf


What I need is constrained triangulation, so I get only triangles in the 
polygons, not in between.

 From what I know PostGIS then only have ST_Tesselate, which is horribly 
slow and very, very picky with what it gets. Since it is more picky than 
ST_Isvalid it is very difficult to handle.


ST_DelaunayTriangles is quite fast, but cannot constrain (if I haven't 
missed something).


Anyway, what I need is also the possibility to get the result as indexes 
into the original point arrays. That is what the GPU wants. I haven't 
implemented that yet, just because I couldn't wrap my head around how to 
create arrays in PostgreSQL.


I also have a plan to suggest an extension to the twkb-format so the 
triangel indexes can be a part of a special geometry-type.

Now in TilelessMap I encode the triangle indexes as 3D pointsand keep 
them in a separate column. But with everything in a twkb geometry we 
have a format ready for pushing into a gpu. Just decode the points and 
tri-index into float arrays and serve to the GPU and it will be happy.

That is what I do in Tilelessmap.



Back to the triangulation code.

It seems pretty fast.

This is from the largest polygon I have got with 249667 vertex points in 
one single polygon (st_dump gives 1 row):

With ST_DelaunayTriangles unconstrained

test=# EXPLAIN ANALYZE select ST_DelaunayTriangles(geom) geom from 
my_riks WHERE ID = 14681;
                                                          QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------
  Index Scan using my_riks_pkey on my_riks  (cost=0.29..8.30 rows=1 
width=32) (actual time=2381.912..2386.171 rows=1 loops=1)
    Index Cond: (id = 14681)
  Planning time: 0.056 ms
  Execution time: 2386.185 ms
(4 rows)

Time: 2386.537 ms (00:02.387)


With the new code constrained

test=# EXPLAIN ANALYZE select triangulate(geom) geom from my_riks WHERE 
ID = 14681;
                                                         QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
  Index Scan using my_riks_pkey on my_riks  (cost=0.29..8.30 rows=1 
width=32) (actual time=522.360..527.080 rows=1 loops=1)
    Index Cond: (id = 14681)
  Planning time: 0.036 ms
  Execution time: 527.095 ms
(4 rows)

Time: 527.471 ms

Getting unconstrained from the new code is about the same speed, which 
is a little strange since the job to constrain is all done after the 
first round of Delauney-triangulation

test=# EXPLAIN ANALYZE select triangulate(geom,0) geom from my_riks 
WHERE ID = 14681;
                                                         QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
  Index Scan using my_riks_pkey on my_riks  (cost=0.29..8.30 rows=1 
width=32) (actual time=516.255..522.467 rows=1 loops=1)
    Index Cond: (id = 14681)
  Planning time: 0.039 ms
  Execution time: 522.482 ms
(4 rows)

Time: 522.793 ms

For smaller geometries the new code is about twice as fast as 
ST_DelaunayTriangles

St_Tessalate cannot be compared on larger polygons, it takes minutes.


The new code now handles some invalidities. There are also possibilities 
to handle more.

Right now the code doesn't always stop gracefully if you find a polygon 
it cannot handle.

I have even had the code unstoppable, so I had to shut down the machine.

So, be warned if yo want to test the code, it is a lot of error handling 
to do.

But if you can spend a reboot at worst, I would be glad if you can test 
it. I have tested on a few million polygons, which seems to work great.

The code also needs a lot of commenting to be easy to follow (and clean 
up and refactoring). I will do that especially if there is interest in 
the code.

To build as extension run make in folder postgis_extension

The code is here:

https://gitlab.com/nicklasaven/triangulation


Thanks


Nicklas Avén



More information about the postgis-devel mailing list