beginnings of self-crossing
This commit is contained in:
parent
ec4b84b36f
commit
5e47e90370
13
notes.txt
13
notes.txt
@ -27,13 +27,12 @@ after a few bends have been skipped. E.g. ends of A<->B cross the line, but
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
If a bend with 180+ deg inflection is found, its line between inflection angles
|
If a bend with 180+ deg sum of inflection angles is found, its line between
|
||||||
(AB in our examples) must be crossed with all the other bends to detect a
|
inflection angles (AB in our examples) must be crossed with all the other bends
|
||||||
possible line-crossing. This is O(N*M), where N is the total number of line
|
to detect a possible line-crossing. This is O(N*M), where N is the total number
|
||||||
segments, and M is the number of qualifying bends. In other words, can be very
|
of line segments, and M is the number of qualifying bends. It is expensive.
|
||||||
computationally expensive.
|
|
||||||
|
|
||||||
This may be simplified: if other bend's endpoints (A' and B') are in the same
|
This may be simplified: if other bend's endpoints (A' and B') are in the same
|
||||||
sub-plane as divided by AB, then the bend can be skipped from checking if it
|
sub-plane as divided by AB, then the bend can be skipped from checking if it
|
||||||
intersects with AB. Some intersections may be missed (see the example), but
|
intersects with AB. Some intersections may be missed (see the last example),
|
||||||
they will be eliminated by just joining A and B.
|
but they will be eliminated by joining A and B anyway.
|
||||||
|
@ -47,7 +47,7 @@ drop table if exists inflections, demo_inflections;
|
|||||||
create table inflections (name text, ways geometry[]);
|
create table inflections (name text, ways geometry[]);
|
||||||
insert into inflections select name, fix_gentle_inflections(ways) from bends;
|
insert into inflections select name, fix_gentle_inflections(ways) from bends;
|
||||||
create table demo_inflections (name text, i bigint, way geometry);
|
create table demo_inflections (name text, i bigint, way geometry);
|
||||||
insert into demo_inflections select a.name, generate_subscripts(a.ways, 1), unnest(a.ways) from inflections a;
|
insert into demo_inflections select name, generate_subscripts(ways, 1), unnest(ways) from inflections;
|
||||||
|
|
||||||
do $$
|
do $$
|
||||||
declare
|
declare
|
||||||
@ -67,3 +67,10 @@ begin
|
|||||||
perform assert_equals('LINESTRING(114 20,133 20,145 15,145 0,136 5,123 7,114 7)', st_astext(vinflections[2]));
|
perform assert_equals('LINESTRING(114 20,133 20,145 15,145 0,136 5,123 7,114 7)', st_astext(vinflections[2]));
|
||||||
perform assert_equals('LINESTRING(123 7,114 7,111 2)', st_astext(vinflections[3]));
|
perform assert_equals('LINESTRING(123 7,114 7,111 2)', st_astext(vinflections[3]));
|
||||||
end $$ language plpgsql;
|
end $$ language plpgsql;
|
||||||
|
|
||||||
|
-- SELF-LINE CROSSING
|
||||||
|
drop table if exists selfcrossing, demo_selfcrossing;
|
||||||
|
create table selfcrossing (name text, ways geometry[]);
|
||||||
|
insert into selfcrossing select name, self_crossing(ways) from inflections;
|
||||||
|
create table demo_selfcrossing (name text, i bigint, way geometry);
|
||||||
|
insert into demo_selfcrossing select name, generate_subscripts(ways, 1), unnest(ways) from selfcrossing;
|
||||||
|
26
wm.sql
26
wm.sql
@ -170,9 +170,35 @@ $$ language plpgsql;
|
|||||||
create or replace function self_crossing(INOUT bends geometry[]) as $$
|
create or replace function self_crossing(INOUT bends geometry[]) as $$
|
||||||
declare
|
declare
|
||||||
pi real;
|
pi real;
|
||||||
|
angle real;
|
||||||
|
p geometry;
|
||||||
|
p1 geometry;
|
||||||
|
p2 geometry;
|
||||||
|
p3 geometry;
|
||||||
|
bend geometry;
|
||||||
begin
|
begin
|
||||||
|
pi = radians(180);
|
||||||
|
|
||||||
|
-- go through the bends and find one where sum of inflection angle is >180
|
||||||
|
foreach bend in array bends loop
|
||||||
|
angle = 0;
|
||||||
|
p3 = null;
|
||||||
|
p2 = null;
|
||||||
|
p1 = null;
|
||||||
|
for p in (select geom from st_dumppoints(bend) order by path[1] asc) loop
|
||||||
|
p3 = p2;
|
||||||
|
p2 = p1;
|
||||||
|
p1 = p;
|
||||||
|
if p3 is null then
|
||||||
|
continue;
|
||||||
|
end if;
|
||||||
|
angle = angle + abs(pi - st_angle(p1, p2, p3));
|
||||||
|
end loop;
|
||||||
|
|
||||||
|
if abs(angle) > pi then
|
||||||
|
raise notice 'maybe self-crossing bend %: %', st_astext(bend), round(degrees(abs(angle)));
|
||||||
|
end if;
|
||||||
|
end loop;
|
||||||
|
|
||||||
end
|
end
|
||||||
$$ language plpgsql;
|
$$ language plpgsql;
|
||||||
|
Loading…
Reference in New Issue
Block a user