QGIS में पड़ोसी टाइल आईडी कैसे निर्धारित करें?


11

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

लेकिन फिर हमने यथार्थवादी उदाहरणों के बारे में सोचना शुरू किया, जहां हम उन पृष्ठों को नहीं खींचना चाहते हैं जिनमें हमारे जिले का हित नहीं है, जैसे कि यह मेरे घर का घर है:

यहाँ छवि विवरण दर्ज करें

इसलिए आज दोपहर मेरे पास एक अजगर स्क्रिप्ट पर एक नाटक था जिसमें 4 पड़ोसियों को काम करने के लिए कहा गया था जिनके लिए मैं प्रत्येक ग्रिड सेल में दिलचस्पी रखता था और उन मूल्यों को अपने ग्रिड में जोड़ दिया (यह उजावल गांधी के ट्यूटोरियल पर आधारित है ):

for f in feature_dict.values():
    print 'Working on %s' % f[_NAME_FIELD]
    geom = f.geometry()
    # Find all features that intersect the bounding box of the current feature.
    # We use spatial index to find the features intersecting the bounding box
    # of the current feature. This will narrow down the features that we need
    # to check neighboring features.
    intersecting_ids = index.intersects(geom.boundingBox())
    # Initalize neighbors list and sum
    neighbors = []
    neighbors_sum = 0
    for intersecting_id in intersecting_ids:
        # Look up the feature from the dictionary
        intersecting_f = feature_dict[intersecting_id]
        int_geom = intersecting_f.geometry()
        centroid = geom.centroid()
        height = geom.boundingBox().height()
        width = geom.boundingBox().width()
        # For our purpose we consider a feature as 'neighbor' if it touches or
        # intersects a feature. We use the 'disjoint' predicate to satisfy
        # these conditions. So if a feature is not disjoint, it is a neighbor.
        if (f != intersecting_f and
            not int_geom.disjoint(geom)):
            above_point = QgsGeometry.fromPoint(QgsPoint(centroid.asPoint().x(),
               centroid.asPoint().y()+height))
            below_point = QgsGeometry.fromPoint(QgsPoint(centroid.asPoint().x(),
               centroid.asPoint().y()-height))
            left_point = QgsGeometry.fromPoint(QgsPoint(centroid.asPoint().x()-width,
               centroid.asPoint().y()))
            right_point = QgsGeometry.fromPoint(QgsPoint(centroid.asPoint().x()+width,
               centroid.asPoint().y()))
            above = int_geom.contains(above_point)   
            below = int_geom.contains(below_point)   
            left = int_geom.contains(left_point)
            right = int_geom.contains(right_point)
            if above:
                print "setting %d as above %d"%(intersecting_f['id'],f['id'])
                f['above']=intersecting_f['id']

            if below:
                print "setting %d as below %d"%(intersecting_f['id'],f['id'])
                f['below']=intersecting_f['id']

            if left:
                print "setting %d as left of %d"%(intersecting_f['id'],f['id'])
                f['left']=intersecting_f['id']

            if right:
                print "setting %d as right of %d"%(intersecting_f['id'],f['id'])
                f['right']=intersecting_f['id']

    # Update the layer with new attribute values.
    layer.updateFeature(f)

layer.commitChanges()

यह ठीक काम करता है।

यहाँ छवि विवरण दर्ज करें

लेकिन पूरी ईमानदारी से उत्तर के लिए एक परीक्षण बिंदु बनाने और फिर सभी संभावित पड़ोसियों का परीक्षण करना गलत लगता है। हालाँकि, अपने मस्तिष्क को नष्ट करने की एक दोपहर के बाद, मैं यह निर्धारित करने के लिए बेहतर तरीका नहीं सोच सकता कि एक विशेष ग्रिड सेल का उत्तरी पड़ोसी क्या है?

आदर्श रूप से मुझे प्रिंट कंपोजर टेक्स्ट बॉक्स में डालने के लिए कुछ सरल चाहिए, लेकिन मुझे संदेह है कि यह पूछने के लिए बहुत अधिक है।


क्या होगा अगर एक तरफ कोई पड़ोसी नहीं है। क्या आप कोठरी सेल का मान एक दिशा में चाहते हैं या आप एक शून्य छोड़ देंगे?
राडोक्सु

मैं उस मामले में एक अशक्त के लिए खुश हूं, मैं आसानी से केवल शून्य या रिक्त नहीं होने पर केवल प्रदर्शन के लिए लेबल सेट कर सकता हूं।
इयान Turton

जवाबों:


3

यदि आप प्रत्येक पृष्ठ सीमा (इंडेक्स लेयर से) को कंपोज़र में बिल्कुल फिट नहीं कर रहे हैं, लेकिन समीपवर्ती पृष्ठों (जैसा कि आपके दूसरे स्क्रीनशॉट में दिखाया गया है) के साथ ओवरलैपिंग बॉर्डर्स हैं, तो आप इंडेक्स लेयर से लेबल का उपयोग कर सकते हैं, इसके साथ नीचे वे मानचित्र सीमा के अंदर होंगे।

यदि कोई ओवरलैप नहीं है, तो आप एक तकनीक का उपयोग कर सकते हैं जिसे मैंने अतीत में सफलतापूर्वक इस्तेमाल किया था (संयोग से E और W ससेक्स के पार!) MapInfo में, जहां मैंने एक छोटी स्क्रिप्ट लिखी थी जिसमें प्रत्येक इंडेक्स फीचर के लिए चार अंकों का एक सेट तैयार किया गया था। , आसन्न सुविधाओं में ऑफसेट, दोनों शीट नंबर की विशेषताओं और ऑफसेट की दिशा के साथ। बिंदु परत को फिर से लेबल उत्पन्न करने के लिए इस्तेमाल किया गया था, साथ ही साथ ऑफसेट के निर्देशन से लेबल के उन्मुखीकरण को एक अच्छे प्रभाव के लिए समायोजित किया जा सकता है।

मैंने यह कोशिश नहीं की है, लेकिन आप नए ज्यामिति जनरेटर स्टाइलिंग कार्यक्षमता के उपयोग के माध्यम से QGIS में एक अलग डेटा परत उत्पन्न करने से बचने में सक्षम हो सकते हैं, यह एक अधिक सुरुचिपूर्ण और गतिशील समाधान के लिए बनायेगा जो MapInfo में प्राप्त करने योग्य नहीं था!


मैं वास्तव में अन्य बहुभुज के लेबल का उपयोग करने के बारे में सोचना चाहिए था! :-) ज्योमेट्री जेनरेटर के साथ एक त्वरित प्रयोग के बाद, मैं एक बाउंडिंग बॉक्स बना सकता हूं, लेकिन एक ग्रिड बनाना कठिन है
इयान टर्टन

मैं ग्रिड के बजाय आसन्न बहुभुज में ऑफसेट लेबल पॉइंट जेनरेट करने की तर्ज पर सोच रहा था। एक अन्य विकल्प यह होगा कि सूचकांक सुविधा के एमबीआर का विस्तार आसन्न सुविधाओं में किया जाए ताकि लेबल खींचा जा सके।
एंडी हरफुट

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

8

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

यहाँ छवि विवरण दर्ज करें

पहले हमें प्रत्येक ग्रिड के लेबल को दिखाने की आवश्यकता है।

लेआउट दृश्य में, मैंने एटलस में कवरेज परत के रूप में ग्रिड का उपयोग किया, मैंने दो नक्शे बनाए: मुख्य दृश्य विंडो मैप, और एक इंडेक्स मैप जो केवल ग्रिड दिखाता है, जैसा कि आप नीचे देख सकते हैं:

यहाँ छवि विवरण दर्ज करें

फिर मैंने निम्नलिखित कार्य किया:

  1. मैंने पूरे ग्रिड को दिखाने के लिए इंडेक्स मैप के पैमाने को समायोजित किया फिर मैंने पैमाने को तय किया
  2. मैंने उपयोग करते समय मानचित्र को पैनिंग से रोकने के लिए दृश्य सीमा तय की Preview atlas, और
  3. मैंने Overviewमुख्य दृश्य मानचित्र की सीमा और स्थान देखने में सक्षम किया , जैसा कि आप नीचे देख सकते हैं:

यहाँ छवि विवरण दर्ज करें

मुख्य दृश्य विंडो के नक्शे के लिए, मैंने प्रत्येक ग्रिड ब्लॉक की सीमा के पैमाने को तय किया, यह सुनिश्चित करने के लिए कि पैमाने कुछ भी नहीं बदला जाएगा, जैसा कि आप नीचे देख सकते हैं;

यहाँ छवि विवरण दर्ज करें

एक इंडेक्स मैप का उपयोग करके, आप आसानी से अन्य टाइल के संदर्भ में प्रत्येक टाइल की आईडी और स्थान देख सकते हैं, तब भी जब आप मुख्य दृश्य मानचित्र विंडो से ग्रिड को बंद कर देते हैं। उदाहरण के लिए, निम्न मानचित्र में एक टाइल आईडी = 14 है, और आप आसपास के टाइल आईडी देख सकते हैं।

यहाँ छवि विवरण दर्ज करें

अपडेट :

मैं अपने उत्तर को अपडेट करूंगा क्योंकि मुझे एहसास हुआ कि आप आसपास के लेआउट की आईडी नहीं बल्कि आसपास के लेआउट के पेज नंबर इंडेक्स को दिखाना चाहते थे।

प्रक्रिया की समझ को आसान बनाने के लिए, मैं नीचे दिखाए गए अनुसार लेआउट पृष्ठ संख्या दिखाने के लिए इंडेक्स मैप में आईडी नंबर अपडेट करूंगा:

यहाँ छवि विवरण दर्ज करें

चूँकि मेरे पास 0 (ज़ीरो) से शुरू होने वाली आईडी, सूचकांक मानचित्र पर दिखाए गए पहले ग्रिड की आईडी 3 से शुरू होगी। इसलिए, मैं एटलस में आईडी नंबर से 2 घटाकर 1 से शुरू करने के लिए पेज नंबर बदलना चाहता हूं: Page number: ID -2, तो मैं वर्तमान पृष्ठ संख्या का उपयोग वर्तमान पृष्ठ, पिछले पृष्ठ, अगले पृष्ठ, ऊपर पृष्ठ और नीचे पृष्ठ के लिए लेबल बनाने के लिए अभिव्यक्ति के संदर्भ में निम्नानुसार करूंगा:

यहाँ छवि विवरण दर्ज करें

  • वर्तमान पाठ में लेबल पाठ बॉक्स में यह अभिव्यक्ति है: Current Page Number: [%@atlas_pagename%]

  • पिछला पृष्ठ अभिव्यक्ति: [%if((@atlas_pagename = 1), Null, '↑ Page Number: ' || (@atlas_pagename - 1))%]चूंकि 1 से पहले कोई पृष्ठ नहीं हैं

  • अगला पृष्ठ अभिव्यक्ति: [%if( (@atlas_pagename = 25), Null, '↓ Page Number: ' || (@atlas_pagename + 1))%]चूंकि 25 के बाद कोई पृष्ठ नहीं हैं

  • पृष्ठ की अभिव्यक्ति: [%if((@atlas_pagename <= 6),NULL,'↑ Page Number: ' || (@atlas_pagename -6))%]चूंकि ऊपरी दिशा में 6 से पहले कोई पृष्ठ नहीं हैं

  • नीचे पृष्ठ अभिव्यक्ति: [%if((@atlas_pagename >= 20), Null, '↓ Page Number: ' || (@atlas_pagename + 6))%]चूंकि निचले दिशा में 20 के बाद कोई पृष्ठ नहीं हैं

कुछ आउटपुट परिणाम:

यहाँ छवि विवरण दर्ज करें

यहाँ छवि विवरण दर्ज करें

यहाँ छवि विवरण दर्ज करें

यहाँ छवि विवरण दर्ज करें


हालांकि उपयोगी, यह उनके सवाल का जवाब नहीं देता है।
विक्टर

@ विक्टर आपकी टिप्पणी के लिए धन्यवाद, मैंने अपना उत्तर अपडेट कर दिया।
अहमदनब

यह आपके उदाहरण (और उसके) में काम करता है, क्योंकि कीमैप / ग्रिड के पक्ष नियमित हैं। यदि वे सीधे नहीं होते हैं तो जोड़ने या घटाना (आपके उदाहरण में 6) की संख्या के बाद से यह काम नहीं करेगा जो आपके द्वारा किए गए एटलस पृष्ठ के आधार पर अलग-अलग होंगे।
विक्टर

2
मैं आपसे सहमत हुँ। यदि ग्रिड नियमित नहीं है तो प्रक्रिया अधिक जटिल होगी। लेकिन जब से वह इसे एक नियमित ग्रिड पर लागू करना चाहता है, मेरे सुझाए गए समाधान में लागू विधि काम करेगी।
अहमदनब

इस तथ्य को ध्यान में रखते हुए, आपके पास एक और अच्छा विचार है! खासकर जब से मेरा ग्रिड नियमित नहीं है!
विक्टर

2

यह समाधान आयताकार ग्रिड के लिए काम करेगा और यह स्वचालित है (मैन्युअल रूप से कुछ भी समायोजित किए बिना किसी भी परिदृश्य के लिए काम करना चाहिए)।

मान लेते हैं कि आपके पास पृष्ठ संख्याओं के साथ एक ग्रिड है। आप पैरामीटर के रूप में ग्रिड परत और उसके पृष्ठ संख्या क्षेत्र का चयन करके मेरी प्रसंस्करण स्क्रिप्ट चला सकते हैं । स्क्रिप्ट right, left, above, belowग्रिड परत में चार फ़ील्ड ( ) बनाती है और प्रत्येक ग्रिड सेल के लिए संबंधित पड़ोसी पृष्ठ आईडी की गणना करती है। फिर आप [% if( "left" is not NULL, 'to page' || "left", "" ) %]पड़ोसी पृष्ठ के लेबल दिखाने के लिए अपनी अभिव्यक्तियों (जैसे, ) का उपयोग कर सकते हैं ।

बस QGIS रिसोर्स शेयरिंग प्लगइन से मेरी रिपॉजिटरी ( https://github.com/gacarrillor/QGIS-Resources.git ) जोड़ें और स्क्रिप्ट स्थापित करें: यहाँ छवि विवरण दर्ज करें

यहाँ छवि विवरण दर्ज करें

यह काम किस प्रकार करता है

स्क्रिप्ट वर्तमान ग्रिड सेल और प्रत्येक इंटरसेक्टिंग सेल दोनों से बाउंडिंग निर्देशांक की तुलना करके संबंध (दाएं, बाएं, ऊपर या नीचे) को निर्धारित करता है। यह पता चला है कि प्रत्येक संबंध के लिए, निर्देशांक में से एक गायब है।

यदि संबंध है above, लापता समन्वय है yMin, यानी, वर्तमान ग्रिड सेल के बाउंडिंग बॉक्स से अन्य सभी 3 निर्देशांक उपरोक्त सेल के बाउंडिंग बॉक्स में मौजूद होंगे। याद रखें कि QGIS बाउंडिंग बॉक्स इस क्रम में परिभाषित किए गए हैं [xMin, yMin, xMax, yMax]:।

एक संख्यात्मक उदाहरण के लिए आइए लंबाई के पक्षों के साथ आयतें लें। कहते हैं कि वर्तमान सेल की बाउंडिंग बॉक्स को परिभाषित किया गया है bbox1=[0,0,1,1]। उपरोक्त सेल के बाउंडिंग बॉक्स को इस प्रकार परिभाषित किया जाएगा bbox2=[0,1,1,2]। Bbox1 से X निर्देशांक bbox2 में मौजूद हैं, जबकि bbox1 का yMinY निर्देशांक bbox2 में गायब है।

हम अपने 4 संबंधों को इस तरह से परिभाषित कर सकते हैं (ओ: वर्तमान, #: लापता):

right: [#,o,o,o]
above: [o,#,o,o]
left:  [o,o,#,o]
below: [o,o,o,#]

जैसा कि आप देख सकते हैं, लापता सूचकांक हमें वह सारी जानकारी देता है जिसकी हमें आवश्यकता है।

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