मिलान खंडों के लिए एल्गोरिदम


23

सेगमेंट से मिलान करने के लिए सबसे अच्छा एल्गोरिदम क्या हैं?

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

अनुरोधित एल्गोरिथ्म में काफी अस्पष्ट वर्णन है क्योंकि एक "मैच" अच्छी तरह से परिभाषित नहीं है, और कई कारकों (अभिविन्यास, सापेक्ष लंबाई, दूरी) का अलग-अलग परिदृश्यों में अलग-अलग वजन हो सकता है; हालाँकि, मैं इस समस्या से निपटने के लिए सामान्य दृष्टिकोण के बारे में एक बुनियादी ज्ञान की तलाश कर रहा हूँ।

ओपन-सोर्स वातावरण (PostGIS, सुडौल, ...) के लिए कार्य कार्यान्वयन का गर्मजोशी से स्वागत है।

नमूना खंड : छवियों के नीचे विवरण देखें।


क्या आप खंड घनत्व का अवलोकन प्रदान करने के लिए अपने डेटा का स्नैपशॉट पोस्ट कर सकते हैं और वे कितने अलग हैं?
जुलिएन

1
मैंने फ़्लिकर पर कुछ चित्र पोस्ट किए हैं, लिंक देखें।
एडम मटन

1
आप "संगम" की खोज करने का प्रयास कर सकते हैं।
कर्क कुएकेंडल

जवाबों:


14

हॉसडॉर्फ़ दूरी में इस्तेमाल किया जा सकता है: मिलान खंडों इस दूरी के अनुसार 'बंद' खंडों हो सकता है। यह खंडों पर गणना करने के लिए काफी सरल है।

JTS में एक निःशुल्क जावा कार्यान्वयन उपलब्ध है - JTS डिस्टेंस पैकेज देखें । आपके पास जेसीएस कंफ्लेशन सूट (अब छोड़ दिया गया, स्रोतों की प्रतिलिपि जैसे कि https://github.com/oschrenk/jcs पर एक नज़र हो सकता है )।


2
हॉसडॉर्फ दूरी GEOS से PostGIS में भी है, इसलिए यह JTS के समान एल्गोरिथ्म है
निकल्स एवन

10

मुझे नहीं पता कि "सर्वश्रेष्ठ" क्या होगा, क्योंकि यह आपके सेगमेंट के विवरण पर निर्भर करेगा।

आम तौर पर अच्छा दृष्टिकोण महत्वपूर्ण ज्यामितीय जानकारी में खंडों को हैश करना है । इसमें न्यूनतम, केंद्र का स्थान (x, y), ओरिएंटेशन (0 से 180 डिग्री), और लंबाई शामिल होगी। उपयुक्त भार के साथ, और अभिविन्यास की कुछ चालाकी (क्योंकि 180 "लगभग" वापस 0 पर वापस आती है), आप तब सभी खंडों के संग्रह के लिए लगभग किसी भी सांख्यिकीय क्लस्टरिंग एल्गोरिदम को लागू कर सकते हैं। ( के-साधन एक अच्छा विकल्प होगा, लेकिन अधिकांश पदानुक्रमित तरीकों को अच्छी तरह से काम करना चाहिए। इस तरह के क्लस्टर विश्लेषण तेजी से और आसानी से लागू होते हैं।) आदर्श रूप से, खंड जोड़े में होंगे (या बेजोड़ खंडों के लिए एकल) और बाकी। आसान है।

अभिविन्यास समस्या से निपटने का एक तरीका लेबल किए गए सेगमेंट की प्रतिलिपि बनाना है। पहली प्रति के ओरिएंटेशन में 180 डिग्री जोड़ें, अगर यह 90 से कम है, और अन्यथा ओरिएंटेशन से 180 डिग्री घटाएं। यह आपके डेटासेट (स्पष्ट रूप से) को बढ़ाता है लेकिन अन्यथा किसी भी तरह से एल्गोरिथ्म को नहीं बदलता है।

वजन की आवश्यकता होती है क्योंकि निर्देशांक, लंबाई और अभिविन्यास के अंतर का अर्थ उनके संबंधित खंडों की समानता के संबंध में काफी अलग चीजें हो सकती हैं। कई अनुप्रयोगों में खंडों के बीच अंतर उनके समापन बिंदुओं के स्थानों में अंतर से उत्पन्न होता है। एक मोटे अनुमान के रूप में, हम खंड की लंबाई में विशिष्ट भिन्नता की उम्मीद कर सकते हैं कि उनके समापन बिंदु के बीच विशिष्ट भिन्नता के समान हो। इसलिए, x, y, और लंबाई से जुड़े वजन लगभग समान होने चाहिए। मुश्किल हिस्सा वेटिंग ओरिएंटेशन है, क्योंकि ओरिएंटेशन की दूरी के साथ बराबरी नहीं की जा सकती है और इससे भी बदतर, शॉर्ट सेगमेंट लंबे सेगमेंट की तुलना में गलत-उन्मुख होने की अधिक संभावना होगी। एक परीक्षण-और-त्रुटि विधि पर विचार करें जो खंडों के बीच एक विशिष्ट अंतराल के आकार के लिए कुछ हद तक गलतफहमी पैदा करता है और तब समायोजित करता है जब तक कि प्रक्रिया अच्छी तरह से काम करने लगती है। मार्गदर्शन के लिए, चलोएल एक विशिष्ट खंड की लंबाई हो। एक छोटा कोण टी डिग्री डिग्री द्वारा अभिविन्यास का परिवर्तन लगभग एल / 2 * टी / 60 की दूरी को पार करेगा (60 एक रेडियन में डिग्री की संख्या का अनुमान लगाता है), जो एल / 120 बार टी है । यह सुझाव देता है कि एक्स, वाई, और लंबाई के लिए इकाई भार से शुरू करें और अभिविन्यास के लिए एल / 120 का वजन ।

संक्षेप में , यह सुझाव है:

  1. लेबल किए गए सेगमेंट की प्रतियां बनाएं (जैसा कि अभिविन्यास को ध्यान में रखते हुए पैराग्राफ में वर्णित है)।

  2. प्रत्येक खंड को चौगुनी (x, y, लंबाई, L / 120 * अभिविन्यास) में परिवर्तित करें जहाँ L एक विशिष्ट खंड की लंबाई है।

  3. चौपाइयों का क्लस्टर विश्लेषण करें। एक अच्छे सांख्यिकीय पैकेज का उपयोग करें ( आर मुक्त है)।

  4. क्लस्टर विश्लेषण आउटपुट का उपयोग लुकअप टेबल के रूप में लेबल वाले सेगमेंट को पास के अनलेबेल्ड सेगमेंट के साथ जोड़ने के लिए करें।


4

मैंने लगभग 5 साल पहले इसी तरह की आवश्यकता वाली परियोजना पर काम किया था। इसमें हाईवे परफॉर्मेंस मॉनिटरिंग सिस्टम (HPMS) ट्रैफिक नेटवर्क लिंक के साथ स्ट्रीट सेंटरलाइन्स ( अपेक्षाकृत उच्च कोऑर्डिनेट प्रिसिजन के साथ) कोऑर्डिनेट करना शामिल था।

जिस समय FHWA ने इस तरह का काम करने के लिए कोई उपकरण उपलब्ध नहीं कराया था। वह बदल गया है, आप जांचना चाह सकते हैं। यहां तक ​​कि अगर आप राजमार्ग डेटा के साथ काम नहीं कर रहे हैं, तब भी उपकरण प्रासंगिक हो सकते हैं।

मैंने इसे आर्कजीआईएस के साथ लिखा था, लेकिन एल्गोरिथ्म को ओपनसोर्स में काम करना चाहिए, जब तक कि यह आईएसईजीएसडी के समान अनुरेखण क्षमता प्रदान करता है :

// features is a collection of features with higher geometry
// Links are a collection features with attributes but low res geometry
For each Link in lowResFeatureclass
    point startPoint = SnapToClosestPoint(Link.StartPoint, hiResfeatures);
    if(startPoint == null)
       continue;
    point endPoint = SnapToClosest(Link.EndPoint, hiResfeatures);
    if(endPoint == null)
       continue;
    polyline trace = Trace(hiResfeatures,startPoint,endPoint);
    if(polyline != null)
    {
        // write out a link with high precision polyline
        Write(Link,polyline);
    }
Next Link

4

यहाँ एक विचार आता है

यदि आप तुलना करने और परीक्षण करने के लिए किसी एक लाइनस्टर को फाड़ते हैं, यदि वर्टेन्कोपाइंट्स अन्य linestring से कुछ दूरी के भीतर है तो तुलना करने के लिए आप कई तरीकों से परीक्षण को नियंत्रित कर सकते हैं।

वो उदाहरण PostGIS में काम करते हैं (जो अनुमान लगा सकते हैं :-))

सबसे पहले, अगर हम कहते हैं कि एक मैच है, यदि तालिका 1 में एक linestring के सभी शीर्ष बिंदु 0.5 मीटर (मानचित्र इकाइयाँ) हैं या table_2 में एक linestring के करीब हैं:

SELECT a.id, b.id FROM
(SELECT ST_NPoints(the_geom) as num_of_points,
(ST_Dumppoints(the_geom)).geom as p, id FROM table_1) a 
INNER JOIN 
table_2 b 
ON ST_DWithin(a.p, b.the_geom, 0.5) GROUP BY a.id, b.id
HAVING COUNT(*)=num_of_points;

तब हम कह सकते हैं कि एक मैच है अगर एक तालिका में linestring में 60% से अधिक vertex_point तालिका 2 में एक linestring की दूरी के भीतर है

SELECT a.id, b.id FROM
(SELECT ST_NPoints(the_geom) as num_of_points, 
(ST_Dumppoints(the_geom)).geom as p, id FROM table_1) a 
INNER JOIN 
table_2 b 
ON ST_DWithin(a.p, b.the_geom, 0.5) GROUP BY a.id, b.id
HAVING COUNT(b.id)/num_of_points::float > 0.6

या हम स्वीकार कर सकते हैं कि एक बिंदु सीमा में नहीं है:

SELECT a.id, b.id FROM
(SELECT ST_NPoints(the_geom) as num_of_points, 
(ST_Dumppoints(the_geom)).geom as p, id FROM table_1) a 
INNER JOIN 
table_2 b 
ON ST_DWithin(a.p, b.the_geom, 0.5) GROUP BY a.id, b.id
HAVING COUNT(b.id)-num_of_points <= 1;

आपको उल्टा भूमिकाओं में तालिका 1 और तालिका 2 के साथ क्वेरी भी चलानी होगी।

मुझे नहीं पता कि यह कितनी तेजी से होगा। ST_Dumppoints वर्तमान में PostGIS में एक sql-function है न कि C-function जो इसे होने की तुलना में धीमा बनाता है। लेकिन मुझे लगता है कि यह वैसे भी काफी तेज होगा।

स्थानिक सूचकांक ST_Dwithin को प्रभावी बनाने में बहुत मदद करेगा।

HTH निकलस


1
+1 यह मेरे द्वारा उपयोग किए गए दृष्टिकोण के समान है (जल्द ही एक उत्तर पोस्ट करेगा)।
एडम मेटन

4

मैंने बाउंड्री जेनरेटर में मैला लाइन खंड (और उन्हें ओवरलैप) से निपटने के लिए कोड लिखा है। मैंने इसके पीछे (काफी प्रारंभिक) गणित लिखा है: http://blog.shoutis.org/2008/10/inside-boundary-generator-computational.html । कोड खुला स्रोत है और उस ब्लॉग पोस्ट से जुड़ा हुआ है।

कोड वास्तव में सरल दृष्टिकोण का अनुसरण करता है:

  • एक खंड-खंड परीक्षण जो आपको बताएगा कि दिए गए कोण और दूरी सहिष्णुता के भीतर दो लाइन खंड ओवरलैप करते हैं, और ओवरलैप की मात्रा।
  • एक त्वरित’अनुकूलित स्थानिक सूचकांक जो डेटासेट में अन्य सभी लाइन खंडों के खिलाफ डेटासेट में प्रत्येक पंक्ति खंड का परीक्षण करने की आवश्यकता को समाप्त करता है।

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

नोट: मैं अनुमान लगा रहा हूँ कि पर्याप्त SQL चॉप्स के साथ आप सेगमेंट-सेगमेंट टेस्ट को WHERE क्लॉज़ में कर सकते हैं ... :)

चीयर्स!


+1 यह एक अच्छा तरीका है; चतुर्भुज का निर्माण करना इसे कम्प्यूटेशनल रूप से श्रेष्ठ बनाता है। लेकिन विवरण में देखभाल की आवश्यकता है: खंड निकटता या समानता (चौराहे के बजाय) का निर्धारण करते समय, आपको इस तथ्य पर ध्यान देने की आवश्यकता है कि आपकी डेटा संरचना एक खंड का एक अनूठा प्रतिनिधित्व प्रदान नहीं करती है: खंड x पर उत्पन्न होने वाला , दिशा v में लंबाई की टी समान रूप से अच्छी तरह से में खंड पैदा होती है x + टी वी में दिशा -v लंबाई के टी
whuber

1

मैंने यहाँ मिलान के लिए एक मोटा प्रोटोटाइप लागू किया है , जो कि उपयोग में आसान है। यह ओपन सोर्स रूटिंग इंजन पर आधारित है और जावा में लिखा है। प्रयुक्त एल्गोरिथ्म यहां वर्णित है

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