1 votos

Recorte de archivos shapefiles vectoriales de forma más eficiente utilizando QGIS?

Tengo un shapefile de río, obtenido del módulo r.watershed, y tiene el siguiente aspecto

enter image description here

Tengo ocho puntos en el río que quiero analizar, y sólo quiero estos segmentos del río (la segunda foto de abajo es el río que quiero)

enter image description here

enter image description here

Así que abro su tabla de atributos para eliminar los segmentos que no quiero, pero creo que no es eficiente.

He probado la herramienta de intersección en las herramientas de geoprocesamiento, pero los resultados no son los deseados.

¿Existe una forma más eficiente de lograr este objetivo?

3voto

Alan Carr Puntos 786

Seleccione las características que están dentro de una distancia de los puntos en lugar de intersecarse (ya que no todas se intersecarán directamente). No estoy seguro de la escala de sus archivos, así que intente dentro de los 10m al principio y si eso no funciona pruebe con una cantidad mayor. A continuación, voltear la selección y eliminar los elementos.

3voto

huckfinn Puntos 698

Si puedes usar Postgresql/PostGIS tengo este fragmento de código para ti. Puede que te sirva de ayuda. La estrategia consiste en calcular la distancia entre cada vértice del río y el punto de la estación (lista de adyacencia) y seleccionar los dos más cercanos para construir el segmento correspondiente. Creo que una transcripción en Python será fácil.

Preparación del conjunto de datos del río:

    -- create a river table 
    CREATE TABLE river (id SERIAL);

    -- add a PostGIS LINESTRING column
    SELECT addGeometryColumn('public','river','geom',4326,'LINESTRING',2);

    -- bring in a river ...
    INSERT INTO  river(geom) 
    VALUES (ST_GeometryFromText(
    'LINESTRING(
      13.6938847 53.8612068,
      13.6974361 53.8628047,
      13.7013093 53.8634454,
      13.7038579 53.8632003,
      13.7058647 53.8627565,
      13.7085524 53.8616235,
      13.7102725 53.8610502,
      13.7127681 53.8602984,
      13.7166154 53.8596167,
      13.7185271 53.8596682,
      13.7216061 53.8607707)',
      4326));

Preparación del conjunto de datos de la estación:

    -- create a table for the river_stations
    CREATE TABLE river_station (id SERIAL);

    -- add a PostGIS POINT column
    SELECT addGeometryColumn('public','river_station','geom',4326,'POINT',2);

    -- Set some pointes near the river 
    INSERT INTO river_station(geom) VALUES
    (ST_GeometryFromText('POINT(13.70 53.85)',4326)),
    (ST_GeometryFromText('POINT(13.71 53.86)',4326));

La función que ayudará a encontrar el segmento.

    -- Function to find the neares segment of a STATION type POINT 
    -- to a LINESTRING hold in table river 
    -- as gives you the corresponding WKT LINESTRING
    CREATE OR REPLACE FUNCTION nearest_segment (GEOMETRY)
    RETURNS TEXT AS $$
    DECLARE result   TEXT;
       pos      INTEGER;
       rec      RECORD;
       station  GEOMETRY;
       river_id INTEGER;
       posX     TEXT;
       posY     TEXT;
    BEGIN

     -- Station Geometry parameter 
     station  := $1;

     -- Flag for adding the comma in WKT
     pos := 0;

     -- LINSTRING prefix in result
     result ='LINESTRING(';   

     -- Find the two closest points of the river goemetry to the station
     FOR rec IN SELECT
      (ST_DumpPoints(geom)).geom as point,
       st_distance((ST_DumpPoints(geom)).geom, station) as distance
     FROM river 
     -- WHERE id = $2 if you want to a special select a river object 
     ORDER BY distance ASCI LIMIT 2 

     LOOP 

      -- FLOAT8 to TEXT conversation of the segement part
        posX := st_X(rec.point)::TEXT; 
        posY := st_Y(rec.point)::TEXT;

     -- BUILD the WKT STRING 
        IF pos = 0 THEN
          result := result||posX||' '||posY;
        ELSE 
          result := result||', '||posX||' '||posY;
        END IF;   

       -- set mark to use commas before
         pos := pos + 1;
      END LOOP;

    -- give back the WKT String, as an alternative a geometry
     RETURN result||')';
   END;
   $$  LANGUAGE plpgsql;

Consultar los segmentos:

   -- Find the segments for the river 
   SELECT 
     st_astext(geom) as station, 
     nearest_segment(geom) as segment
    FROM
      river_station;

El resultado:

           station      |                      segment                       
   --------------------+----------------------------------------------------------
     POINT(13.7 53.85)  | LINESTRING(13.6938847 53.8612068, 13.6974361 53.8628047)
     POINT(13.71 53.86) | LINESTRING(13.7102725 53.8610502, 13.7085524 53.8616235)

Puede haber problemas, si dos segmentos de ríos diferentes están muy cerca de la estación. Entonces necesitará un parámetro (un river_id en el conjunto de estaciones) para resolver la situación ambigua.

Para añadir los ID's de las river_stations se pueden utilizar sentencias SQL:

Prepara la mesa para colocar los segmentos:

     CREATE TABLE river_segments (id SERIAL, ref_station INTEGER);
     SELECT addGeometryColumn('public','river_segments','geom',4326,'LINESTRING',2);

Introduzca los conjuntos de datos:

     INSERT INTO river_segments (ref_station, geom)
        SELECT 
          id as ref_station, 
          ST_GeometryFromText(nearest_segment(geom),4326) AS geom 
     FROM river_station;

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X