การย้าย / ชดเชยตำแหน่งจุดโดยใช้ ArcPy หรือ ModelBuilder?


10

ฉันมีเลเยอร์ CAD ที่ไม่มีการอ้างอิงทางภูมิศาสตร์จำนวนหนึ่ง (ดูคำถามนี้ ) ที่มีคุณสมบัติการเพิ่มความคิดเห็นแบบข้อความ ฉันได้สร้างแบบจำลองเพื่อแปลงข้อความให้เป็นจุด แต่หลังจากแปลงคำอธิบายประกอบเป็นคุณลักษณะแบบจุดฉันเห็นว่าจุดยึดข้อความ CAD ไม่ตรงกับจุดศูนย์กลางของข้อความ CAD (ซึ่งเป็นจุดที่อยู่)

ดังนั้นฉันต้องการเขียนโปรแกรม (ใช้ ArcPy หรือ ModelBuilder) [ย้าย] คุณลักษณะที่สัมพันธ์กับตำแหน่งปัจจุบัน (delta x, y)โดยใช้ค่า X, Y ที่วัดได้ที่ฉันจะให้

สิ่งนี้จะช่วยให้ฉันย้ายจุด GIS กลับไปที่ที่พวกเขาอยู่แทนจุดยึด CAD ชดเชย

ฉันจะทำงานนี้ให้สำเร็จได้อย่างไร


@PolyGeo ให้คำตอบที่ยอดเยี่ยมโดยใช้SHAPE @ XY IN 10.1 แต่ขณะนี้ฉันกำลังใช้งาน 10.0 10.0 ความคิดใด ๆ

คำตอบ:


17

รหัสนี้ควรทำโดยใช้โทเค็น SHAPE @ XY ที่มาพร้อมกับarcpy.da.UpdateCursorใน 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]])

รูปแบบการเข้ารหัสใช้ที่นี่มาจากArcPy คาเฟ่


ฮึ ฉันใช้เวลาจนถึงเช้านี้เพื่อตระหนักว่าSHAPE @ XYมีเฉพาะใน 10.1 และ บริษัท ของฉันยังใช้ 10.0 นี่เป็นคำตอบที่ดี (ไปข้างหน้า) แต่ฉันจะรอและดูว่าใครมีคำแนะนำสำหรับ 10.0 ขอบคุณ!
RyanKDalton

ข้อมูลเพิ่มเติมเกี่ยวกับกระบวนการที่คล้ายกันสำหรับใครก็ตามที่อ่านข้อความนี้ ยังคง 10.1 arcpy.wordpress.com/2013/06/07/disperse-overlapping-points
theJones

นี่เป็นการตั้งค่าจริงหรือไม่? ไม่เคยใช้ UpdateCursor เช่นนั้นมาก่อน ฉันมักจะทำ + = แล้วอัปเดตแถว มิฉะนั้นสิ่งเดียวที่ฉันทำในเวอร์ชั่นของฉันคือ UpdateCursor ใช้ ['SHAPE @ X', 'SHAPE @ Y'] เพื่อให้คุณสามารถเข้าถึงมันเป็นแถว [0] และแถว [1] แทนที่จะต้องทำแถว [0 ] [0] และแถว [0] [1] คิดว่าอ่านมันง่ายขึ้นนิดหน่อย
eseglem

ใช่นั่นเป็นวิธีที่ถูกต้องในการอัพเดตแถว ที่จริงแล้วฉันไม่เคยเห็นค่าที่ส่งผ่านใน updateRow () จนกระทั่งสองสามสัปดาห์ที่ผ่านมา อันที่จริงมันเป็นตัวอย่างสำหรับการปรับปรุงรูปทรงเรขาคณิต
Paul

ขอบคุณมากสำหรับคำตอบของคุณ PolyGeo! จริงๆแล้วฉันประทับใจมากที่รหัสทำงานโดยไม่มีการดัดแปลง ฉันกำลังใช้งาน ArcGIS Desktop 10.6
Rie Mino

8

ฉัน credit @ artwork21 ที่นำฉันไปสู่ทางออกสุดท้าย ฉันพบสคริปต์เกือบสมบูรณ์ในบทความช่วยเหลือออนไลน์ ArcGIS 10.0 ชื่อ " คำนวณฟิลด์ตัวอย่าง " ซึ่งอยู่ภายใต้หมวดหมู่ย่อย " ตัวอย่างโค้ด - รูปทรงเรขาคณิต " และ " สำหรับคลาสคุณลักษณะจุดเปลี่ยนพิกัด x ของแต่ละจุด 100 "

สคริปต์สุดท้ายที่ฉันใช้ภายในเครื่องมือ ModelBuilder "คำนวณฟิลด์" คือ:

นิพจน์:

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

โดยที่ShiftXและShiftYเป็นตัวแปร (ตามพารามิเตอร์) ที่กำหนดไว้บนผืนผ้าใบ ModelBuilder

ประเภทนิพจน์:

PYTHON_9.3

บล็อครหัส:

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

เนื่องจากแบบจำลองทั้งหมดทำงานในชุดที่เลือกคุณควรจะสามารถสร้างสิ่งนี้เป็นเครื่องมือทั่วไปที่จะทำงานร่วมกับรุ่น / เครื่องมืออื่น ๆ ในช่วงตัวสร้างแบบจำลองอื่น ๆ โมเดลที่ง่ายมากที่ฉันสร้างขึ้น (ในฐานะ "ปลั๊กอิน" ไปยังรุ่นอื่นเพื่อเปลี่ยนค่าพิกัด) มีลักษณะเช่นนี้ ด้วยวิธีนี้ฉันสามารถควบคุมการเปลี่ยนแปลงแบบต่อชุดการเลือก (ตามที่กำหนดไว้ในรุ่นอื่น):

โมเดล ShiftXY

มันใช้งานได้อย่างมีเสน่ห์ขอขอบคุณทุกท่านที่ให้การสนับสนุน!


เป็นไปได้หรือไม่ที่จะเลื่อนคุณสมบัติตามค่าในตารางเก็บไว้ในคอลัมน์?
Losbaltica

1
มันควรจะเป็น. เพียงกำหนดพารามิเตอร์ ShiftX และ ShiftY ให้กับคอลัมน์ที่เหมาะสม
RyanKDalton

ฉันสับสนกับสิ่งที่คุณส่งผ่านที่นี่ในฐานะ "รูปร่าง" คุณช่วยฉันหน่อยได้ไหม?
jbchurchill

"Expression" แสดงพารามิเตอร์ที่ถูกส่งผ่านไปยังฟังก์ชั่นรหัสบล็อกที่ชื่อ shiftXYCoordinates () ดังนั้นพารามิเตอร์แรกคือ! SHAPE! ซึ่งเป็นฟิลด์รูปร่างจากเลเยอร์
RyanKDalton

5

นอกจากนี้คุณยังสามารถใช้สคริปต์ตัวคำนวณฟิลด์นี้เพื่อย้ายตำแหน่งของสถานที่:

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!)

คุณสามารถรวมวิธีคำนวณเขตข้อมูลพิเศษในแบบจำลองของคุณโดยใช้ฟังก์ชันด้านบน


นั่นเป็นวิธีที่น่าสนใจที่จะทำฉันไม่รู้จริง ๆ ว่าคุณสามารถคำนวณฟิลด์บนฟิลด์รูปร่างได้ นี่อาจเป็นวิธีที่ง่ายที่สุดในการทำถ้ามันเป็นเซตออฟเซ็ตสำหรับคะแนนทั้งหมด มันอาจจะเร็วกว่าที่จะทำ point.X + = myMoveX และ point.Y + = myMoveY แทนที่จะต้องผ่านพิกัด X และ Y
eseglem

5

ฉันปรับโซลูชันเพื่อย้าย / เปลี่ยนจุดชี้ไปในทิศทางที่แน่นอน (มุม) และระยะทางที่กำหนด

ดูเหมือนกับ:

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

และถูกเรียกว่า shiftXYCoordinates (! SHAPE !,! Angle!, 5000) หากคุณมีฟิลด์“ angle” สำหรับคุณสมบัติของคะแนน (หรือมีค่าคงที่แน่นอน) ควรกำหนดมุมเป็นทศนิยม 0 จะเลื่อน“ ขึ้น”, 90“ ถูกต้อง” และอื่น ๆ ฉันได้รับหลังจากสร้างคุณลักษณะดัชนีแถบแผนที่และแปลงให้เป็นคะแนน

ตรวจสอบให้แน่ใจว่าได้เลือกชื่อฟิลด์“ รูปร่าง” ก่อนใช้งาน :)

(โซลูชันทดสอบใน ArcMap 10.0 SP5)


4

อย่างที่คุณเห็นมันง่ายขึ้นมากใน 10.1 เมื่อคุณเข้าถึงโทเค็นเคอร์เซอร์

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

2

ใช้งานได้กับ 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.