Di chuyển / bù đắp các vị trí điểm bằng ArcPy hoặc ModelBuilder?


10

Tôi có một số lớp CAD không tham chiếu địa lý (xem câu hỏi này ) có các tính năng chú thích văn bản. Tôi đã tạo một mô hình để chuyển đổi văn bản thành các điểm, nhưng sau khi chuyển đổi chú thích thành một điểm kỳ công, tôi thấy rằng các điểm neo văn bản CAD không trùng với trung tâm của văn bản CAD (là nơi các điểm thuộc về).

Do đó, tôi muốn lập trình (sử dụng ArcPy hoặc ModelBuilder) [di chuyển] một tính năng liên quan đến vị trí hiện tại của nó (delta x, y) bằng cách sử dụng giá trị X, Y mà tôi sẽ cung cấp.

Điều này sẽ cho phép tôi di chuyển các điểm GIS trở lại vị trí của chúng, thay vì điểm neo CAD bù.

Làm thế nào tôi có thể hoàn thành nhiệm vụ này?


@PolyGeo đã đưa ra một câu trả lời tuyệt vời bằng SHAPE @ XY IN 10.1, nhưng hiện tại tôi đang chạy 10.0. Bất kỳ ý tưởng 10.0?

Câu trả lời:


17

Mã này sẽ làm điều đó bằng cách sử dụng mã thông báo SHAPE @ XY đi kèm với arcpy.da.UpdateCoder trong 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]])

Mẫu mã được sử dụng ở đây đến từ ArcPy Café .


Ừ! Phải đến sáng nay tôi mới nhận ra rằng SHAPE @ XY chỉ có sẵn trong 10.1 và công ty của tôi vẫn đang sử dụng 10.0. Đây là một câu trả lời tuyệt vời (tiếp theo), nhưng tôi sẽ chờ xem liệu có ai có bất kỳ đề xuất nào cho 10.0 không. Cảm ơn!
RyanKDalton

Thông tin thêm về một quá trình tương tự cho bất cứ ai đọc điều này. Vẫn 10.1. arcpy.wordpress.com/2013/06/07/disperse-overlaps-point
theJones 15/07/13

Đây thực sự là thiết lập các giá trị bất cứ nơi nào? Chưa bao giờ sử dụng UpdateCthon như thế trước đây. Thông thường tôi làm + = và sau đó cập nhật hàng. Mặt khác, điều duy nhất tôi làm khác trong phiên bản của mình là UpdateCoder sử dụng ['SHAPE @ X', 'SHAPE @ Y'] để bạn có thể truy cập chúng dưới dạng hàng [0] và hàng [1] thay vì phải thực hiện hàng [0] ] [0] và hàng [0] [1]. Hãy nghĩ rằng nó chỉ dễ dàng hơn một chút để đọc cho tôi.
eseglem

Vâng, đó là một cách hợp lệ để cập nhật các hàng. Trên thực tế, tôi chưa bao giờ thấy một giá trị nào được truyền trong updateRow () cho đến vài tuần trước. Nó thực sự là một ví dụ để cập nhật hình học.
Paul

Cảm ơn rất nhiều vì câu trả lời của bạn PolyGeo! Tôi thực sự ấn tượng rằng mã làm việc mà không cần sửa đổi. Tôi đang chạy ArcGIS Desktop 10.6
Rie Mino

8

Tôi ghi có @ tác phẩm nghệ thuật21 đã dẫn tôi đến giải pháp cuối cùng của tôi. Tôi thực sự đã tìm thấy một tập lệnh gần như hoàn chỉnh trong bài viết trợ giúp trực tuyến ArcGIS 10.0 có tên là " Tính toán ví dụ trường ", được liệt kê trong danh mục con " Mẫu mã hình học hình học " và " Đối với lớp tính năng điểm, hãy thay đổi tọa độ x của mỗi điểm bằng 100 "

Kịch bản cuối cùng mà tôi đã sử dụng trong công cụ "Trường tính toán" ModelBuilder là:

Biểu hiện:

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

trong đó ShiftXShiftY là các biến (dưới dạng tham số) được xác định trên khung vẽ ModelBuilder.

Loại biểu thức:

PYTHON_9.3

Khối mã:

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

Vì tất cả các mô hình hoạt động trên một bộ đã chọn, bạn cũng có thể tạo nó như một công cụ chung sẽ hoạt động cùng với các mô hình / công cụ khác trong các phiên xây dựng mô hình khác. Mô hình rất đơn giản mà tôi đã tạo (dưới dạng "plugin" cho các mô hình khác để thay đổi giá trị tọa độ) trông như thế này. Bằng cách đó, tôi có thể kiểm soát sự thay đổi trên cơ sở mỗi lựa chọn (như được xác định trong các mô hình khác):

Mô hình ShiftXY

Nó làm việc như một cơ duyên, cảm ơn tất cả các đầu vào của bạn!


có thể thay đổi tính năng theo giá trị bên trong bảng, được lưu trữ trong cột không?
Losbaltica

1
Nó nên Chỉ cần gán các tham số ShiftX và ShiftY cho các cột thích hợp.
RyanKDalton

Tôi bối rối bởi những gì bạn đang đi qua ở đây là "hình dạng". Bạn có thể giúp tôi không?
jbeclill

"Biểu thức" hiển thị các tham số đang được truyền vào hàm khối mã được gọi là shiftXYCoordins (). Vì vậy, tham số đầu tiên là! SHAPE!, Đó là trường hình dạng từ lớp.
RyanKDalton

5

Bạn cũng có thể sử dụng tập lệnh máy tính trường này để di chuyển các vị trí tính năng:

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

Bạn có thể bao gồm một phương thức Trường tính toán bổ sung trong mô hình của mình bằng hàm trên.


Đó là một cách thú vị để làm điều đó, tôi thực sự không biết bạn có thể tính toán trường trên trường hình dạng. Đây thực sự có thể là cách dễ nhất để hoàn thành nó nếu nó là phần bù cho tất cả các điểm. Có lẽ sẽ nhanh hơn để làm point.X + = myMoveX và point.Y + = myMoveY thay vì cần phải chuyển qua tọa độ X và Y cho nó.
eseglem

5

Tôi điều chỉnh giải pháp để di chuyển / dịch chuyển điểm theo một hướng nhất định (góc) và một khoảng cách nhất định.

Giống như:

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

và được gọi như shiftXYCoordLS Góc nên được đưa ra trong độ thập phân. 0 sẽ dịch chuyển lên Up, 90 ngay, ngay lập tức. Tôi đã nhận được chúng sau khi tạo các tính năng chỉ mục bản đồ dải và chuyển đổi chúng thành điểm.

Ngoài ra, hãy đảm bảo chọn Tên trường Tên hình dạng trước khi chạy :)

(Giải pháp được thử nghiệm trong ArcMap 10.0 SP5)


4

Như bạn có thể thấy, trong 10.1 sẽ dễ dàng hơn rất nhiều khi bạn có quyền truy cập vào mã thông báo con trỏ.

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

Điều này hoạt động cho 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.