move section of self_crossing to a separate function
This commit is contained in:
parent
fd1250a73b
commit
5491f574e6
65
wm.sql
65
wm.sql
@ -209,6 +209,34 @@ begin
|
|||||||
end
|
end
|
||||||
$$ language plpgsql;
|
$$ language plpgsql;
|
||||||
|
|
||||||
|
drop function if exists if_selfcross;
|
||||||
|
create function if_selfcross(
|
||||||
|
bendi geometry,
|
||||||
|
bendj geometry
|
||||||
|
) returns geometry as $$
|
||||||
|
declare
|
||||||
|
a geometry;
|
||||||
|
b geometry;
|
||||||
|
partitions geometry;
|
||||||
|
begin
|
||||||
|
a = st_pointn(bendi, 1);
|
||||||
|
b = st_pointn(bendi, -1);
|
||||||
|
partitions = st_split(bendj, st_makeline(a, b));
|
||||||
|
|
||||||
|
if st_numgeometries(partitions) = 1 then
|
||||||
|
return null;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
if st_numgeometries(partitions) = 2 and
|
||||||
|
(st_contains(bendj, a) or st_contains(bendj, b)) then
|
||||||
|
return null;
|
||||||
|
end if;
|
||||||
|
|
||||||
|
return partitions;
|
||||||
|
end
|
||||||
|
$$ language plpgsql;
|
||||||
|
|
||||||
|
|
||||||
-- self_crossing eliminates self-crossing from the bends, following the
|
-- 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".
|
||||||
drop function if exists self_crossing;
|
drop function if exists self_crossing;
|
||||||
@ -220,7 +248,6 @@ declare
|
|||||||
pi constant real default radians(180);
|
pi constant real default radians(180);
|
||||||
i int4;
|
i int4;
|
||||||
j int4;
|
j int4;
|
||||||
prev_length int4;
|
|
||||||
a geometry;
|
a geometry;
|
||||||
b geometry;
|
b geometry;
|
||||||
multi geometry;
|
multi geometry;
|
||||||
@ -234,25 +261,18 @@ begin
|
|||||||
-- self-crossing. now try to find another bend in this line that
|
-- self-crossing. now try to find another bend in this line that
|
||||||
-- crosses an imaginary line of end-vertices
|
-- crosses an imaginary line of end-vertices
|
||||||
|
|
||||||
|
-- To understand the block below, I suggest you take a pencil and paper,
|
||||||
|
-- draw a self-crossing bend (fig6 from the article works well), and
|
||||||
|
-- figure out what happens here, by hand. I know it's hard to follow.
|
||||||
|
-- Apologies.
|
||||||
|
|
||||||
-- go through each bend in the given line, and see if has a potential to
|
-- go through each bend in the given line, and see if has a potential to
|
||||||
-- cross bends[i].
|
-- cross bends[i].
|
||||||
for j in 1..i-1 loop
|
for j in 1..i-1 loop
|
||||||
a = st_pointn(bends[i], 1);
|
select if_selfcross(bends[i], bends[j]) into multi;
|
||||||
b = st_pointn(bends[i], -1);
|
continue when multi is null;
|
||||||
multi = st_split(bends[j], st_makeline(a, b));
|
|
||||||
continue when st_numgeometries(multi) = 1;
|
|
||||||
continue when st_numgeometries(multi) = 2 and
|
|
||||||
(st_contains(bends[j], a) or st_contains(bends[j], b));
|
|
||||||
|
|
||||||
-- vertices, segments and stars are aligned, we are changing the bend
|
|
||||||
mutated = true;
|
mutated = true;
|
||||||
|
|
||||||
-- To understand the block below, I suggest you take a pencil and paper,
|
|
||||||
-- draw a self-crossing bend (fig6 from the article works well), and
|
|
||||||
-- figure out what happens here, by hand. I know it's hard to follow.
|
|
||||||
-- Apologies.
|
|
||||||
prev_length = array_length(bends, 1);
|
|
||||||
|
|
||||||
-- remove first vertex of the following bend, because the last
|
-- remove first vertex of the following bend, because the last
|
||||||
-- segment is always duplicated with the i'th bend.
|
-- segment is always duplicated with the i'th bend.
|
||||||
bends[i+1] = st_removepoint(bends[i+1], 0);
|
bends[i+1] = st_removepoint(bends[i+1], 0);
|
||||||
@ -262,26 +282,19 @@ begin
|
|||||||
st_npoints(bends[j])-1,
|
st_npoints(bends[j])-1,
|
||||||
st_pointn(bends[i], st_npoints(bends[i]))
|
st_pointn(bends[i], st_npoints(bends[i]))
|
||||||
);
|
);
|
||||||
bends = bends[1:j] || bends[i+1:prev_length];
|
bends = bends[1:j] || bends[i+1:];
|
||||||
exit;
|
exit;
|
||||||
end loop;
|
end loop;
|
||||||
|
|
||||||
for j in reverse array_length(bends, 1)..i+1 loop
|
for j in reverse array_length(bends, 1)..i+1 loop
|
||||||
a = st_pointn(bends[i], 1);
|
select if_selfcross(bends[i], bends[j]) into multi;
|
||||||
b = st_pointn(bends[i], -1);
|
continue when multi is null;
|
||||||
multi = st_split(bends[j], st_makeline(a, b));
|
|
||||||
continue when st_numgeometries(multi) = 1;
|
|
||||||
continue when st_numgeometries(multi) = 2 and
|
|
||||||
(st_contains(bends[j], a) or st_contains(bends[j], b));
|
|
||||||
|
|
||||||
-- vertices, segments and stars are aligned, we are changing the bend
|
|
||||||
mutated = true;
|
mutated = true;
|
||||||
|
|
||||||
-- To understand the block below, I suggest you take a pencil and paper,
|
-- To understand the block below, I suggest you take a pencil and paper,
|
||||||
-- draw a self-crossing bend (fig6 from the article works well), and
|
-- draw a self-crossing bend (fig6 from the article works well), and
|
||||||
-- figure out what happens here, by hand. I know it's hard to follow.
|
-- figure out what happens here, by hand. I know it's hard to follow.
|
||||||
-- Apologies.
|
-- Apologies.
|
||||||
prev_length = array_length(bends, 1);
|
|
||||||
-- remove last vertex of the previous bend, because the last
|
-- remove last vertex of the previous bend, because the last
|
||||||
-- segment is duplicated with the i'th bend.
|
-- segment is duplicated with the i'th bend.
|
||||||
bends[i-1] = st_removepoint(bends[i-1], st_npoints(bends[i-1])-1);
|
bends[i-1] = st_removepoint(bends[i-1], st_npoints(bends[i-1])-1);
|
||||||
@ -290,7 +303,7 @@ begin
|
|||||||
st_pointn(bends[i], 1),
|
st_pointn(bends[i], 1),
|
||||||
st_removepoint(st_geometryn(multi, st_numgeometries(multi)), 0)
|
st_removepoint(st_geometryn(multi, st_numgeometries(multi)), 0)
|
||||||
);
|
);
|
||||||
bends = bends[1:i] || bends[j+1:prev_length];
|
bends = bends[1:i] || bends[j+1:];
|
||||||
exit;
|
exit;
|
||||||
end loop;
|
end loop;
|
||||||
end loop;
|
end loop;
|
||||||
|
Loading…
Reference in New Issue
Block a user