Accrocher la couche de ligne au réseau dans QGIS ou PostGIS

11

J'ai des données GPS que j'ai prises sur les itinéraires de bus, et maintenant je voudrais les accrocher à mon réseau routier. Les deux couches sont des couches de lignes dans une base de données PostGIS. J'aimerais utiliser QGIS ou PostGIS, mais si je dois utiliser GRASS ou ArcMap, ça va aussi. Merci!

Pour clarifier, j'essaie d'aligner des lignes sur des lignes, pas des points sur des lignes.

mattwigway
la source

Réponses:

3

J'avais l'habitude d'avoir cette fonction que j'utilisais. Attention, cela change la géométrie de la table de points existante. Je ne l'ai pas utilisé depuis longtemps, mais il semble que cela devrait faire l'affaire. Pour autant que je m'en souvienne, cela fonctionne bien si vous avez des index spatiaux sur les deux tables. Pour l'appeler

SELECT snap_point_to_line ('points_table', 'line_table', 500). Il se cassera avec une tolérance de 500, 500 étant l'unité de votre système de projection. Je travaillais avec Lambert.

    CREATE OR REPLACE FUNCTION snap_point_to_line(points_table character varying, line_table character varying, tolerance double precision)
      RETURNS boolean AS
    $BODY$
    DECLARE         
            srid integer;
            i integer;

            row record;
            row_1 record;
            closest_distance double precision;

            query varchar;
            snapped_point geometry;
    BEGIN

      --Get the srid of the points table
        FOR row IN EXECUTE 'select getsrid(the_geom) as srid from '||points_table||' where gid = (select min(gid) from '||points_table||')' LOOP
        END LOOP;
        srid := row.srid;


     -- Add a column in which it will store the closest nodes from the line
     FOR row IN EXECUTE 'SELECT the_geom FROM '||points_table LOOP

        query := 'SELECT ST_Transform(the_geom,'||srid||') as the_geom, ST_Distance(GeometryFromText('''||ST_AsText(row.the_geom)||''','||srid||'), ST_Transform(the_geom,'||srid||')) as distance FROM ' ||line_table||' ORDER BY ST_Distance(GeometryFromText('''||ST_AsText(row.the_geom)||''','||srid||'), ST_Transform(the_geom,'||srid||'))  LIMIT 1';
        RAISE NOTICE '%',query; 
        FOR row_1 IN EXECUTE query LOOP
            closest_distance := row_1.distance;

            --If below the distance threeshold, then snap the point
            IF closest_distance < tolerance THEN
                snapped_point := ST_line_interpolate_point(ST_LineMerge(row_1.the_geom),ST_line_locate_point(ST_LineMerge(row_1.the_geom), row.the_geom));

                --UPDATE the_geometry
                EXECUTE 'UPDATE '||points_table||' SET the_geom = GeometryFromText('''||ST_AsText(snapped_point)||''','||srid||') WHERE ST_AsText(the_geom) = '''||ST_AsText(row.the_geom)||'''';

            END IF;
END LOOP;   
    END LOOP;
    RETURN true;
    END;
   $BODY$
    LANGUAGE 'plpgsql' VOLATILE STRICT
    COST 100;
    ALTER FUNCTION snap_point_to_line(character varying, character varying, double precision) OWNER TO yourowner;
Fabien Ancelin
la source
Merci; existe-t-il un moyen de faire ce snap lignes en lignes? Je ne pense pas que les fonctions de référencement linéaire fonctionneront. (J'ai ajouté une clarification à la question d'origine).
mattwigway