Podría proponer una función en postgreSQL como la siguiente.
CREATE OR REPLACE FUNCTION public.__bvv_segmentize_by(
tabname text,
geomname text,
condition text,
partnumber integer)
RETURNS table(id integer, len double precision, segment geometry(linestring, 4326))
LANGUAGE 'plpgsql'
AS $BODY$
DECLARE
expr text;
r record;
pntnum integer;
i integer;
pnt_1 geometry;
pnt_2 geometry;
line_geom geometry;
len double precision;
delta double precision;
accum_len double precision;
threshold double precision;
BEGIN
expr = 'select ST_LineMerge(%s) as geom from %s where %s limit 1';
expr = format(expr, geomname, tabname, condition);
raise notice 'expr=%', expr;
threshold = 0.001;
for r in execute expr
loop
line_geom = r.geom;
len = ST_Length(line_geom);
delta = 1.0 / partnumber;
accum_len = 0;
i = 0;
loop
pnt_1 = ST_LineInterpolatePoint(line_geom, accum_len);
accum_len = accum_len + delta;
if accum_len > 1.0 and (accum_len - 1.0) < threshold
then
accum_len = 1.0;
end if;
exit when accum_len > 1.0;
pnt_2 = ST_LineInterpolatePoint(line_geom, accum_len);
i = i + 1;
return query select i, ST_Length(ST_MakeLine(pnt_1, pnt_2)),ST_MakeLine(pnt_1, pnt_2);
end loop;
end loop;
END
$BODY$;
Si crea una tabla con un campo geométrico MultiLineString como
CREATE TABLE public.test_1
(
id bigint NOT NULL,
geom geometry(MultiLineString,3857),
CONSTRAINT test_1_pkey PRIMARY KEY (id)
)
y dibujar una MultiLineString
después de realizar la siguiente consulta (el último parámetro 6 es un número de segmentos)
select id, len, segment from __bvv_segmentize_by('test_1', 'geom', 'id=1', 6)
obtendrá la siguiente tabla
y la siguiente vista de mapa donde encontrará su MultiLineString dividida en 6 partes