আর্কজিআইএস পাইথন সরঞ্জাম - টুলভালিডেটর শ্রেণিতে কাস্টম স্ক্রিপ্ট আমদানি করা


9

আমি একটি টুলভালিডেটর ক্লাস কাস্টমাইজ করার বিষয়ে গত সপ্তাহে একটি প্রশ্ন পোস্ট করেছি এবং খুব ভাল উত্তর পেয়েছি। প্রস্তাবিত সমাধানগুলির সাথে কাজ করার জন্য, আমি একটি কাস্টম মডিউল তৈরি করেছি যা ডিবিতে অনুসন্ধানগুলি সম্পাদন করে, এবং টুলভালিডেটর শ্রেণি (ড্রপ-ডাউন তালিকার জন্য মান সরবরাহ করতে) এবং পরে জিওপ্রসেসিং স্ক্রিপ্টে (অন্যটি পেতে ড্রপ-ডাউন তালিকায় নির্বাচিত আইটেমগুলির উপর ভিত্তি করে পরামিতি)। যাইহোক, আমি আসলে টুলভিডিয়েটার শ্রেণিতে কাস্টম মডিউলটি কল করতে পারি না। আমি ভাগ্যবিহীন পথে যুক্ত হওয়ার চেষ্টা করছি। আমি যখন এই পরিবর্তনগুলি স্ক্রিপ্টে প্রয়োগ করার চেষ্টা করি তখন আমি একটি রানটাইম ত্রুটি পাই: [এর্নো 9] খারাপ ফাইল বর্ণনাকারী। যদি আমি আমদানি লাইনটি মন্তব্য করি তবে কোনও ত্রুটি নেই।

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

আপনারা অনেকেই জিজ্ঞাসা করতে পারেন কেন আমি কেবল আরকোবজেক্টস সহ একটি কাস্টম সরঞ্জাম বাস্তবায়ন করি না। কারণটি হ'ল আমার শেষ ব্যবহারকারীদের কাছে তাদের কম্পিউটারে কোনও ডল নিবন্ধনের জন্য প্রয়োজনীয় প্রাইভেলিজ নেই।

আপডেট: এটি আমার সাথে আরকিজিআইএস 10 তে ঘটছিল মজার ব্যাপারটি যথেষ্ট, আমি প্রাথমিকভাবে টুলভালিডেটর শ্রেণীর প্রাথমিক পর্বের ফাংশনগুলির অভ্যন্তরের পথটিতে সংযোজন করছিলাম। যদি আমি টুলভালিডেটর শ্রেণীর বাইরে অ্যাপ্লিকেশন (অর্থাত্ উপরে) করি তবে সবকিছু প্রত্যাশার মতো কাজ করে।

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

আপডেট 2: আমি আমার সমস্যার সঠিক কারণ খুঁজে পেয়েছি বলে মনে করি। এই পোস্টে কোড স্নিপেটে, আমি সাইন.প্যাথটিতে প্রকৃত পাথ (প্রাক্তন সি: / ওয়ার্কিং / সামোয়ার্ডার) হিসাবে প্রদর্শিত হবে তা সংযোজন করছি। আমার প্রকৃত টুলভালিডেটর ক্লাসে, আমি os.path.dirname(__file__)"" \ আমার_স্পেশাল_ফোল্ডার ... " ব্যবহার করে একটি আপেক্ষিক পথ তৈরি করছিলাম। আমি প্রত্যাশা করছিলাম যে os.path.dirname(__file__)টুলবক্সের পথটি ফিরিয়ে আনবে, যেহেতু এতে টুলভালিডেটর শ্রেণি রয়েছে। আমি বিষয়টি দেখতে এসেছি। আমি যতদূর বলতে পারি, টুলভালিডেটর ক্লাসটি আসলে কোনও .py ফাইলে লেখা হয় না এবং আমি অনুমান করি যে এই কোডটি মেমরির ক্ষেত্রে পাইথন ইন্টারপ্রেটারের কাছে প্রেরণ করা হয়েছে, তাই __file__অকেজো, বা কিছু টেম্প স্ক্রিপ্ট স্থির থাকে এবং তারপরে এক্সিকিফল ( path_to_script) বলা হয়, আবার রেন্ডারিং__file__বেহুদা। আমি নিশ্চিত যে আমিও মিস করছি এমন আরও কিছু কারণ রয়েছে।

দীর্ঘ গল্প সংক্ষিপ্ত, আমি যদি একটি হার্ডকোডযুক্ত পথ ব্যবহার করি তবে sys.append কোথাও কাজ করে, অপেক্ষাকৃত পাথগুলি টুলভালিডেটর শ্রেণিতে এত ভাল কাজ করে না।


এটি কি 9.3 বা 10 এ আছে?
জেসন শিয়েরার

এসরিতে এখানে এটি পুনরুত্পাদন করতে আমরা সমস্যায় পড়ছি, যদি আমরা কারণটি আলাদা করি তবে আমরা 10.0 এসপি 3 এর জন্য কোনও ফিক্স ব্যাকপোর্ট করতে পারি। এরই মধ্যে, আমি মনে করি আপনি আগেরটির সাথে আটকে আছেন এবং পরবর্তী ব্যবহারের ধরণটি নয়।
জেসন শিয়েরার

উত্তর:


3

আমি যেভাবে এটি করি তা হ'ল, আর্কজিআইএস বা আরকগ্যাটালগ শুরু করার পরে প্রথমে একটি ডামি সরঞ্জাম চালান ("একবার এটি চালান") ডামি.পি স্ক্রিপ্ট কল করে। এটি করার পরে আপনি sys.argv [0] ব্যবহার করে যাচাইকারীটিতে পাইথন স্ক্রিপ্টগুলি আমদানি করতে পারেন। এটি সেই ফোল্ডারে নির্দেশ করবে যেখানে প্রথম স্ক্রিপ্টটি ছিল। তারপরে আপনি ডি ভ্যালিডেটর শ্রেণিতে প্রয়োজনীয় স্ক্রিপ্ট আমদানি করতে পারেন।

"এটিকে একবার চালান" সরঞ্জাম দ্বারা ডামি.পি স্ক্রিপ্ট বলা হয়:

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

দুঃখিত, বিন্যাসের সঠিক সম্মান জানাতে পারছেন না, মার্টেন ট্রম্প


3

অবশেষে ফাটল এই ভয়াবহ বাগ! উদাহরণস্বরূপ, আপনি যখন কোনও আপেক্ষিক মডিউল বা প্যাকেজ আমদানি করতে পরিবর্তনগুলি প্রয়োগ করার চেষ্টা করেন, আপনি নিম্নলিখিত ত্রুটিটি দেখতে পাবেন:

এখানে চিত্র বর্ণনা লিখুন

বিকল্প 1:
কেবলমাত্র বিকাশকারীদের জন্য, পাইথনপথটিতে মডিউলটির পুরো পথ যুক্ত করুন । কার্যকর হওয়ার আগে আপনাকে আরক্যাম্যাপ / আর্কিটেলগল পুনঃসূচনা করতে হবে। কোনও আপেক্ষিক পথ থেকে মোডিউল আমদানি করতে নীচের কোডটি ব্যবহার করুন (স্থাপনার জন্য)। চিন্তা করবেন না, শেষ ব্যবহারকারীকে তাদের পাইথনপ্যাথ ভেরিয়েবলটিতে কোনও সংযোজনের দরকার নেই, এটি কার্যকর হবে!

বিকল্প 2:
হার্ড-কোডেড পথটি সংযোজন করতে নীচের কোডে একটি অতিরিক্ত লাইন যুক্ত করুন, উদাহরণস্বরূপ: sys.path.append (r "c: \ temp \ test \ scripts")
আপনি যখন স্থাপনা করার জন্য প্রস্তুত থাকেন, আপনার একটি বহিরাগত ডিরেক্টরি, তবে এটির কোনও ব্যাপার নয়, সবার সাথেই এন্ডুয়েজারের কম্পিউটারে কাজ করা উচিত কারণ আপনি যে প্রথম পথটি যুক্ত করেছিলেন সেটি ছিল আপেক্ষিক ডিরেক্টরি (আমাদের লক্ষ্যটি ছিল কেবল ব্যর্থতা ডায়ালগটি পেরিয়ে যাওয়া)।

উভয় বিকল্পের জন্য কোড সাধারণ:

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

হালনাগাদ

বিদায়ের দুষ্ট কাটানো এবং পেস্ট করা! আমি কোডের নমুনা আপডেট করেছি যাতে টুলভালিডেটর ক্লাসটি পাঠাগার থেকে আমদানি করা হয়। আমি যখন একবার সরঞ্জাম পরামিতি প্রথম সেট করা হয় কাটা এবং পেস্ট। আমি এই কোড স্নিপিটটি আমদানি করা সরঞ্জামদৃশকের ডকস্ট্রিংয়ে সঞ্চয় করি।

এই উদাহরণে, উত্স ডিরেক্টরি নাম টিবিএক্স নামের উপর ভিত্তি করে। আপনার যদি বিভিন্ন উত্স ডিরেক্টরিতে দুটি সরঞ্জামবাক্স থাকে তবে এই পদ্ধতির সংঘর্ষগুলি এড়ানো হবে। উত্স ফোল্ডার নামকরণের জন্য আমি যে স্ট্যান্ডার্ডটি ব্যবহার করেছি তা নিম্নরূপ:
TOOLBOXNAME__anything.tbx -> TOOLBOXNAME.src

কেন "__Yantoming"? যেহেতু বাইনারি ফাইলগুলি আমাদের ডিভিসিএসে একীভূত করা যায় না, তাই আমরা ব্যক্তিদের জন্য সরঞ্জাম নির্ধারণ করতে পারি এবং পরিবর্তনগুলি হারাতে উদ্বেগ না করে। সরঞ্জামটি চূড়ান্ত হয়ে গেলে, এটি কেটে মাস্টারে আটকানো হয়।

ড্রপডাউনটি জনসাধারণের জন্য আমার উত্স ফোল্ডারে ফাইলগুলি অ্যাক্সেস করার প্রয়োজন ছিল, আপনার আমদানি করা মডিউলটির মধ্যে থেকে টুলবক্সে পাথ পেতে এই পদ্ধতিটি ব্যবহার করুন :

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

এটি কি এমন হতে পারে যে টুলভালিডেটর কোডটি প্যারামিটারের ডিফল্ট মান সেট করছে? স্ক্রিপ্ট সরঞ্জামের বৈশিষ্ট্যে প্যারামিটারের 'ডিফল্ট মান' সেটিংটি পরীক্ষা করুন।
blah238

পরামর্শের জন্য ধন্যবাদ. আমি পরীক্ষা করে দেখেছি এবং ডিফল্ট মানটি সরঞ্জাম বাক্সে সেট করা নেই ... তবে আমি সরঞ্জামবক্সটি অনুলিপি করে সমস্ত কিছুর নতুন নামকরণ করেছি এবং মানটি এখনও উভয় অনুলিপিতেই টিকে আছে। অতএব আমি আমার ক্যাশে ধারণাটি ত্যাগ করব এবং পরামর্শ দেব যে এটি আসলে .tbx ফাইলে সংরক্ষণ করা যেতে পারে, যা এখনও অদ্ভুত আচরণ।
এমজে

2

আমদানি বৈধতা মডিউলের শীর্ষে রেখে ToolValidatorক্লাসের বাইরে আমার জন্য ভাল কাজ করে বলে মনে হচ্ছে - আমি 10.0 এসপি 2 তে আছি। তবে আমি আমদানি করা মডিউলটির সাথে কোথাও কিন্তু কিছু করছি না 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:
    ...

আমি টুলভালিডেটর শ্রেণীর বাইরে আমদানি করার চেষ্টা করেছি তবে এটি আমদানির বিবরণীতে ব্যর্থ হবে। কোনও স্ক্রিপ্ট চালানোর আগে আপনি কি নতুনভাবে খোলা আর্কিটেলোগল ব্যবহার করছেন? আমি কল্পনা করব যে এজন্য ইএসআরআই ত্রুটিটি পুনরুত্পাদন করতে অসুবিধা হচ্ছে ... এটি কোনও নতুন স্ক্রিপ্ট চালানোর আগে কেবল নতুন খোলা অ্যাপ্লিকেশনটিতে ঘটে।
এমজে

এটি আমার জন্য নতুনভাবে খোলা আর্ককিগ্ল্যাজ সহ কাজ করে। আমি ভাবছি যদি এটি কোনও ক্লাস বনাম কোনও ফাংশন আমদানি করে যা সমস্যা?
blah238

ধন্যবাদ, আপনি হয়ত কিছু করতে পারেন .... আমি অস্পষ্টভাবে একটি ঘটনা মনে করি যেখানে এটি কাজ করেছিল যখন আমি সরাসরি কোনও ফাংশন আমদানি করি, আমি আরও কিছু পরীক্ষা করব।
এমজে

খুব অদ্ভুত আচরণ ... যতক্ষণ না আমি এটিকে ভেঙে ফেলতে পারি তা কাজ করবে। এটি ভাঙার পরে, এটি ধারাবাহিকভাবে একটি ত্রুটি নিক্ষেপ করবে। বিকাশকারী মেশিনে পাইথনপথ ব্যবহার করা বা দ্বিতীয় হার্ড কোডড পাথ সংযোজন, উপরে উল্লিখিত হিসাবে, কৌশলটি করেছেন।
এমজে

0

আমি আমার বৈধতাটিকে পাই ফাইলটিতে আমদানি করে এবং বিদ্যমান টিবিএক্সের সরঞ্জামের বৈধতার মধ্যে থেকে কল করে এটি স্থানান্তরিত করতে সক্ষম হয়েছি। কীটি কনস্ট্রাক্টরের ভিতরে আমদানি কল করছিল। যদি আমি এটিকে টুলভালিডেটর শ্রেণীর বাইরে থেকে ডাকি তবে আমদানি ব্যর্থ। টিবিএক্সের বৈধতা ট্যাবটির ভিতরে আমার যা ছিল তা এখানে।

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

আমার বৈধতা যুক্তিটি তখন এক্সপোর্টপার্সেল ইন্টারেক্টেড.টুলভ্যালিডেটারে থাকত। যেখানে এটি আরও সহজে বজায় রাখা যায়।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.