יותר

לא ניתן לחזור ולחזור כראוי על IFeatureCursor (מתקשר ל- ArcObjects מ- Python)


התחלתי לאחרונה להשתמש בכמה מ- ArcObjects בתוך מודולי ה- Python שלי. לאחר שכל הפוסטים והתובנות השימושיות ששיתפו @matt wilkie et al הצלחתי להתחיל די מהר (התקנת הקומטיפים עם פיפ והורדת קטע 10.2 מ- Pierssen ושינוי "10.2" ל- "10.3" בכל מקום).

אני מנסה לחזור על זהIFeatureCursorולקבל את כל התכונות בתוך מחלקת תכונה. עם זאת, אני מחזיר רק את התכונה העדכנית ביותר (עם ערך ObjectID הגבוה ביותר).

מכאן יש 6 תכונות במחלקת התכונותxrange (6)כדי שיהיה פשוט.

מאת comtypes.client יבוא GetModule, CreateObject מ snippets102 ייבוא ​​GetStandaloneModules, InitStandalone # בפעם הראשונה, צריך לייבא את "StandaloneModules". יכול להגיב מאוחר יותר. #GetStandaloneModules () InitStandalone () def iterate_features (): # קבל את מודול GDB esriGeodatabase = GetModule (r "C:  Program Files (x86)  ArcGIS  Desktop10.3  com  esriGeoDatabase.olb") esriDataSourcesGDB = "C:  Program Files (x86)  ArcGIS  Desktop10.3  com  esriDataSourcesGDB.olb") # צור קובץ מצביע geodatabase file_gdb_pointer = CreateObject (progid = esriDataSourcesGDB.FileGDBWorkspaceFactory, interface = esriGeodatabase_File_Factory_File_Factory_Factory_Factory_Factory_Factory_Factory_Factory_Factory_Factory_Factory_Filey_Comment (r "C:  GIS  arcobjects  MyData.gdb", hWnd = 0) #תוכן גישה בתוך gdb feature_workspace = file_gdb.QueryInterface (esriGeodatabase.IFeatureWorkspace) in_fc = feature_workspace.OpenFeatureClass ("Warehouses"): in__ "" "מחזיר מצביעים לאובייקטים של IFeature בתוך תכונת Class" "" cur = in_fc.Search (None, True) עבור i in xrange (6): feature_obj = yield cur.NextFeature () feats = [feat for feat in enum_features (in_fc) )] הדפס [f.OID עבור f בהישגים] iterate_features ()

השורההדפס [f.OID עבור f בהישגים]החזרות[6, 6, 6, 6, 6, 6].

מה אני עושה לא נכון? אותו היגיון עם מחולל/תשואה (def enum_features ()) פועל מצוין כאשר חוזר על שיעורי תכונות בתוך מערך הנתונים של התכונות.

הfeats_OIDs = [feat.OID עבור הישג ב- enum_features (in_fc)]ייתן תוצאות נכונות,[1, 2, 3, 4, 5, 6], מבלי שאעשה שינויים בקוד. נראה שהבעיה היא כשאני יוצר רשימת תכונות[הישג על הישג ב- enum_features (in_fc)], כולם מתייחסים לאותה תכונה (כי כשאני בוחן כל אחד מהם מאוחר יותר, לכל אחד מהם יש את אותו OID).


אני חושב שגישה טובה יותר עשויה להיות לקבל את הספירה תחילה באמצעותFeatureCount ()שיטת הIFeatureClassמִמְשָׁק. זה עבד בשבילי:

יבוא arcobjects # העותק שלי של קטעי קטע מתוך comtypes.client יבוא CreateObject יבוא os pars = r'C:  TEMP  frontage_test.gdb  parcels 'fc = arcobjects.OpenFeatureClass (*os.path.split (pars)) def enum_features (fc ): יבוא comtypes.gen.esriGeoDatabase כ esriGeoDatabase qf = CreateObject (progid = esriGeoDatabase.QueryFilter, interface = esriGeoDatabase.IQueryFilter) #תוכל להשתמש NewObj גם כאן אם יש לך את זה ב- qfcc (fc) .חפש (qf, True) אחר i ב- xrange (count): cur curved. NextFeature () עבור ft in enum_features (fc): print ft.OID

ומן שליחפצי קשתמודול, זו הפונקציה OpenFeatureClass () שלי:

def OpenFeatureClass (sFileGDB, sFCName): InitStandalone () יבוא comtypes.gen.esriGeoDatabase כמו esriGeoDatabase יבוא comtypes.gen.esriDataSourcesGDB כמו esriDataSourcesGDB pWSF = NewObj (esriDataSourcesGDB.FileGDBWorkspaceFactory,  esriGeoDatabase.IWorkspaceFactory2) PWS = pWSF.OpenFromFile (sFileGDB, 0) pFWS = CType (pWS, esriGeoDatabase.IFeatureWorkspace) # קבע אם קיים FC לפני שתנסה לפתוח # http://edndoc.esri.com/arcobjects/9.2/ComponentHelp/esriGeoDatabase/IWorkspace2_NameExists.htm # 5 = סוג נתונים מסוג class = pWS type = 2 (pWS, esriGeoDatabase.IWorkspace2) אם pWS2.NameExists (5, sFCName): pFC = pFWS.OpenFeatureClass (sFCName) אחר: pFC = אין הדפסה '** % s לא נמצא' % sFCName החזר pFC

לַעֲרוֹך

@Alex Tereshenkov העלה את השאלה כיצד להכניס זאת לרשימת הצעותIFeatureאובייקטים, ואת זה ניתן לעשות עם הבנת רשימה. אז התשובה היא כן.

>>> features = [ft for ft in enum_features (fc)] >>> features [: 5] # המון תכונות, אז בואו רק נראה את כמה [, , , , ] >>>

עריכה 2:

מצאתי את הבעיה. אנחנו לא ממש רוצים למחזר את השורות. ברגע ששיניתי את זה לשקר, נוכל להוציא כל אחדIFeatureלתוך רשימה.

cur = fc.Search (None, False) #אין למחזר אובייקט IFeature זה!

אז עכשיו כשאתה עושה את זה אתה אמור לקבל אובייקט לכל שורה:

features = [ft for ft in enum_features (fc)] הדפס [ft.OID עבור ft בתכונות [: 5]]

זה מפורט במסמכי העזרה:

פרמטר המיחזור שולט בהתנהגות הקצאת אובייקטים בשורה. סמנים למיחזור מייבשים מחדש אובייקט תכונה יחיד בכל אחזור וניתן להשתמש בהם כדי לייעל את הגישה לקריאה בלבד, למשל בעת ציור. זה לא חוקי לשמור הפניה לאובייקט תכונה המוחזר על ידי סמן מיחזור על פני מספר שיחות ל- NextFeature בסמן. אין לשנות תכונות שהוחזרו על ידי סמן מיחזור. סמנים שאינם ממוחזרים מחזירים אובייקט תכונה נפרד בכל אחזור. ניתן לשנות ולשמור את התכונות שמוחזרות על ידי סמן שאינו ממוחזר בהתנהגות פולימורפית.

ה- Geodatabase מבטיח "סמנטיקה ייחודית של מופעים" על אובייקטים של תכונה שאינם ממוחזרים שנאספו במהלך הפעלת עריכה. במילים אחרות, אם התכונה שאוחזרה על ידי סמן חיפוש כבר קיבלה מיידיות והפנייה אליה מופנית על ידי היישום המתקשר, אז ההחזרה לאובייקט התכונה הקיים מוחזרת.

סמנים של תכונה שאינם ממוחזרים חזרו משיטת החיפוש צריך לשמש בעת העתקת תכונות מהסמן לסמן הוספה של מחלקה אחרת. הסיבה לכך היא שסמן מיחזור עושה שימוש חוזר באותה גיאומטריה ובנסיבות מסוימות כל התכונות שמוכנסות לסמן ההכנסה עשויות להיות בעלות אותה גיאומטריה. שימוש בסמן שאינו מיחזור מבטיח שכל גיאומטריה ייחודית.


צפו בסרטון: ArcMAP Addin using C#. ArcGIS and Visual Studio (אוֹקְטוֹבֶּר 2021).