200 मिलियन अंकों के पॉलीगॉन विश्लेषण में प्वाइंट के लिए सबसे तेज़ समाधान की तलाश [बंद]


35

मेरे पास एक CSV है जिसमें निम्नलिखित प्रारूप के साथ 200 मिलियन अवलोकन हैं:

id,x1,y1,x2,y2,day,color
1,"-105.4652334","39.2586939","-105.4321296","39.2236632","Monday","Black"
2,"-105.3224523","39.1323299","-105.4439944","39.3352235","Tuesday","Green"
3,"-104.4233452","39.0234355","-105.4643990","39.1223435","Wednesday","Blue"

निर्देशांक (X1 / y1 और x2 / y2) के प्रत्येक सेट के लिए, मैं यूएस जनगणना ट्रैक्ट या जनगणना ब्लॉक को असाइन करना चाहता हूं जो कि इसके भीतर आता है (मैंने यहां जनगणना के टाइगर आकार को डाउनलोड किया है: ftp://ftp2.canim.gov/ geo / tiger / TIGER2011 / TRACT / tl_2011_08_tract.zip )। इसलिए, मुझे प्रत्येक अवलोकन के लिए दो बार एक बिंदु-बहुभुज ऑपरेशन करने की आवश्यकता है। यह महत्वपूर्ण है कि मैच बहुत सटीक हों।

सॉफ्टवेयर सीखने के लिए समय सहित, ऐसा करने का सबसे तेज़ तरीका क्या है? मेरे पास 48GB मेमोरी वाले कंप्यूटर तक पहुंच है - यदि यह एक प्रासंगिक बाधा हो सकती है।

कई धागे PostGIS या Spatialite का उपयोग करने की सलाह देते हैं (Spatialite का उपयोग करना आसान लगता है - लेकिन क्या यह PostGIS के रूप में कुशल है?)। यदि वे सबसे अच्छे विकल्प हैं, तो क्या एक स्थानिक सूचकांक (RTree?) को आबाद करना अनिवार्य है? यदि हां, तो कोई ऐसा कैसे करता है (जैसे कि सेंसस ट्रैक्ट शेपफाइल का उपयोग करके)? मैं किसी भी सिफारिश के लिए बहुत आभारी रहूंगा जिसमें उदाहरण कोड (या कोड के लिए एक संकेतक) शामिल हैं।

मेरा पहला प्रयास (इस साइट को खोजने से पहले) ने अमेरिकी जनगणना ब्लॉक पर डेटा (100,000 अंक) की सदस्यता के एक स्थानिक जुड़ाव (X1 / y1 केवल) करने के लिए ArcGIS का उपयोग किया। इससे पहले कि मैं इस प्रक्रिया को मारता 5 घंटे लग गए। मैं एक ऐसे समाधान की उम्मीद कर रहा हूं जिसे 40 घंटे के कंप्यूटिंग समय के दौरान पूरे डेटासेट पर लागू किया जा सकता है।

पहले पूछे गए एक प्रश्न के लिए क्षमा याचना - मैंने उत्तरों के माध्यम से पढ़ा है, और मैं सोच रहा हूं कि सिफारिशों को कैसे लागू किया जाए। मैंने कभी भी SQL, Python, C का उपयोग नहीं किया है, और केवल एक बार पहले भी ArcGIS का उपयोग किया है - मैं एक पूर्ण शुरुआत हूं।


3
40 घंटे प्रति सेकंड लगभग 2800 पॉइंट-बहुभुज संचालन के बराबर होंगे। यह सिर्फ मेरे दिमाग में संभव नहीं लगता। मुझे पता नहीं है कि कौन सा सॉफ्टवेयर का टुकड़ा (आर्कजीआईएस, पोस्टजीआईएस, स्पैटियालाइट आदि) सबसे तेज है, लेकिन एक स्थानिक सूचकांक बिना किसी संदेह के आवश्यक है।
उफ्फ कूसगार्ड

1
यदि पॉलीगॉन जटिल नहीं है तो कोई समस्या नहीं होनी चाहिए। सूचकांक (PostGIS में) से लाभ इस बात पर निर्भर करेगा कि बहुभुज कितने बड़े हैं। छोटे बहुभुज (छोटे बाउंडिंग बॉक्स) जितना अधिक इंडेक्स में मदद करेंगे। संभवत: यह संभव है।
निकलस एवन

1249 बहुभुज ~ 600 अंक प्रति बहुभुज के साथ।
उफ्फ कुसगार्ड

3
@ यूफे कूसगार्ड, हां यह बिल्कुल संभव है। तुमने मुझे यह एक कोशिश दे दी। नीचे से जवाब।
निकलैस एवन

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

जवाबों:


27

ST_DWithin ST_Intersects की तुलना में मेरे परीक्षण में तेज़ था। यह आश्चर्य की बात है, खासकर जब से तैयार ज्यामिति एल्गोरिथ्म इस तरह के मामलों पर किक करने वाला है। मुझे लगता है कि एक मौका है कि यह काफी तेज होगा जितना मैंने यहां दिखाया है।


मैंने कुछ और परीक्षण किए और दो चीजों ने गति को लगभग दोगुना कर दिया। सबसे पहले, मैंने एक नए कंप्यूटर पर कोशिश की, लेकिन अभी भी एक बहुत ही साधारण लैपटॉप, शायद SATA3 ssd -disks को छोड़कर।

फिर नीचे दिए गए क्वेरी ने पुराने लैपटॉप पर 62 सेकंड के बजाय 18 सेकंड का समय लिया। आगे मैंने पाया कि जब मैंने लिखा था कि पॉइंट-टेबल पर सूचकांक आवश्यक नहीं था, तो मैं पहले पूरी तरह से गलत था। उस सूचकांक के साथ ST_Intersects ने अपेक्षा के अनुरूप व्यवहार किया और चीजें बहुत तेज़ हो गईं। मैंने पॉइंट-टेबल में अंकों की संख्या को बढ़ाकर 1 मिलियन अंक और क्वेरी:

CREATE TABLE points_ct AS
SELECT imported_ct.gid as ct_gid, t.gid as point_id 
FROM imported_ct , t WHERE ST_Intersects(imported_ct.geom , t.geom);

72 सेकंड में चलता है। चूंकि 1249 पॉलीगॉन है, इसलिए 72 सेकंड में 1249000000 परीक्षण किए जाते हैं। यह प्रति सेकंड लगभग 17000000 परीक्षण करता है। या प्रति सेकंड सभी बहुभुज के खिलाफ लगभग 14000 अंक का परीक्षण।

इस परीक्षण से आपके 400000000 अंक परीक्षण करने के लिए लगभग 8 घंटे लगने चाहिए ताकि कई कोर को लोड वितरित करने में कोई परेशानी न हो। PostGIS मुझे प्रभावित करने के लिए कभी नहीं रोकता है :-)


सबसे पहले, परिणाम की कल्पना करने के लिए आप परिणाम तालिका में बिंदु ज्यामिति जोड़ सकते हैं, इसे उदाहरण के लिए QGIS में खोलें और इसे आयातित_ct फ़ील्ड पर अद्वितीय मानों के साथ शैली दें।

दूसरा, हाँ, आप दाएं (या बाएं) का उपयोग करके किसी भी बहुभुज के बाहर गिरने वाले बिंदुओं को इस तरह से जोड़ सकते हैं:

CREATE TABLE points_ct AS
SELECT imported_ct.gid as ct_gid, t.gid as point_id 
FROM imported_ct right join t ON ST_Intersects(imported_ct.the_geom , t.geom);

यदि यह संभव हो तो मुझे सत्यापित करने के लिए मैंने कुछ परीक्षण किए हैं।

पहले कुछ मुझे समझ में नहीं आता है आपके पास प्रति पंक्ति दो अंक हैं। क्या हमेशा एक ही बहुभुज में दोनों बिंदु होते हैं? फिर किसी एक बिंदु पर गणना करना पर्याप्त है। यदि वे दो अलग-अलग बहुभुजों में हो सकते हैं, तो आपको एक बिंदु पंक्ति को दो बहुभुज से जोड़ने के लिए एक मार्ग की आवश्यकता होगी।

परीक्षणों से यह उचित लगता है, लेकिन आपको एक से अधिक सीपीयू-कोर पर लोड फैलाने के लिए कुछ रचनात्मक समाधान की आवश्यकता हो सकती है।

मैंने 4 साल पुराने लैपटॉप पर दोहरी कोर सेंट्रिनो सीपीयू (लगभग 2.2 गीगाहर्ट्ज़ मुझे लगता है), 2 जीबी रैम के साथ परीक्षण किया। यदि आपके पास 48 बीजी रैम है, तो मुझे लगता है कि आपके पास बहुत अधिक सीपीयू-पावर भी है।

मैंने जो किया वह 100000 अंकों के साथ एक यादृच्छिक बिंदु तालिका बनाने के लिए था:

CREATE TABLE t AS
WITH r AS
(SELECT ST_Extent(the_geom)::geometry ext FROM imported_ct)
SELECT ST_Point(x,y) AS geom FROM 
(SELECT GENERATE_SERIES(1,100000)) s,
(SELECT ST_Xmin(ext)+(random()*(ST_Xmax(ext)-ST_Xmin(ext))) x, ST_Ymin(ext)+(random()*(ST_Ymax(ext)-ST_Ymin(ext))) y FROM r
) f;

फिर एक gid जोड़ना जैसे:

ALTER TABLE t ADD COLUMN GID SERIAL;

फिर चल रहा है:

CREATE TABLE points_ct AS
SELECT imported_ct.gid as ct_gid, t.gid as point_id FROM imported_ct , t WHERE ST_Dwithin(imported_ct.the_geom , t.geom,0);

लगभग 62 सेकंड लगते हैं (समान अंक के साथ अपने आर्कगिस परिणाम की तुलना करें)। परिणाम मेरी तालिका में अंक को जनगणना पथ के साथ तालिका में जीआईडी ​​के साथ जोड़ने वाली एक तालिका है।

उस गति के साथ आप लगभग 34 घंटों में 200 मिल पॉइंट करेंगे। इसलिए, यदि यह किसी एक बिंदु की जांच करने के लिए पर्याप्त है, तो मेरा पुराना लैपटॉप एक कोर के साथ कर सकता है।

लेकिन अगर आपको दोनों बिंदुओं को जांचने की आवश्यकता है तो यह कठिन हो सकता है।

जब आप db के विरुद्ध कई सत्रों को शुरू करके और अलग-अलग क्वेरीज़ को चलाकर एक से अधिक कोर को मैन्युअल रूप से वितरित कर सकते हैं।

50000 अंकों और दो सीपीयू-कोर के साथ मेरे उदाहरण में मैंने कोशिश की:

CREATE TABLE t1 as
SELECT imported_ct.gid as ct_gid, t.gid as point_id FROM imported_ct , t WHERE t.gid >50000 and  ST_Dwithin(imported_ct.the_geom , t.geom,0);

रनिंग के रूप में एक ही समय में एक db- सत्र पर:

CREATE TABLE t2 as
SELECT imported_ct.gid as ct_gid, t.gid as point_id FROM imported_ct , t WHERE t.gid <=50000 and  ST_Dwithin(imported_ct.the_geom , t.geom,0);

एक और डीबी-सत्र पर।

इसने लगभग 36 सेकंड का समय लिया इसलिए यह पहले उदाहरण की तुलना में थोड़ा धीमा है, जो एक ही समय में डिस्क लेखन पर निर्भर करता है। लेकिन जब से बिथ कोर एक ही समय में काम कर रहे हैं, तो यह मेरे समय के 36 सेकंड से ज्यादा नहीं हुआ।

टेबल टी 1 और टी 2 को आजमाने के लिए:

CREATE TABLE t3 AS 
SELECT * FROM t1
UNION ALL
SELECT * FROM t2;

लगभग आधा सेकंड का उपयोग कर।

तो, नए हार्डवेयर के साथ और कई कोर पर लोड वितरित करने से यह बिल्कुल संभव होना चाहिए, भले ही असली दुनिया परीक्षण के मामले से धीमी हो।

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


1
मैंने सिर्फ .tl_2011_08_trac का नाम बदलकर import_ctc कर दिया क्योंकि इसे लिखना आसान था। इसलिए, मेरी आयातित क्वेरी को केवल .tl_2011_08_trac में बदलें और आपको ठीक जाना चाहिए।
निकलस एवन

2
@meer BTW, template_postgis_20 का उपयोग करके भविष्य के डेटाबेस के लिए टेम्पलेट के अलावा और कुछ भी अनुशंसित नहीं है। जब से आपको PostGIS 2.0 लगता है, अगर आपके पास भी PostgreSQL 9.1 है तो आप बस एक नया db बना सकते हैं और "CREATE EXTENSION POSTGIS" चला सकते हैं।
निकलस एवन

1
हां, यह एक और टाइपो था जो मुझे लगता है कि मैंने कुछ मिनट पहले तय किया था। उसके लिए माफ़ करना। इसके बजाय ST_Intersects संस्करण आज़माएं, जो कि बहुत तेज़ होना चाहिए।
निकोलस एवन

1
@meer हर बिंदु के प्रभावित न होने का कारण यह है कि यादृच्छिक बिंदुओं को एक आयत में रखा गया है और मुझे लगता है कि मानचित्र वास्तव में एक आयत नहीं है। मैं पोस्ट में एक संपादन करूंगा कि परिणाम कैसे देखें।
निकलस एवेन

1
@ यूफे कूसगार्ड, हां, मुझे लगता है कि आप इसे इस तरह से रख सकते हैं। यह एक समय में एक बहुभुज लेता है और किनारों के एक पेड़ का निर्माण करके इसे तैयार करता है। फिर यह सभी बिंदुओं की जांच करता है (कि सूचकांक तैयार किए गए बक्सों को ओवरलैप करके घुसपैठ के रूप में छांटा गया है) उस तैयार बहुभुज के खिलाफ।
निकलस एवेन

4

शायद सबसे आसान तरीका PostGIS के साथ है। इंटरनेट पर कुछ ट्यूटोरियल हैं कि कैसे PostGIS में csv / txt पॉइंट डेटा आयात किया जाए। link1

मैं PostGIS में बिंदु-इन-बहुभुज खोजों के प्रदर्शन के बारे में निश्चित नहीं हूं; यह आर्कजीआईएस से तेज होना चाहिए। GIST स्थानिक सूचकांक जो PostGIS का उपयोग करता है वह बहुत तेज है। लिंक 2 लिंक 3

आप MongoDB भू-स्थानिक सूचकांक का भी परीक्षण कर सकते हैं । लेकिन इसे शुरू करने के लिए थोड़ा और समय चाहिए। मेरा मानना ​​है कि MongoDB वास्तव में तेज़ हो सकता है। मैंने बिंदु-इन-बहुभुज खोजों के साथ इसका परीक्षण नहीं किया है इसलिए यह सुनिश्चित नहीं किया जा सकता है।

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