Tìm kiếm nếu trường tồn tại trong lớp đối tượng


8

Tôi có một vài chục lớp tính năng, một trong số đó chứa trường tôi đang tìm kiếm. Chúng được lưu trữ trong một số cơ sở dữ liệu địa lý tập tin khác nhau.

Có cách nào nhanh chóng tìm kiếm từng lớp tính năng để tìm lớp có trường của tôi không? Hay tôi phải kiểm tra bảng thuộc tính của mỗi người trong Danh mục? Một số tệp có cùng tên nhưng được lưu trữ ở các vị trí riêng biệt.

Tôi muốn có thể thực hiện điều này bên trong một Calculate Valuecông cụ trong ModelBuilder, để mỗi lần tôi cần, tôi có thể chạy mô hình trên một tệp gdb duy nhất và nó sẽ tìm kiếm trong tất cả các lớp tính năng trong gdb đó và tìm trường .

Cho đến nay, tôi có một trình lặp lớp tính năng lặp lại trên tất cả các lớp tính năng trong tệp gdb theo cách đệ quy. Bên trong Calculate Valuetôi có đoạn mã sau:

findField(r"%Feature%", "%Search Field%")

def findField(fc, fi):
  lst = arcpy.ListFields(fc)
  for f in lst:
    if f.name == fi:
      return fc
    else:
      return "not found"

Các giá trị trả về được thu thập Output Valuesdưới dạng chuỗi. Đầu ra cho tất cả các lớp đối tượng đã "không tìm thấy", mặc dù trường tồn tại ít nhất 4 trong số chúng. nhập mô tả hình ảnh ở đây


Bạn đang cố gắng tính giá trị của cái gì? Bạn đang cố gắng chèn hồ sơ vào một bảng? Nó không có ý nghĩa nhiều với những gì bạn đang cố sử dụng công cụ Tính giá trị cho ...
RyanKDalton

Tôi đã đặt mã Python bên trong Calculate Valueđể tìm kiếm trường và để trả về đường dẫn của lớp đối tượng dưới dạng chuỗi nếu nó tìm thấy trường - xem câu trả lời của tôi dưới đây.
Cindy Jayakumar

Câu trả lời:


4

Tôi muốn một sự hiểu biết danh sách thay vì các hoạt động chuỗi (như câu trả lời được chấp nhận). Theo tôi, đây là dễ đọc và pythonic hơn. Hơn nữa, cách tiếp cận hiểu danh sách có thể được mở rộng bằng cách thêm chức năng ( str.lower()như @RyanDalton đã làm) rất dễ dàng.

def findField(fc, fi):
  fieldnames = [field.name for field in arcpy.ListFields(fc)]
  if fi in fieldnames:
    return "found in " +fc
  else:
    return "not found in " +fc

Nếu bạn thích một lót if-other Statement:

def findField(fc, fi):
  fieldnames = [field.name for field in arcpy.ListFields(fc)]
  return "found in " + fc if fi in fieldnames else "not found in " + fc

Hoặc thậm chí ngắn hơn, nhưng ít đọc hơn:

    def findField(fc, fi):
      return "found in " + fc if fi in [field.name for field in arcpy.ListFields(fc)] else "not found in " + fc

Vâng, đây sẽ là câu trả lời thích hợp hơn bây giờ. Tôi đã hỏi câu hỏi này từ rất lâu rồi, tôi nhớ rằng 9 tháng tôi đã lãng phí trên ModelBuilder trước khi chuyển sang Python hoàn toàn thay vì hack các bit và miếng ghép với nhau.
Cindy Jayakumar

20

Kiểm tra chức năng này từ Bjorn Kuiper để kiểm tra xem có tồn tại trường không :

def FieldExist(featureclass, fieldname):
    fieldList = arcpy.ListFields(featureclass, fieldname)

    fieldCount = len(fieldList)

    if (fieldCount == 1):
        return True
    else:
        return False

với ví dụ sau về việc sử dụng:

    if (not FieldExist(myFeatureClass, "myField")):
      arcpy.AddError("Field 'myField' does not exist in " + myFeatureClass)
      sys.exit()

Cuối cùng tôi đã sử dụng một cái gì đó tương tự, nhưng nó không hoàn toàn cho đầu ra mà tôi đang tìm kiếm.
Cindy Jayakumar

12

bạn có thể sử dụng Arcpy:

import arcpy

myField = "test"

env.workspace = "D:/test/data.gdb"
fcs = arcpy.ListFeatureClasses()

for f in fcs:
    fieldList = arcpy.ListFields(f)
    for field in fieldList:   
         if field.name == myField:
             print f

Bên cạnh đó, bạn có thể sử dụng os.walk cho các tệp trong ổ đĩa của mình dưới dạng:

path = r"C:"
for root, dirs, files in os.walk(path):
    for fileName in files:
            .........

Tôi hy vọng nó sẽ giúp bạn....


Tôi đã thử nó, và trong khi mã có ý nghĩa, nó không làm gì cả. Tôi đã kiểm tra nó bằng cách sử dụng một trường thuộc bốn lớp tính năng của tôi - tập lệnh đã chạy nhưng không xuất ra bất cứ thứ gì.
Cindy Jayakumar

oh xin lỗi, tôi quên lặp lại các trường trong fieldset, bây giờ tôi cập nhật câu trả lời của mình và tôi đã kiểm tra nó.
Aragon

Tôi đã thử với mã được cập nhật, nó chạy nhưng không có đầu ra mặc dù trường nằm trong một số lớp tính năng trong cơ sở dữ liệu địa lý.
Cindy Jayakumar

3

Arabella, có phải chiếc featureclass của bạn trong Bộ dữ liệu tính năng? Nếu vậy, giải pháp của @ Aragon sẽ không hoạt động vì bạn cần xem qua các bộ dữ liệu tính năng và sau đó kiểm tra featureclass.

Sử dụng mã của @ Aragon cũng như mã của @ gotchula từ Liệt kê tất cả các lớp tính năng trong GDB, bao gồm cả trong bộ dữ liệu tính năng , tôi đã tạo mã sau đây sẽ đọc qua tất cả các bộ dữ liệu tính năng và featureclass trong cơ sở dữ liệu địa lý.

LƯU Ý : Theo mặc định ListFields có vẻ phân biệt chữ hoa chữ thường. Tôi đã thêm mã để chuyển đổi cả tên trường do người dùng xác định và tên ListField thành chữ thường cho các tìm kiếm không phân biệt chữ hoa chữ thường. Bạn có thể cũng muốn vô hiệu hóa hầu hết các câu lệnh in, nhưng tôi đã để chúng ở đó để bạn có thể theo dõi mã khi nó đang chạy. Tôi cũng đã tạo ra hàm phụ FindField bên trong để tôi có thể gọi nó nhiều lần trong tập lệnh mà không phải mã lại.

import arcpy

def FindField(fc,myField):
    fieldList = arcpy.ListFields(fc)
    for field in fieldList:
        if str.lower(str(field.name)) == str.lower(myField):
            print "    " + fc + " contains fieldname: " + myField

myField = "test"
arcpy.env.workspace = "D:/test/data.gdb"

#Search root level featureclasses
for fc in arcpy.ListFeatureClasses():
    print "Searching root level Featureclasses..."
    print "  Searching " + fc
    FindField(fc,myField)

#Search Feature Datasets
for fds in arcpy.ListDatasets('','feature'):
    print "Searching FeatureDataset: " + fds

    for fc in arcpy.ListFeatureClasses('','',fds):
        print "  Searching Featureclass... " + fc
        FindField(fc,myField)

Tôi sẽ chạy nó trong một mô hình, vì vậy tôi đã điều chỉnh nó một chút và thử nghiệm nó. Tôi không chắc chắn những gì tôi muốn Calculate Valuetrở lại mặc dù - tôi có thể return "true" if FindField(fc,myField) =="true" else "false"?
Cindy Jayakumar

Ah, chỉ nhận ra rằng bình luận trước đây của tôi sẽ không cho tôi biết bất cứ điều gì. Cũng chạy thử nghiệm boolean bên trong mô hình không trả về gì.
Cindy Jayakumar

Bình định giá trị? Xét nghiệm Boolean? Tôi nghĩ bạn nên làm rõ câu hỏi của bạn về chính xác những gì bạn đang sau.
RyanKDalton

Tôi đã chỉnh sửa câu hỏi.
Cindy Jayakumar

2

Một vài người đã nhảy xung quanh cách tôi sẽ làm điều này, nhưng tôi chỉ muốn thêm một cách dễ dàng để thực hiện điều này:

if 'fieldname' in [f.name for f in arcpy.ListFields(fc)]:
    ## do something.

Điều gì có thể hữu ích hơn (nếu bạn đang lặp qua nhiều lớp tính năng) Tôi sẽ sử dụng ngược lại ở trên như một bộ lọc:

for fc in arcpy.ListFeatureClasses():
    if not 'fieldname' in [f.name for f in arcpy.ListFields(fc)]:
        continue
    ## now do something with the feature class.

1

Tìm thấy câu trả lời với một số trợ giúp từ mã trong câu trả lời cho câu hỏi này . Tôi lấy tất cả các tên trường, chuyển đổi chúng thành một chuỗi và sau đó tìm kiếm chuỗi cho trường của tôi. Mã trong Calculate Valuebây giờ trông như sau:

def findField(fc, fi):
  fieldList = arcpy.ListFields(fc)
  nameList = []
  for f in fieldList:
    nameList.append(f.name)
  str_lst = "!" + "!, !".join(nameList) + "!"
  return "found in" +fc if str_lst.find(fi) > 0 else "not found in " +fc

Các Output Valuesbây giờ chứa danh sách đầy đủ các lớp đối tượng trong đó có lĩnh vực tôi tìm kiếm, và not foundcho phần còn lại.

Thu thập giá trị đầu ra

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.