EDIT Eu editei a resposta para gerenciar situações particulares (devido a valores de ângulo específicos) e para não exibir as linhas pontilhadas quando um ângulo redondo é definido.
Proponho uma solução recorrendo apenas à simbologia e rotulagem baseadas em regras.
Antes de começar, quero enfatizar que vou focar a atenção na explicação das coisas mínimas a serem feitas para reproduzir o resultado desejado: isso significa que alguns outros parâmetros menores (como tamanhos, larguras etc.) devem ser facilmente ajustados por você para melhor atender às suas necessidades.
Além disso, esta solução só funciona se você assumir que o 0
grau é norte em vez de sul (se 0
for sul, seria suficiente somar um 180
valor toda vez que aparecer um '90' em fórmulas que lidam com ângulos, por exemplo, cos(radians(90))
se tornaria cos(radians(180 + 90))
). Eu preferia fazer isso apenas para dar uma solução mais geral.
Styling
Renderizaremos os pontos com Single symbol
ae recorrendo a uma Simple Marker
e três Geometry generator
camadas de símbolos:
Na explicação adicional, seguirei a mesma ordem dos símbolos na imagem acima.
1) Marcador Simples
Eu escolhi o símbolo padrão de uma estrela negra (essa é a parte mais fácil deste tutorial), com um tamanho de 3 mm e uma largura de 0,4 mm.
2) Gerador de geometria n ° 1
Adicione uma nova camada de símbolo e selecione o Geometry generator
tipo:
Insira esta expressão no Expression
campo:
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
Acabamos de definir a primeira linha que aponta para o ponto em que o setor de luz começa. Essa linha tem 1000 m de comprimento e é criada apenas quando o ângulo de abertura da luz do setor não é um ângulo redondo (isso acontece para evitar que a linha quebre um círculo inteiro).
3) Gerador de Geometria No. 2
O mesmo que acima, mas, nesta etapa, você precisa usar esta expressão:
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
Acabamos de definir a primeira linha que aponta para o ponto em que o setor de luz termina. Essa linha tem 1000 m de comprimento e é criada apenas quando o ângulo de abertura da luz do setor não é um ângulo redondo (isso acontece para evitar que a linha quebre um círculo inteiro).
4) Gerador de geometria n ° 3
Insira esta expressão no Expression
campo:
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
Acabamos de definir o arco entre os pontos inicial e final do setor de luz (observe que 2000
é um valor arbitrário, porque estou tentando criar um polígono para interceptar o limite do círculo com um raio de 900 m).
Além disso, precisamos definir a cor que é armazenada no "VARIS"
campo. Para fazer isso, precisamos especificá-lo com uma expressão personalizada. Siga a seta na imagem abaixo:
e digite esta expressão depois de clicar no Edit...
botão:
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
Observe que, para essa camada de símbolo, criei duas linhas: a linha superior define a cor a ser usada (na verdade, defino a expressão personalizada para essa), enquanto a inferior é útil para definir uma borda preta (ela terá uma largura maior que a da linha superior). Lembre-se também de definir Flat
as Cap style
duas linhas para evitar sobreposição de cores.
Marcação
1) Configurando os rótulos
Vá para Layer Properties
> Labels
e, como sempre, siga as setas vermelhas:
e digite esta expressão:
CASE
WHEN "VARIS" = 'vi' THEN 'G'
WHEN "VARIS" = 'v' THEN 'W'
WHEN "VARIS" = 'p' THEN 'R'
END
Acabamos de definir a regra de cores usando o valor armazenado no "VARIS"
campo.
2) Definindo o posicionamento para etiquetas
Selecione a Placement
opção no Labels
Menu e selecione Offset from point
.
Então, com referência à imagem abaixo:
siga a seta vermelha e digite esta expressão:
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
Em seguida, siga a seta verde e digite esta expressão:
CASE
WHEN "ALKUKULMA" >= "LOPPUKULMA"
THEN
180-(("ALKUKULMA" + "LOPPUKULMA")/2)
WHEN "ALKUKULMA" < "LOPPUKULMA"
THEN
- (("ALKUKULMA" + "LOPPUKULMA")/2)
END
Resultado final
Se você executou corretamente as tarefas anteriores, poderá obter este resultado:
Bônus
Como os parâmetros secundários eram muitos para serem abordados completamente nesta resposta, anexei o estilo aqui : você pode abrir esse código com qualquer editor de texto e salvá-lo como um arquivo QGIS Layer Style (ou seja, com uma .qml
extensão).
O estilo acima foi criado usando o QGIS 2.18.4 (ele deve ter o mesmo nome do shapefile que você está usando).