Створення рівновіддалених точок у QGIS?


22

Я намагаюся створити точки (новий шар) на певній відстані вздовж дороги (існуючий шар) в QGIS. Створення регулярних точок кожного метра на рівні округу за допомогою ArcGIS Desktop? дає рішення для ArcGIS. Як цього досягти в QGIS? Додавання точок до точкового векторного шару за допомогою QGIS? пояснює, як створювати точки, але нічого не робить щодо відстані.


(Я застосував запропоновані рішення з різною мірою довжини, оскільки я не знав перетворення) @ Рішення Натанса працювало певною мірою, я отримав ...

введіть тут опис зображення. Тут проекція цих рівновіддалених точок відрізняється від початкової лінії.

З пропозицією @ underdark я зрозумів

це зображенняде точки не здаються рівновіддаленими. Я здогадуюсь, що з обома цими проблемами прогнозування є якісь я не розумію.



2
Пару балів. По-перше, лінія повинна знаходитись у проектованій CRS (не у лат / lon). По-друге, чи ваша лінія справжня полілінія? Я не думаю, що жоден метод буде працювати належним чином у рядку, що містить рядок окремих рядків. Нік.
nhopton

Крім того, з моїм кодом, вам не потрібно телефонувати на import locateлінію більше одного разу. Просто зателефонуйте один раз, тоді ви можете зателефонувати locate.pointsAlongLine(30)стільки, скільки вам потрібно
Натан W

Інший метод (враховуючи, що Sextant, як пропонують деякі відповіді тут, - це QGIS <2.0) - також використовувати плагін під назвою QChainage.
Енді

Відповіді:


14

Примітка. Зараз існує плагін QGIS QChainage. Це все це робить і багато іншого. Код нижче застарів у QGIS 2.0 та вище.

Ось якийсь код Python, який ви можете вставити у файл та використовувати всередині QGIS:

QGIS має в ньому метод API для здійснення посилань на вкладиші, але я не міг змусити його працювати правильно, але я зв’яжусь з автором коду і побачу, чи я щось робив не так.

Наразі вам знадобиться вишукана бібліотека Python, яку ви все одно повинні встановити, оскільки зручно мати її. Він також має чудову документацію на веб-сайті http://toblerity.github.com/shapely/manual.html

Цей розділ я використовую в наступному прикладі http://toblerity.github.com/shapely/manual.html#interoperation .

Більшість наведених нижче кодів є кодовою табличкою QGIS, просто створюючи функції, шари, перетворюючи з wkb і wkt і назад. Основним бітом є той, point = line.interpolate(currentdistance)який повертає точку на відстані вздовж прямої. Ми просто загортаємо це в петлю, поки не закінчимося з лінії.

import qgis
from qgis.core import *
from PyQt4.QtCore import QVariant
from shapely.wkb import loads
from shapely.wkt import dumps

vl = None
pr = None

def createPointsAt(distance, geom):
    if distance > geom.length():
        print "No Way Man!"
        return

    length = geom.length()
    currentdistance = distance
    feats = []  

    while currentdistance < length: 
        line = loads(geom.asWkb())
        point = line.interpolate(currentdistance)
        fet = QgsFeature()
        fet.setAttributeMap( { 0 : currentdistance } )
        qgsgeom = QgsGeometry.fromWkt(dumps(point))
        fet.setGeometry(qgsgeom)
        feats.append(fet)
        currentdistance = currentdistance + distance

    pr.addFeatures(feats)
    vl.updateExtents()

def pointsAlongLine(distance):
    global vl
    vl = QgsVectorLayer("Point", "distance nodes", "memory")
    global pr
    pr = vl.dataProvider()  
    pr.addAttributes( [ QgsField("distance", QVariant.Int) ] )
    layer = qgis.utils.iface.mapCanvas().currentLayer()
    for feature in layer.selectedFeatures():
        geom = feature.geometry()
        createPointsAt(distance, geom)

    QgsMapLayerRegistry.instance().addMapLayer(vl)

Скопіювавши і вставте вищезазначений код у файл, я зателефонував до свого locate.py у ~./qgis/pythonкаталог (тому що він знаходиться на шляху Python) і просто зробив це на консолі Python всередині QGIS.

 import locate
 locate.pointsAlongLine(30)

Це створить новий точковий шар з точками на кожні 30 метрів уздовж вибраних ліній, наприклад:

введіть тут опис зображення

Примітка. Код є досить грубим і може знадобитися очищення.

РЕДАКТУВАННЯ: Найновіша розробка QGIS-розробників тепер може робити це на самому світі.

Змініть цикл while createPointsAtна:

 while currentdistance < length: 
    point = geom.interpolate(distance)
    fet = QgsFeature()
    fet.setAttributeMap( { 0 : currentdistance } )
    fet.setGeometry(point)
    feats.append(fet)
    currentdistance = currentdistance + distance

і ви можете видалити

from shapely.wkb import loads
from shapely.wkt import dumps

Дякую @Nathan Я не міг отримати пакет Shapely для свого пітона. Я встановив python 2.7, але інсталятор Shapely каже, що python 2.7 відсутній у моєму реєстрі. Чи є інший спосіб встановити Shapely.
Stat-R

Я дотримувався stackoverflow.com/questions/3652625/… і вводив вищевказані два рядки для виклику locateта користування ним, але все одно не отримав рівновіддалених балів. Крім того, я неофіт в Python, тому я не зрозумів, де запустити python з кодом (1) в каталозі qgis або (2), що в C: \ Python27 \?
Stat-R

На якій ОС ви працюєте?
Nathan W

Windows 7 Professional
Stat-R

створіть файл python, C:\Users\{you user name}\.qgis\pythonпісля чого перезапустіть QGIS, якщо він відкритий, і перейдіть до `Плагіни-> . Load a line layer, select a line a call Імпортувати імпорт консолі Python` таlocate.pointsAlongLine(30)
Nathan W

5

Ви можете використовувати плагін QGIS GRASS v.to.points для створення точок по лініях через рівні проміжки часу

# convert line to points; dmax = distance between points
v.to.points -i -v -t in=road out=road_pts type=line dmax=90

Я використовував dmax як 100, і отримані прогнози для кожного наступні. (Я не знаю, як CRS призначається сам.)CRS of Original Shape file, the line = EPSG:26915 - NAD83 / UTM zone 15N, CRS of Grass line vector obtained using v.in.ogr = EPSG:4269 - NAD83, CRS of Grass points vector obtained using v.to.points = EPSG:4326 - WGS 84
Stat-R

Тепер також так: QGIS -> Sextante -> GRASS -> v.to.points
markusN

5

Якщо ви хочете побудувати ланцюг із встановленими інтервалами вздовж лінії дороги, ви можете скористатися плагіном "Профілі від лінії", щоб зробити це. Вам потрібна DEM під шаром лінії дороги, але процедура швидка і дуже проста. Нік.

введіть тут опис зображення


це досить хороший і простий метод теж, дякую!
Шеферджо

2

Будьте уважні, що модель даних Shapely (Python) / GEOS (C ++) визначена в площині. Отже, якщо ваші точки складаються з позицій GPS (широта, довгота) за допомогою shapely.geometry.LineString.interpolate(distance)методу, виведете положення GPS на евклідовій відстані вздовж заданої LineString.

Метод Shapely interpolate()заснований на geos::linearref::LengthIndexedLineкласі GEOS, використовуючи extractPointметод.

Імовірно, однаково розташована інтерполяція в площині широти-довготи достатня для застосувань, що враховують відносно невеликі відстані. В цілому, однак, слід враховувати відстань у сфері для GIS-додатків (як визначено в WGS84 ).

Я можу придумати два обхідні шляхи за допомогою модуля Shapely:

  • LineStringвластивості - це всі задані точки та лінійно-інтерпольовані криві вздовж них. Можливо, ви можете написати член, який здійснює доступ до інтерпольованих кривих, і реалізувати наступний інтеграл рядка, що замінює евклідову відстань. Мені подобається такий підхід, оскільки за допомогою кускової безперервної кривої бажані точки можна отримати, обчисливши перетини сусідніх кіл по кривій з радіусом r = radian_measure(arc_length) = arc_length / R, де R дорівнює радіусу Землі в заданому положенні.
  • кодуйте свій власний метод інтерполяції (не торкаючись коду Shapely), використовуючи відповідну функцію відстані (наприклад, формула Гаверсина).

Для цього я хотів би звернутися до наступного питання StackOverflow і зокрема до цієї відповіді :

Можна формувати рівновіддалені точки вздовж кривої. Але для отримання реальної відповіді повинно бути більше визначення того, що ви хочете. Вибачте, але код, який я написав для цього завдання, є в MATLAB, але я можу описати загальні ідеї. Існує три можливості.

По-перше, чи є пункти справді рівновіддаленими від сусідів з точки зору простої евклідової відстані? Для цього було б знаходження перетину в будь-якій точці кривої з колом фіксованого радіуса. Потім просто ступіть по кривій.

Далі, якщо ви маєте намір відстань - значення відстані вздовж самої кривої, якщо крива є кусочно лінійною, проблему знову легко зробити. Просто ступіть по кривій, оскільки відстань на відрізку лінії легко виміряти.

Нарешті, якщо ви плануєте, щоб крива була кубічним сплайном, знову це не неймовірно складно, але це трохи більше роботи. Тут хитрість полягає в тому, щоб:

  • Обчисліть кускову лінійну довжину дуги від точки до точки вздовж кривої. Назвіть це т. Утворіть пару кубічних сплайнів, x (t), y (t).

  • Диференціюйте x і y як функції t. Оскільки це кубічні сегменти, це легко. Похідні функції будуть кусочно
    квадратичними.

  • Використовуйте розв'язувач оди для переміщення по кривій, інтегруючи функцію диференціальної довжини дуги. У MATLAB ODE45 чудово працював.

Таким чином, один інтегрується

sqrt((x')^2 + (y')^2)

Знову ж таки, у MATLAB можна встановити ODE45 для ідентифікації тих локацій, де функція перетинає певні задані точки.

Якщо ваші навички MATLAB вирішують завдання, ви можете переглянути код у interparc для отримання додаткових пояснень. Це досить добре коментований код.

3 : http://www.mathworks.com/matlabcentral/fileexchange/34874-interparc


1

Sextante має інструмент, який може працювати для вас. Sextante можна завантажити з сховища плагінів Qgis.

Шукайте:
"Інструменти для шарів ліній"
"Лінії до рівномірних точок"


Цей плагін, здається, недоступний для QGIS 2 або 3.
Martin Burch
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.