Menetapkan ID titik untuk masing-masing atribut awal dan akhir polyline?

9

Saya memiliki dua shapefile, Point dan Polyline. Saya mencoba untuk mengisi lapisan polyline saya dengan ID data titik (systemID) di mana garis mulai ke tempat mereka berakhir; misalnya. buat dua kolom (dari dan ke). Garis sudah memiliki arah aliran yang ditugaskan padanya. Saya menggunakan alat ArcHydro tetapi Arcpy juga baik-baik saja.

Di ArcHydro saya telah mencoba menggunakan Alat Atribut> Hasilkan Dari / Ke Node untuk baris tetapi ini menciptakan nilai untuk dan dari yang bukan dari data titik saya. Alternatif saya yang lain adalah menggunakan Feature to Vertices dan menggabungkan hasilnya ke tabel data poin saya untuk mendapatkan systemID. Tetapi kemudian saya harus memperbarui lapisan polyline juga. Saya yakin ada cara yang lebih mudah untuk melakukannya.

Catatan: tidak semua garis memiliki titik di simpul, nilai kosong baik untuk mereka.

JrUser
sumber
Jadi poin Anda memiliki bidang 'systemID' yang perlu masuk dalam FNode, bidang TNode di polyline ... apakah itu benar?
Michael Stimson
Ada pertanyaan seperti ini di sini di suatu tempat dengan jawaban yang pada dasarnya baris ke titik mulai dan berakhir sebagai kelas fitur yang terpisah, memotong dua (secara individu) dengan data titik Anda untuk mendapatkan id, lalu spasial bergabung dengan mereka kembali ke garis menggunakan garis ID dan penugasan ke bidang awal atau akhir yang benar (mungkin merupakan penghitungan bidang di sana). Sepertinya saya tidak dapat menemukannya sekarang. Ditemukan saat menggali sekitar untuk yang satu ini .
Chris W
Ini dia: gis.stackexchange.com/questions/85082 Dan itu adalah Fitur Vertices untuk poin, bukan garis atau fitur ke poin. Cukup banyak apa yang Anda sebutkan di akhir pertanyaan.
Chris W
@ Chris , saya sangat suka jawaban FelixIP untuk yang itu. Hanya dua atribut yang bergabung.
Michael Stimson

Jawaban:

12

Terkadang lebih baik tidak menggunakan solusi out of the box. Inilah sebabnya saya sarankan

  1. Populasikan bidang X dan Y di lapisan simpul, konversikan ke bilangan bulat, katakan cm. Buat bidang string dan isi dengan merangkai representasi string bilangan bulat.
  2. Lakukan hal serupa di tabel tautan untuk titik pertama dalam bentuk.
  3. Gabung tabel node ke tautan menggunakan bidang yang dibuat terbaru dan transfer nodeID ke bidang FROM.

Goto 2, tetapi gunakan titik terakhir untuk menetapkan TO nodeID

FelixIP
sumber
Suka itu! Bidang menghitung sesuatu seperti str (bulat (! Bentuk! .FirstPoint.X, 3)) + "," + str (bulat (! Bentuk! .FirstPoint.Y, 3)) (Python parser) untuk dari node, str (bulat (! Bentuk! .LastPoint.X, 3)) + "," + str (bulat (! Bentuk! .LastPoint.Y, 3)) untuk ke node, kemudian mirip dengan titik (sebagai teks) kemudian bergabung ... Cara terbaik untuk menggabungkan spasial tanpa rasa sakit Felix! Membulatkan ke digit yang lebih signifikan untuk data geografis (seperti 7 atau 8).
Michael Stimson
Sangat cepat juga dalam lingkungan scripting, di mana tentu saja kamus menggantikan bergabung dengan tabel lambat
FelixIP
Int (X * 100) jika mereka diproyeksikan dalam metres. Selalu gunakan kode Michael
FelixIP
Jelas lebih sederhana daripada metode dalam pertanyaan yang saya tautkan di atas. Lebih sedikit langkah, lebih sedikit alat, dan tidak ada batasan level lisensi. Gagasan menarik untuk mengubah join spasial menjadi join atribut biasa.
Chris W
1

Saya melakukan hal yang sama beberapa bulan yang lalu. Saya menggunakan arcpy tetapi skripnya terlalu panjang untuk dikirim di sini jadi saya akan memberi Anda garis besar tentang apa yang saya lakukan.

  1. Saya menggunakan gabungan spasial untuk mendeteksi titik / node mana dalam fitur garis tertentu.

  2. Karena sambungan spasial tidak memperhitungkan arah aliran, saya menggunakan arcpy untuk memastikan titik awal dan titik akhir mana. Saya bisa melakukan ini dengan menggunakan fungsi menjelaskan busur untuk mengekstrak informasi koordinat untuk simpul mulai / akhir dari fitur garis dan membandingkannya dengan nilai koordinat titik-titik yang terhubung.

  3. Akhirnya, setelah saya menentukan titik to / from mana yang saya gunakan fungsi setValue untuk mengisi bidang ke / dari dalam dataset polyline asli.

Jelas, ada sedikit lebih dari ini tetapi saya telah menguraikan poin utama.

Geord359
sumber
Dalam jaringan geometrik saya, arah aliran bisa dalam salah satu arah mata angin. Saya tidak bisa memastikan arah aliran dari perbandingan koordinat mentah kecuali saya juga menggunakan raster arah aliran atau sesuatu yang setara. Bahkan itu bisa menjadi masalah karena kadang-kadang pipa miring terhadap kontur alami atau air dipompa ke atas bukit. Bagaimana Anda bisa yakin bahwa arah aliran Anda benar?
Priscilla
1

Saya terinspirasi oleh @FelixIP, tetapi saya ingin menulis solusi tanpa bergabung atau membuat file tambahan, karena jaringan saya cukup besar dengan 400K + pipa dan 500K + node.

Membangun jaringan geometrik memaksa X, Y dari node dan ujung pipa menjadi bertepatan. Anda dapat mengakses lokasi ini dengan token bentuk dalam kursor busur dan mencocokkannya. Token bentuk untuk garis mengembalikan array simpul sesuai urutan penggambarannya. Di jaringan saya, urutan undian pipa sangat QA'd karena kami menggunakan ini untuk mengatur arah aliran. Jadi, simpul pertama adalah awal pipa, dan simpul terakhir adalah ujung pipa.

Referensi: ASSETID = id pipa, UNITID = simpul id di awal pipa, UNITID2 = simpul id di ujung pipa.

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)
Priscilla
sumber
Ini 90% dari apa yang saya lakukan, tetapi saya tidak melalui pipa dua kali, karena kamus node sudah tersedia.
FelixIP