Присвоєння ідентифікаторів точки відповідним початковим і кінцевим атрибутам полілінії?


9

У мене є два профілі, Point і Polyline. Я намагаюся заповнити мій полілінійний шар ідентифікатором точкових даних (systemID), де лінії починаються там, де вони закінчуються; напр. створити два стовпці (від і до). У рядках вже призначений напрямок потоку. Я використовую інструменти ArcHydro, але Arcpy також чудово.

У ArcHydro я спробував використовувати інструменти атрибутів> Створити з / до вузлів для рядків, але це створює значення для "до" і "з", які не є моїми даними даних. Іншою моєю альтернативою було використання Feature to Vertices та приєднання результату до моєї таблиці даних точок для отримання systemID. Але тоді мені доведеться також оновити полілінійний шар. Я впевнений, що існує простіший спосіб зробити це.

Примітка: не всі рядки мають точки у вершинах, порожні значення для них добре.


Отже, у ваших точок є поле "systemID", яке потрібно пройти в FNode, поля TNode в поліліній ... це правильно?
Майкл Стімсон

Тут десь є таке питання з відповіддю, яке в основному є лінією, щоб почати і закінчити як окремі класи функцій, перетинати два (окремо) з вашими даними про точку, щоб отримати ідентифікатори, а потім просторово приєднати їх до рядків за допомогою рядка Ідентифікатор та присвоєння правильному початковому чи кінцевому полі (можливо, там обчислюється поле). Я, здається, зараз не можу його знайти. Знайшли його, коли копали навколо цього .
Кріс Ш

Ось це: gis.stackexchange.com/questions/85082 І це було Feature Vertices до точок, а не до рядків чи до пунктів. Досить багато того, що ви згадуєте в кінці питання.
Кріс Ш

@ChrisW, мені дуже подобається відповідь від FelixIP на цю. Це лише два об'єднання атрибута.
Майкл Стімсон

Відповіді:


12

Іноді краще не використовувати нестандартний розчин. Ось чому я пропоную

  1. Заселіть X та Y поля у шарі вузлів, перетворіть їх у цілі числа, скажімо, cm. Створіть рядок і заповніть його, об'єднавши рядкові репрезентації цілих чисел.
  2. Зробіть подібне в таблиці посилань для першої точки форми.
  3. Приєднайте таблицю вузлів до посилань, використовуючи останні створені поля та перенесіть nodeID у поле FROM.

Перейдіть 2, але використовуйте останню точку, щоб призначити TO nodeID


Люблю це! Поле обчислює щось на зразок str (круглий (! Форма!. FirstPoint.X, 3)) + "," + str (круглий (! Форма!. FirstPoint.Y, 3)) (аналізатор Python) для від вузла, str (круг (! Shape! .LastPoint.X, 3)) + "," + str (круглий (! Shape! .LastPoint.Y, 3)) для node, то схожий на точку (як текст), а потім приєднайтеся ... Відмінний спосіб просторового з'єднання без болю Фелікс! Округніть до більш значущих цифр для географічних даних (наприклад, 7 або 8).
Майкл Стімсон

Надзвичайно швидкий, а також у сценаріїв, де звичайно словник замінює повільне приєднання таблиці
FelixIP

Int (X * 100), якщо вони проектуються в метри. Альтернативно використовуйте код Майкла
FelixIP

Однозначно простіше, ніж метод у питанні, яке я зв'язав вище. Менше кроків, менша кількість інструментів та відсутність обмежень на рівні ліцензії. Цікава ідея перетворити просторове з'єднання у звичайний атрибут приєднання.
Кріс Ш

1

Я те саме робив кілька місяців тому. Я використовував arcpy, але сценарій занадто довгий для публікації тут, тому я дам вам контур того, що я зробив.

  1. Я використовував просторове з'єднання, щоб визначити, які точки / вузли були в межах певної функції лінії.

  2. Оскільки просторове з'єднання не враховує напрямок потоку, я використав arcpy, щоб визначити, яка була початкова точка, а яка була кінцева точка. Я зміг це зробити за допомогою функції опису arcpy для отримання інформації про координати для вершин початку та кінця функції рядка та порівняв їх із значеннями координат з'єднаних точок.

  3. Нарешті, як тільки я розробив, який із пунктів до / з яких я використовував, я використовував функцію setValue, щоб заповнити поля в / з полів у вихідному наборі даних поліліній.

Очевидно, що в цьому є трохи більше, ніж це, але я окреслив основні моменти.


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

1

Мене надихнуло @FelixIP, але я хотів написати рішення без приєднання або створення зайвих файлів, оскільки моя мережа досить велика з 400K + трубами та 500K + вузлами.

Геометрична мережа побудови змушує X, Y вузлів, а кінці труби збігаються. Ви можете отримати доступ до цих місць за допомогою маркерів фігури в курсорних курсорах і зіставити їх. Маркери форми для ліній повертають масив вершин у тому порядку, в якому вони були намальовані. У моїй мережі порядок тяги труб дуже сильно QA'd, оскільки ми використовуємо це для встановлення напрямків потоку. Отже, перша вершина - це початок труби, а остання вершина - кінець труби.

Довідка: ASSETID = ідентифікатор труби, UNITID = ідентифікатор вузла на початку труби, UNITID2 = ідентифікатор вузла в кінці труби.

nodes = "mergeNodes"
pipes = "SEWER_1"

nodeDict = {}
pipeDict = {}

#populate node dictionary with X,Y as the key and node ID as the value
for node in arcpy.da.SearchCursor(nodes, ["UNITID", "SHAPE@XY"]):
    nodeDict[(node[1][0], node[1][1])] = node[0]

#populate pipe dictionary with pipe ID as the key and list of X,Y as values 
#vertices populated in the order that the line was draw
#so that [0] is the first vertex and [-1] is the final vertex
for pipe in arcpy.da.SearchCursor(pipes, ["ASSETID", "SHAPE@"]):
    for arrayOb in pipe[1]:
        for point in arrayOb:
            if pipe[0] in pipeDict:
                pipeDict[pipe[0]].append((point.X, point.Y))
            else: 
                pipeDict[pipe[0]] = [(point.X, point.Y)]

#populate UNITID with the first vertex of the line
#populate UNITID2 with the final vertex of the line
with arcpy.da.UpdateCursor(pipes, ["ASSETID", "UNITID", "UNITID2"]) as cur:
    for pipe in cur:
        if pipeDict[pipe[0]][0] in nodeDict:
            pipe[1] = nodeDict[pipeDict[pipe[0]][0]]
        if pipeDict[pipe[0]][-1] in nodeDict:
            pipe[2] = nodeDict[pipeDict[pipe[0]][-1]]
        cur.updateRow(pipe)

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