एक पहुंच क्षेत्र में एक बहुभुज का निर्माण


10

मैं वर्तमान में समकालिक और अंतर्निहित एल्गोरिदम के क्षेत्र में काम कर रहा हूं। अब समस्याओं का क्या कारण है, यदि आइसोक्रोन स्वयं की गणना नहीं है, लेकिन परिणामों की कल्पना है।
मेरे आइसोक्रोन एल्गोरिथ्म के परिणाम बिंदु और किनारे हैं। वास्तव में मेरे पास एक कार्यशील समाधान है, लेकिन 3873 किनारों के लिए और 1529 नोड्स के लिए चीजें हमेशा के लिए लगती हैं (मेरे लेनोवो T440s लैपटॉप पर लगभग 2.0 सेकंड) जिसमें 2015 कोर i7 सीपीयू और एक बहुत तेज एसएसडी होता है)। सेकंड के बजाय मुझे कुछ और पसंद है जैसे कि msec :-)।

हो सकता है कि कोई व्यक्ति पॉलीगॉन बनाने के लिए आवश्यक गणना समय को कम करने में मेरी मदद कर सकता है जो कि उपलब्ध क्षेत्रों की कल्पना करता है।

लेकिन रुकिए ... पहले चीजें पहले!
यहां किनारों का एक दृश्य है कि मैं अपने Isochrone गणना परिणाम (कंकाल की मौजूदा कंकाल) आइसोक्रोन का गणना परिणाम हूं: ये किनारों को पोस्टजीआईएस डेटाबेस तालिका में संग्रहीत किया जाता है और सरल लिनेस्टर हैं।

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

वर्तमान में मैं इस क्वेरी का उपयोग कर रहा हूं:

SELECT ST_AsGeoJson(St_Transform(ST_Multi(ST_Collect(polygons)), 4326)) AS coverage FROM (
    SELECT ST_MakePolygon(ST_ExteriorRing(ST_GeometryN(segments, generate_series(1, ST_NumGeometries(segments))))) AS polygons FROM (
        SELECT ST_Union(ST_Buffer("GEOMETRY", 20, 'quad_segs=2')) AS segments FROM my_edges AS a
    ) AS b
) AS c

मैंने पहले से ही कुछ प्रयोग किए हैं और मैंने बहुत सारे दस्तावेज भी पढ़े हैं, लेकिन मैं सिर्फ एक बेहतर समाधान नहीं खोज सकता।
मेरी नजर में बड़ी समस्या ST_Union का उपयोग है (जैसा कि डॉक्स में कहा गया है कि यह कार्य धीमा हो सकता है)। बहुत दिलचस्प बात यह है कि इसे ST_Collect के साथ प्रतिस्थापित करने से ST_Buffer गणना धीमी हो जाती है, ताकि सभी-सभी निम्नलिखित क्वेरी में अधिक समय लगे, हालांकि यह किनारों के बीच के क्षेत्रों को नहीं भरता है (यह केवल लाइनों के चारों ओर एक बफर बनाता है ):

SELECT ST_AsGeoJson(St_Transform(ST_Multi(ST_Collect(polygons)), 4326)) AS coverage FROM (
    SELECT ST_Buffer(ST_Collect(ST_LineMerge("GEOMETRY")), 20, 'quad_segs=2') AS polygons FROM my_edges AS a
) AS b

यह मेरे सिस्टम पर लगभग 3.8 सेकंड लेता है (इसलिए लगभग दो बार)। इस छोटे बेंचमार्क से मेरा पहला निष्कर्ष यह है कि ST_Buffer अप्रत्याशित रूप से धीमा हो जाता है जब यह मल्टीलाइनस्ट्रेस (यहां तक ​​कि जब प्रत्येक पंक्ति के लिए बफ़र्स बनाने और बफ़र्स को मर्ज करने की तुलना में धीमा हो जाता है - जो मेरी नज़र में सिर्फ अजीब है)

मैंने अल्फा-आकृतियों (pgRout से कार्यान्वयन का उपयोग करके) का उपयोग करने की भी कोशिश की, लेकिन चूंकि कोई अल्फा मान सेट करने के लिए नहीं है (और वास्तव में मुझे अब ऐसा मूल्य निर्धारित करने के लिए कौन सा मूल्य नहीं होगा) मुझे बस एक महान बहुभुज मिलता है ( इसलिए मैं अलग-अलग क्षेत्रों के रूप में बहुत दक्षिण और पूर्व में क्षेत्रों को खो दूंगा जो कि मैं नहीं चाहता)।
इसके अलावा ST_Polygonize (जो मेरे दिमाग में आई पहली चीज थी) कोई भी परिणाम देने योग्य नहीं था, लेकिन शायद मैं यहां से चूक गया ...

क्या PostGIS में दिखाए गए क्षेत्र को बनाने का एक बेहतर तरीका है? शायद जावा कोड (jts) या क्लाइंट साइड जावास्क्रिप्ट कोड (jsts) का उपयोग करके भी? वास्तव में मैं कुछ विस्तार खोने के साथ रह सकता था जब तक कि मेरे परिणाम में दिखाए गए क्षेत्र अलग-अलग रहते हैं और गणना बहुत तेज हो जाती है।


क्या आप सिर्फ ST_Exteriorring (ST_Dump (ST_Union (ST_Buffer (geom, ....)))) का उपयोग नहीं कर सकते हैं। कुछ भी बफ़र के रूप में देख रहे हैं, वैसे भी एक बहुभुज होगा, और ST_Union सभी इंटरसेक्टिंग ज्यामितीयों को जोड़ेगा, इसलिए MakePolygon या GeometryN की कोई आवश्यकता नहीं है। आपको Linestrings के लिए परीक्षण करने की आवश्यकता हो सकती है जो कभी-कभी बफर के बाद ST_Union से निकलते हैं, लेकिन ST_GeometryType (जियोम) के साथ यह आसान है। जहाँ तक जावा या jsts का उपयोग करने का संबंध है, आप कर सकते हैं, लेकिन यह तेज़ होने की संभावना नहीं है, यह देखते हुए कि एक। पोस्टगिस (GEOS) कार्यों का बड़ा हिस्सा पहले स्थान पर JTS के C / C ++ पोर्ट हैं।
जॉन पॉवेल

आप सही हैं, यह काम करता है, लेकिन वास्तव में यह तेज़ नहीं है (~ 3.1secs लेता है, जबकि ज्यामिति का उपयोग करते हुए 2secs लेता है)। यहाँ मैंने क्या उपयोग किया है: SELECT ST_AsGeoJson (ST_Transform (ST_Exteriorring (ST_Dump (ST_BUnion (STOMuffRY ", 20)))))) geom), 4326)) my_edges से;
निकोलस क्रिस्मर

@ john-barça: ओह .. मैं अपने दृष्टिकोण को आजमाते समय ST_Buffer में quad_segs = 2 भाग को गलत मानता हूं ... उस परिवर्तन के साथ प्रश्न भी (लगभग 2secs दोनों) हैं। हालाँकि, यह अभी भी बहुत धीमा है (मेरी नज़र में), क्या इसे आज़माने का एक और तरीका है?
निकोलस क्रिस्मर

दिलचस्प समस्या .... क्या आप कुछ परीक्षण डेटा साझा करना चाहते हैं?
dbaston

अगर इससे मुझे कुछ डेटा साझा करने में खुशी होती है। मेरे द्वारा की जाने वाली सभी चीजें ओपन-सोर्स हैं, इसलिए यह एक बड़ी समस्या नहीं होनी चाहिए। पहली बात ध्यान दें: परीक्षण के लिए एक वेब एप्लिकेशन dbis-isochrone.uibk.ac.at:8080/testing पर स्थित है । मेरे द्वारा काम की जाने वाली चीजों के बारे में अधिक जानकारी dbis-isochrone.uibk.ac.at पर देखी जा सकती है । वेबसाइट के "लिंक" खंड में कुछ और संदर्भ हैं (कुछ परीक्षण डेटा सहित)
निकोलस क्रिस्मर

जवाबों:


5

GeoJSON क्रमांकन को अलग करते हुए, निम्नलिखित मेरे लैपटॉप पर लगभग 6.3 सेकंड लेता है:

SELECT
  ST_MakePolygon(
    ST_ExteriorRing(
      (ST_Dump(
        ST_Union(
          ST_Buffer(geom, 20, 2)))).geom))
FROM bz_edges

OpenJUMP में डेटा को देखते हुए, मैंने आउटपुट के वांछित स्तर के सापेक्ष सड़क क्षेत्रों में काफी विस्तार से देखा। ऐसा लगता है कि इन लाइनों के ऑन-द-फ्लाई सरलीकरण से भी PostGIS में एक बड़ा स्पीडअप उत्पन्न हो सकता है:

SELECT
  ST_MakePolygon(
    ST_ExteriorRing(
      (ST_Dump(
        ST_Union(
          ST_Buffer(ST_Simplify(geom, 10), 20, 2)))).geom))
FROM bz_edges

जो 2.3 सेकंड के लिए चीजों को नीचे लाता है। मुझे लगा कि मक्खी पर गणना करने के बजाय, मैं सामान्यकृत ज्यामिति को एक अलग कॉलम में संग्रहीत करके बेहतर कर सकता हूं, लेकिन वास्तव में इससे कोई अतिरिक्त लाभ नहीं मिला।

आप कितना कोड लिखने के लिए तैयार हैं, इसके आधार पर, आप जावा में लगभग निश्चित रूप से बेहतर कर सकते हैं, अगर और कुछ नहीं क्योंकि आप कई कोर का लाभ उठा सकते हैं। (इसके लायक क्या है, इसके लिए जेटीएस 2.8 सेकंड में ऑपरेशन करता है)। CascadedPolygonUnionसंघ के कुछ कार्यों को समानांतर में करने के लिए एक दृष्टिकोण का विस्तार किया जा सकता है । (अपडेट - यहां एक Par समानांतरCascadedPolygonUnion है )

मैंने नमूना डेटा में देखा कि किनारों को उनके प्रारंभ और अंत नोड्स के संदर्भ में संग्रहीत किया जाता है, अर्थात, आपके पास एक पूर्व-निर्मित ग्राफ़ है। मुझे संदेह है कि आप इन बहुभुजों को बहुत तेज़ी से उत्पन्न कर सकते हैं यदि आप सामान्य ज्यामिति संचालन का उपयोग करने के बजाय ग्राफ़ से काम करते हैं। उदाहरण के लिए, मुझे लगता है कि आप ऐसा कुछ कर सकते हैं:

  1. ग्राफ के जुड़े घटकों की पहचान करें
  2. प्रत्येक जुड़े घटक के लिए, न्यूनतम X समन्वय के साथ नोड ढूंढें (घटक के बाहर होने की गारंटी)
  3. घटक के किनारों पर चलना, जब संभव हो तो हमेशा बाएं (या दाएं) मुड़ना। यह आपको प्रत्येक घटक की बाहरी रिंग देगा।
  4. बाहरी रिंग और बफर को उचित रूप से पॉलीगोनाइज़ करें।

धन्यवाद ... सरलीकरण एक महान और यहां तक ​​कि "सरल" सुधार है। यह मेरे लैपटॉप पर आवश्यक समय को 1.5 सेकेंड तक ले गया। यह वह जगह नहीं है जहां मैं रहना चाहता हूं, लेकिन थोड़ा बेहतर है।
निकोलस क्रिस्मर

आपके सुझाए गए समाधान के बारे में (अंक 1-4)। लगता है भी बहुत सरल है और एक कोशिश के काबिल है। मैंने ऐसा ही कुछ सोचा था, लेकिन मैं बिंदु 1 (इसलिए बहुत जल्दी :-)) पर अटक गया हूं। कोई कैसे जुड़े घटकों की पहचान करेगा (केवल एक चीज जो मैं सोच सकता हूं कि एक पुनरावर्ती क्वेरी है जो बहुत धीमी हो सकती है)।
निकोलस क्रिस्मर

@NikolausKrismer मैं इस तरह के कार्यों के लिए JGraphT और करघा दोनों का उपयोग करता हूं । यदि आप इसके बजाय अपने स्वयं के ग्राफ तरीके लिखते हैं (सर्वश्रेष्ठ प्रदर्शन के लिए बुरा विचार नहीं), तो गहराई-पहली खोज आपको घटक मिल जाएगी। (आप उन्हें आगामी PostGIS 2.2 में पा सकते हैं, ST_ClusterIntersectingलेकिन मुझे लगता है कि आप डेटाबेस से बाहर किसी भी तरह का ग्राफ़ प्रसंस्करण चाहते हैं, इसलिए यह उपयोगी नहीं है)।
dbaston

ये कुछ महान संकेत हैं। मैंने JGraphT को देखा और यह निश्चित रूप से मेरी समस्या को हल करने में मदद कर सकता है। हालाँकि, मैंने Postgis 2.2 और ST_ClusterIntersecting फ़ंक्शन को भी देखा -> ऊपर के मामले में विभिन्न समूहों की पहचान करने में लगभग 200-250msec लगते हैं। यह मेरे लिए ठीक है (JGraphT निश्चित रूप से बेहतर कर सकता है)। अब मुझे एक्सटरनलिंग बनाने से निपटना है (ST_ExteriorRing विफल, क्योंकि ST_MakePolygon का कहना है कि मेरे लिंक कोई शेल नहीं हैं)
निकोलस क्रिस्मर

मुझे दो जटिलताएँ दिखाई देती हैं: (ए) आपको न केवल बाहरी रिंग की जरूरत है, बल्कि उस रिंग से बाहर की ओर विस्तार करने वाले किसी भी सेगमेंट और (बी) ऐसा लगता है कि आपकी लाइनें वास्तव में कुछ चौराहों पर नहीं फैलती हैं। यदि आपको ग्राफ़ वॉक के परिणामों से ज्यामिति बनाने की कोशिश करने जा रहे हैं तो आपको (बी) को ठीक करने की आवश्यकता होगी।
dbaston
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.