Làm cách nào để thêm Hướng và Khoảng cách vào bảng thuộc tính?


18

bất cứ ai có thể giúp đỡ. tôi chỉ muốn thêm hướng (Mang: tức là N 25 35 E) và Khoảng cách (Chiều dài: 125 mét) làm trường mới của tôi trong dữ liệu đa tuyến / dòng. Có một trình cắm để tạo các trường này không? tôi đã cố sử dụng "xuất / thêm cột hình học" trong dữ liệu dòng của mình, nhưng chỉ thêm giá trị "Độ dài".


Cho đến nay tôi có thể sử dụng plugin mmqgis để cho tôi khoảng cách. Đang khám phá vấn đề hướng.
Willy

1
Dữ liệu polyline của bạn trông như thế nào? Khoảng cách tương đối dễ tính - tuy nhiên, 'mang' có thể thay đổi theo chiều dài của một đa tuyến. Bạn đang tìm kiếm mang từ điểm bắt đầu đến điểm cuối ?
Simbamangu

Vâng, tôi đang tìm kiếm mang từ điểm bắt đầu đến điểm kết thúc ... cảm ơn
arzandia

1
Bạn có muốn khoảng cách đường thẳng từ điểm bắt đầu đến điểm cuối hoặc chiều dài của đường theo đường dẫn của đường không? Chúng có thể thay đổi lớn nếu đoạn đường có các đường cong trung gian hoặc các thay đổi hướng khác.
RyanKDalton-OffTheGridMaps

Câu trả lời:


42

Bạn có thể tính toán mang trong Máy tính Trường trong QGIS. Điều này hoạt động theo tọa độ UTM (số liệu) trên khoảng cách nhỏ (hàng trăm km), nhưng cần một cái gì đó tinh vi hơn cho khoảng cách lớn hoặc cho độ thập phân.

Mở bảng thuộc tính cho lớp dòng của bạn, chuyển đổi chỉnh sửa và nhấp vào nút Máy tính trường để mở hộp thoại:

nhập mô tả hình ảnh ở đây

Tạo một trường mới dưới dạng thập phân với độ chính xác 1 hoặc 2.

Dán mã này vào hộp "Biểu thức" và nhấp vào "OK": (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)))

Phần đầu tiên tính toán tiếp tuyến nghịch đảo của sự khác biệt x và y và chuyển đổi nó thành độ (180 / pi). Phần thứ hai thêm 180 hoặc 360 vào con số kết quả để mang ổ đỡ từ 0-360 °.


2
Một giải pháp thanh lịch nhất, cảm ơn. Tôi muốn đề cập rằng nếu bạn cần xác định ổ đỡ cho từng phân đoạn của đa tuyến, bạn có thể thực hiện việc này bằng cách tách shapefile dòng bằng trình cắm 'Tính năng phân tách'. Sau đó tải shapefile (split) mới và làm theo quy trình trên.
nhopton

1
@arzandia - lưu ý rằng bạn PHẢI sử dụng QGIS 1.9 (xem trang chủ để tải xuống bản beta) vì các hàm xat () và yat () không hoạt động trong 1.7 mà bạn đang sử dụng!
Simbamangu

tôi đã sử dụng phích cắm trong bạn đã đề cập. như bạn có thể thấy hình ảnh, tên của lớp được "tách ra" ...
arzandia

1
Để trả lời câu hỏi của riêng tôi, "Có, bạn có thể chèn các giá trị trường cho yat (0) / yat (-1) và xat (0) / xat (-1)."
cbunn

1
Đối với tôi, tôi đã phải thực hiện một số thay đổi cho tập lệnh để nó hoạt động: (atan ((xat (0) -xat (1)) / (yat (0) -yat (1)))) * 180 / 3.14159 + (180 * (((yat (0) -yat (1)) <0) + (((xat (0) -xat (1)) <0 VÀ (yat (0) - yat (1))> 0) * 2)))
oskarlin

21

Bạn không cần một plugin. Tất cả mọi thứ đều nằm trong lớp QssPoint của PyQGIS

Nếu bạn kiểm tra nội dung của lớp điểm QGIS với hàm dir () tích hợp sẵn trong Python Console.

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']

Bạn có thể thấy có các hàm phương vịsqrDist và sau một vài lần thử:

- 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)

Vấn đề nhập mô tả hình ảnh ở đây

Vì vậy, trong bảng điều khiển 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()

bây giờ xy chứa tất cả các nút (điểm) của dòng

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

Sử dụng tất cả các điểm nút của dòng:

1) góc phương vị i đến điểm i + 1 (+/- 180 °) (các nút của một dòng)

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) khoảng cách euclide giữa điểm i và điểm 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
[...]

Sau đó, không khó để thêm các giá trị này vào bảng thuộc tính.

Tôi sử dụng kỹ thuật này để phân tích các dòng dõi (địa chất) với matplotlib và plugin Script Runner

nhập mô tả hình ảnh ở đây


5
+1 - Giải pháp tốt đẹp! Phải ... học ... Python ...
Simbamangu

Đây là một giải pháp tuyệt vời và siêu có giá trị cho các nhà địa chất .. nhưng cũng rất phức tạp
Shawn

10

Giải pháp được cung cấp bởi @Simbamangu khá hiệu quả nhưng không bao gồm tất cả các trường hợp. Ví dụ: áp dụng công thức với chuyển vị ngang sẽ NULL kết quả, do đó bạn phải sử dụng công thức này trong Máy tính trường của 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.