कुशलता से 200k बहुभुज के पहले क्रम के पड़ोसियों को ढूंढना


14

208,781 जनगणना ब्लॉक समूहों में से हर एक के लिए, मैं इसके पहले क्रम के पड़ोसियों के सभी के आईडी आईडी प्राप्त करना चाहूंगा। मेरे पास सभी TIGER सीमाएँ हैं और एक एकल 1GB आकृति में विलय हो गई हैं।

मैंने एक ArcPython स्क्रिप्ट की कोशिश की, जो इसके मूल में BOUNDARY_TOUCHES के लिए SelectLayerByLocation का उपयोग करता है, लेकिन यह प्रत्येक ब्लॉक समूह के लिए 1 सेकंड से अधिक समय लेता है जो मुझे पसंद है की तुलना में धीमा है। यह तब भी है जब मैं SelectLayerByLocation खोज को उसी राज्य में समूहों को ब्लॉक करने के लिए सीमित करता हूं। मुझे यह स्क्रिप्ट मिली , लेकिन यह आंतरिक रूप से SelectLayerByLocation का भी उपयोग करता है इसलिए यह अधिक तेज़ नहीं है।

समाधान के लिए आर्क-आधारित होना जरूरी नहीं है - मैं अन्य पैकेजों के लिए खुला हूं, हालांकि मैं पायथन के साथ सबसे सहज कोडिंग कर रहा हूं।


2
संस्करण 9.3 के बाद से, ऐसा करने के लिए स्थानिक सांख्यिकी टूलबॉक्स में उपकरण हैं। 10.0 से शुरू, वे बहुत कुशल हैं। मुझे याद है कि तुलनात्मक आकार ( एक राज्य के भीतर सभी ब्लॉक ) के आकार पर एक समान ऑपरेशन चलाना और यह 30 मिनट में पूरा हो गया, जिसमें से 15 सिर्फ डिस्क I / O के लिए - और यह दो साल पहले एक बहुत धीमी मशीन पर था। पायथन स्रोत कोड सुलभ है, भी।
whuber

स्थानिक सांख्यिकी में किस जियोप्रोसेसिंग टूल का आपने उपयोग किया?
dmahr

1
मैं इसका नाम भूल गया; यह विशेष रूप से बहुभुज पड़ोसी संबंधों की एक तालिका बनाने के लिए है। हेल्प सिस्टम आपको पड़ोसी आधारित स्थानिक सांख्यिकी टूल चलाने से पहले इस तालिका को बनाने के लिए प्रोत्साहित करता है, ताकि हर बार जब वे दौड़ते हैं तो टूल को इस जानकारी को फ्लाई पर पुनः स्थापित न करना पड़े। कम से कम 9.x संस्करण में एक महत्वपूर्ण सीमा, यह था कि आउटपुट .dbf प्रारूप में था। बड़े इनपुट शेपफाइल के लिए, जो काम नहीं करेगा, जिस स्थिति में आपको या तो ऑपरेशन को टुकड़ों में तोड़ना होगा या बेहतर प्रारूप में आउटपुट करने के लिए पायथन कोड को हैक करना होगा।
whuber


हाँ बस यही। अजगर कोड आंतरिक आर्कजीआईएस क्षमताओं (जो स्थानिक अनुक्रमित का उपयोग करता है) का पूरी तरह से शोषण करता है, जिससे एल्गोरिथ्म काफी तेज हो जाता है।
whuber

जवाबों:


3

यदि आपके पास डेस्कटॉप के लिए ArcGIS 10.2, या संभवतः पहले पहुंच है, तो मुझे लगता है कि बहुभुज पड़ोसी (विश्लेषण) टूल:

बहुभुज संदर्भ (ओवरलैप्स, संयोग किनारों, या नोड्स) के आधार पर आँकड़ों के साथ एक तालिका बनाता है।

बहुभुज पड़ोसी

अब इस कार्य को और अधिक आसान बना सकते हैं।


धन्यवाद, PolyGeo मैंने स्वीकृत उत्तर को अपडेट कर दिया है, ताकि बहुभुज पड़ोसी उपकरण को थोड़ा और एक्सपोज़र मिले। यह निश्चित रूप से मेरे मैनुअल पायथन-आधारित विधि से अधिक मजबूत है, हालांकि मुझे यकीन नहीं है कि बड़े डेटासेट के साथ स्केलेबिलिटी की तुलना कैसे की जाती है।
dmahr

मैं वर्तमान में 10.3 का उपयोग कर रहा हूं, और यह ~ 300K जनगणना ब्लॉकों के साथ मेरी आकृति पर विफल रहता है।
शाम

@soandos ऐसा लगता है कि यह एक नए प्रश्न के रूप में शोध करने / पूछने लायक हो सकता है।
PolyGeo

8

ArcGIS से बचने के समाधान के लिए, pysal का उपयोग करें । आप का उपयोग करके सीधे आकार से वजन प्राप्त कर सकते हैं:

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

या

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

अधिक जानकारी के लिए डॉक्स के लिए प्रमुख ।


3

बस एक अद्यतन। व्हीबर की सलाह का पालन करने के बाद, मैंने पाया कि जेनरेट स्पैटियल वेट मैट्रिक्स केवल पड़ोसियों को निर्धारित करने के लिए पायथन लूप और शब्दकोशों का उपयोग करता है। मैंने नीचे की प्रक्रिया को पुन: पेश किया।

पहला भाग प्रत्येक ब्लॉक समूह के प्रत्येक शीर्ष से होकर गुजरता है। यह कुंजी के रूप में शीर्ष निर्देशांक के साथ एक शब्दकोश बनाता है और मूल्य के रूप में समन्वय करने वाले ब्लॉक समूह आईडी की एक सूची है। ध्यान दें कि इसके लिए एक स्थूल रूप से साफ-सुथरे डेटासेट की आवश्यकता होती है, क्योंकि केवल पड़ोसी के संबंध के रूप में सही वर्टेक्स / वर्टेक्स ओवरलैप पंजीकृत होगा। सौभाग्य से, इस संबंध में जनगणना ब्यूरो के टाइगर ब्लॉक समूह शेपफाइल्स ठीक हैं।

दूसरा भाग प्रत्येक ब्लॉक समूह के प्रत्येक शीर्ष के माध्यम से फिर से चलता है। यह कुंजी के रूप में ब्लॉक ग्रुप आईडी के साथ एक शब्दकोश बनाता है और उस समूह के पड़ोसी आईडी को मूल्यों के रूप में ब्लॉक करता है।

# Create dictionary of vertex coordinate : [...,IDs,...]
BlockGroupVertexDictionary = {}
BlockGroupCursor = arcpy.SearchCursor(BlockGroups.shp)
BlockGroupDescription = arcpy.Describe(BlockGroups.shp)
BlockGroupShapeFieldName = BlockGroupsDescription.ShapeFieldName
#For every block group...
for BlockGroupItem in BlockGroupCursor :
    BlockGroupID = BlockGroupItem.getValue("BKGPIDFP00")
    BlockGroupFeature = BlockGroupItem.getValue(BlockGroupShapeFieldName)
    for BlockGroupPart in BlockGroupFeature:
        #For every vertex...
        for BlockGroupPoint in BlockGroupPart:
            #If it exists (and isnt empty interior hole signifier)...
            if BlockGroupPoint:
                #Create string version of coordinate
                PointText = str(BlockGroupPoint.X)+str(BlockGroupPoint.Y)
                #If coordinate is already in dictionary, append this BG's ID
                if PointText in BlockGroupVertexDictionary:
                    BlockGroupVertexDictionary[PointText].append(BlockGroupID)
                #If coordinate is not already in dictionary, create new list with this BG's ID
                else:
                    BlockGroupVertexDictionary[PointText] = [BlockGroupID]
del BlockGroupItem
del BlockGroupCursor


#Create dictionary of ID : [...,neighbors,...]
BlockGroupNeighborDictionary = {}
BlockGroupCursor = arcpy.SearchCursor(BlockGroups.shp)
BlockGroupDescription = arcpy.Describe(BlockGroups.shp)
BlockGroupShapeFieldName = BlockGroupDescription.ShapeFieldName
#For every block group
for BlockGroupItem in BlockGroupCursor:
    ListOfBlockGroupNeighbors = []
    BlockGroupID = BlockGroupItem.getValue("BKGPIDFP00")
    BlockGroupFeature = BlockGroupItem.getValue(BlockGroupShapeFieldName)
    for BlockGroupPart in BlockGroupFeature:
        #For every vertex
        for BlockGroupPoint in BlockGroupPart:
            #If it exists (and isnt interior hole signifier)...
            if BlockGroupPoint:
                #Create string version of coordinate
                PointText = str(BlockGroupPoint.X)+str(BlockGroupPoint.Y)
                if PointText in BlockGroupVertexDictionary:
                    #Get list of block groups that have this point as a vertex
                    NeighborIDList = BlockGroupVertexDictionary[PointText]
                    for NeighborID in NeighborIDList:
                        #Don't add if this BG already in list of neighbors
                        if NeighborID in ListOfBGNeighbors:
                            pass
                        #Add to list of neighbors (as long as its not itself)
                        elif NeighborID != BlockGroupID:
                            ListOfBGNeighbors.append(NeighborID)
    #Store list of neighbors in blockgroup object in dictionary
    BlockGroupNeighborDictionary[BlockGroupID] = ListOfBGNeighbors

del BlockGroupItem
del BlockGroupCursor
del BlockGroupVertexDictionary

मुझे लगता है कि मैं दूसरे भाग के लिए एक अलग तरीके का इस्तेमाल कर सकता हूं, जो मुझे लगता है कि फिर से शेफाइल के माध्यम से लूपिंग की आवश्यकता नहीं थी। लेकिन यह वही है जो मैंने इस्तेमाल किया, और यह एक समय में ब्लॉक समूहों के लिए भी बहुत अच्छा काम करता है। मैंने इसे पूरे यूएसए के साथ करने की कोशिश नहीं की है, लेकिन यह पूरे राज्य के लिए निष्पादित कर सकता है।


2

PostgreSQL और PostGIS का उपयोग करने के लिए एक विकल्प हो सकता है । मैंने इस साइट पर समान गणना करने के बारे में कुछ प्रश्न पूछे हैं:

मैंने पाया कि यह जानने के लिए कि सीखने के सॉफ्टवेयर के विभिन्न टुकड़े आपस में कैसे फिट होते हैं, एक स्टेप लर्निंग कर्व है, लेकिन मैंने इसे बड़े वेक्टर लेयर्स पर कैलकुलेशन करने के लिए अद्भुत पाया है। मैंने लाखों पॉलीगनों पर कुछ निकटतम पड़ोसी गणनाएँ चलाई हैं और यह आर्कगिस की तुलना में त्वरित है।


1

बस कुछ टिप्पणियाँ ... esri / ArcGIS विधि वर्तमान में सूचनाओं को रखने के लिए शब्दकोशों का उपयोग करती है, लेकिन मूल गणना C ++ में बहुभुज पड़ोसी उपकरण का उपयोग करके की जाती है। यह उपकरण एक तालिका उत्पन्न करता है जिसमें संदर्भ संबंधी जानकारी के साथ-साथ साझा सीमा की लंबाई की तरह वैकल्पिक संकेतन होते हैं। अगर आप स्टोर करना चाहते हैं तो जेनरेट स्पैटियल वेट मैट्रिक्स टूल का उपयोग कर सकते हैं और बाद में बार-बार जानकारी का उपयोग कर सकते हैं। शब्दकोश [यादृच्छिक अभिगम] w / संदर्भ जानकारी:

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

जहां inputFC = किसी भी प्रकार की बहुभुज सुविधा वर्ग, मास्टरफ़िल्ड पूर्णांक और "रिग", "क्वीन"} में पूर्णांक की "विशिष्ट आईडी" फ़ील्ड है।

पायथन उपयोगकर्ताओं के लिए सारणीबद्ध पहलू को छोड़ना और सीधे एक पुनरावृत्ति पर जाने के प्रयास हैं, जो कई उपयोग मामलों को बहुत तेजी से आगे बढ़ाएगा। PySAL और R में spdep पैकेज शानदार विकल्प हैं [देखें radek का उत्तर] । मुझे लगता है कि आपको इन पैकेजों में डेटा प्रारूप के रूप में शेपफाइल्स का उपयोग करने की आवश्यकता है जो ट्यून डब्ल्यू / इस थ्रेड्स इनपुट प्रारूप में है। यह सुनिश्चित नहीं है कि वे कैसे बहुभुज और साथ ही बहुभुज के भीतर बहुभुज से निपटते हैं। SWM और साथ ही मेरे द्वारा बताए गए फ़ंक्शन को उन स्थानिक संबंधों को "ROOK" और "QUEEN" पड़ोसियों के रूप में गिना जाएगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.