如何在属性表中添加方向和距离?


18

任何可以提供帮助的人。我只想在多义线/线数据中添加方向(轴承:即N 25 35 E)和距离(长度:125米)作为我的新字段。是否有插件来生成这些字段?我试图在行数据中使用“导出/添加几何列”,但仅添加了“长度”值。


到目前为止,我可以使用mmqgis插件给我距离。我正在探索方向问题。
Willy 2012年

1
您的折线数据是什么样的?距离相对容易计算-但是,“轴承”可能会在多段线的长度上发生变化。您是否正在寻找从起点终点的方位?
Simbamangu 2012年

是的,即时通讯正在寻找从起点到终点的方位...谢谢
arzandia'4

1
您是要从起点到终点的直线距离,还是沿着直线路径的直线长度?如果线段具有中间曲线或其他方向变化,则这些变化可能很大。
RyanKDalton-OffTheGridMaps 2012年

Answers:


42

您可以在QGIS的字段计算器中计算方位角。这适用于小距离(几百公里)内的UTM(公制)坐标,但是对于大距离或十进制度数,则需要更复杂的方法。

打开您的线图层的属性表,切换编辑,然后单击“字段计算器”按钮以打开对话框:

在此处输入图片说明

以1或2的精度创建一个新的字段作为十进制。

将此代码粘贴到“表达式”框中,然后单击“确定”: (atan((xat(-1)-xat(0))/(yat(-1)-yat(0)))) * 180/3.14159 + (180 *(((yat(-1)-yat(0)) < 0) + (((xat(-1)-xat(0)) < 0 AND (yat(-1) - yat(0)) >0)*2)))

第一部分计算x和y差的反正切,并将其转换为度数(180 / pi)。第二部分将180或360添加到所得图形中,以提供0-360°的方位角。


2
一个最优雅的解决方案,谢谢。我提到过,如果您需要确定折线的每个线段的方位,可以通过使用“分割要素”插件分割线shapefile来实现。然后加载新的(拆分)shapefile,并按照上述步骤操作。
nhopton'4

1
@arzandia-请注意,由于xat()和yat()函数在您正在使用的1.7中不起作用,因此您必须使用QGIS 1.9(有关beta下载,请参见主页)!
Simbamangu '04年

我已经使用了您提到的插件。如您所见,该图层的名称为“
splitted

1
要回答我自己的问题,“是的,您可以为yat(0)/ yat(-1)和xat(0)/ xat(-1)插入字段值。”
cbunn

1
对我来说,我必须对脚本进行一些更改才能使其正常工作:(atan((xat(0)-xat(1))/(yat(0)-yat(1))))* 180 / 3.14159 + (180 *(((yat(0)-yat(1))<0)+((((xat(0)-xat(1))<0 AND(yat(0)-yat(1))> 0) * 2)))
oskarlin'2

21

您不需要插件。一切都在PyQGIS的QgsPoint类中

如果使用Python控制台中的Python内置函数dir()检查QGIS点类的内容。

dir(point])
['__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__'
, '__getitem__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__module__', 
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', 
'__str__', '__subclasshook__', '__weakref__', 'azimuth', 
'multiply', 'set', 'setX', 'setY', 'sqrDist', 'sqrDistToSegment', 'toDegreesMinutesSeconds', 'toString', 'wellKnownText', 'x', 'y']

您可以看到有方位角sqrDist函数,并且经过几次尝试:

- xy[0].azimuth(xy[1]) or xy[1].azimuth(xy[0]) gives the azimuth direction between two points(in degrees, +/- 180°)
- xy[0].sqrDist(xy[1]) give the square distance between two points (in the unit of the project)

问题 在此处输入图片说明

因此,在Python控制台中

def select_all(layer):
     layer.select([])
     layer.setSelectedFeatures([obj.id() for obj in layer])

myline = qgis.utils.iface.activeLayer()
select_all(myline)
for elem in myline.selectedFeatures():
      xy = elem.geometry().asPolyline()

现在xy包含该行的所有节点(点)

# first point
print "x=%2d y=%2d" % (xy[0].x(),xy[0].y())
x=112935 y=117784
# and others...

使用线的所有节点:

1)方位角i至点i + 1(+/- 180°)(一条线的节点)

for i in range(len(xy)-1):
     print "x=%2d y=%2d azim=%6.1f azim2=%6.1f" % (xy[i].x(), xy[i].y(), xy[i].azimuth(xy[i+1]), xy[i+1].azimuth(xy[i]))

x=112935 y=117784 azim= 168.4 azim2= -11.6
x=113032 y=117312 azim=-167.5 azim2=  12.5
x=112926 y=116835 azim= 177.3 azim2=  -2.7
x=112943 y=116472 azim= 145.1 azim2= -34.9
[...]

2)点i与点i + 1之间的欧式距离

for i in range(len(xy)-1):
     print "x=%2d y=%2d dist=%6.1f" % (xy[i].x(), xy[i].y(), xy[i].sqrDist(xy[i+1]))

x=112935 y=117784 dist=232533.9
x=113032 y=117311 dist=238243.6
x=112926 y=116835 dist=131839.8
x=112943 y=116472 dist=209268.1
[...]

之后,将这些值添加到属性表并不是很困难。

我使用这项技术通过matplotlib和Script Runner插件来分析线条(地质)

在此处输入图片说明


5
+1-不错的解决方案!必须...学习... Python ...
Simbamangu'5

这对地质学家来说是一个很好的解决方案,而且非常有价值。.但也很复杂
Shawn

10

@Simbamangu提供的解决方案非常有效,但不能涵盖所有情况。例如,将公式与水平位移一起应用将使结果为NULL,因此必须在QGIS的字段计算器中使用此公式

case
when yat(-1)-yat(0) < 0 or yat(-1)-yat(0) > 0 then 
(atan((xat(-1)-xat(0))/(yat(-1)-yat(0)))) * 180/3.14159 + 
(180 *
(((yat(-1)-yat(0)) < 0) + 
(((xat(-1)-xat(0)) < 0 AND (yat(-1) - yat(0)) >0)*2)
))
when ((yat(-1)-yat(0)) = 0 and (xat(-1) - xat(0)) >0) then 90
when ((yat(-1)-yat(0)) = 0 and (xat(-1) - xat(0)) <0) then 270
end
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.