5 votos

Automáticamente puntos de ajuste a la línea termina en dos capas separadas?

He interestatales de los estados unidos rampa final de ubicación de puntos de datos que necesito para que coincida con la red de carreteras de datos. Todos los puntos están fuera por un par de metros de ellos fueron recogidos en el campo. Tengo la esperanza de que hay una manera de hacer coincidir automáticamente/snap todos los puntos a los nodos finales de las rampas si dentro de los 20 metros. Yo no puedo hacerlo manualmente, ya que hay más de 30.000 puntos. La red de carreteras y la rampa de puntos son diferentes capas.

EDITAR

Las líneas azules son las de on/off de acceso y salida de una carretera interestatal. Los puntos rojos son el campo de la recogida de la ubicación de la final de la rampa de despegue. Necesito los puntos rojos para auto complemento a la final de la rampa de despegue.

Después de pensar en esto, y la meta de todo lo que realmente necesita es los puntos de inicio y final de cada rampa y una forma de diferenciar entre ellos. Voy a preguntar en una cuestión diferente. Sin embargo, para mayor claridad pensé que iba a publicar lo que originalmente se solicita.

No he encontrado ninguna información sobre cómo se ajustan de forma automática los puntos a la línea termina en forma masiva. Nada de lo que me he encontrado con que fue similar no traducir.

enter image description here enter image description here

3voto

Geoffrey Puntos 228

Usted puede ejecutar el código siguiente desde la Consola de Python:

searching_dist = 20 # Set it as you want

lines = QgsMapLayerRegistry.instance().mapLayersByName('line')[0] # Replace 'line' with the name of the line layer
points = QgsMapLayerRegistry.instance().mapLayersByName('points')[0] # Replace 'points' with the name of the point layer

cr = points.crs()
dist_calc = QgsDistanceArea()
dist_calc.setSourceCrs(cr)
dist_calc.setEllipsoid(cr.ellipsoidAcronym())
dist_calc.setEllipsoidalMode(cr.geographicFlag())

# This layer contains all the points created along the line (it isn't an output)
crs = points.crs().toWkt()
temp_pts = QgsVectorLayer('Point?crs='+ crs, 'temp_pts' , 'memory')
prov = temp_pts.dataProvider()

tmp_points = {}
index = QgsSpatialIndex()
for line in lines.getFeatures():
    line_geom = line.geometry()
    (first_line_point, end_line_point) = (line_geom.interpolate(0).asPoint(), line_geom.interpolate(line.geometry().length()).asPoint())
    pt1 = QgsFeature()
    pt1.setGeometry(QgsGeometry.fromPoint(first_line_point))
    (result, feat) = prov.addFeatures([pt1])
    tmp_points[feat[0].id()] = feat[0]
    index.insertFeature(feat[0])
    pt2 = QgsFeature()
    pt2.setGeometry(QgsGeometry.fromPoint(end_line_point))
    (result, feat) = prov.addFeatures([pt2])
    tmp_points[feat[0].id()] = feat[0]
    index.insertFeature(feat[0])

for point in points.getFeatures():
    geom = point.geometry()
    nearest = index.nearestNeighbor(geom.asPoint(), 1)
    tmp_pt_geom = tmp_points[nearest[0]].geometry()
    dist = dist_calc.measureLine(geom.asPoint(), tmp_pt_geom.asPoint())
    if dist <= searching_dist:
        points.dataProvider().changeGeometryValues({point.id(): tmp_pt_geom})
points.triggerRepaint()

Para que funcione, sólo necesita preliminar de la carga del punto y de la línea de las capas en el Panel Capas y, a continuación, escriba sus nombres en caso necesario (he dejado un comentario en el código anterior). Además, es necesario especificar una búsqueda de distancia (yo usé 20 m, establecido como quieras).

Finalmente, el código anterior editar directamente las geometrías dentro de la capa de puntos, así que recuerde de crear una copia de seguridad de sus datos antes de intentarlo.

Como un ejemplo, a partir de esta situación:

enter image description here

usted recibirá este resultado:

enter image description here

y, el zoom más sobre ella (como lo hizo en su pregunta original):

enter image description here

EDITAR

Si desea ajustar los puntos por considerar el final de la línea de nodos, se puede utilizar esta ligeramente editado código:

searching_dist = 20 # Set it as you want

lines = QgsMapLayerRegistry.instance().mapLayersByName('line')[0] # Replace 'line' with the name of the line layer
points = QgsMapLayerRegistry.instance().mapLayersByName('points')[0] # Replace 'points' with the name of the point layer

cr = points.crs()
dist_calc = QgsDistanceArea()
dist_calc.setSourceCrs(cr)
dist_calc.setEllipsoid(cr.ellipsoidAcronym())
dist_calc.setEllipsoidalMode(cr.geographicFlag())

# This layer contains all the points created along the line (it isn't an output)
crs = points.crs().toWkt()
temp_pts = QgsVectorLayer('Point?crs='+ crs, 'temp_pts' , 'memory')
prov = temp_pts.dataProvider()

tmp_points = {}
index = QgsSpatialIndex()
for line in lines.getFeatures():
    line_geom = line.geometry()
    end_line_point = line_geom.interpolate(line.geometry().length()).asPoint()
    pt1 = QgsFeature()
    pt1.setGeometry(QgsGeometry.fromPoint(end_line_point))
    (result, feat) = prov.addFeatures([pt1])
    tmp_points[feat[0].id()] = feat[0]
    index.insertFeature(feat[0])

for point in points.getFeatures():
    geom = point.geometry()
    nearest = index.nearestNeighbor(geom.asPoint(), 1)
    tmp_pt_geom = tmp_points[nearest[0]].geometry()
    dist = dist_calc.measureLine(geom.asPoint(), tmp_pt_geom.asPoint())
    if dist <= searching_dist:
        points.dataProvider().changeGeometryValues({point.id(): tmp_pt_geom})
points.triggerRepaint()

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