Chỉnh sửa điểm cuối trong Polyline bằng ArcPy?


8

Tôi đang cố gắng tạo một công cụ chụp điểm cuối đa tuyến trong Python bằng ArcGIS 10. bằng cách sử dụng Công cụ tìm kiếm Tôi đọc trong các giá trị cho một mảng các đối tượng dòng (chứa id tính năng của dòng và hai đối tượng "Endpoint" - trước tiên và cuối cùng - chứa tọa độ X và Y của mỗi), sau đó xử lý một số phép nội suy dữ liệu của các điểm để cung cấp cho tất cả các điểm giá trị chính xác của chúng.

Cho đến nay, phần đó hoạt động hoàn hảo. Tuy nhiên, khi tôi cố gắng quay lại và chỉnh sửa shapefile, tôi có thể thấy dữ liệu mà tôi đang thay đổi, nhưng dường như tôi không thể chỉnh sửa nó.

Đây là mã để cập nhật các trường:

# --------------------------
#
# Update the file with the new EPs
#
# --------------------------

# Create update cursor
#
rows = arcpy.UpdateCursor(outputDirectory + "\\" + trails_fc + ".shp")

# Enter for loop for each feature/row
#
i = 0
for row in rows:
    # Create the geometry object
    #
    feat = row.getValue(shapefieldname)

    partnum = 0

    if feat.getPart(partnum)[0].X != allLines[i].startEP.x:
        arcpy.AddMessage("Change: " + str(feat.getPart(partnum)[0].X) + " to " + str(allLines[i].startEP.x) )
        feat.getPart(partnum)[0].X = allLines[i].startEP.x

    rows.updateRow(row)

    arcpy.AddMessage("Now is: " + str(feat.getPart(partnum)[0].X))

    i+=1

Bài đọc của tôi bao gồm các câu như thế này:

Thay đổi: -105.512166832 thành -105.699533165 Bây giờ là: -105.512166832

Vì một số lý do, các hàng không được cập nhật. Và đối với cuộc sống của tôi, tôi không thể tìm thấy một hướng dẫn hoặc hướng dẫn về cách chỉnh sửa một điểm cụ thể trong đa tuyến. Tôi chỉ có thể tìm cách chỉnh sửa một điểm dưới dạng một trường trong một shapefile điểm.

Còn ai có ý tưởng nào không?


1
Bạn chỉ có giấy phép ArcView? Nếu bạn có ArcEditor / ArcInfo, bạn đang cố gắng thực hiện điều gì bằng cách xây dựng công cụ snap của riêng bạn mà công cụ xử lý địa lý SNAP của Arc10 sẽ không thực hiện được (ArcToolbox> Công cụ chỉnh sửa)? ( help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#// Thay )
RyanKDalton

Có thể có một cách khác, nhưng tôi đang cố gắng hiểu cách thao tác tọa độ cho dù công cụ đó có hoàn toàn nguyên bản hay không. Đó là nhiều kinh nghiệm hơn cho chức năng.
Sói Kivak

Câu trả lời:


6

Thật không may, bạn không thể gán trực tiếp các giá trị mới cho hình dạng hiện có của một tính năng - thay vào đó, bạn phải tạo một đối tượng hình học mới và cập nhật trường hình dạng của đối tượng đó với đối tượng mới đó. May mắn thay, các đối tượng mảng có một replacephương thức. Vì vậy, thay vì cố gắng sửa đổi trực tiếp tọa độ X của điểm bên trong mảng, bạn cần phải:

  • Tạo một arcpy.Pointđối tượng mới với tọa độ chính xác (có vẻ như bạn có thể đã làm điều này rồi)
  • Nhận một bản sao của đối tượng mảng được lưu trữ trong trường Hình dạng của hàng
  • Sử dụng replacephương pháp để đặt điểm mong muốn trong mảng của bạn với điểm đã sửa đổi
  • Tạo một đối tượng Polyline mới với mảng đó
  • Sử dụng setValuephương thức của đối tượng hàng để cập nhật trường Hình dạng với Polyline mới, chính xác của bạn
  • Sử dụng updateRowphương thức của đối tượng con trỏ để chèn hàng đã thay đổi vào tập dữ liệu.

Cụ thể:

for r in cur:
    ary = r.getValue("SHAPE").getPart(0)
    ary.replace(0,correct_point_object) # first arg 0 replaces the first point in the line
    newLine = arcpy.Polyline(ary)
    r.setValue("SHAPE",newLine)
    cur.updateRow(r)

Lưu ý replacephương thức lấy một chỉ mục và một giá trị. Thật không may, nó không chấp nhận ví dụ -1 như một chỉ mục đến điểm cuối cùng trong mảng. Tuy nhiên bạn có thể nói my_array[my_array.count].

Có vẻ như bạn đang tính toán tọa độ X ở một nơi khác và truy xuất chúng sau này. Nếu đây là trường hợp, có lẽ tôi sẽ đi cả con lợn và tạo các đối tượng Polyline mới với các điểm chính xác cho mỗi dòng trong khi bạn đang tính toán tọa độ chính xác. Điều này có thể sẽ dễ dàng hơn & sạch hơn. Bằng cách đó, mã của bạn có thể giống như

row_num = 0
    for r in cur:
        r.setValue(shapeField,correct_geometry_list[row_num])
        cur.updateRow(r)
        row_num += 1

Mà, ít nhất là đối với tôi, rõ ràng hơn một chút ... nhưng đó là phong cách!

Chỉnh sửa để thêm:

Tôi không thể phù hợp với điều này trong một bình luận. Không nhìn thấy mã của bạn, thật khó để biết nó có thể rơi ở đâu. Đây là một kịch bản thử nghiệm hoàn chỉnh phù hợp với tôi. Hy vọng nó sẽ phục vụ như là một tài liệu tham khảo. Lưu ý rằng ở đây tôi đang tính toán hình học mới trực tiếp từ hình cũ, thay vì thực hiện hai lần chuyền; điều đó có thể hoặc không thể tùy thuộc vào cách bạn thực hiện các tính toán vị trí chụp nhanh của mình. Ngoài ra, lần này tôi đang xây dựng một mảng hoàn toàn mới dựa trên mảng cũ thay vì sử dụng replacephương thức này, trong trường hợp cần thiết.

import arcpy

def offsetPoint(old_point,X_distance,Y_distance):
    """Trivial function to offset a point - replace with what you're
actually doing."""
    new_point = arcpy.Point(old_point.X+X_distance,
                            old_point.Y+Y_distance)
    return new_point

def offsetFirstPointInLine(line_geom,X_distance,Y_distance):
    """Takes a Polyline geometry object and returns a new Polyline with
the first point of the first part offset by the distance given."""
    array = line_geom.getPart(0)
    first_point = array[0]
    new_point = offsetPoint(first_point,X_distance,Y_distance)

    # Build a new array with your new point in the 0th position, and
    # the rest of the points from the old array.
    new_array = arcpy.Array([new_point]+
                            [array.getObject(x) for x in range(1,array.count)])

    # Then make a new Polyline object with that array.
    new_line = arcpy.Polyline(new_array)
    return new_line

fc = r"C:\Users\student\Documents\ArcGIS\Default.gdb\SomeStorms"

cur = arcpy.UpdateCursor(fc)

for r in cur:
    geom = r.getValue("SHAPE")
    r.setValue("SHAPE",offsetFirstPointInLine(geom,-45000,-5000))
    cur.updateRow(r)

del r,cur

Hy vọng rằng sẽ giúp làm sáng tỏ nó.


Tôi đã có cảm giác chìm đó có thể là trường hợp. Cảm ơn bạn rất nhiều vì đã giải thích làm thế nào để làm điều đó! Tôi nghĩ rằng tôi sẽ chỉ tạo ra toàn bộ polylines như bạn nói. Bằng cách đó tôi có nhiều quyền kiểm soát hơn nếu tôi muốn quay lại và điều chỉnh thứ khác.
Sói Kivak

Thật không may, tôi đã không làm cho nó hoạt động. Một cái gì đó rất kỳ lạ đang diễn ra. Nếu tôi sử dụng "ary = r.getValue (" SHAPE "). GetPart (0)" và sau đó ngay lập tức tạo một đa tuyến từ ary và đặt giá trị, shapefile trông hoàn toàn khác. Điều này không nên xảy ra, phải không?
Sói Kivak

Thật khó để nói chính xác những gì sai; Tôi đã cập nhật câu trả lời với một giải pháp đầy đủ hơn trong trường hợp nó giúp. Trên thực tế - có vẻ như bạn đang tạo mảng, sau đó sửa đổi điểm; thay vào đó, bạn nên tạo một điểm mới, sau đó sửa đổi mảng để bao gồm điểm đó (hoặc tạo một mảng mới với điểm đó như trên).
ThomM

ThomM: Cảm ơn đã giải thích mở rộng! Tôi rất trân trọng điều này! Như tôi đã tìm ra ngày hôm qua, tôi đang tạo các lớp arcpy.Array (), arcpy.Point () và sử dụng lớp arcpy.Ployline () một cách chính xác. Nhưng có vẻ như có một lỗi trong lập trình thực tế của hàm tạo lớp arcpy.Ployline (). Tôi đã gửi báo cáo lỗi, nhưng có vẻ như hàm tạo cho arcpy.Polyline () đang 'tung ra' hoặc bỏ qua arcpy.Point () với các giá trị tương tự nhưng vẫn duy nhất. Vì vậy, trong khi tôi nghĩ vấn đề của tôi là thiếu hiểu biết về cách thức hoạt động của nó, thì có vẻ như đó có thể là một lỗi.
Sói Kivak
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.