Як додати напрямок та відстань до таблиці атрибутів?


18

кожен, хто може допомогти. Я просто хочу додати напрямок (підшипник: тобто N 25 35 E) та відстань (довжина: 125 метрів) як моє нове поле в даних про полілінії / лінії. чи є плагін для створення цих полів? я намагався використовувати "експорт / додавання геометричних стовпців" у моїх рядкових даних, але було додано лише значення "Довжина".


Поки я можу використовувати плагін mmqgis, щоб дати мені відстань. Досліджую проблему напрямку.
Віллі

1
Як виглядають ваші полілінійні дані? Відстань обчислити досить просто - однак, "опора" може змінюватися по довжині полілінії. Ви шукаєте підшипник від початкової точки до кінцевої точки ?
Simbamangu

Так, я шукаю підшипника від початкової точки до кінцевої точки ... дякую
arzandia

1
Ви хочете відстань прямої лінії від початкової точки до кінцевої точки або довжину лінії, що слідує шляху лінії? Вони можуть сильно відрізнятися, якщо в сегменті лінії є проміжні криві або інші зміни напрямку.
RyanKDalton-OffTheGridMaps

Відповіді:


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 / пі). Друга частина додає або 180 або 360 до отриманої фігури, щоб дати підшипник від 0-360 °.


2
Найелегантніше рішення, дякую. Я зазначу, що якщо вам потрібно визначити підшипник для кожного сегмента полілінії, ви можете зробити це, розділивши профіль форми лінії за допомогою плагіну "Розділити функцію". Потім завантажте новий (розділений) файл форми і виконайте вищевказану процедуру.
nhopton

1
@arzandia - зауважте, що ОБОВ'ЯЗКОВО використовувати QGIS 1.9 (див. домашню сторінку для завантаження бета-версії), оскільки функції xat () та yat () не працюють у 1.7, який ви використовуєте!
Simbamangu

Я вже використовував плагін у вас, про який ви згадали. як ви бачите зображення, назва шару "
розколота

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)))
оскарлін

21

Вам не потрібен плагін. Все в класі QgsPoint PyQGIS

Якщо ви вивчаєте вміст класу точок QGIS за допомогою вбудованої функції dir () Python в консолі Python.

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

Це прекрасне рішення і надзвичайно цінне для геологів .. але також так складно
Шон

10

Рішення, яке надає @Simbamangu, є досить ефективним, але охоплює не всі випадки. Наприклад, застосовуючи формулу з горизонтальним покажчиком, НУЛЬНИЙ результат, тому ви повинні використовувати цю формулу в Польовому калькуляторі 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.