أكثر

العثور بكفاءة على الجيران من الدرجة الأولى لـ 200 ألف مضلع

العثور بكفاءة على الجيران من الدرجة الأولى لـ 200 ألف مضلع


لكل مجموعة من مجموعات كتل التعداد 208،781 ، أود استرداد معرّفات FIPS لجميع جيرانها من الدرجة الأولى. لقد تم تنزيل جميع حدود TIGER ودمجها في ملف شكل واحد بسعة 1 جيجابايت.

لقد جربت برنامج ArcPython النصي الذي يستخدم SelectLayerByLocation لـ BOUNDARY_TOUCHES في جوهره ، ولكنه يستغرق أكثر من ثانية واحدة لكل مجموعة كتلة وهي أبطأ مما أريد. هذا حتى بعد أن حددت بحث SelectLayerByLocation لحظر المجموعات في نفس الحالة. لقد عثرت على هذا البرنامج النصي ، ولكنه يستخدم أيضًا SelectLayerByLocation داخليًا لذا فهو ليس أسرع.

لا يجب أن يكون الحل قائمًا على Arc - أنا منفتح على الحزم الأخرى ، على الرغم من أنني أشعر براحة أكبر في البرمجة باستخدام Python.


إذا كان لديك وصول إلى ArcGIS 10.2 for Desktop ، أو ربما قبل ذلك ، فأعتقد أن أداة Polygon Neighbours (التحليل) التي:

يُنشئ جدولاً بإحصائيات بناءً على تواصل المضلع (التداخلات أو الحواف المتزامنة أو العقد).

قد تجعل هذه المهمة أسهل بكثير الآن.


للحصول على حل يتجنب ArcGIS ، استخدم pysal. يمكنك الحصول على الأوزان مباشرة من ملفات الأشكال باستخدام:

w = pysal.rook_from_shapefile ("… /pysal/examples/columbus.shp")

أو

w = pysal.queen_from_shapefile ("… /pysal/examples/columbus.shp")

توجه إلى المستندات لمزيد من المعلومات.


مجرد تحديث. بعد اتباع نصيحة Whuber ، وجدت أن Generate Spatial Weights Matrix ببساطة تستخدم حلقات وقواميس Python لتحديد الجيران. أنا استنساخ العملية أدناه.

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

الجزء الثاني يمر عبر كل رأس من كل مجموعة كتلة مرة أخرى. يقوم بإنشاء قاموس بمعرفات مجموعة الحظر كمفاتيح ومعرفات جوار تلك المجموعة المحظورة كقيم.

# إنشاء قاموس إحداثيات قمة الرأس: [… ، المعرفات ،…] BlockGroupVertexDictionary = {} BlockGroupCursor = arcpy.SearchCursor (BlockGroups.shp) BlockGroupDescription = arcpy.Describe (BlockGroups.shp) BlockGroupShapeFieldName = BlockGroupsDescription.ShapeFieldName ... BlockGroupItem في BlockGroupCursor: BlockGroupID = BlockGroupItem.getValue ("BKGPIDFP00") BlockGroupFeature = BlockGroupItem.getValue (BlockGroupShapeFieldName) لـ BlockGroupPart في BlockGroupFeature: # من أجل كل قمة ... لـ BlockGartroup هي فارغة إذا كان BlockGroupPoint: #Create إصدار سلسلة من الإحداثي PointText = str (BlockGroupPoint.X) + str (BlockGroupPoint.Y) # إذا كان التنسيق موجودًا بالفعل في القاموس ، قم بإلحاق معرف BG هذا إذا كان PointText في BlockGroupVertexDictionary: BlockGroupVertexDictionary [PointText]. # إذا لم يكن التنسيق موجودًا بالفعل في القاموس ، فأنشئ قائمة جديدة بمعرف BG هذا وإلا: BlockGroupVertexDictionary [Poi ntText] = [BlockGroupID] del BlockGroupItem del BlockGroupCursor # إنشاء قاموس للمعرف: [... ، الجيران ، ...] BlockGroupNeighborDictionary = {} BlockGroupCursor = arcpy.SearchCursor (BlockGroups.shp) BlockGroupDescription = arcpy.Describe (BlockGroups.shp) .ShapeFieldName # لكل مجموعة كتل لـ BlockGroupItem في BlockGroupCursor: ListOfBlockGroupNeighbours = [] BlockGroupID = BlockGroupItem.getValue ("BKGPIDFP00") BlockGroupFeature = BlockGroupItem.getValue (BlockGroupShapeFieldName) إنه موجود (وليس دلالة الفتحة الداخلية) ... إذا كان BlockGroupPoint: #Create إصدار سلسلة من تنسيق PointText = str (BlockGroupPoint.X) + str (BlockGroupPoint.Y) إذا كان PointText في BlockGroupVertexDictionary: # احصل على قائمة مجموعات الكتل التي تحتوي على هذه النقطة على أنها a vertex NeighborIDList = BlockGroupVertexDictionary [PointText] لـ NeighborID في NeighborIDList: # Don't ad d إذا كان BG هذا موجودًا بالفعل في قائمة الجيران إذا كان NeighborID في ListOfBGNeighbours: مرر # Add إلى قائمة الجيران (طالما أنه ليس هو نفسه) elif NeighborID! = BlockGroupID: ListOfBGNeighbours.append (NeighborID) #Store قائمة الجيران في كائن blockgroup في قاموس BlockGroupNeighborDictionary [BlockGroupID] = ListOfBGNeighbours del BlockGroupItem del BlockGroupCursor del BlockGroupVertexDictionary

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


قد يكون البديل هو استخدام PostgreSQL و PostGIS. لقد طرحت بعض الأسئلة حول كيفية إجراء عمليات حسابية مماثلة على هذا الموقع:

لقد وجدت أن هناك منحنى تعليمي حاد لمعرفة كيف تتلاءم الأجزاء المختلفة من البرنامج معًا ، لكنني وجدت أنه من الرائع إجراء العمليات الحسابية على طبقات متجهية كبيرة. لقد أجريت بعض حسابات الجوار الأقرب على ملايين المضلعات وكان ذلك سريعًا مقارنةً بـ ArcGIS.


فقط بعض التعليقات ... تستخدم طريقة esri / ArcGIS حاليًا القواميس للاحتفاظ بالمعلومات ولكن الحسابات الأساسية تتم في C ++ باستخدام أداة Polygon Neighbours. تنشئ هذه الأداة جدولًا يحتوي على معلومات الاتصال بالإضافة إلى السمات الاختيارية مثل طول الحدود المشتركة. يمكنك استخدام أداة Generate Spatial Weights Matrix Tool إذا كنت تريد تخزين المعلومات ثم إعادة استخدامها مرارًا وتكرارًا. يمكنك أيضًا استخدام هذه الوظيفة في WeightsUtilities لإنشاء قاموس [وصول عشوائي] مع معلومات الاتصال:

contDict = polygonNeighborDict (inputFC ، masterField ، contiguityType = "ROOK")

حيث inputFC = أي نوع من فئة معلم المضلع ، masterField هو حقل "المعرف الفريد" للأعداد الصحيحة و contiguityType في {"ROOK" ، "QUEEN"}.

هناك جهود في esri لتخطي الجانب الجدولي لمستخدمي Python والانتقال مباشرة إلى مكرر مما يجعل العديد من حالات الاستخدام أسرع بكثير. PySAL وحزمة spdep في R هما بدائل رائعة [انظر إجابة radek]. أعتقد أنك مطالب باستخدام ملفات الأشكال كتنسيق البيانات في هذه الحزم التي تكون متناغمة مع تنسيق إدخال الخيوط. لست متأكدًا من كيفية تعاملهم مع المضلعات المتداخلة وكذلك المضلعات داخل المضلعات. إنشاء إدارة النفايات الصلبة وكذلك الوظيفة التي وصفتها ستحسب تلك العلاقات المكانية على أنها جيران "روك" و "ملكة".


شاهد الفيديو: من البيضاء. حرفي كرا محل تجاري لممارسة نشاطه ومول المحل موظف بالجماعة وعضو بحزب سياسي قطع عليه الضوء