РЕДАКТИРОВАТЬ Я отредактировал ответ для управления конкретными ситуациями (из-за определенных значений углов) и для того, чтобы не отображать пунктирные линии, когда задан круглый угол.
Я предлагаю решение, только возвращаясь к символике и маркировке на основе правил.
Прежде чем начать, я хочу подчеркнуть, что я сосредоточу внимание на объяснении минимальных действий, которые необходимо выполнить для воспроизведения желаемого результата: это означает, что некоторые другие второстепенные параметры (такие как размеры, ширина и т. Д.) Должны быть легко настроены вами для лучшего соответствия вашим потребностям.
Кроме того, это решение работает только в том случае, если вы предполагаете, что 0
градус - это север, а не юг (вместо этого, если бы 0
юг, было бы достаточно суммировать 180
значение каждый раз, когда в формулах, которые имеют дело с углами, например cos(radians(90))
, стало бы, становится равным «90» cos(radians(180 + 90))
). Я предпочел сделать это только ради более общего решения.
стайлинг
Мы будем отображать точки с помощью a 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 (он должен иметь то же имя используемого вами шейп- файла ).