QGIS'te sektör ışıkları yaratılıyor mu?


24

QGIS 2.18 kullanıyorum. Harita üzerinde navigasyon amaçlı sektör ışıkları yaratmam gerekiyor.

Işık sektörü verilerini haritada gösteren becon_id, başlangıç ​​derecesi, bitiş derecesi ve renk şeklinde, haritada gösterilmesi gereken 500'ün üzerinde şamandıra, fener ve deniz fenerinin bulunduğu bir alan olarak veriyorum. Her fener için, her biri bir ışık sektörünü (örneğin beyaz bir sektörü) tanımlayan birçok satır olabilir.

Sonuç, aşağıdakine benzer şekilde olmalıdır: Işık renkleri, renk alanındaki (RGW) karakter olarak işaretlenmiş renk ve şamandıra / fener / deniz fenerinden 100m'den 1000m'ye kadar noktalı çizgilerle doğru renklerde.

Bu büyük olasılıkla kurallara dayalı bir sembol olarak yaratılmalıdır, fakat sanırım biraz python gerekiyor?

görüntü tanımını buraya girin

Aşağıda 114 ila 154 derece arasında yeşil bir alana, 154 ila 168 derece arasında beyaz bir alana, 168 ila 237 arasında kırmızı bir alana, bir yeşil alana sahip olan bir deniz fenerinin (ne yazık ki yukarıdaki değil) şekil dosyası verilerinin bir örneği verilmiştir. 237 ile 314 derece arasında bir sektör, 314 ile 320 arasında beyaz bir sektör, 320 ile 337 arasında kırmızı bir sektör (bazı nedenlerden dolayı 0 kuzey değil güney):

şekil dosyası tablosu örneği



2
Lütfen, örnek bir veri kümesi yükleyip sorunuzu, beklediğiniz sonucun tam olarak ne olduğunu tam olarak açıklayarak düzenleyebilir misiniz? Ekteki resimde sadece bir sembol ve renk evreni görüyorum.
mgri

1
Örnek veriler burada yardımcı olacaktır. Sektörel ışık başına bir özellik veya şamandıra başına bir özellik var mı? Kama Tampon eklentisi burada yardımcı olabilir, ancak bunun ne kadar kolay olduğu, verilerinizin nasıl kurulduğuna bağlı olacaktır.
Steven Kay

Merhaba @mgri ve Steven, ben örnek veri ekledim ve soruyu netleştirmeye çalıştım :), teşekkürler!
Benjamin Donner

1
@mgri çizgiler değişken değildir, ancak resimdeki gibi ışık sektörleri arasında statik olarak 900 m uzunluğunda çizgiler olarak gösterilmesi gereken çizgilerdir. Öngörülen referans sistemi.
Benjamin Donner

Yanıtlar:


50

EDIT Belirli durumları yönetmek (belirli açı değerleri nedeniyle) ve yuvarlak bir açı tanımlandığında noktalı çizgileri görüntülememek için cevabı değiştirdim.


Sadece kurala dayalı semboloji ve etiketleme ile tekrar ederek bir çözüm öneriyorum.

Başlamadan önce, istenen sonucu elde etmek için yapılacak en az şeyin açıklanmasına odaklanacağımın altını çizmek istiyorum: bu, diğer bazı küçük parametrelerin (boyutlar, genişlikler vb.) Sizin tarafınızdan kolayca ayarlanabilmesi gerektiği anlamına gelir. ihtiyaçlarınızı daha iyi karşılamak için.

Ayrıca, bu çözüm yalnızca0 derecenin Güney yerine Kuzey olduğunu varsayarsanız çalışır (Güney ise 0, bunun yerine, 180açılarla ilgilenen formüllerde her zaman '90' görünen bir değer toplamak yeterli cos(radians(90))olacaktır cos(radians(180 + 90))). Bunu daha genel bir çözüm vermek adına yapmayı tercih ettim.


Şekillendirme

Noktaları a ile işaretleyeceğiz Single symbolve bir Simple Markerve üç Geometry generatorsembol katmanına tekrarlayarak :

görüntü tanımını buraya girin

Daha fazla açıklamada, yukarıdaki resimdeki sembollerin aynı sırasını izleyeceğim.

1) Basit Marker

3 mm büyüklüğüne ve 0,4 mm genişliğe sahip siyah bir yıldızın varsayılan sembolünü seçtim (bu, bu eğitimin kolay kısmıdır).

2) Geometri Jeneratör No. 1

Yeni bir sembol katmanı ekleyin ve aşağıdaki Geometry generatortürü seçin :

görüntü tanımını buraya girin

Bu ifadeyi Expressionalana ekleyin :

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

Işık sektörünün başladığı noktaya işaret eden ilk çizgiyi henüz tanımladık. Bu çizgi 1000 m uzunluğundadır ve yalnızca sektör ışığının açılma açısı yuvarlak bir açı olmadığında oluşturulur (bu, çizginin tüm daireyi kırmasını önlemek için olur).

3) Geometri Jeneratör No. 2

Yukarıdakiyle aynı, ancak bu adımda, bu ifadeyi kullanmanız gerekir:

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

Işık sektörünün son bulduğu noktaya işaret eden ilk çizgiyi henüz tanımladık. Bu çizgi 1000 m uzunluğundadır ve yalnızca sektör ışığının açılma açısı yuvarlak bir açı olmadığında oluşturulur (bu, çizginin tüm daireyi kırmasını önlemek için olur).

4) Geometri Jeneratör No. 3

Bu ifadeyi Expressionalana ekleyin :

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

Işık sektörünün başlangıç ​​ve bitiş noktaları arasındaki arkı az önce tanımladık (lütfen 2000keyfi bir değer olduğunu unutmayın, çünkü 900 m yarıçapı olan dairenin sınırlarıyla kesişecek bir çokgen oluşturmaya çalışıyorum ).

Ayrıca, "VARIS"alanda depolanan rengi de ayarlamamız gerekir . Bunu yapmak için, bunu özel bir ifade ile belirtmemiz gerekir. Aşağıdaki resimdeki oku izleyin:

görüntü tanımını buraya girin

ve daha sonra Edit...düğmeyi tıkladıktan sonra bu ifadeyi yazın :

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

Lütfen, bu sembol katmanı için iki satır oluşturduğumu unutmayın: üst satır kullanılacak rengi tanımlar (aslında bunun için özel ifadeyi ayarlarım), alt satır ise siyah kenarlık tanımlamak için yararlı olur ( üst çizgiden daha büyük olan bir genişlik). Ayarlamak için de hatırla Flatolarak Cap styleörtüşen herhangi bir rengi kaçınmak için her iki hatları için.


etiketleme

1) Etiketleri ayarlama

Git Layer Properties> Labelsve her zamanki gibi kırmızı okları izleyin:

görüntü tanımını buraya girin

ve sonra bu ifadeyi yazın:

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

"VARIS"Alanda depolanan değeri kullanarak renk kuralını henüz tanımladık .

2) Etiketler için yerleşimin ayarlanması

Menüden Placementseçeneği seçin Labelsve seçin Offset from point.

Ardından, aşağıdaki resme referansla:

görüntü tanımını buraya girin

kırmızı oku takip edin ve şu ifadeyi yazın:

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

Ardından yeşil oku izleyin ve şu ifadeyi yazın:

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

Son sonuç

Önceki görevleri doğru bir şekilde gerçekleştirdiyseniz, bu sonucu elde edebilmeniz gerekir:

görüntü tanımını buraya girin

Bonus

Küçük parametreler bu cevap içinde tamamen kaplanamayacak kadar çok olduğundan, buradaki stili ekledim : bu kodu herhangi bir metin düzenleyicide açıp QGIS Katman Stili dosyası (örneğin bir .qmluzantıyla) olarak kaydedebilirsiniz .

Yukarıdaki stil, QGIS 2.18.4 kullanılarak oluşturulmuştur (kullandığınız şekil dosyasının adıyla aynı olmalıdır).


3
Harika görünüyor, gerçekten size geometri jeneratörünün gücünü gösteriyor. Oluşturması yavaş mı?
HeikkiVesanto

2
@ Vesanto, altı özelliğe (yani altı sektör ışığı) sahip bir noktada test ettim ve anında oluşturuldu. Yüzlerce özellikle uğraşırken de hızlı olması gerektiğini düşünüyorum, çünkü sağlayıcılara çağrı yapmayan bir şey veya benzer bir şey yok, ancak Well Know Text gibi birkaç matematiksel işlem ve geometri var.
mgri

2
Bunun gibi sorular / cevaplar, QGIS'in ne kadar çok yönlü olabileceğini gösteriyor!
Joseph

1
@mgri sen Üstad, fevkalade iyi bir çözüm ve çok çalışmayı içeren harika bir açıklama, TEŞEKKÜRLER!
Benjamin Donner

1
@mgri bu bölgedeki bir dağ sizden sonra isimlendirilmelidir, teşekkür ederim !! Biraz test ettim ve eklediğiniz çözümlerde hiçbir sorun bulunmadı :)!
Benjamin Donner
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.