wip: intersect_patience
This commit is contained in:
parent
8094d21ded
commit
dd80541453
@ -589,7 +589,7 @@ table~\ref{table:scale-halfcirlce-diameter}.
|
|||||||
|
|
||||||
Sometimes, when working with {\WM}, it is useful to convert between
|
Sometimes, when working with {\WM}, it is useful to convert between
|
||||||
half-circle's diameter $D$ and adjusted size $A_{adj}$. These easily derive
|
half-circle's diameter $D$ and adjusted size $A_{adj}$. These easily derive
|
||||||
from circle's area formula $A = 2\pi r^2$. Diameter:
|
from circle's area formula $A = 2\pi \frac{D}{2}^2$:
|
||||||
|
|
||||||
\[
|
\[
|
||||||
D = 2\sqrt{\frac{2 A_{adj}}{\pi}}
|
D = 2\sqrt{\frac{2 A_{adj}}{\pi}}
|
||||||
@ -868,7 +868,7 @@ The smaller the distance $d$, the more similar the bends are.
|
|||||||
|
|
||||||
\subsection{Elimination Operator}
|
\subsection{Elimination Operator}
|
||||||
|
|
||||||
NOTE: not implemented.
|
NOTE: implemented, explain.
|
||||||
|
|
||||||
\subsection{Combination Operator}
|
\subsection{Combination Operator}
|
||||||
|
|
||||||
@ -876,7 +876,7 @@ NOTE: not implemented.
|
|||||||
|
|
||||||
\subsection{Exaggeration Operator}
|
\subsection{Exaggeration Operator}
|
||||||
|
|
||||||
NOTE: not implemented.
|
NOTE: implemented, explain. Also {\texttt intersection\_tolerance} parameter.
|
||||||
|
|
||||||
\section{Program Implementation}
|
\section{Program Implementation}
|
||||||
|
|
||||||
|
@ -109,4 +109,4 @@ end $$ language plpgsql;
|
|||||||
|
|
||||||
delete from wm_debug where name in (select distinct name from wm_rivers);
|
delete from wm_debug where name in (select distinct name from wm_rivers);
|
||||||
delete from wm_demo where name in (select distinct name from wm_rivers);
|
delete from wm_demo where name in (select distinct name from wm_rivers);
|
||||||
insert into wm_demo (name, way) select name, ST_SimplifyWM(way, 37.5, name) from wm_rivers;
|
insert into wm_demo (name, way) select name, ST_SimplifyWM(way, 37.5, null, name) from wm_rivers;
|
||||||
|
@ -56,8 +56,8 @@ insert into wm_figures (name, way) values ('isolated-2', 'LINESTRING(250 100,246
|
|||||||
|
|
||||||
delete from wm_debug where name in (select distinct name from wm_figures);
|
delete from wm_debug where name in (select distinct name from wm_figures);
|
||||||
delete from wm_demo where name in (select distinct name from wm_figures);
|
delete from wm_demo where name in (select distinct name from wm_figures);
|
||||||
insert into wm_demo (name, way) select name, ST_SimplifyWM(way, .1, name) from wm_figures where name not in ('fig8', 'isolated-1');
|
insert into wm_demo (name, way) select name, ST_SimplifyWM(way, .1, null, name) from wm_figures where name not in ('fig8', 'isolated-1');
|
||||||
insert into wm_demo (name, way) select name, ST_SimplifyWM(way, 14, name) from wm_figures where name in ('fig8', 'isolated-1', 'isolated-2');
|
insert into wm_demo (name, way) select name, ST_SimplifyWM(way, 14, null, name) from wm_figures where name in ('fig8', 'isolated-1', 'isolated-2');
|
||||||
|
|
||||||
drop function if exists wm_debug_get;
|
drop function if exists wm_debug_get;
|
||||||
create function wm_debug_get(
|
create function wm_debug_get(
|
||||||
|
59
IV/wm.sql
59
IV/wm.sql
@ -481,6 +481,7 @@ $$ language plpgsql;
|
|||||||
create function wm_exaggeration(
|
create function wm_exaggeration(
|
||||||
INOUT bendattrs wm_t_bend_attrs[],
|
INOUT bendattrs wm_t_bend_attrs[],
|
||||||
dhalfcircle float,
|
dhalfcircle float,
|
||||||
|
intersect_patience integer,
|
||||||
dbgname text default null,
|
dbgname text default null,
|
||||||
dbggen integer default null,
|
dbggen integer default null,
|
||||||
OUT mutated boolean
|
OUT mutated boolean
|
||||||
@ -489,19 +490,56 @@ declare
|
|||||||
desired_size constant float default pi()*(dhalfcircle^2)/8;
|
desired_size constant float default pi()*(dhalfcircle^2)/8;
|
||||||
tmpbendattr wm_t_bend_attrs;
|
tmpbendattr wm_t_bend_attrs;
|
||||||
i integer;
|
i integer;
|
||||||
|
n integer;
|
||||||
last_id integer;
|
last_id integer;
|
||||||
begin
|
begin
|
||||||
mutated = false;
|
mutated = false;
|
||||||
|
<<bendloop>>
|
||||||
for i in 1..array_length(bendattrs, 1) loop
|
for i in 1..array_length(bendattrs, 1) loop
|
||||||
if bendattrs[i].isolated and bendattrs[i].adjsize < desired_size then
|
if bendattrs[i].isolated and bendattrs[i].adjsize < desired_size then
|
||||||
mutated = true;
|
|
||||||
tmpbendattr.bend = wm_exaggerate_bend(
|
tmpbendattr.bend = wm_exaggerate_bend(
|
||||||
bendattrs[i].bend,
|
bendattrs[i].bend,
|
||||||
bendattrs[i].adjsize,
|
bendattrs[i].adjsize,
|
||||||
desired_size
|
desired_size
|
||||||
);
|
);
|
||||||
|
|
||||||
|
-- does tmpbendattrs.bend intersect with the previous or next
|
||||||
|
-- intersect_patience bends? If they do, abort exaggeration for this one.
|
||||||
|
|
||||||
bendattrs[i] = tmpbendattr;
|
bendattrs[i] = tmpbendattr;
|
||||||
|
|
||||||
|
-- Do close-by bends intersect with this one? Special
|
||||||
|
-- handling first, because 2 vertices need to be removed before checking.
|
||||||
|
n = st_npoints(bendattrs[i-1].bend);
|
||||||
|
if n > 3 then
|
||||||
|
continue when st_overlaps(tmpbendattr.bend,
|
||||||
|
st_removepoint(st_removepoint(bendattrs[i-1].bend, n-1), n-2));
|
||||||
|
end if;
|
||||||
|
|
||||||
|
n = st_npoints(bendattrs[i+1].bend);
|
||||||
|
if n > 3 then
|
||||||
|
continue when st_intersects(tmpbendattr.bend,
|
||||||
|
st_removepoint(st_removepoint(bendattrs[i+1].bend, 0), 0));
|
||||||
|
end if;
|
||||||
|
|
||||||
|
-- now loop over the next intersect_patience
|
||||||
|
for n in -intersect_patience+1..intersect_patience-1 loop
|
||||||
|
continue when n in (-1, 0, 1);
|
||||||
|
continue when i+n < 1;
|
||||||
|
continue when i+n > array_length(bendattrs, 1);
|
||||||
|
|
||||||
|
if st_overlaps(tmpbendattr.bend, bendattrs[i+n].bend) then
|
||||||
|
insert into wm_manual(name, way) values
|
||||||
|
('intersecter', tmpbendattr.bend),
|
||||||
|
('intersectee', bendattrs[i+n].bend);
|
||||||
|
raise notice '[%] % intersects with %', dbggen, i, i+n;
|
||||||
|
continue bendloop;
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
-- no intersections within intersect_patience. Mutate bend.
|
||||||
|
mutated = true;
|
||||||
|
|
||||||
-- 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
|
||||||
@ -690,6 +728,7 @@ drop function if exists ST_SimplifyWM;
|
|||||||
create function ST_SimplifyWM(
|
create function ST_SimplifyWM(
|
||||||
geom geometry,
|
geom geometry,
|
||||||
dhalfcircle float,
|
dhalfcircle float,
|
||||||
|
intersect_patience integer default 10,
|
||||||
dbgname text default null
|
dbgname text default null
|
||||||
) returns geometry as $$
|
) returns geometry as $$
|
||||||
declare
|
declare
|
||||||
@ -703,6 +742,9 @@ declare
|
|||||||
mutated boolean;
|
mutated boolean;
|
||||||
l_type text;
|
l_type text;
|
||||||
begin
|
begin
|
||||||
|
if intersect_patience is null then
|
||||||
|
intersect_patience = 10;
|
||||||
|
end if;
|
||||||
l_type = st_geometrytype(geom);
|
l_type = st_geometrytype(geom);
|
||||||
if l_type = 'ST_LineString' then
|
if l_type = 'ST_LineString' then
|
||||||
lines = array[geom];
|
lines = array[geom];
|
||||||
@ -736,7 +778,8 @@ begin
|
|||||||
bendattrs = wm_isolated_bends(bendattrs, dbgname, gen);
|
bendattrs = wm_isolated_bends(bendattrs, dbgname, gen);
|
||||||
|
|
||||||
select * from wm_exaggeration(
|
select * from wm_exaggeration(
|
||||||
bendattrs, dhalfcircle, dbgname, gen) into bendattrs, mutated;
|
bendattrs, dhalfcircle, intersect_patience, dbgname, gen
|
||||||
|
) into bendattrs, mutated;
|
||||||
|
|
||||||
-- TODO: wm_combination
|
-- TODO: wm_combination
|
||||||
|
|
||||||
@ -750,6 +793,18 @@ begin
|
|||||||
bends[j] = bendattrs[j].bend;
|
bends[j] = bendattrs[j].bend;
|
||||||
end loop;
|
end loop;
|
||||||
lines[i] = st_linemerge(st_union(bends));
|
lines[i] = st_linemerge(st_union(bends));
|
||||||
|
if st_geometrytype(lines[i]) != 'ST_LineString' then
|
||||||
|
raise 'Got % instead of ST_LineString. '
|
||||||
|
'Does the exaggerated bend intersect? '
|
||||||
|
'If so, try increasing intersect_patience.',
|
||||||
|
st_geometrytype(lines[i]);
|
||||||
|
|
||||||
|
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;
|
||||||
|
end if;
|
||||||
gen = gen + 1;
|
gen = gen + 1;
|
||||||
continue;
|
continue;
|
||||||
end if;
|
end if;
|
||||||
|
Loading…
Reference in New Issue
Block a user