Memindahkan / mengganti lokasi titik menggunakan ArcPy atau ModelBuilder?

10

Saya memiliki sejumlah lapisan CAD non-georeferensi (lihat pertanyaan ini ) yang memiliki fitur anotasi teks. Saya telah membuat model untuk mengonversi teks menjadi titik, tetapi setelah mengonversi anotasi ke kelas Featureeclass, saya melihat bahwa titik jangkar teks CAD tidak sesuai dengan pusat teks CAD (di mana titik berada).

Oleh karena itu, saya ingin programatik (menggunakan ArcPy atau Modelbuilder) [pindah] fitur relatif terhadap lokasi saat ini (delta x, y) menggunakan X diukur, nilai Y yang saya akan memberikan.

Ini akan memungkinkan saya untuk memindahkan poin GIS kembali ke tempat mereka berada, alih-alih titik jangkar CAD offset.

Bagaimana saya bisa menyelesaikan tugas ini?


@PolyGeo memberikan jawaban yang bagus menggunakan SHAPE @ XY IN 10.1, tetapi saat ini saya menjalankan 10.0. Ada 10,0 ide?

RyanKDalton
sumber

Jawaban:

17

Kode ini harus melakukannya menggunakan token SHAPE @ XY yang datang dengan arcpy.da.UpdateCursor di ArcGIS 10.1.

import arcpy
# Set some variables
fc = r"C:\temp\test.gdb\testFC"
fc2 = r"C:\temp\test.gdb\testFCcopy"
xOffset = 0.001
yOffset = 0.001
# Code to make a copy which will have its coordinates moved (and can be compared with original)
if arcpy.Exists(fc2):
    arcpy.Delete_management(fc2)
arcpy.Copy_management(fc,fc2)
# Perform the move
with arcpy.da.UpdateCursor(fc2, ["SHAPE@XY"]) as cursor:
    for row in cursor:
        cursor.updateRow([[row[0][0] + xOffset,row[0][1] + yOffset]])

Pola pengkodean yang digunakan di sini berasal dari ArcPy Café .

PolyGeo
sumber
Ugh! Butuh waktu hingga pagi ini untuk menyadari bahwa SHAPE @ XY hanya tersedia dalam 10.1, dan perusahaan saya masih menggunakan 10.0. Ini adalah jawaban yang bagus (maju), tapi saya akan menunggu dan melihat apakah ada yang punya saran untuk 10.0. Terima kasih!
RyanKDalton
Informasi lebih lanjut tentang proses serupa untuk siapa saja yang membaca ini. Masih 10.1. arcpy.wordpress.com/2013/06/07/disperse-overlapping-points
theJones
Apakah ini benar-benar menetapkan nilai di mana saja? Belum pernah menggunakan UpdateCursor seperti itu sebelumnya. Biasanya saya melakukan + = dan kemudian memperbarui baris. Kalau tidak, satu-satunya hal yang saya lakukan berbeda dalam versi saya adalah UpdateCursor menggunakan ['SHAPE @ X', 'SHAPE @ Y'] sehingga Anda dapat mengaksesnya sebagai baris [0] dan baris [1] daripada harus melakukan baris [0] ] [0] dan baris [0] [1]. Pikirkan itu hanya sedikit lebih mudah dibaca untukku.
eseglem
Ya, itu adalah cara yang sah untuk memperbarui baris. Sebenarnya, saya belum pernah melihat nilai yang lewat di updateRow () sampai beberapa minggu yang lalu. Sebenarnya itu adalah contoh untuk memperbarui geometri.
Paul
Terima kasih banyak atas jawaban Anda PolyGeo! Sebenarnya saya cukup terkesan bahwa kode itu bekerja tanpa modifikasi. Saya menjalankan ArcGIS Desktop 10.6
Rie Mino
8

Saya menghargai @ artwork21 karena telah mengarahkan saya ke solusi akhir saya. Saya benar-benar menemukan skrip yang hampir lengkap di artikel bantuan online ArcGIS 10.0 yang disebut " Calculate Field samples ", yang tercantum di bawah subkategori " Sampel kode — geometri " dan " Untuk kelas fitur titik, geser koordinat x setiap titik dengan 100 "

Script terakhir yang saya gunakan dalam alat "Menghitung Bidang" ModelBuilder adalah:

Ekspresi:

shiftXYCoordinates(!SHAPE!,%ShiftX%,%ShiftY%)

di mana ShiftX dan ShiftY adalah variabel (sebagai parameter) yang ditentukan pada kanvas ModelBuilder.

Jenis Ekspresi:

PYTHON_9.3

Blok Kode:

def shiftXYCoordinates(shape,x_shift,y_shift):
   point = shape.getPart(0)
   point.X += float(x_shift)
   point.Y += float(y_shift)
   return point

Karena semua model bekerja pada set yang dipilih, Anda juga harus dapat membuat ini sebagai alat generik yang akan bekerja bersama dengan model / alat lain di sesi pembuat model lainnya. Model yang sangat sederhana yang saya buat (sebagai "plugin" ke model lain untuk menggeser nilai koordinat) terlihat seperti ini. Dengan begitu saya bisa mengontrol shift berdasarkan per-seleksi-set (seperti yang didefinisikan dalam model lain):

Model ShiftXY

Itu bekerja seperti pesona, terima kasih atas masukan Anda!

RyanKDalton
sumber
apakah mungkin untuk menggeser fitur berdasarkan nilai di dalam tabel, disimpan dalam kolom?
Losbaltica
1
Harus. Cukup tetapkan parameter ShiftX dan ShiftY ke kolom yang sesuai.
RyanKDalton
Saya bingung dengan apa yang Anda lewati di sini sebagai "bentuk". Bisakah Anda membantu saya?
jbchurchill
"Ekspresi" menunjukkan parameter yang dilewatkan ke fungsi kode-blok yang disebut shiftXYCoordinates (). Jadi parameter pertama adalah! SHAPE !, yang merupakan bidang bentuk dari layer.
RyanKDalton
5

Anda juga dapat menggunakan skrip kalkulator bidang ini untuk memindahkan lokasi fitur:

def XYsetVALUE( shape, X_value, Y_value): 
  myMoveX = 0.001
  myMoveY = 0.001
  point = shape.getPart(0) 
  point.X = X_value + myMoveX
  point.Y = Y_value + myMoveY
  return point 

XYsetVALUE (! SHAPE !,! X_COORD !,! Y_COORD!)

Anda bisa memasukkan metode Menghitung Bidang tambahan dalam model Anda menggunakan fungsi di atas.

artwork21
sumber
Itu cara yang menarik untuk melakukannya, saya tidak benar-benar tahu Anda dapat menghitung bidang pada bidang bentuk. Ini mungkin sebenarnya cara termudah untuk menyelesaikannya jika itu merupakan set offset untuk semua poin. Mungkin akan lebih cepat untuk melakukan point.X + = myMoveX dan point.Y + = myMoveY daripada harus melewati koordinat X dan Y untuk itu.
eseglem
5

Saya mengadaptasi solusi untuk memindahkan / menggeser titik poin ke arah tertentu (sudut) dan jarak tertentu.

Seperti:

def shiftXYCoordinates(shape,angle,distance):
point = shape.getPart(0)
point.Y += distance * math.cos(math.radians(angle))
point.X += distance * math.sin(math.radians(angle))
return point

dan dipanggil seperti shiftXYCoordinates (! SHAPE !,! Angle!, 5000), jika Anda memiliki bidang "sudut" untuk fitur poin Anda (atau dengan konstanta tentu saja). Sudut harus diberikan dalam derajat desimal. 0 akan menggeser "ke atas", 90 "ke kanan" dll. Saya mendapatkannya setelah membuat fitur indeks peta strip dan mengubahnya menjadi poin.

Juga pastikan untuk memilih Nama Bidang "Bentuk" sebelum menjalankan :)

(Solusi diuji dalam ArcMap 10.0 SP5)

kgl
sumber
4

Seperti yang Anda lihat, itu jauh lebih mudah di 10.1 ketika Anda mendapatkan akses ke token kursor.

import arcpy
# Code to move features in copy of same dataset
fc = r"C:\temp\test.gdb\testFC"
fc2 = r"C:\temp\test.gdb\testFCcopy"
xOffset = 0.001
yOffset = 0.001
if arcpy.Exists(fc2):
    arcpy.Delete_management(fc2)
arcpy.Copy_management(fc, fc2)

shape = arcpy.Describe(fc2).ShapeFieldName

cursor = arcpy.UpdateCursor(fc2)
for row in cursor:    
    point = row.getValue(shape).getPart()
    row.setValue(shape, arcpy.Point(point.X + xOffset, point.Y + yOffset))
    cursor.updateRow(row) 

del point, row, cursor
Paul
sumber
2

Ini bekerja untuk 10.0:

# Featureclass here
FC = r'featureclass'

fcount = 0
shapefield = arcpy.Describe(FC).shapeFieldName
featureUpdate = arcpy.UpdateCursor(FC)
for f in featureUpdate:
    # Hard coded shifts but easy enough to set up a lookup function if needed
    sLon = 0.001
    sLat = 0.001
    # Optional but I like to count to see where it is at in the process
    if fcount % 1000 == 0:
        print('Updating feature %s...' %(fcount))
    # Get the original value
    cF = f.getValue(shapefield)
    cPNT = cF.getPart()
    # Create a new point with the shifted value
    sPNT = arcpy.Point(cPNT.X - sLon, cPNT.Y - sLAT)
    # Set the shapefield to the new point and update feature
    f.setValue(shapefield, sPNT)
    featureUpdate.updateRow(f)
    fcount += 1
del featureUpdate
orang asing
sumber