编辑我编辑了用于管理特定情况(由于特定角度值)和在定义圆角时不显示虚线的答案。
我仅通过重复基于规则的符号体系和标签来提出一种解决方案。
在开始之前,我想强调一下,我将把注意力集中在对再现所需结果的最小操作的解释上:这意味着您还可以轻松调整一些其他次要参数(例如大小,宽度等)为了更好地满足您的需求。
此外,该解决方案仅在假设0
度数为北而不是南的情况下才有效(如果0
为南,则180
每次在处理角度的公式中出现“ 90”(例如cos(radians(90))
变为cos(radians(180 + 90))
)时,将一个值相加就足够了)。我更愿意这样做只是为了给出更通用的解决方案。
造型
我们将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 m,仅在扇形灯的开度角不是圆角时才创建(这是为了避免该线会破坏整个圆)。
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 m,仅在扇形灯的开度角不是圆角时才创建(这是为了避免该线会破坏整个圆)。
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 m的圆的边界相交的多边形)。
此外,我们需要设置存储在"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创建的(必须与您使用的shapefile具有相同的名称)。