EDYCJA Edytowałem odpowiedź na zarządzanie konkretnymi sytuacjami (ze względu na określone wartości kątów) i za brak wyświetlania kropkowanych linii, gdy zdefiniowano kąt okrągły.
Proponuję rozwiązanie, powracając tylko do opartej na regułach symboliki i znakowania.
Przed rozpoczęciem chcę podkreślić, że skupię uwagę na wyjaśnieniu minimalnych czynności, które należy wykonać, aby odtworzyć pożądany rezultat: oznacza to, że niektóre inne drobne parametry (takie jak rozmiary, szerokości itp.) Powinny być łatwo dostosowane przez ciebie dla lepszego dopasowania do twoich potrzeb.
Co więcej, to rozwiązanie działa tylko wtedy , gdy założymy, że 0
stopień to Północ zamiast Południa (jeśli 0
jest to Południe, wystarczyłoby sumowanie 180
wartości za każdym razem, gdy pojawia się „90” w formułach, które dotyczą kątów, np. cos(radians(90))
Stałyby się cos(radians(180 + 90))
). Wolałem to robić tylko po to, aby dać bardziej ogólne rozwiązanie.
Stylizacja
Wyrenderujemy punkty za pomocą Single symbol
i, powtarzając się do jednej Simple Marker
i trzech Geometry generator
warstw symboli:
W dalszym objaśnieniu zastosuję tę samą kolejność symboli na powyższym obrazku.
1) Prosty znacznik
Wybrałem domyślny symbol czarnej gwiazdy (jest to łatwiejsza część tego samouczka), mający rozmiar 3 mm i szerokość 0,4 mm.
2) Generator geometrii nr 1
Dodaj nową warstwę symboli i wybierz Geometry generator
typ:
Wstaw to wyrażenie w Expression
pole:
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
Właśnie zdefiniowaliśmy pierwszą linię, która wskazuje punkt, od którego zaczyna się sektor światła. Ta linia ma 1000 m długości i jest tworzona tylko wtedy, gdy kąt otwarcia światła sektorowego nie jest kątem okrągłym (dzieje się tak, aby uniknąć pęknięcia całego okręgu).
3) Generator geometrii nr 2
To samo co powyżej, ale na tym etapie musisz użyć tego wyrażenia:
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
Właśnie zdefiniowaliśmy pierwszą linię, która wskazuje punkt, w którym kończy się sektor światła. Ta linia ma 1000 m długości i jest tworzona tylko wtedy, gdy kąt otwarcia światła sektorowego nie jest kątem okrągłym (dzieje się tak, aby uniknąć pęknięcia całego okręgu).
4) Generator geometrii nr 3
Wstaw to wyrażenie w Expression
pole:
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
Właśnie zdefiniowaliśmy łuk między punktami początkowym i końcowym sektora lekkiego (pamiętaj, że 2000
jest to dowolna wartość, ponieważ próbuję utworzyć wielokąt przecinający się z granicą okręgu o promieniu 900 m).
Ponadto musimy ustawić kolor, który jest przechowywany w "VARIS"
polu. W tym celu musimy podać niestandardowe wyrażenie. Postępuj zgodnie ze strzałką na obrazku poniżej:
a następnie wpisz to wyrażenie po kliknięciu Edit...
przycisku:
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
Pamiętaj, że dla tej warstwy symboli utworzyłem dwie linie: górna linia określa kolor, który ma być używany (w rzeczywistości ustawiam dla niej niestandardowe wyrażenie), podczas gdy dolna jest przydatna do definiowania czarnej ramki (będzie miała szerokość, która jest większa niż górna linia). Pamiętaj również, aby ustawić Flat
jak Cap style
dla obu linii, aby uniknąć nakładania się kolorów.
Etykietowanie
1) Ustawianie etykiet
Przejdź do Layer Properties
> Labels
i, jak zwykle, postępuj zgodnie z czerwonymi strzałkami:
a następnie wpisz to wyrażenie:
CASE
WHEN "VARIS" = 'vi' THEN 'G'
WHEN "VARIS" = 'v' THEN 'W'
WHEN "VARIS" = 'p' THEN 'R'
END
Właśnie zdefiniowaliśmy regułę koloru za pomocą wartości zapisanej w "VARIS"
polu.
2) Ustawienie położenia etykiet
Wybierz Placement
opcję w Labels
menu i wybierz Offset from point
.
Następnie w odniesieniu do poniższego obrazu:
postępuj zgodnie z czerwoną strzałką i wpisz to wyrażenie:
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
Następnie postępuj zgodnie z zieloną strzałką i wpisz to wyrażenie:
CASE
WHEN "ALKUKULMA" >= "LOPPUKULMA"
THEN
180-(("ALKUKULMA" + "LOPPUKULMA")/2)
WHEN "ALKUKULMA" < "LOPPUKULMA"
THEN
- (("ALKUKULMA" + "LOPPUKULMA")/2)
END
Ostateczny wynik
Jeśli poprawnie wykonałeś poprzednie zadania, powinieneś być w stanie uzyskać ten wynik:
Premia
Ponieważ drugorzędnych parametrów było zbyt wiele, aby można je było w całości ująć w tej odpowiedzi, załączyłem tutaj styl : możesz otworzyć ten kod w dowolnym edytorze tekstu i zapisać go jako plik stylu warstwy QGIS (tj. Z .qml
rozszerzeniem).
Powyższy styl został stworzony przy użyciu QGIS 2.18.4 (musi mieć tę samą nazwę, z której korzystasz).