Si encuentras alguna parte que no entiendes puedes dejarlo en los comentarios y haremos todo lo posible de ayudarte lo más rápido posible.
Solución:
- Con PyQGIS en la consola de Python, consulte Cómo agregar dirección y distancia a attribute ¿mesa? para los azimuts de los segmentos de una línea (con las funciones de azimut de Puntos: punto1.azimut (punto2))
- pero puede usar muchos otros módulos de Python como Shapely y Fiona sin usar QGIS ver Python: traitement des couches vectorielles dans une perspectiva géologique, lecture et enregistrement des couches sous forme de dictionnaires con el módulo Fiona (en francés)
from shapely.geometry import Point, LineString, mapping
import fiona
import math
def azimuth(point1, point2):
'''azimuth between 2 shapely points (interval 0 - 180°, for my work)'''
angle = math.atan2(point2.x - point1.x, point2.y - point1.y)
return math.degrees(angle)if angle>0 else math.degrees(angle) + 180
def pair(list):
'''Iterate over pairs in a list '''
for i in range(1, len(list)):
yield list[i-1], list[i]
with fiona.collection('testline.shp', 'r') as input:
# copy of the input schema'
schema = input.schema.copy()
# creation of a new field for storing azimuth
schema['properties']['azimuth'] = 'int'
# copy of the original shapefile with the field azimuth to a new shapefile
with fiona.collection('testline_azim.shp', 'w', 'ESRI Shapefile', schema) as output:
for line in input:
# use of pair function to extract the line segments
for seg_start, seg_end in pair(line['geometry']['coordinates']):
line_start = Point(seg_start)
line_end = Point(seg_end)
segment = LineString([line_start.coords[0],line_end.coords[0]])
elem =
elem['properties'] = line['properties']
elem['properties']['azimuth'] = azimuth(line_start, line_end)
elem['geometry'] = mapping(segment)
output.write(elem)
Resultado
imagen de PortailSIG
Con HIERBA:
- dividir la polilínea en segmentos individuales con v.split vértices = 1
- cargar el acimut de cada segmento en el attribute tabla con opción v.to.db = azimut
ver Ángulo entre segmentos de una polilínea o acimut de líneas con v.to.db?
Actualizar
en la consola Python de QGIS con solo PyQGIS
from PyQt4.QtCore import *
import math
def select_all(layer):
layer.select([])
layer.setSelectedFeatures([obj.id() for obj in layer])
# theoretical azimuth function but you can use `point1.azimuth(point2)`, look below
def azimut(point1, point2):
'''azimuth between 2 QGIS points ->must be adapted to 0-360°'''
angle = math.atan2(point2.x() - point1.x(), point2.y() - point1.y())
return math.degrees(angle)
def pair(list):
'''Iterate over pairs in a list '''
for i in range(1, len(list)):
yield list[i-1], list[i]
mylayer = qgis.utils.iface.activeLayer()
# select all the elements of the layer
select_all(mylayer)
# Memory layer
v_layer = QgsVectorLayer("LineString", "azimuth_lines", "memory")
pr = v_layer.dataProvider()
pr.addAttributes( [ QgsField("azimuth", QVariant.Int), QgsField("az_pt1pt2",QVariant.Int),QgsField("az_pt2-1",QVariant.Int)])
for elem in mylayer.selectedFeatures():
line = elem.geometry().asPolyline()
for seg_start, seg_end in pair(line):
line_start = QgsPoint(seg_start)
line_end = QgsPoint(seg_end)
seg = QgsFeature()
seg.addAttribute(0, QVariant(int(azimut(line_start,line_end))))
# with the functions of PyQGIS
seg.addAttribute(1, QVariant(int(line_start.azimuth(line_end))))
seg.addAttribute(2, QVariant(int(line_end.azimuth(line_start))))
seg.setGeometry(QgsGeometry.fromPolyline([line_start, line_end]))
pr.addFeatures( [ seg ] )
v_layer.updateExtents()
v_layer.updateFieldMap()
QgsMapLayerRegistry.instance().addMapLayers([v_layer])
Resultado
y 360-159 = 201-180 = 21
Para el registro: ahora puede hacer esto fácilmente con QGIS solo (desde versiones posteriores de QGIS): primero use la herramienta ‘explotar líneas’, produciendo todos los segmentos de línea, luego calcule el azimut con la calculadora de campo:
degrees(azimuth( start_point($geometry), end_point($geometry)) )
terminado..
Comentarios y puntuaciones
Recuerda que tienes concesión de añadir una tasación acertada si te fue útil.
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)