merge wm_isolated_bends and wm_bend_attrs
This commit is contained in:
parent
63bde6c7f5
commit
12b0784840
131
wm.sql
131
wm.sql
@ -81,8 +81,7 @@ 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_addpoint(bends[i], st_startpoint(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(
|
||||||
@ -321,13 +320,11 @@ begin
|
|||||||
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 function if exists wm_st_intersects_neighbors;
|
||||||
drop type if exists wm_t_attrs;
|
drop type if exists wm_t_attrs;
|
||||||
create type wm_t_attrs as (
|
create type wm_t_attrs as (
|
||||||
area real,
|
|
||||||
adjsize real,
|
adjsize real,
|
||||||
baselinelength real,
|
baselinelength real,
|
||||||
curvature real,
|
curvature real,
|
||||||
@ -337,37 +334,65 @@ 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 setof wm_t_attrs as $$
|
) returns wm_t_attrs[] as $$
|
||||||
declare
|
declare
|
||||||
cmp float;
|
isolation_threshold constant real default 0.5;
|
||||||
i int4;
|
attrs wm_t_attrs[];
|
||||||
polygon geometry;
|
attr wm_t_attrs;
|
||||||
bend geometry;
|
bend geometry;
|
||||||
res wm_t_attrs;
|
i int4;
|
||||||
|
needs_curvature real;
|
||||||
|
skip_next boolean;
|
||||||
|
dbglastid integer;
|
||||||
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];
|
||||||
res = null;
|
attr.adjsize = 0;
|
||||||
res.adjsize = 0;
|
attr.baselinelength = st_distance(st_startpoint(bend), st_endpoint(bend));
|
||||||
res.baselinelength = st_distance(st_startpoint(bend), st_endpoint(bend));
|
attr.curvature = wm_inflection_angle(bend) / st_length(bend);
|
||||||
res.curvature = wm_inflection_angle(bend) / st_length(bend);
|
attr.isolated = false;
|
||||||
res.isolated = false;
|
|
||||||
if st_numpoints(bend) >= 3 then
|
if st_numpoints(bend) >= 3 then
|
||||||
res.adjsize = wm_adjsize(bend);
|
attr.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', res.adjsize,
|
'adjsize', attrs[i].adjsize,
|
||||||
'baselinelength', res.baselinelength,
|
'baselinelength', attrs[i].baselinelength,
|
||||||
'curvature', res.curvature
|
'curvature', attrs[i].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;
|
||||||
|
|
||||||
|
return attrs;
|
||||||
end $$ 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.
|
||||||
@ -574,7 +599,6 @@ declare
|
|||||||
leftsize float;
|
leftsize float;
|
||||||
rightsize float;
|
rightsize float;
|
||||||
i int4;
|
i int4;
|
||||||
bend geometry;
|
|
||||||
begin
|
begin
|
||||||
mutated = false;
|
mutated = false;
|
||||||
|
|
||||||
@ -624,55 +648,6 @@ begin
|
|||||||
end if;
|
end if;
|
||||||
end $$ language plpgsql;
|
end $$ language plpgsql;
|
||||||
|
|
||||||
create function wm_isolated_bends(
|
|
||||||
INOUT attrs wm_t_attrs[],
|
|
||||||
bends geometry[],
|
|
||||||
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_attrs;
|
|
||||||
i int4;
|
|
||||||
last_id integer;
|
|
||||||
begin
|
|
||||||
for i in 1..array_length(attrs, 1) loop
|
|
||||||
if dbgname is not null then
|
|
||||||
insert into wm_debug (stage, name, gen, nbend, way, props) values(
|
|
||||||
'fisolated_bends', dbgname, dbggen, i, bends[i],
|
|
||||||
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(attrs, 1) then
|
|
||||||
continue;
|
|
||||||
end if;
|
|
||||||
|
|
||||||
res = attrs[i];
|
|
||||||
if skip_next then
|
|
||||||
skip_next = false;
|
|
||||||
else
|
|
||||||
this = attrs[i].curvature * isolation_threshold;
|
|
||||||
if attrs[i-1].curvature < this and
|
|
||||||
attrs[i+1].curvature < this then
|
|
||||||
res.isolated = true;
|
|
||||||
attrs[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(
|
||||||
geom geometry,
|
geom geometry,
|
||||||
@ -753,8 +728,7 @@ 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 not mutated then
|
||||||
attrs = array((select wm_bend_attrs(bends, dbgname, gen)));
|
attrs = wm_bend_attrs(bends, dbgname, gen);
|
||||||
attrs = wm_isolated_bends(attrs, bends, dbgname, gen);
|
|
||||||
|
|
||||||
select * from wm_exaggeration(
|
select * from wm_exaggeration(
|
||||||
bends, attrs, dhalfcircle, intersect_patience, dbgname, gen
|
bends, attrs, dhalfcircle, intersect_patience, dbgname, gen
|
||||||
@ -772,16 +746,17 @@ begin
|
|||||||
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
|
||||||
-- For manual debugging, usually when wm_exaggeration returns
|
|
||||||
-- ST_MultiLineString. Uncomment the code below and `raise notice`.
|
|
||||||
--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. '
|
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
|
||||||
|
-- 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;
|
--exit lineloop;
|
||||||
end if;
|
end if;
|
||||||
gen = gen + 1;
|
gen = gen + 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user