ciao Andrea,
> Two things.
>
> One is a question. With ST_Snap() we have three new vertices
> inserted into the Linestring that exactly match each Point. Is this
> required to use ST_Split, or I can use it also when my points simply
> are snappep properly along a line segment?
>
interpolating more "snapping point(s)" it's not a strict requirement
for ST_Split(); anyway it could become a practical requirement in
many real world cases.
the real problem is that ST_Split() requires a strict intersection
between the linestring (input) and the point (blade), and due to
the finite precision of DOUBLE this could easily become a painful
nightmare.
if the linestring is exactly horizontal or vertical this is an
absolutely trivial condition, and we can expect the same for few
others "simple" slope values (e.g. 45, 30 or 60 degrees); but
assuming an arbitrary slope you can easily encounter many failures.
just as a recall and to clarify better the general terms of the
question: you can amuse yourself by testing various intersections
between two straight segments, then checking if the intersection
point do really intersects both lines. something like this:
CREATE TABLE segm1 (id INTEGER);
SELECT AddGeometryColumn('segm1', 'geom', -1, 'LINESTRING', 'XY');
INSERT INTO segm1 VALUES (1,
ST_GeomFromText('LINESTRING(0 0, 100 100)', -1));
INSERT INTO segm1 VALUES (2,
ST_GeomFromText('LINESTRING(0.0001 0, 100 100)', -1));
INSERT INTO segm1 VALUES (3,
ST_GeomFromText('LINESTRING(0 0.0000001, 100 100)', -1));
INSERT INTO segm1 VALUES (4,
ST_GeomFromText('LINESTRING(0 0, 99.99999999 100)', -1));
INSERT INTO segm1 VALUES (5,
ST_GeomFromText('LINESTRING(0 0, 100 99.99999999999)', -1));
CREATE TABLE segm2 (id INTEGER);
SELECT AddGeometryColumn('segm2', 'geom', -1, 'LINESTRING', 'XY');
INSERT INTO segm2 VALUES (1,
ST_GeomFromText('LINESTRING(100 0, 0 100)', -1));
INSERT INTO segm2 VALUES (2,
ST_GeomFromText('LINESTRING(100 0.0001, 0 100)', -1));
INSERT INTO segm2 VALUES (3,
ST_GeomFromText('LINESTRING(100.0000001 0, 0 100)', -1));
INSERT INTO segm2 VALUES (4,
ST_GeomFromText('LINESTRING(100 0, 0.00000001 100)', -1));
INSERT INTO segm2 VALUES (5,
ST_GeomFromText('LINESTRING(100 0, 0 99.99999999999)', -1));
SELECT id_a, id_b, ST_AsText(pt) AS point,
ST_Intersects(ln_a, pt) AS ok_line1,
ST_Intersects(ln_b, pt) AS ok_line2
FROM (SELECT
l1.id AS id_a,
l2.id AS id_b,
ST_Intersection(l1.geom, l2.geom) AS pt,
l1.geom AS ln_a, l2.geom AS ln_b
FROM segm1 AS l1, segm2 AS l2);
as you can easily check by yourself, an apparently valid intersection
point is always returned; but not always such point do really
intersects both segments.
there is no "black magic" in all this; it simply is what you can
expect from using arithmetic computations based on finite precision
DOUBLE. there is no way to circvumvent such issues.
> Another one is a perspective, and in particular that one of a
> software
> final user. I have made my "snapping by hand" using QGIS 2.6. Now I
> have discovered that the snap to line does not work and it's in some
> way only a visual snapping. Am I wrong?
> I know that everything we made with GIS tools has a degree of
> approximation,
>
you have not to specifically blame GIS tools; this is a general
issue affecting any scientific/mathematical sw based on DOUBLE
(floating point numbers).
you always have to carefully consider that after all you are
usning finite precision computations, and you have to safely
shield your code (and data) against the many hidden pitfalls
you can easily encounter.
> but if I use a snap tool, often it will be useful to me
> to make some network analysis.
>
this is a typical topology task: and producing sane and sound
topology data surely isn't a trivial task.
some kind of appropriate "preliminary preparation/validation"
is often required, and using ST_Snap() if frequently required
so to create robust and affordable snap-points not subject to
the fancy amenities of finite arithmetics.
baciamo le mani a Voscenza,
Sandro