bring back working wm.sql

main
Motiejus Jakštys 2021-05-19 22:57:49 +03:00 committed by Motiejus Jakštys
parent e20781aa85
commit b7a9d559e2
1 changed files with 255 additions and 209 deletions

464
wm.sql
View File

@ -81,14 +81,16 @@ begin
dbgpolygon = null; dbgpolygon = null;
if st_npoints(bends[i]) >= 3 then if st_npoints(bends[i]) >= 3 then
dbgpolygon = st_makepolygon( dbgpolygon = st_makepolygon(
st_addpoint(bends[i], st_startpoint(bends[i])) st_addpoint(bends[i],
st_startpoint(bends[i]))
); );
end if; end if;
insert into wm_debug(stage, name, gen, nbend, way) values( insert into wm_debug(stage, name, gen, nbend, way) values(
'bbends-polygon', dbgname, dbggen, i, dbgpolygon); 'bbends-polygon', dbgname, dbggen, i, dbgpolygon);
end loop; end loop;
end if; end if;
end $$ language plpgsql; end
$$ language plpgsql;
-- wm_fix_gentle_inflections moves bend endpoints following "Gentle Inflection -- wm_fix_gentle_inflections moves bend endpoints following "Gentle Inflection
-- at End of a Bend" section. -- at End of a Bend" section.
@ -139,7 +141,8 @@ begin
'cinflections-polygon', dbgname, dbggen, i, dbgpolygon); 'cinflections-polygon', dbgname, dbggen, i, dbgpolygon);
end loop; end loop;
end if; end if;
end $$ language plpgsql; end
$$ language plpgsql;
-- wm_fix_gentle_inflections1 fixes gentle inflections of an array of lines in -- wm_fix_gentle_inflections1 fixes gentle inflections of an array of lines in
-- one direction. An implementation detail of wm_fix_gentle_inflections. -- one direction. An implementation detail of wm_fix_gentle_inflections.
@ -201,7 +204,8 @@ begin
end loop; end loop;
end loop; end loop;
end $$ language plpgsql; end
$$ language plpgsql;
-- wm_if_selfcross returns whether baseline of bendi crosses bendj. -- wm_if_selfcross returns whether baseline of bendi crosses bendj.
-- If it doesn't, returns a null geometry. -- If it doesn't, returns a null geometry.
@ -231,7 +235,9 @@ begin
end if; end if;
return multi; return multi;
end $$ language plpgsql; end
$$ language plpgsql;
-- wm_self_crossing eliminates self-crossing from the bends, following the -- wm_self_crossing eliminates self-crossing from the bends, following the
-- article's section "Self-line Crossing When Cutting a Bend". -- article's section "Self-line Crossing When Cutting a Bend".
@ -299,7 +305,8 @@ begin
unnest(bends) unnest(bends)
); );
end if; end if;
end $$ language plpgsql; end
$$ language plpgsql;
drop function if exists wm_inflection_angle; drop function if exists wm_inflection_angle;
create function wm_inflection_angle (IN bend geometry, OUT angle real) as $$ create function wm_inflection_angle (IN bend geometry, OUT angle real) as $$
@ -317,14 +324,17 @@ begin
continue when p3 is null; continue when p3 is null;
angle = angle + abs(pi() - st_angle(p1, p2, p3)); angle = angle + abs(pi() - st_angle(p1, p2, p3));
end loop; end loop;
end $$ language plpgsql; end
$$ language plpgsql;
drop function if exists wm_bend_attrs; drop function if exists wm_bend_attrs;
drop function if exists wm_isolated_bends;
drop function if exists wm_elimination; drop function if exists wm_elimination;
drop function if exists wm_exaggeration; drop function if exists wm_exaggeration;
drop function if exists wm_st_intersects_neighbors; drop type if exists wm_t_bend_attrs;
drop type if exists wm_t_attrs; create type wm_t_bend_attrs as (
create type wm_t_attrs as ( bend geometry,
area real,
adjsize real, adjsize real,
baselinelength real, baselinelength real,
curvature real, curvature real,
@ -334,66 +344,40 @@ create function wm_bend_attrs(
bends geometry[], bends geometry[],
dbgname text default null, dbgname text default null,
dbggen integer default null dbggen integer default null
) returns wm_t_attrs[] as $$ ) returns setof wm_t_bend_attrs as $$
declare declare
isolation_threshold constant real default 0.5; cmp float;
attrs wm_t_attrs[];
attr wm_t_attrs;
bend geometry;
i int4; i int4;
needs_curvature real; polygon geometry;
skip_next boolean; bend geometry;
dbglastid integer; res wm_t_bend_attrs;
begin begin
for i in 1..array_length(bends, 1) loop for i in 1..array_length(bends, 1) loop
bend = bends[i]; bend = bends[i];
attr.adjsize = 0; res = null;
attr.baselinelength = st_distance(st_startpoint(bend), st_endpoint(bend)); res.bend = bend;
attr.curvature = wm_inflection_angle(bend) / st_length(bend); res.adjsize = 0;
attr.isolated = false; res.baselinelength = st_distance(st_startpoint(bend), st_endpoint(bend));
res.curvature = wm_inflection_angle(bend) / st_length(bend);
res.isolated = false;
if st_numpoints(bend) >= 3 then if st_numpoints(bend) >= 3 then
attr.adjsize = wm_adjsize(bend); res.adjsize = wm_adjsize(bend);
end if; end if;
attrs[i] = attr;
end loop;
for i in 1..array_length(attrs, 1) loop
if dbgname is not null then if dbgname is not null then
insert into wm_debug (stage, name, gen, nbend, way, props) values( insert into wm_debug (stage, name, gen, nbend, way, props) values(
'ebendattrs', dbgname, dbggen, i, bend, 'ebendattrs', dbgname, dbggen, i, bend,
jsonb_build_object( jsonb_build_object(
'adjsize', attrs[i].adjsize, 'adjsize', res.adjsize,
'baselinelength', attrs[i].baselinelength, 'baselinelength', res.baselinelength,
'curvature', attrs[i].curvature, 'curvature', res.curvature
'isolated', false
) )
) returning id into dbglastid; );
end if;
-- first and last bends can never be isolated by definition
if skip_next or i = 1 or i = array_length(attrs, 1) then
skip_next = false;
continue;
end if;
needs_curvature = attrs[i].curvature * isolation_threshold;
if attrs[i-1].curvature < needs_curvature and
attrs[i+1].curvature < needs_curvature then
attr = attrs[i];
attr.isolated = true;
attrs[i] = attr;
skip_next = true;
if dbgname is not null then
update wm_debug
set props=props || jsonb_build_object('isolated', true)
where id=dbglastid;
end if;
end if; end if;
return next res;
end loop; end loop;
end;
return attrs; $$ language plpgsql;
end $$ language plpgsql;
-- sm_st_split a line by a point in a more robust way than st_split. -- sm_st_split a line by a point in a more robust way than st_split.
-- See https://trac.osgeo.org/postgis/ticket/2192 -- See https://trac.osgeo.org/postgis/ticket/2192
@ -417,44 +401,55 @@ end $$ language plpgsql;
-- wm_exaggerate_bend exaggerates a given bend. Must be a simple linestring. -- wm_exaggerate_bend exaggerates a given bend. Must be a simple linestring.
drop function if exists wm_exaggerate_bend; drop function if exists wm_exaggerate_bend;
create function wm_exaggerate_bend(INOUT bend geometry) as $$ create function wm_exaggerate_bend(
INOUT bend geometry,
size float,
desired_size float
) as $$
declare declare
scale constant float default 1.2; -- exaggeration enthusiasm scale constant float default 2; -- per-step scaling factor
midpoint geometry; -- midpoint of the baseline midpoint geometry; -- midpoint of the baseline
splitbend geometry; -- bend split across its half splitbend geometry; -- bend split across its half
bendm geometry; -- bend with coefficients to prolong the lines bendm geometry; -- bend with coefficients to prolong the lines
points geometry[]; points geometry[];
begin begin
if size = 0 then
raise 'invalid input: zero-area bend';
end if;
midpoint = st_lineinterpolatepoint(st_makeline( midpoint = st_lineinterpolatepoint(st_makeline(
st_pointn(bend, 1), st_pointn(bend, 1),
st_pointn(bend, -1) st_pointn(bend, -1)
), .5); ), .5);
splitbend = wm_st_split(bend, st_lineinterpolatepoint(bend, .5)); while size < desired_size loop
-- Convert bend to LINESTRINGM, where M is the fraction by how splitbend = wm_st_split(bend, st_lineinterpolatepoint(bend, .5));
-- much the point will be prolonged: -- Convert bend to LINESTRINGM, where M is the fraction by how
-- 1. draw a line between midpoint and the point on the bend. -- much the point will be prolonged:
-- 2. multiply the line length by M. Midpoint stays intact. -- 1. draw a line between midpoint and the point on the bend.
-- 3. the new set of lines form a new bend. -- 2. multiply the line length by M. Midpoint stays intact.
-- Uses linear interpolation; can be updated to gaussian or similar; -- 3. the new set of lines form a new bend.
-- then interpolate manually instead of relying on st_addmeasure. -- Uses linear interpolation; can be updated to gaussian or similar;
bendm = st_collect( -- then interpolate manually instead of relying on st_addmeasure.
st_addmeasure(st_geometryn(splitbend, 1), 1, scale), bendm = st_collect(
st_addmeasure(st_geometryn(splitbend, 2), scale, 1) st_addmeasure(st_geometryn(splitbend, 1), 1, scale),
); st_addmeasure(st_geometryn(splitbend, 2), scale, 1)
);
points = array(( points = array((
select st_scale( select st_scale(
st_makepoint(st_x(geom), st_y(geom)), st_makepoint(st_x(geom), st_y(geom)),
st_makepoint(st_m(geom), st_m(geom)), st_makepoint(st_m(geom), st_m(geom)),
midpoint midpoint
) )
from st_dumppoints(bendm) from st_dumppoints(bendm)
order by path[1], path[2] order by path[1], path[2]
)); ));
bend = st_setsrid(st_makeline(points), st_srid(bend)); bend = st_setsrid(st_makeline(points), st_srid(bend));
end $$ language plpgsql; size = wm_adjsize(bend);
end loop;
end
$$ language plpgsql;
-- wm_adjsize calculates adjusted size for a polygon. Can return 0. -- wm_adjsize calculates adjusted size for a polygon. Can return 0.
drop function if exists wm_adjsize; drop function if exists wm_adjsize;
@ -479,62 +474,12 @@ begin
if cmp > 0 then if cmp > 0 then
adjsize = (area*(0.75/cmp)); adjsize = (area*(0.75/cmp));
end if; end if;
end $$ language plpgsql; end
$$ language plpgsql;
drop function if exists wm_st_intersects_neighbors;
create function wm_st_intersects_neighbors(
bends geometry[],
bend geometry,
i integer,
intersect_patience integer
) returns boolean as $$
declare
n integer;
neighbor geometry;
begin
-- Do close-by bends intersect with this one? Special
-- handling first, because 2 vertices need to be removed before checking.
n = st_npoints(bends[i-1]);
if n > 3 and st_intersects(bend,
st_removepoint(st_removepoint(bends[i-1], n-1), n-2)) then
return true;
end if;
n = st_npoints(bends[i+1]);
if n > 3 and st_intersects(bend,
st_removepoint(st_removepoint(bends[i+1], 0), 0)) then
return true;
end if;
-- Go through all the neighbors and see if the enlarged bend intersects
-- with any of them. If yes -- abort enlargement.
for n in -intersect_patience+1..intersect_patience-1 loop
continue when i+n < 1 or n in (-1, 0, 1);
continue when i+n > array_length(bends, 1);
-- More special handling: if the neigbhoring bend has 3 vertices, the
-- neighbor's neighbor may just touch the bend; in this
-- case, the nearest vertex should be removed before comparing.
neighbor = bends[i+n];
if st_npoints(neighbor) > 2 then
if n = -2 and st_npoints(bends[i+n+1]) = 3 then
neighbor = st_removepoint(neighbor, st_npoints(neighbor)-1);
elsif n = 2 and st_npoints(bends[i+n-1]) = 3 then
neighbor = st_removepoint(neighbor, 0);
end if;
end if;
if st_intersects(bend, neighbor) then
return true;
end if;
end loop;
return false;
end $$ language plpgsql;
-- wm_exaggeration is the Exaggeration Operator described in the WM paper. -- wm_exaggeration is the Exaggeration Operator described in the WM paper.
create function wm_exaggeration( create function wm_exaggeration(
INOUT bends geometry[], INOUT bendattrs wm_t_bend_attrs[],
attrs wm_t_attrs[],
dhalfcircle float, dhalfcircle float,
intersect_patience integer, intersect_patience integer,
dbgname text default null, dbgname text default null,
@ -543,58 +488,87 @@ create function wm_exaggeration(
) as $$ ) as $$
declare declare
desired_size constant float default pi()*(dhalfcircle^2)/8; desired_size constant float default pi()*(dhalfcircle^2)/8;
bend geometry; tmpbendattr wm_t_bend_attrs;
neighbor geometry; tmpint geometry;
size float;
i integer; i integer;
this_mutated boolean; n integer;
last_id integer;
begin begin
mutated = false; mutated = false;
i = 0; <<bendloop>>
while i < array_length(attrs, 1) loop for i in 1..array_length(bendattrs, 1) loop
i = i + 1; if bendattrs[i].isolated and bendattrs[i].adjsize < desired_size then
tmpbendattr.bend = wm_exaggerate_bend(
bendattrs[i].bend,
bendattrs[i].adjsize,
desired_size
);
continue when not attrs[i].isolated; -- does tmpbendattrs.bend intersect with the previous or next
this_mutated = false; -- intersect_patience bends? If they do, abort exaggeration for this one.
-- keep increasing this bend until either size permits, or it hits a
-- neighboring bend (intersect_patience number of neighbors will be
-- checked). When the size is right, stick it to the line.
size = attrs[i].adjsize;
while size < desired_size loop
bend = wm_exaggerate_bend(bends[i]);
exit when wm_st_intersects_neighbors(bends, bend, i, intersect_patience);
this_mutated = true; -- Do close-by bends intersect with this one? Special
bends[i] = bend; -- handling first, because 2 vertices need to be removed before checking.
size = wm_adjsize(bend); n = st_npoints(bendattrs[i-1].bend);
end loop; if n > 3 then
continue when not this_mutated; continue when st_intersects(tmpbendattr.bend,
st_removepoint(st_removepoint(bendattrs[i-1].bend, n-1), n-2));
end if;
mutated = true; n = st_npoints(bendattrs[i+1].bend);
-- Stick the right-sized bend to the line if n > 3 then
----------------------------------------- continue when st_intersects(tmpbendattr.bend,
-- Remove last vertex of the previous bend and first vertex of the next st_removepoint(st_removepoint(bendattrs[i+1].bend, 0), 0));
-- bend, because bends always share a line segment together. end if;
bend = st_removepoint(bends[i-1], st_npoints(bends[i-1])-1);
bends[i-1] = bend;
bend = st_removepoint(bends[i+1], 0);
bends[i+1] = bend;
if dbgname is not null then for n in -intersect_patience+1..intersect_patience-1 loop
insert into wm_debug (stage, name, gen, nbend, way) values( continue when n in (-1, 0, 1);
'gexaggeration', dbgname, dbggen, i, bends[i]); continue when i+n < 1;
continue when i+n > array_length(bendattrs, 1);
-- More special handling: if the neigbhoring bend has 3 vertices, the
-- neighbor's neighbor may just touch the tmpbendattr.bend; in this
-- case, the nearest vertex should be removed before comparing.
tmpint = bendattrs[i+n].bend;
if st_npoints(tmpint) > 2 then
if n = -2 and st_npoints(bendattrs[i+n+1].bend) = 3 then
tmpint = st_removepoint(tmpint, st_npoints(tmpint)-1);
elsif n = 2 and st_npoints(bendattrs[i+n-1].bend) = 3 then
tmpint = st_removepoint(tmpint, 0);
end if;
end if;
continue bendloop when st_intersects(tmpbendattr.bend, tmpint);
end loop;
-- No intersections within intersect_patience, mutate bend!
mutated = true;
bendattrs[i] = tmpbendattr;
-- remove last vertex of the previous bend and first vertex of the next
-- bend, because bends always share a line segment together this is
-- duplicated in a few places, because PostGIS does not allow (?)
-- mutating an array when passed to a function.
tmpbendattr.bend = st_removepoint(
bendattrs[i-1].bend,
st_npoints(bendattrs[i-1].bend)-1
);
bendattrs[i-1] = tmpbendattr;
tmpbendattr.bend = st_removepoint(bendattrs[i+1].bend, 0);
bendattrs[i+1] = tmpbendattr;
if dbgname is not null then
insert into wm_debug (stage, name, gen, nbend, way) values(
'gexaggeration', dbgname, dbggen, i, bendattrs[i].bend
);
end if;
end if; end if;
-- Next bend was modified, so `isolated` is not valid for neighbor's
-- neighbor. Skip over.
i = i + 2;
end loop; end loop;
end $$ language plpgsql; end $$ language plpgsql;
create function wm_elimination( create function wm_elimination(
INOUT bends geometry[], INOUT bendattrs wm_t_bend_attrs[],
attrs wm_t_attrs[],
dhalfcircle float, dhalfcircle float,
dbgname text default null, dbgname text default null,
dbggen integer default null, dbggen integer default null,
@ -605,54 +579,119 @@ declare
leftsize float; leftsize float;
rightsize float; rightsize float;
i int4; i int4;
j int4;
tmpbendattr wm_t_bend_attrs;
dbgbends geometry[];
begin begin
mutated = false; mutated = false;
i = 1; i = 1;
while i < array_length(attrs, 1)-1 loop while i < array_length(bendattrs, 1)-1 loop
i = i + 1; i = i + 1;
continue when attrs[i].adjsize = 0; continue when bendattrs[i].adjsize = 0;
continue when attrs[i].adjsize > desired_size; continue when bendattrs[i].adjsize > desired_size;
if i = 2 then if i = 2 then
leftsize = attrs[i].adjsize + 1; leftsize = bendattrs[i].adjsize + 1;
else else
leftsize = attrs[i-1].adjsize; leftsize = bendattrs[i-1].adjsize;
end if; end if;
if i = array_length(attrs, 1)-1 then if i = array_length(bendattrs, 1)-1 then
rightsize = attrs[i].adjsize + 1; rightsize = bendattrs[i].adjsize + 1;
else else
rightsize = attrs[i+1].adjsize; rightsize = bendattrs[i+1].adjsize;
end if; end if;
continue when attrs[i].adjsize >= leftsize; continue when bendattrs[i].adjsize >= leftsize;
continue when attrs[i].adjsize >= rightsize; continue when bendattrs[i].adjsize >= rightsize;
-- Local minimum. Elminate bend! -- Local minimum. Elminate bend!
mutated = true; mutated = true;
bends[i] = st_makeline(st_pointn(bends[i], 1), st_pointn(bends[i], -1)); tmpbendattr.bend = st_makeline(
st_pointn(bendattrs[i].bend, 1),
st_pointn(bendattrs[i].bend, -1)
);
bendattrs[i] = tmpbendattr;
-- remove last vertex of the previous bend and -- remove last vertex of the previous bend and
-- first vertex of the next bend, because bends always -- first vertex of the next bend, because bends always
-- share a line segment together -- share a line segment together
bends[i-1] = st_removepoint(bends[i-1], st_npoints(bends[i-1])-1); tmpbendattr.bend = st_removepoint(
bends[i+1] = st_removepoint(bends[i+1], 0); bendattrs[i-1].bend,
st_npoints(bendattrs[i-1].bend)-1
);
bendattrs[i-1] = tmpbendattr;
tmpbendattr.bend = st_removepoint(bendattrs[i+1].bend, 0);
bendattrs[i+1] = tmpbendattr;
-- the next bend's adjsize is now messed up; it should not be taken -- the next bend's adjsize is now messed up; it should not be taken
-- into consideration for other local minimas. Skip over 2. -- into consideration for other local minimas. Skip over 2.
i = i + 2; i = i + 2;
end loop; end loop;
if dbgname is not null then if dbgname is not null then
for j in 1..array_length(bendattrs, 1) loop
dbgbends[j] = bendattrs[j].bend;
end loop;
insert into wm_debug(stage, name, gen, nbend, way) values( insert into wm_debug(stage, name, gen, nbend, way) values(
'helimination', 'helimination',
dbgname, dbgname,
dbggen, dbggen,
generate_subscripts(bends, 1), generate_subscripts(dbgbends, 1),
unnest(bends) unnest(dbgbends)
); );
end if; end if;
end $$ language plpgsql; end
$$ language plpgsql;
create function wm_isolated_bends(
INOUT bendattrs wm_t_bend_attrs[],
dbgname text default null,
dbggen integer default null
) as $$
declare
-- if neighbor's curvatures are within this fraction of the current bend
isolation_threshold constant real default 0.5;
this real;
skip_next bool;
res wm_t_bend_attrs;
i int4;
last_id integer;
begin
for i in 1..array_length(bendattrs, 1) loop
if dbgname is not null then
insert into wm_debug (stage, name, gen, nbend, way, props) values(
'fisolated_bends', dbgname, dbggen, i, bendattrs[i].bend,
jsonb_build_object('isolated', false)
) returning id into last_id;
end if;
-- first and last bends cannot be isolated
if i = 1 or i = array_length(bendattrs, 1) then
continue;
end if;
res = bendattrs[i];
if skip_next then
skip_next = false;
else
this = bendattrs[i].curvature * isolation_threshold;
if bendattrs[i-1].curvature < this and
bendattrs[i+1].curvature < this then
res.isolated = true;
bendattrs[i] = res;
skip_next = true;
if dbgname is not null then
update wm_debug
set props=props || jsonb_build_object('isolated', true)
where id=last_id;
end if;
end if;
end if;
end loop;
end
$$ language plpgsql;
drop function if exists ST_SimplifyWM_Estimate; drop function if exists ST_SimplifyWM_Estimate;
create function ST_SimplifyWM_Estimate( create function ST_SimplifyWM_Estimate(
@ -678,7 +717,8 @@ begin
npoints = npoints + st_numpoints(lines[i]); npoints = npoints + st_numpoints(lines[i]);
end loop; end loop;
secs = npoints / 33; secs = npoints / 33;
end $$ language plpgsql; end
$$ language plpgsql;
-- ST_SimplifyWM simplifies a given geometry using Wang & Müller's -- ST_SimplifyWM simplifies a given geometry using Wang & Müller's
-- "Line Generalization Based on Analysis of Shape Characteristics" algorithm, -- "Line Generalization Based on Analysis of Shape Characteristics" algorithm,
@ -702,7 +742,7 @@ declare
line geometry; line geometry;
lines geometry[]; lines geometry[];
bends geometry[]; bends geometry[];
attrs wm_t_attrs[]; bendattrs wm_t_bend_attrs[];
mutated boolean; mutated boolean;
l_type text; l_type text;
begin begin
@ -733,37 +773,42 @@ begin
select * from wm_self_crossing(bends, dbgname, gen) into bends, mutated; select * from wm_self_crossing(bends, dbgname, gen) into bends, mutated;
if not mutated then if mutated then
attrs = wm_bend_attrs(bends, dbgname, gen); lines[i] = st_linemerge(st_union(bends));
gen = gen + 1;
select * from wm_exaggeration( continue;
bends, attrs, dhalfcircle, intersect_patience, dbgname, gen
) into bends, mutated;
end if; end if;
bendattrs = array((select wm_bend_attrs(bends, dbgname, gen)));
bendattrs = wm_isolated_bends(bendattrs, dbgname, gen);
select * from wm_exaggeration(
bendattrs, dhalfcircle, intersect_patience, dbgname, gen
) into bendattrs, mutated;
-- TODO: wm_combination -- TODO: wm_combination
if not mutated then if not mutated then
select * from wm_elimination( select * from wm_elimination(
bends, attrs, dhalfcircle, dbgname, gen) into bends, mutated; bendattrs, dhalfcircle, dbgname, gen) into bendattrs, mutated;
end if; end if;
if mutated then if mutated then
for j in 1..array_length(bendattrs, 1) loop
bends[j] = bendattrs[j].bend;
end loop;
lines[i] = st_linemerge(st_union(bends)); lines[i] = st_linemerge(st_union(bends));
if st_geometrytype(lines[i]) != 'ST_LineString' then if st_geometrytype(lines[i]) != 'ST_LineString' then
raise notice 'Got % (in %) instead of ST_LineString. ' -- For manual debugging:
--insert into wm_manual(name, way)
--select 'non-linestring-' || a.path[1], a.geom
--from st_dump(lines[i]) a
--order by a.path[1];
raise 'Got % (in %) instead of ST_LineString. '
'Does the exaggerated bend intersect with the line? ' 'Does the exaggerated bend intersect with the line? '
'If so, try increasing intersect_patience.', 'If so, try increasing intersect_patience.',
st_geometrytype(lines[i]), dbgname; st_geometrytype(lines[i]), dbgname;
-- For manual debugging, usually when wm_exaggeration returns --exit lineloop;
-- ST_MultiLineString. Uncomment the code below and change `raise`
-- to `raise notice` above.
insert into wm_manual(name, way)
select 'non-linestring-' || a.path[1], a.geom
from st_dump(lines[i]) a
order by a.path[1];
exit lineloop;
end if; end if;
gen = gen + 1; gen = gen + 1;
continue; continue;
@ -776,4 +821,5 @@ begin
elseif l_type = 'ST_MultiLineString' then elseif l_type = 'ST_MultiLineString' then
return st_union(lines); return st_union(lines);
end if; end if;
end $$ language plpgsql; end
$$ language plpgsql;