ArcGIS Python Tool - Nhập tập lệnh tùy chỉnh vào lớp ToolValidator


9

Tôi đã đăng một câu hỏi tuần trước về việc tùy chỉnh một lớp ToolValidator và nhận được một số câu trả lời rất tốt. Khi làm việc với các giải pháp được đề xuất, tôi đã tạo ra một mô-đun tùy chỉnh thực hiện các truy vấn trên db và sẽ được cả lớp ToolValidator gọi (để cung cấp các giá trị cho danh sách thả xuống) và sau đó trong tập lệnh xử lý địa lý (để lấy khác tham số dựa trên các mục được chọn trong danh sách thả xuống). Tuy nhiên, tôi dường như không thể thực sự gọi mô-đun tùy chỉnh trong lớp ToolValidator. Tôi đã cố gắng nối vào con đường không có may mắn. Khi tôi cố gắng áp dụng những thay đổi này cho tập lệnh, tôi gặp lỗi thời gian chạy: [Errno 9] Mô tả tệp xấu. Nếu tôi nhận xét ra dòng nhập khẩu, không có lỗi.

sys.path.append('my_custom_module_directory')
import my_custom_module

Nhiều bạn có thể hỏi tại sao tôi không triển khai một công cụ tùy chỉnh với ArcObjects. Lý do là người dùng cuối của tôi không có các cáo buộc cần thiết để đăng ký BẤT K d dlls nào trên máy tính của họ.

CẬP NHẬT: Điều này đã xảy ra với tôi trong ArcGIS 10. Điều thú vị là, ban đầu tôi đã nối thêm vào đường dẫn bên trong hàm initiazeParameter của lớp ToolValidator. Nếu tôi thực hiện nối thêm bên ngoài (tức là trên đầu trang) của lớp ToolValidator, mọi thứ sẽ hoạt động như mong đợi.

sys.path.append('C:/Working/SomeFolder')
import somescript -------->THIS WORKS

class ToolValidator:
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""

  def __init__(self):
    """Setup arcpy and the list of tool parameters."""
    import arcpy
    sys.path.append('C:/Working/SomeFolder')
    import somescript -------> THIS DOESNT WORK
    self.params = arcpy.GetParameterInfo()

CẬP NHẬT 2: Tôi nghĩ rằng tôi đã tìm thấy nguyên nhân thực sự của vấn đề của tôi. Trong đoạn mã trong bài đăng này, tôi đã thêm các đường dẫn có vẻ là đường dẫn thực (ví dụ: C: / Work / someFolder) vào sys.path. Trong lớp ToolValidator thực tế của tôi, tôi đã xây dựng một đường dẫn tương đối bằng cách sử dụng os.path.dirname(__file__)+ "\ my_special_folder ...". Tôi đã dự đoán rằng os.path.dirname(__file__)sẽ trả về đường dẫn của hộp công cụ, vì nó chứa lớp ToolValidator. Tôi đã đến để tìm thấy đây không phải là trường hợp. Theo như tôi có thể nói, lớp ToolValidator thực sự không bao giờ được ghi vào tệp .py và tôi suy đoán mã này được truyền cho trình thông dịch python trong bộ nhớ, vì vậy __file__vô dụng hoặc một số tập lệnh tạm thời được duy trì và sau đó thực thi ( path_to_script) được gọi, kết xuất lại__file__vô ích. Tôi chắc chắn có những lý do khác tôi cũng bị mất.

Tóm lại, nếu tôi sử dụng một đường dẫn được mã hóa cứng, sys.append hoạt động ở bất cứ đâu, các đường dẫn tương đối không hoạt động tốt trong lớp ToolValidator.


Đây là trong 9.3 hay 10?
Jason Scheirer

Chúng tôi đang gặp sự cố khi tái tạo điều này tại Esri, nếu chúng tôi cô lập nguyên nhân, chúng tôi có thể đưa ra bản sửa lỗi cho 10.0 SP3. Trong khi đó, tôi cho rằng bạn bị mắc kẹt với mẫu trước và không sử dụng mẫu sau.
Jason Scheirer

Câu trả lời:


3

Cách tôi làm là, sau khi khởi động ArcGIS hoặc ArcCatalog, trước tiên hãy chạy một công cụ giả ("Chạy cái này một lần") bằng cách gọi một tập lệnh dummy.py. Sau khi làm điều đó, bạn có thể nhập các tập lệnh python trong trình xác nhận bằng cách sử dụng sys.argv [0]. Điều này sẽ trỏ đến thư mục chứa tập lệnh đầu tiên. Sau đó, bạn có thể nhập tập lệnh cần thiết trong Lớp xác thực.

Tập lệnh dummy.py được gọi bởi công cụ "Chạy cái này một lần":

import arcgisscripting, sys, os
gp = arcgisscripting.create(9.3)

# set up paths to Toolshare, scripts en Tooldata
scriptPath = sys.path[0]  
toolSharePath = os.path.dirname(scriptPath)
toolDataPath = toolSharePath + os.sep + "ToolData"
gp.addmessage("scriptPath: " + scriptPath)
gp.addmessage("toolSharePath: " + toolSharePath)
gp.addmessage("toolDataPath: " + toolDataPath)

# Use this to read properties, VERY handy!!
import ConfigParser
config = ConfigParser.SafeConfigParser()
config.readfp(open(scriptPath + os.sep + 'properties.ini'))
activeOTAP = config.get('DEFAULT', 'activeOTAP')
activeprojectspace = config.get('DEFAULT', 'activeprojectspace')
activeproject = config.get('DEFAULT', 'activeproject')
activesdeconnection = config.get('DEFAULT', 'activesdeconnection')

Xin lỗi, không thể có được định dạng đúng Trân trọng, Maarten Tromp


3

Cuối cùng đã phá được lỗi khủng khiếp này! Ví dụ: khi bạn cố gắng áp dụng các thay đổi để nhập mô-đun hoặc gói tương đối, bạn có thể thấy lỗi sau:

nhập mô tả hình ảnh ở đây

Tùy chọn 1:
Chỉ dành cho nhà phát triển, thêm đường dẫn đầy đủ vào mô-đun vào PYTHONPATH . Bạn sẽ cần khởi động lại ArcMap / ArcCatalog trước khi nó có hiệu lực. Sử dụng mã dưới đây để nhập mô-đun từ một đường dẫn tương đối (để triển khai). Đừng lo lắng, người dùng cuối không cần bất kỳ bổ sung nào vào biến PYTHONPATH của họ, nó sẽ hoạt động!

Tùy chọn 2:
Thêm một dòng bổ sung vào mã bên dưới để nối thêm đường dẫn được mã hóa cứng, ví dụ: sys.path.append (r "c: \ temp \ test \ scripts")
Khi bạn đã sẵn sàng triển khai, bạn có một thư mục không liên quan, nhưng không thành vấn đề, tất cả nên hoạt động trên máy tính của enduser vì đường dẫn đầu tiên bạn thêm là thư mục tương đối (mục tiêu của chúng tôi là vượt qua hộp thoại thất bại).

Mã chung cho cả hai tùy chọn:

import os
import sys

tbxPath = __file__.split("#")[0]
srcDirName = os.path.basename(tbxPath).rstrip(".tbx").split("__")[0] + ".src" 
tbxParentDirPath =  os.path.dirname(tbxPath)
srcDirPath = os.path.join(tbxParentDirPath, srcDirName)

sys.path.append(srcDirPath)
# sys.path.append(r"c:\temp\test\scripts")  #option2

from esdlepy.metrics.validation.LandCoverProportions import ToolValidator

Cập nhật

Chia tay ác cắt và dán! Tôi đã cập nhật mẫu mã để lớp ToolValidator được nhập từ thư viện. Tôi cắt và dán chỉ một lần khi các tham số công cụ được đặt lần đầu tiên. Tôi lưu trữ đoạn mã này trong chuỗi tài liệu của ToolValidator đang được nhập.

Trong ví dụ này, tên thư mục nguồn dựa trên tên tbx. Cách tiếp cận này tránh va chạm nếu bạn có hai hộp công cụ với các thư mục nguồn khác nhau. Tiêu chuẩn tôi đã sử dụng để đặt tên thư mục nguồn như sau:
TOOLBOXNAME__anything.tbx -> TOOLBOXNAME.src

Tại sao "__ mọi thứ"? Vì các tệp nhị phân không thể được hợp nhất trong DVCS của chúng tôi, chúng tôi có thể gán các công cụ cho các cá nhân và không lo lắng về việc mất các thay đổi. Khi công cụ được hoàn thành, nó được cắt và dán vào bản gốc.

Tôi cũng cần truy cập các tệp trong thư mục nguồn để điền vào danh sách thả xuống, sử dụng phương pháp này để nhận đường dẫn đến hộp công cụ từ trong mô-đun đã nhập của bạn:

import __main__
tbxPath = __main__.__file__.split("#")[0]

Có thể là mã ToolValidator đang đặt giá trị mặc định của tham số? Kiểm tra cài đặt 'Giá trị mặc định' của tham số trong thuộc tính công cụ tập lệnh.
blah238

Cám ơn vì sự gợi ý. Tôi đã kiểm tra và giá trị mặc định không được đặt trong hộp công cụ ... nhưng tôi đã sao chép hộp công cụ và đổi tên mọi thứ và giá trị vẫn tồn tại trong cả hai bản sao. Do đó, tôi sẽ từ bỏ ý tưởng bộ nhớ cache của mình và đề xuất rằng nó thực sự có thể được lưu trữ trong tệp .tbx, đây vẫn là hành vi kỳ quặc.
MJ

2

Đặt các mục nhập ở đầu mô-đun xác nhận, bên ngoài ToolValidatorlớp có vẻ hoạt động tốt đối với tôi - Tôi đang ở trên 10.0 SP2. Tuy nhiên tôi không làm gì với mô-đun nhập ở bất cứ đâu ngoài updateParameters.

import os
import sys
scriptDir = os.path.join(os.path.dirname(__file__.split("#")[0]), "Scripts") 
sys.path.append(scriptDir)
from someModuleInScriptDir import someFunction

class ToolValidator:
    ...

Tôi đã thử nhập bên ngoài lớp ToolValidator nhưng nó sẽ thất bại trong câu lệnh nhập. Bạn có đang sử dụng ArcCatalog mới mở, trước khi bất kỳ tập lệnh nào được chạy không? Tôi sẽ tưởng tượng đây là lý do tại sao ESRI gặp khó khăn khi tái tạo lỗi ... nó chỉ xảy ra trong một ứng dụng mới mở trước khi bất kỳ tập lệnh nào được chạy.
MJ

Nó hoạt động với tôi với ArcCatalog mới mở. Tôi tự hỏi nếu nó đang nhập một lớp so với một chức năng đó là vấn đề?
blah238

Cảm ơn, bạn có thể đang làm gì đó .... Tôi mơ hồ nhớ một trường hợp nó hoạt động khi tôi nhập trực tiếp một chức năng, tôi sẽ thực hiện thêm một số thử nghiệm.
MJ

Hành vi rất kỳ quặc ... nó sẽ hoạt động cho đến khi tôi xoay sở để phá vỡ nó. Sau khi phá vỡ nó, nó sẽ liên tục đưa ra một lỗi. Sử dụng PYTHONPATH trên máy của nhà phát triển hoặc nối thêm đường dẫn được mã hóa cứng thứ hai, như đã nêu ở trên, đã thực hiện thủ thuật này.
MJ

0

Tôi đã có thể di chuyển xác thực của mình vào một tệp py bằng cách nhập nó và gọi nó từ bên trong xác thực công cụ của TBX hiện có. Chìa khóa đã gọi việc nhập bên trong hàm tạo. Nếu tôi gọi nó từ bên ngoài lớp ToolValidator thì quá trình nhập thất bại. Đây là những gì tôi đã có trong tab xác nhận của TBX.

import arcpy
import os
import sys

class ToolValidator(object):
   """Class for validating a tool's parameter values and controlling
   the behavior of the tool's dialog."""

def __init__(self):
   """Setup arcpy and the list of tool parameters."""
   self.scriptDir = os.path.dirname(__file__.split("#")[0])
   sys.path.append(self.scriptDir)
   import ExportParcelIntersected
   self.validator = ExportParcelIntersected.ToolValidator()
   self.params = self.validator.params

 def initializeParameters(self):
   """Refine the properties of a tool's parameters.  This method is
   called when the tool is opened."""
   self.validator.initializeParameters()
   return

 def updateParameters(self):
   """Modify the values and properties of parameters before internal
   validation is performed.  This method is called whenever a parameter
   has been changed."""
   self.validator.updateParameters()
   return

 def updateMessages(self):
   """Modify the messages created by internal validation for each tool
   parameter.  This method is called after internal validation."""
   self.validator.updateMessages()
   return

Logic xác thực của tôi sau đó sống trong ExportParcelIntersected.ToolValidator (). Nơi mà nó có thể được duy trì dễ dàng hơn.

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.