QGIS में सेक्टर लाइट्स बनाना?


24

मैं QGIS 2.18 का उपयोग कर रहा हूं। मुझे मानचित्र पर नेविगेशनल उद्देश्यों के लिए सेक्टर लाइट्स बनाने की आवश्यकता है।

मेरे पास प्रकाश क्षेत्र का डेटा है क्योंकि 500 ​​से अधिक buoys, बीकन और प्रकाशस्तंभों के साथ एक आकार आकार में becon_id, प्रारंभ डिग्री, अंत डिग्री और रंग देने वाले फ़ील्ड के रूप में मानचित्र पर दिखाए जाने की आवश्यकता है। प्रत्येक बीकन के लिए, कई पंक्तियाँ हो सकती हैं, प्रत्येक एक प्रकाश क्षेत्र का वर्णन करती है (उदाहरण के लिए एक सफेद क्षेत्र)

अंतिम परिणाम नीचे के बारे में दिखना चाहिए: सही रंगों में प्रकाश क्षेत्र, रंग क्षेत्र (आरजीडब्ल्यू) में चरित्र के रूप में चिह्नित रंग के साथ, और बोया / बीकन / लाइटहाउस से 100 मीटर से 1000 मीटर तक बिंदीदार रेखाएं।

यह सबसे अधिक संभावना एक शासित-आधारित प्रतीक के रूप में बनाया जाना चाहिए, लेकिन मुझे लगता है कि कुछ अजगर की जरूरत है?

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

यहाँ नीचे एक लाइटहाउस के डेटा का उदाहरण दिया गया है (दुर्भाग्यवश ऊपर वाला नहीं), जिसमें 114 और 154 डिग्री के बीच एक ग्रीन सेक्टर, 154 और 168 डिग्री के बीच एक सफेद सेक्टर, 168 और 237 डिग्री के बीच एक लाल सेक्टर, एक हरा है 237 और 314 डिग्री के बीच का क्षेत्र, 314 और 320 डिग्री के बीच का एक सफेद सेक्टर, 320 और 337 डिग्री के बीच एक लाल क्षेत्र (किसी कारण से, 0 उत्तर नहीं बल्कि दक्षिण):

आकार तालिका उदाहरण



2
कृपया, क्या आप एक नमूना डेटासेट अपलोड कर सकते हैं और अपने प्रश्न को विस्तृत करके बता सकते हैं कि वास्तव में आप क्या अपेक्षा करते हैं? संलग्न छवि में मैं केवल प्रतीकों और रंगों का एक ब्रह्मांड देखता हूं।
मैग्री

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

हाय @mgri और स्टीवन, मैंने उदाहरण डेटा जोड़ा और प्रश्न को स्पष्ट करने की कोशिश की :), धन्यवाद!
बेंजामिन डोनर

1
@ मैग्री लाइन्स एक वेरिएबल नहीं हैं, लेकिन इमेज की तरह लाइट सेक्टर्स के बीच की लाइन्स को 900 मी लंबी लाइनों के रूप में स्टैटिकली दिखाया जाना चाहिए। अनुमानित संदर्भ प्रणाली।
बेंजामिन डोनर

जवाबों:


50

EDIT I ने विशेष स्थितियों (विशिष्ट कोण मानों के कारण) के प्रबंधन के लिए और एक गोल कोण परिभाषित होने पर बिंदीदार रेखाओं को प्रदर्शित नहीं करने के लिए उत्तर संपादित किया।


मैं केवल नियम-आधारित सिम्बॉलॉजी और लेबलिंग के आवर्ती द्वारा एक समाधान का प्रस्ताव करता हूं।

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

इसके अलावा, यह समाधान केवल तभी काम करता है जब आप यह मान लेते हैं कि 0डिग्री दक्षिण के बजाय उत्तर है (यदि 0दक्षिण है, इसके बजाय, यह 180हर बार एक मान को पर्याप्त करेगा जो कि '90' के फॉर्मूले में दिखाई देता है जो कोणों के साथ व्यवहार करते हैं, जैसे cos(radians(90))बन जाएगा cos(radians(180 + 90)))। मैंने केवल अधिक सामान्य समाधान देने के लिए ऐसा करना पसंद किया।


स्टाइलिंग

हम Single symbolएक Simple Markerऔर तीन Geometry generatorप्रतीक परतों के आवर्ती के साथ अंक प्रस्तुत करेंगे :

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

आगे की व्याख्या में, मैं ऊपर की छवि में प्रतीकों के उसी क्रम का पालन करूंगा।

1) सरल मार्कर

मैंने एक ब्लैक स्टार का डिफ़ॉल्ट चिन्ह चुना (यह इस ट्यूटोरियल का सबसे आसान हिस्सा है), जिसका आकार 3 मिमी और चौड़ाई 0.4 मिमी है।

2) ज्यामिति जनरेटर नंबर 1

एक नई प्रतीक परत जोड़ें और Geometry generatorप्रकार चुनें :

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

इस एक्सप्रेशन को Expressionफ़ील्ड में डालें :

CASE
WHEN abs( "ALKUKULMA" - "LOPPUKULMA") < 360
THEN
make_line(
 $geometry,
 make_point(
  $x + 1000*cos(radians(90 - "ALKUKULMA")),
  $y + 1000*sin(radians(90 - "ALKUKULMA"))
  )
)
END

हमने केवल पहली पंक्ति को परिभाषित किया है जो उस बिंदु की ओर इंगित करता है जहां प्रकाश क्षेत्र शुरू होता है। यह रेखा 1000 मीटर लंबी है और इसे केवल तभी बनाया जाता है जब सेक्टर प्रकाश का उद्घाटन कोण एक गोल कोण नहीं होता है (यह बचने के लिए होता है कि लाइन एक पूरे वृत्त को तोड़ देगी)।

3) ज्यामिति जनरेटर नंबर 2

ऊपर के समान लेकिन, इस चरण में, आपको इस अभिव्यक्ति का उपयोग करने की आवश्यकता है:

CASE
WHEN abs( "ALKUKULMA" - "LOPPUKULMA") < 360
THEN
make_line(
 $geometry,
 make_point(
  $x + 1000*cos(radians(90 - "LOPPUKULMA")),
  $y + 1000*sin(radians(90 - "LOPPUKULMA"))
  )
)
END

हमने केवल पहली पंक्ति को परिभाषित किया है जो उस बिंदु की ओर इंगित करती है जहां प्रकाश क्षेत्र समाप्त होता है। यह रेखा 1000 मीटर लंबी है और इसे केवल तभी बनाया जाता है जब सेक्टर प्रकाश का उद्घाटन कोण एक गोल कोण नहीं होता है (यह बचने के लिए होता है कि लाइन एक पूरे वृत्त को तोड़ देगी)।

4) ज्यामिति जेनरेटर नंबर 3

इस एक्सप्रेशन को Expressionफ़ील्ड में डालें :

CASE

WHEN abs("ALKUKULMA" - "LOPPUKULMA") <= 180 AND "ALKUKULMA" >= "LOPPUKULMA"
THEN
difference(
 boundary(
  buffer(
   $geometry, 900)
   ),
  make_polygon(
   geom_from_wkt(
    geom_to_wkt(
     make_line(
      $geometry,
      make_point($x + 2000*cos(radians(90 - "ALKUKULMA" )), $y + 2000*sin(radians((90 - "ALKUKULMA" )))),
      make_point($x + 2000*cos(radians(90 - ("LOPPUKULMA" + "ALKUKULMA")/2 )), $y + 2000*sin(radians((90 - ("LOPPUKULMA" + "ALKUKULMA")/2 )))),
      make_point($x + 2000*cos(radians(90 - "LOPPUKULMA")), $y + 2000*sin(radians((90 - "LOPPUKULMA")))),
      $geometry)
   )  
  )
 )
)

WHEN abs("ALKUKULMA" - "LOPPUKULMA") <= 180 AND "ALKUKULMA" <= "LOPPUKULMA"
THEN
intersection(
 boundary(
  buffer(
   $geometry, 900)
   ),
  make_polygon(
   geom_from_wkt(
    geom_to_wkt(
     make_line(
      $geometry,
      make_point($x + 2000*cos(radians(90 - "ALKUKULMA" )), $y + 2000*sin(radians((90 - "ALKUKULMA" )))),
      make_point($x + 2000*cos(radians(90 - ("LOPPUKULMA" + "ALKUKULMA")/2 )), $y + 2000*sin(radians((90 - ("LOPPUKULMA" + "ALKUKULMA")/2 )))),
      make_point($x + 2000*cos(radians(90 - "LOPPUKULMA")), $y + 2000*sin(radians((90 - "LOPPUKULMA")))),
      $geometry)
   )  
  )
 )
)

WHEN abs("ALKUKULMA" - "LOPPUKULMA") > 180 AND "ALKUKULMA" >= "LOPPUKULMA"
THEN
intersection(
 boundary(
  buffer(
   $geometry, 900)
   ),
  make_polygon(
   geom_from_wkt(
    geom_to_wkt(
     make_line(
      $geometry,
      make_point($x + 2000*cos(radians(90 - "ALKUKULMA" )), $y + 2000*sin(radians((90 - "ALKUKULMA" )))),
      make_point($x - 2000*cos(radians(90 - ("LOPPUKULMA" + "ALKUKULMA")/2 )), $y - 2000*sin(radians((90 - ("LOPPUKULMA" + "ALKUKULMA")/2 )))),
      make_point($x + 2000*cos(radians(90 - "LOPPUKULMA")), $y + 2000*sin(radians((90 - "LOPPUKULMA")))),
      $geometry)
   )  
  )
 )
)

WHEN abs("ALKUKULMA" - "LOPPUKULMA") > 180 AND "ALKUKULMA" <= "LOPPUKULMA"
THEN
difference(
 boundary(
  buffer(
   $geometry, 900)
   ),
  make_polygon(
   geom_from_wkt(
    geom_to_wkt(
     make_line(
      $geometry,
      make_point($x + 2000*cos(radians(90 - "ALKUKULMA" )), $y + 2000*sin(radians((90 - "ALKUKULMA" )))),
      make_point($x - 2000*cos(radians(90 - ("LOPPUKULMA" + "ALKUKULMA")/2 )), $y - 2000*sin(radians((90 - ("LOPPUKULMA" + "ALKUKULMA")/2 )))),
      make_point($x + 2000*cos(radians(90 - "LOPPUKULMA")), $y + 2000*sin(radians((90 - "LOPPUKULMA")))),
      $geometry)
   )  
  )
 )
)


END

हमने प्रकाश क्षेत्र के शुरुआती और अंतिम बिंदुओं के बीच चाप को परिभाषित किया है (कृपया ध्यान दें कि 2000यह एक मनमाना मूल्य है क्योंकि मैं एक बहुभुज बनाने की कोशिश कर रहा हूं, जिसमें 900 मीटर की त्रिज्या वाली सीमा के साथ एक दूसरे को काटना है)।

इसके अलावा, हमें उस रंग को सेट करने की आवश्यकता है जो "VARIS"फ़ील्ड में संग्रहीत है । ऐसा करने के लिए, हमें इसे एक कस्टम अभिव्यक्ति के साथ निर्दिष्ट करने की आवश्यकता है। नीचे दी गई छवि में तीर का पालन करें:

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

और फिर Edit...बटन पर क्लिक करने के बाद इस अभिव्यक्ति को टाइप करें:

CASE
WHEN  "VARIS" = 'vi' THEN color_rgb(51,160,44)
WHEN "VARIS" = 'v' THEN color_rgb(255,255,255)
WHEN "VARIS" = 'p' THEN color_rgb(227,26,28)
END

कृपया ध्यान दें कि, इस प्रतीक परत के लिए, मैंने दो लाइनें बनाईं: ऊपरी रेखा रंग को उपयोग करने के लिए परिभाषित करती है (वास्तव में मैं इस एक के लिए कस्टम अभिव्यक्ति सेट करता हूं), जबकि निचली एक काली सीमा को परिभाषित करने के लिए उपयोगी है (इसमें होगा) एक चौड़ाई जो ऊपरी रेखा से एक से बड़ी है)। किसी भी रंग अतिव्यापी से बचने के लिए दोनों पंक्तियों के Flatरूप में सेट करने के Cap styleलिए भी याद रखें ।


लेबलिंग

1) लेबल सेट करना

पर जाएं Layer Properties> Labelsऔर हमेशा की तरह, लाल तीर का पालन करें:

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

और फिर यह अभिव्यक्ति टाइप करें:

CASE
WHEN "VARIS" = 'vi' THEN 'G'
WHEN "VARIS" = 'v' THEN 'W'
WHEN "VARIS" = 'p' THEN 'R'
END

हमने केवल "VARIS"क्षेत्र में संग्रहीत मूल्य का उपयोग करके रंग नियम को परिभाषित किया है ।

2) लेबल के लिए प्लेसमेंट सेट करना

मेनू Placementमें विकल्प चुनें Labelsऔर चुनें Offset from point

फिर, नीचे की छवि के संदर्भ में:

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

लाल तीर का अनुसरण करें और इस अभिव्यक्ति को टाइप करें:

CASE
WHEN "ALKUKULMA" > "LOPPUKULMA"
THEN
concat(
 -1000*cos(radians(90 - ("ALKUKULMA" + "LOPPUKULMA")/2)),
  ',',
  1000*sin(radians(90 - ("ALKUKULMA" + "LOPPUKULMA")/2))
)
WHEN "ALKUKULMA" <= "LOPPUKULMA"
THEN
concat(
 1000*cos(radians(90 - ("ALKUKULMA" + "LOPPUKULMA")/2)),
  ',',
  -1000*sin(radians(90 - ("ALKUKULMA" + "LOPPUKULMA")/2))
)
END

फिर, हरे तीर का अनुसरण करें और इस अभिव्यक्ति को टाइप करें:

CASE
WHEN "ALKUKULMA" >= "LOPPUKULMA"
THEN
180-(("ALKUKULMA" + "LOPPUKULMA")/2)
WHEN "ALKUKULMA" < "LOPPUKULMA"
THEN
- (("ALKUKULMA" + "LOPPUKULMA")/2)
END

अंतिम परिणाम

यदि आपने पिछले कार्यों को सही ढंग से किया है, तो आपको यह परिणाम प्राप्त करने में सक्षम होना चाहिए:

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

बोनस

चूंकि इस उत्तर के भीतर पूरी तरह से कवर होने के लिए मामूली पैरामीटर बहुत अधिक थे, इसलिए मैंने यहां शैली संलग्न की है : आप इस कोड को किसी भी टेक्स्ट एडिटर के साथ खोल सकते हैं और इसे QGIS लेयर स्टाइल फाइल के रूप में सहेज सकते हैं (अर्थात .qmlएक्सटेंशन के साथ )।

उपरोक्त शैली QGIS 2.18.4 का उपयोग करके बनाई गई थी (इसमें आपके द्वारा उपयोग किए जाने वाले आकार का नाम समान होना चाहिए)।


3
बहुत अच्छा लग रहा है, वास्तव में आपको ज्यामिति जनरेटर की शक्ति दिखाता है। क्या यह रेंडर करना धीमा है?
हिक्कीवेसंतो

2
@Vesanto मैंने छह सुविधाओं (यानी छह सेक्टर रोशनी) वाले एक बिंदु पर इसका परीक्षण किया और इसे तुरंत प्रस्तुत किया। मुझे लगता है कि सैकड़ों फीचर्स के साथ काम करते समय यह तेजी से होना चाहिए क्योंकि प्रदाताओं या कुछ इसी तरह की कोई कॉल नहीं है, लेकिन केवल कुछ ऑपरेशंस और जियोमेट्रीज जैसे वेल नो टेक्स्ट।
माजरी

2
प्रश्न / उत्तर जैसे ये वास्तव में दिखाते हैं कि QGIS कितना बहुमुखी हो सकता है!
जोसेफ

1
@mgri आप द मास्टर हैं, एक कल्पनात्मक रूप से अच्छा समाधान और बहुत सारे काम से जुड़े एक महान विवरण, धन्यवाद!
बेंजामिन डोनर

1
@ इस क्षेत्र में एक पहाड़ का नाम आपके नाम पर रखा जाना चाहिए, धन्यवाद !! मैंने थोड़ा परीक्षण किया है और आपके अतिरिक्त समाधानों के साथ कोई समस्या नहीं मिली है :)!
बेंजामिन डोनर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.