Wyświetlanie symboli anteny na mapie: symbole lub obiekty punktowe (wielokąty)

12

Chcę pokazać sieć komórkową na mapie. Dane wejściowe to plik .csv, w którym każdy ciąg jest sektorem komórkowym. Atrybuty to: identyfikator sektora, jego współrzędne, azymut i kąt szerokości wiązki anteny.

Wartości szerokości wiązki anteny mieszczą się w zakresie od 30 do 360 stopni. Szerokość wiązki anteny 360 oznacza, że ​​musi być pokazana na mapie jako okrąg. Anteny o innych szerokościach wiązki muszą być pokazane jako sektory o odpowiednich kątach apertury.

wprowadź opis zdjęcia tutaj

Czy można pokazać anteny tylko za pomocą symboli? Wiem, jak stworzyć własny symbol SVG i mam nadzieję, że uda mi się go obrócić zgodnie z azymutem. Ale czy jest jakiś sposób na zastosowanie zmiennej szerokości wiązki anteny zgodnie z jej wartością atrybutu od 30 do 360 stopni?

Myślę, że symbole są najlepszym sposobem na narysowanie anten ze względu na dynamiczną wizualizację na mapie zgodnie ze skalą widoku, jeśli jest to możliwe w QGIS.

Oczywiście zadanie można rozwiązać, rysując odpowiednie wielokąty jako element warstwy, ale byłoby to rozwiązanie obejścia.

E Bobrov
źródło
Więc musisz narysować łuk we właściwym kierunku, który jest inny dla każdej strony?
Nathan W
Wcale nie, jeśli dobrze rozumiem. Musi to być odcinek koła (lub cały okrąg w przypadku szerokości wiązki = 360), jak pokazano na rysunku.
E Bobrov
Tak, o to mi chodzi.
Nathan W
Dobra, widzę. Mówiąc ogólnie, symbol łuku nie jest ściśle potrzebny. Głównymi atrybutami są azymut i szerokość wiązki. Mogę użyć dowolnego symbolu, aby narysować anteny, a nie tylko łuk.
E Bobrov
Prawdopodobnie znalazłem przykład, który może pomóc: Tworzenie niestandardowych typów warstw symboli . Ale nie jestem pewien. Czy ktoś próbował stworzyć własną klasę warstw symboli, która rysuje na przykład kierunek każdej warstwy w zależności od jej atrybutu (tj. Azymutu anteny w słowach na obrazku powyżej)?
E Bobrov

Odpowiedzi:

7

Kilka dni temu dodano nową wtyczkę do QGIS o nazwie Algorytm przetwarzania bufora klinowego . Wygląda na to, że może być interesujące.

Jak sama nazwa wskazuje, jest to algorytm przetwarzania, więc musisz go uruchomić z przybornika przetwarzania. Nie miałem jeszcze okazji tego spróbować.

Tworzy sektory kół - jak normalny bufor kołowy, ale kąt i promień klina można ustawić za pomocą wartości pola.

Dokumentację i zrzuty ekranu można zobaczyć na stronie github

Steven Kay
źródło
10

Jeśli chcesz używać tylko symboliki, proponuję rozwiązanie inspirowane moją odpowiedzią z podobnego pytania: Tworzenie świateł sektorowych w QGIS? .


Zgodnie z podobnym podejściem i zakładając, że pracujesz nad Projekowanym CRS (zamiast tego, jeśli używasz Geograficznego Układu Współrzędnych, zobacz notatkę na końcu odpowiedzi), chcę podkreślić, że skupię uwagę na wyjaśnieniu minimalnych czynności, które należy wykonać, aby odtworzyć pożądany wynik: oznacza to, że niektóre inne drobne parametry (takie jak rozmiary, szerokości itp.) powinny być łatwo regulowane przez użytkownika w celu lepszego dopasowania do potrzeb.

Ponadto zakładam, że "AZIMUTH"jest to pole przechowujące wartości azymutu i "BEAMWIDTH"pole przechowujące szerokości wiązki anteny.

Rozwiązanie

Wyrenderujemy punkty za pomocą Single symboli, powtarzając się do jednej Simple Markeri dwóch Geometry generatorwarstw symboli:

wprowadź opis zdjęcia tutaj

W dalszym objaśnieniu zastosuję tę samą kolejność symboli na powyższym obrazku.

1) Prosty znacznik

Wybrałem domyślny symbol czerwonego koła (jest to łatwiejsza część tego samouczka) o rozmiarze 3 mm i szerokości 0,4 mm.

2) Generator geometrii nr 1

Dodaj nową warstwę symboli i wybierz Geometry generatororaz LineString / MultiLineStringtypy:

wprowadź opis zdjęcia tutaj

Wstaw to wyrażenie w Expressionpole:

make_line(
 $geometry,
 make_point($x + 300*cos(radians(90 -  "AZIMUTH" )), $y + 300*sin(radians((90 - "AZIMUTH" ))))
)

Właśnie zdefiniowaliśmy strzałkę wskazującą na zestaw azymutu (przy tworzeniu strzałki pamiętaj, aby wybrać Arrowtyp warstwy symbolu pod Lineopcją z głównego menu symboli). Pamiętaj, że 300reprezentuje odległość w metrach i jest to dowolna wartość, więc możesz ją zmienić w zależności od potrzeb.

3) Generator geometrii nr 2

Dodaj nową warstwę symboli i wybierz Geometry generatortyp oraz Polygon / MultiPolygontypy:

wprowadź opis zdjęcia tutaj

Wstaw to wyrażenie w Expressionpole:

CASE
WHEN ("BEAMWIDTH") <= 180
THEN
intersection(
  buffer(
   $geometry, 200),
  make_polygon(
   geom_from_wkt(
    geom_to_wkt(
     make_line(
      $geometry,
      make_point($x + 2000*cos(radians(90 -  "AZIMUTH" - "BEAMWIDTH"/2 )), $y + 2000*sin(radians((90 - "AZIMUTH" - "BEAMWIDTH"/2 )))),
      make_point($x + 2000*cos(radians(90 -  "AZIMUTH" )), $y + 2000*sin(radians((90 - "AZIMUTH" )))),
      make_point($x + 2000*cos(radians(90 - "AZIMUTH" + "BEAMWIDTH" /2)), $y + 2000*sin(radians((90 - "AZIMUTH" + "BEAMWIDTH"/2)))),
      $geometry)
     )
    )
   )
  )

WHEN ("BEAMWIDTH") > 180
THEN
difference(
  buffer(
   $geometry, 200),
   make_polygon(
    geom_from_wkt(
     geom_to_wkt(
      make_line(
       $geometry,
       make_point($x + 2000*cos(radians(90 -  "AZIMUTH" - "BEAMWIDTH"/2 )), $y + 2000*sin(radians((90 - "AZIMUTH" - "BEAMWIDTH"/2 )))),
       make_point($x - 2000*cos(radians(90 -  "AZIMUTH" )), $y - 2000*sin(radians((90 - "AZIMUTH" )))),
       make_point($x + 2000*cos(radians(90 - "AZIMUTH" + "BEAMWIDTH" /2)), $y + 2000*sin(radians((90 - "AZIMUTH" + "BEAMWIDTH"/2)))),
       $geometry)
      )
     )
    )
   )

END

Właśnie zdefiniowaliśmy sektor. Należy pamiętać, że 200i 2000reprezentują odległości w metrach i są arbitralne wartości, ponieważ staram się stworzyć wielokąt do przecięcia z okręgu o promieniu 200 m, więc nie krępuj się je zmieniać w zależności od potrzeb.

Ostateczny wynik

Jeśli poprawnie wykonasz poprzednie zadania, powinieneś być w stanie uzyskać wyniki takie jak te (etykiety są dodawane oprócz tego rozwiązania i powinny one tylko lepiej wyjaśniać kontekst):

wprowadź opis zdjęcia tutaj

Uwaga

Jeśli używasz Geograficznego Układu Współrzędnych , tj. Jeśli masz do czynienia ze stopniami, a nie odległościami, powinno wystarczyć użycie odpowiednich wartości, gdy użyłem odległości w poprzednich formułach. Odległości, które zastosowałem to:

  • 300 m (patrz generator geometrii nr 1);
  • 200 m (patrz generator geometrii nr 2);
  • 2000 m (patrz Geometry Generator nr 2);

więc można zastąpić go innym arbitralnych wartości wyrażone w stopniach (na przykład 0.0002, 0.002i tak dalej).

Premia

Tutaj załączyłem styl : możesz otworzyć ten kod w dowolnym edytorze tekstu i zapisać go jako plik stylu warstwy QGIS (tj. Z .qmlrozszerzeniem).

Powyższy styl został utworzony za pomocą QGIS 2.18.4 (musi mieć tę samą nazwę, z której korzystasz).

mgri
źródło
Czy szukałeś tego rozwiązania? Czy to działa?
mgri
Twoje rozwiązanie całkowicie rozwiązuje sprawę opisaną w temacie! Wdrożyłem go i zrozumiałem, że mój własny prawdziwy przypadek jest nieco inny. Przepraszam, to moja wina.
E Bobrov
1) Gęstość moich sektorów na mapie jest różna, tzn. W przypadku krótkich odległości między sektorami zdefiniowana odległość w kodzie spowoduje nakładanie się wielu sektorów, zmiana powiększenia mapy nie pomogłaby, więc będzie raczej trudna czytać mapę. Ale w przypadku dużych odległości między sektorami pokazane sektory będą bardzo małe i być może trudne do odczytania na mapie. Używanie pojedynczych symboli jest wolne od tego problemu, ich skale zmieniają się wraz z powiększaniem mapy.
E Bobrov
2) I występują zniekształcenia szerokości wiązki: szerokość wiązki 360 stopni wygląda jak elipsy, sektory o różnych azymutach, ale ta sama szerokość wiązki nie wygląda jak sektory o równoważnych szerokościach wiązki. Czy to dlatego, że używam systemu współrzędnych geograficznych? Teraz różne kąty długości / szerokości geograficznej reprezentują różną odległość między punktami na ziemi. Tak więc rozwiązanie musiało zostać zlokalizowane na obszarach Ziemi, na których znajdują się sektory.
E Bobrov
W każdym razie twoje rozwiązanie i odniesienie do podobnej odpowiedzi „Tworzenie świateł sektorowych w QGIS?” pomógł mi zobaczyć przydatne funkcje. Jeszcze raz dziękuję.
E Bobrov
4

Wielkie uznanie dla mgri.

W naszej warstwie testowej wszystko działało sprawnie. W warstwie produkcyjnej po dwóch / trzech godzinach udało mi się wyśledzić problem z geometrią $ . Eksportowałem warstwę punktową z platformy, nie zauważyłem, ale był to MultiPoint . Wydawało się to powodować problemy: strzała nie została narysowana; i o dziwo tylko obliczone punkty zrobiły wielokąt kół.

Kolejną rzeczą jest to, że używam zmiennego promienia . (nie jestem pewien, czy w tym przypadku jest to właściwe słowo, można również nazwać go „długością wiązki” lub cokolwiek innego).

Oto, czego używam teraz, z warstwą typu geometrii MultiPoints (podczas gdy w rzeczywistości wszystkie funkcje są jednym punktem), i działa dla mnie w QGis 2.18.3

Wyrażenie strzałki Brak strzałki, jeśli 360 °.

CASE

WHEN ("BEAMWIDTH") = 360
THEN 
make_line(
 make_point($x, $y),
 make_point($x + "RADIUS"*cos(radians(90 -  "AZIMUTH" )), $y + "RADIUS"*sin(radians((90 - "AZIMUTH" ))))
)

END

Wyrażenie wielokąta

CASE

WHEN ("BEAMWIDTH") <= 180
THEN
intersection(
  buffer(
   make_point($x,$y), "RADIUS"),
  make_polygon(
   geom_from_wkt(
    geom_to_wkt(
     make_line(
      make_point($x,$y),
      make_point($x + "RADIUS"*2*cos(radians(90 -  "AZIMUTH" - "BEAMWIDTH"/2 )), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" - "BEAMWIDTH"/2 )))),
      make_point($x + "RADIUS"*2*cos(radians(90 -  "AZIMUTH" )), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" )))),
      make_point($x + "RADIUS"*2*cos(radians(90 - "AZIMUTH" + "BEAMWIDTH" /2)), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" + "BEAMWIDTH"/2)))),
      make_point($x,$y))
     )
    )
   )
  )

WHEN ("BEAMWIDTH") > 180
THEN
difference(
  buffer(
   make_point($x,$y), "RADIUS"),
   make_polygon(
    geom_from_wkt(
     geom_to_wkt(
      make_line(
       make_point($x,$y),
       make_point($x + "RADIUS"*2*cos(radians(90 -  "AZIMUTH" - "BEAMWIDTH"/2 )), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" - "BEAMWIDTH"/2 )))),
       make_point($x - "RADIUS"*2*cos(radians(90 -  "AZIMUTH" )), $y - "RADIUS"*2*sin(radians((90 - "AZIMUTH" )))),
       make_point($x + "RADIUS"*2*cos(radians(90 - "AZIMUTH" + "BEAMWIDTH" /2)), $y + "RADIUS"*2*sin(radians((90 - "AZIMUTH" + "BEAMWIDTH"/2)))),
       make_point($x,$y))
      )
     )
    )
   )

END
jbostoen
źródło
Moja odpowiedź zaproponowała ogólne podejście: ponieważ w problemie było wiele zmiennych, stworzenie unikalnej procedury rozwiązywania każdej sytuacji było całkiem niemożliwe. Dzięki za wskazanie go i zaproponowanie podejścia z funkcjami MultiPoint z pewnością pomoże komuś w przyszłości.
mgri
1

Zostałem obdarzony częściowym rozwiązaniem w sieci bez żadnych dodatkowych wtyczek, tylko qgis po wyjęciu z pudełka. Nie pokazuje szerokości wiązki anteny, wystarczy obrócić prosty znacznik we właściwym kierunku: użyj prostego znacznika i obróć go z azymutem anteny + 180 stopni (Właściwości warstwy> Pojedynczy simbol-> Znacznik-> Prosty znacznik-> trójkąt-> obrót-> edycja -> wpisz <180 + „azymut anteny”> w polu wyrażenia. Ustaw także Góra w polu Punkt zakotwiczenia znacznika). Konieczne jest użycie <180 + „azymutu anteny”> ze względu na niewłaściwy kierunek osadzonego prostego znacznika trójkąta. W przeciwnym razie pokaże niewłaściwy kierunek anteny.

E Bobrov
źródło