أكثر

لا يمكن تكرار IFeatureCursor بشكل صحيح (استدعاء ArcObjects من Python)

لا يمكن تكرار IFeatureCursor بشكل صحيح (استدعاء ArcObjects من Python)


لقد بدأت مؤخرًا في استخدام بعض عناصر ArcObjects داخل وحدات Python النمطية الخاصة بي. بعد الحصول على جميع المنشورات والأفكار المفيدة التي شاركهاmatt wilkie وآخرون ، تمكنت من البدء بسرعة كبيرة (تثبيت comtypes مع pip وتنزيل المقتطف 10.2 من Pierssen وتغيير "10.2" إلى "10.3" في كل مكان).

أحاول التكرارIFeatureCursorواحصل على جميع الميزات داخل فئة الميزات. ومع ذلك ، سأستعيد أحدث ميزة فقط (بأعلى قيمة ObjectID).

هناك 6 ميزات في فئة الميزة وبالتالياكس رانج (6)لتبسيط الأمر.

من comtypes.client استيراد GetModule و CreateObject من snippets102 استيراد GetStandaloneModules و InitStandalone # أول مرة تحتاج إلى استيراد "StandaloneModules". يمكن التعليق عليها لاحقًا. #GetStandaloneModules () InitStandalone () def iterate_features (): # Get the GDB module esriGeodatabase = GetModule (r "C:  Program Files (x86)  ArcGIS  Desktop10.3  com  esriGeoDatabase.olb") esriDataSourcesGDB = GetModule (r "C:  Program Files (x86)  ArcGIS  Desktop10.3  com  esriDataSourcesGDB.olb") # إنشاء مؤشر قاعدة بيانات جغرافية ملف file_gdb_pointer = CreateObject (progid = esriDataSourcesGDB.FileGDBWorkspaceFactory ، الواجهة = esriGeodactory.IWorkFrompaceFrom) (r "C:  GIS  arcobjects  MyData.gdb"، hWnd = 0) #access content within gdb feature_workspace = file_gdb.QueryInterface (esriGeodatabase.IFeatureWorkspace) in_fc = feature_workspace.OpenFeatureClass ("Warehouses") تُعيد "" "مؤشرات إلى كائنات IFeature داخل فئة الميزة" "" cur = in_fc.Search (بلا ، صحيح) لـ i في xrange (6): feature_obj = العائد 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)]، يشيرون جميعًا إلى نفس الميزة (لأنني عندما أستكشف كل واحد منهم لاحقًا ، يكون لكل منهم نفس معرف الكائن).


أعتقد أن الأسلوب الأفضل هو الحصول على العد أولاً باستخدامFeatureCount ()طريقةIFeatureClassواجهه المستخدم. لقد نجح هذا بالنسبة لي:

import arcobjects # نسختي من المقتطفات من comtypes.client import CreateObject import os pars = r'C:  TEMP  frontage_test.gdb  parcels 'fc = arcobjects.OpenFeatureClass (* os.path.split (pars)) def enum_features (fc ): import comtypes.gen.esriGeoDatabase كـ esriGeoDatabase qf = CreateObject (progid = esriGeoDatabase.QueryFilter، interface = esriGeoDatabase.IQueryFilter) #can استخدام NewObj هنا أيضاً إذا كان لديك في عدد المقتطفات الخاصة بك = fc.FeatureCount (qf) cur = البحث (qf ، صحيح) عن i في xrange (count): إنتاج cur.NextFeature () لـ ft in enum_features (fc): print ft.OID

ومن بلديكائنات قوسيةالوحدة النمطية ، هذه هي وظيفة OpenFeatureClass () الخاصة بي:

def OpenFeatureClass (sFileGDB، sFCName): InitStandalone () استيراد comtypes.gen.esriGeoDatabase كـ esriGeoDatabase import comtypes.gen.esriDataSourcesGDB كـ esriDataSourcesGDB pWSF = NewObj (esriDataSourcesGDB.FileGFactory ،. pFWS = CType (pWS، esriGeoDatabase.IFeatureWorkspace) # تحديد ما إذا كان FC موجودًا قبل محاولة فتح # http://edndoc.esri.com/arcobjects/9.2/ComponentHelp/esriGeoDatabase/IWorkspace2_NameExists.htm # 5 = نوع بيانات فئة الميزة pWS2 = (pWS، esriGeoDatabase.IWorkspace2) إذا كان pWS2.NameExists (5، sFCName): pFC = pFWS.OpenFeatureClass (sFCName) وإلا: pFC = بلا طباعة '**٪ s غير موجود'٪ sFCName يُرجع pFC

تعديل

أثارAlex Tereshenkov مسألة كيفية إدراج هذا في قائمة المؤشراتIF Featureالكائنات ، ويمكن القيام بذلك باستخدام قائمة الفهم. لذلك فإن الجواب هو نعم.

>>> features = [ft for ft in enum_features (fc)] >>> features [: 5] # الكثير من الميزات ، لذا لنعرض فقط أول بضعة [, , , , ] >>>

تحرير 2:

لقد وجدت المشكلة. لا نريد في الواقع إعادة تدوير الصفوف. بمجرد أن أغير ذلك إلى خطأ ، يمكننا الخروج من كل منهماIF Featureفي قائمة.

cur = fc.Search (لا شيء ، خطأ) # لا تقم بإعادة تدوير كائن IFeature!

الآن عند القيام بذلك ، يجب أن تحصل على كائن لكل صف:

features = [ft for ft in enum_features (fc)] print [ft.OID for ft in features [: 5]]

تم وضع هذا في مستندات المساعدة:

تتحكم معلمة إعادة التدوير في سلوك تخصيص كائن الصف. تعمل مؤشرات إعادة التدوير على إعادة ترطيب عنصر ميزة واحد في كل عملية إحضار ويمكن استخدامها لتحسين الوصول للقراءة فقط ، على سبيل المثال ، عند الرسم. من غير القانوني الاحتفاظ بمرجع على كائن ميزة يتم إرجاعه بواسطة مؤشر إعادة التدوير عبر مكالمات متعددة إلى NextFeature على المؤشر. لا يجب تعديل الميزات التي يتم إرجاعها بواسطة مؤشر إعادة التدوير. ترجع المؤشرات غير القابلة لإعادة التدوير كائن ميزة منفصل على كل عملية إحضار. يمكن تعديل الميزات التي يتم إرجاعها بواسطة مؤشر غير إعادة التدوير وتخزينها بسلوك متعدد الأشكال.

تضمن قاعدة البيانات الجغرافية "دلالات مثيل فريدة" على كائنات ميزة غير قابلة لإعادة التدوير تم جلبها أثناء جلسة التحرير. بمعنى آخر ، إذا تم بالفعل إنشاء مثيل للميزة التي تم استردادها بواسطة مؤشر البحث وتمت الإشارة إليها بواسطة تطبيق الاستدعاء ، فسيتم إرجاع مرجع إلى كائن الميزة الموجود.

تم إرجاع مؤشرات ميزة عدم إعادة التدوير من طريقة البحث يجب يتم استخدامها عند نسخ ميزات من المؤشر إلى مؤشر إدراج لفئة أخرى. وذلك لأن مؤشر إعادة التدوير يعيد استخدام نفس الشكل الهندسي وفي بعض الظروف قد يكون لجميع الميزات المدرجة في مؤشر الإدخال نفس الشكل الهندسي. يضمن استخدام مؤشر عدم إعادة التدوير أن تكون كل هندسة فريدة.


شاهد الفيديو: تعلم لغة بايثون من الصفر الى الاحتراف. كورس كامل