I would like to render contours using Mapnik. The problem is that some contours are very long which makes rendering too slow and so I decided to spling long contours to multiple smaller segments. Input table (generated with gdal_contour
):
gis=> \d contour;
Table "public.contour"
Column | Type | Collation | Nullable | Default
--------------+-----------------------------+-----------+----------+------------------------------------------
ogc_fid | integer | | not null | nextval('contour_ogc_fid_seq'::regclass)
id | numeric(8,0) | | |
height | numeric(12,3) | | |
wkb_geometry | geometry(LineString,900914) | | |
Indexes:
"contour_pkey" PRIMARY KEY, btree (ogc_fid)
"contour_wkb_geometry_geom_idx" gist (wkb_geometry)
I am no GIS or PostGIS proffesional but I tried my best and came up with following query:
create table contour_split as select
ogc_fid,
height,
(select st_makeline((x).geom) from (select st_dumppoints(wkb_geometry) as x offset round(start) limit round(start + seg_len) - round(start)) as sub3) as geom
from
(
select
ogc_fid,
wkb_geometry,
height,
n_pts / ceil(n_pts / 1000.0) as seg_len,
generate_series(
0,
n_pts - n_pts / ceil(n_pts / 1000.0),
n_pts / ceil(n_pts / 1000.0)
) as start
from
(select *, st_numpoints(wkb_geometry) as n_pts from contour) as sub1
) as sub2;
The problem is that this query is very slow. There are over 1.6M rows in the contours
table and the query is running for several hours already.
I've also tried to do it with intermediate tables but the speed (of the last query) is still slow:
alter table contour add column np int;
update contour set np = st_numpoints(wkb_geometry);
create table contour_tmp as select
ogc_fid,
generate_series(
0,
np - np / ceil(np / 1000.0),
np / ceil(np / 1000.0)
) as start
from contour;
create table contour_split as
select
ogc_fid
height,
(
select
st_makeline((x).geom)
from
(
select
st_dumppoints(wkb_geometry) as x offset round(start)
limit
round(start + np / ceil(np / 1000.0)) - round(start)
) as ddd
)
from
contour
join contour_tmp using (ogc_fid);
Can somebody see there something "obvious" what could improve the speed of the query? Is there a better approach to achieve even splitting linestrings to not to be longer than 1000 points? ST_Subdivide
returns uneven results - some segments are very short. Or to make Mapnik fast even with long contour linestrings?
Version information: POSTGIS="2.5.1 r17027" [EXTENSION] PGSQL="110" GEOS="3.7.1-CAPI-1.11.1 27a5e771" PROJ="Rel. 5.2.0, September 15th, 2018" GDAL="GDAL 2.4.0, released 2018/12/14" LIBXML="2.9.4" LIBJSON="0.12.1" LIBPROTOBUF="1.3.1" RASTER