3.4. 点¶
CSS样式教程的下一站是点的表示。
点符号学回顾:
点仅用于表示位置,不形成形状。线条的视觉宽度不会随比例而变化。
SLD使用 PointSymbolizer 记录如何绘制线条形状。
点的标签定位到点位置。
由于点本身没有固有的形状,因此重点放在用适当的符号标记位置上。
参考文献:
Point Symbology (用户手册CSS属性列表)
Points (用户手册CSS食谱)
Styled Marks (用户手册CSS样式)
Point (用户手册SLD参考)
这个练习利用了 ne:populated_places
层。
导航到 风格 页。
点击 Add a new style 并选择以下选项:
姓名:
point_example
工作区:
No workspace
格式:
CSS
将初始CSS定义替换为以下内容并单击 apply :
* { mark: symbol(circle); }
并使用 Layer Preview 选项卡以预览结果。
3.4.1. 作记号¶
点用强制属性表示 mark .
SLD标准提供了与点符号一起使用的“众所周知”符号: circle
, square
, triangle
, arrow
, cross
, star
和 x
.
作为一个 密钥属性 存在 mark 触发生成适当的点符号。
* { mark: symbol(square); }
地图预览:
在继续之前,我们将使用选择器将显示的数据量减少到合理的水平。
[ SCALERANK < 1 ] { mark: symbol(square); }
使图像更加清晰:
其他属性可用于控制标记的演示文稿:
这个 mark-size 属性用于控制符号大小。
这个 mark-rotation 属性控制方向,接受以度为单位的输入。
同时尝试这两种设置:
[ SCALERANK < 1 ] { mark: symbol(square); mark-size: 8; mark-rotation: 45; }
结果在每个位置用菱形标记:
现在我们已经为点位置分配了一个符号,我们可以使用 pseudo-selector 设置结果形状的样式。
:符号 -为CSS文档中的所有符号提供样式。
:标记 -为CSS文档中的所有标记符号提供样式。
这种形式的伪选择器用于所有标记:
[ SCALERANK < 1 ] { mark: symbol(square); mark-size: 8; mark-rotation: 45; } :mark{ fill: white; stroke: black; }
将标记更新为带黑色轮廓的白色正方形。
第二种方法用于在同一文档中单独配置符号。
:nth-symbol(1) -如果需要,我们可以在文档中指定要修改的符号。
:nth-mark(1) -为CSS文档中的第一个标记符号提供样式。
使用这种方法,标记可以由多个符号组成,每个符号都有自己的设置:
[ SCALERANK < 1 ] { mark: symbol(square),symbol(cross); mark-size: 16,14; mark-rotation: 0,45; } :nth-mark(1){ fill: red; stroke: black; } :nth-mark(2){ fill: black; stroke: white; }
产生有趣的复合符号效果:
3.4.2. 图解的¶
符号也可以由外部图形提供,
这项技术显示在初始文件中:“airport.svg”css示例。
要使用外部图形,需要两条信息。
mark 属性定义为 url 对图像的引用。
mark-mime 属性用于告诉呈现引擎期望的文件格式
此技术用于引用放置在Styles目录中的文件。
[ SCALERANK < 1 ] { mark: url(port.svg); mark-mime: "image/svg"; }
在每个位置绘制所提供的形状:
这个 mark 属性 url 参考也可用于参考外部图像。我们可以使用geoserver徽标。
[ SCALERANK < 1 ] { mark: url("http://localhost:8080/geoserver/web/wicket/resource/org.geoserver.web.GeoServerBasePage/img/logo.png"); mark-mime: "image/png"; mark-size: 16; }
如地图预览所示。
3.4.3. 标签¶
标签现在已经熟悉我们的经验线串和多边形。
关键属性 mark 和 标签 需要标记点位置。
替换
point_example
包括以下内容:[ SCALERANK < 1 ] { mark: symbol(circle); label: [NAME]; }
确认结果
Map
预览。每个标签都是从提供的点开始绘制的——这是不幸的,因为它确保每个标签将与使用的符号重叠。为了解决这个限制,我们将使用SLD控件来放置标签:
label-anchor 提供两个值,表示标签相对于起始标签位置的对齐方式。
label-offset 用于提供使用和X和Y偏移的初始位移。对于点,建议使用此偏移调整符号所用区域的标签位置。
备注
财产 label-anchor 定义相对于由结果标签形成的边界框的定位点位置。定位点位置将捕捉到由点位置和位移偏移生成的标签位置。
同时使用这两个工具,我们可以将标签置于符号下方的中心,注意所用的位移提供了符号尺寸所需区域之外的偏移量。
[ SCALERANK < 1 ] { mark: symbol(circle); mark-size: 10; label: [NAME]; label-offset: 0 -12; label-anchor: 0.5 1.0; font-fill: black; }
每个标签现在都放在标记下面。
剩下的一个问题是标签和符号之间的重叠。
geoserver提供了一个特定于供应商的参数,允许符号参与标签冲突解决,防止标签重叠任何符号。这严重限制了可用于贴标签的区域,最好与最大位移供应商选择结合使用。
mark-label-obstacle vendor参数要求渲染引擎避免在指示符号的顶部绘制标签。
label-max-displacement vendor参数为渲染引擎提供冲突解决期间允许其移动标签的最大距离。
label-padding vendor参数告诉渲染引擎提供地图上标签之间的最小距离,确保它们不会重叠。
更新我们的示例以使用这些设置:
[ SCALERANK < 1 ] { mark: symbol(circle); mark-size: 10; label: [NAME]; label-offset: 0 -12; label-anchor: 0.5 1.0; font-fill: black; mark-label-obstacle: true; label-max-displacement: 100; label-padding: 2; }
使图像更加清晰:
3.4.4. 动感造型¶
我们会很快使用 标尺 根据@scale选择器选择内容。
[@scale < 4000000] { mark: symbol(circle); } [@scale > 4000000] [@scale < 8000000] [SCALERANK < 7] { mark: symbol(circle); } [@scale > 8000000] [@scale < 17000000] [SCALERANK < 5] { mark: symbol(circle); } [@scale > 17000000] [@scale < 35000000] [SCALERANK < 4] { mark: symbol(circle); } [@scale > 35000000] [@scale < 70000000][SCALERANK < 3] { mark: symbol(circle); } [@scale > 70000000] [@scale < 140000000][SCALERANK < 2] { mark: symbol(circle); } [@scale > 140000000] [SCALERANK < 1] { mark: symbol(circle); } * { mark-size: 6; }
点击 Submit 更新 Map 在每一步之后。
要添加标签,我们必须同时使用 密钥属性 在每个比例选择器中标记和标签,使用规则级联定义一次标记大小和字体信息。
[@scale < 4000000] { mark: symbol(circle); label: [NAME]; } [@scale > 4000000] [@scale < 8000000] [SCALERANK < 7] { mark: symbol(circle); label: [NAME]; } [@scale > 8000000] [@scale < 17000000] [SCALERANK < 5] { mark: symbol(circle); label: [NAME]; } [@scale > 17000000] [@scale < 35000000] [SCALERANK < 4] { mark: symbol(circle); label: [NAME]; } [@scale > 35000000] [@scale < 70000000][SCALERANK < 3] { mark: symbol(circle); label: [NAME]; } [@scale > 70000000] [@scale < 140000000][SCALERANK < 2] { mark: symbol(circle); label: [NAME]; } [@scale > 140000000] [SCALERANK < 1] { mark: symbol(circle); label: [NAME]; } * { mark-size: 6; font-fill: black; font-family: "Arial"; font-size: 10; }
我们将使用 label-offset 和 label-anchor 将标签放置在每个符号的上方。
将以下两行添加到 * 选择器:
* { mark-size: 6; font-fill: black; font-family: "Arial"; font-size: 10; label-anchor: 0.5 0; label-offset: 0 6; }
对特定于供应商的参数进行一点处理,可以防止标签与每个符号发生冲突,同时使渲染引擎在允许重新定位标签的范围内具有一定的灵活性。
将以下供应商选项添加到 * 选择器:
* { mark-size: 6; font-fill: black; font-family: "Arial"; font-size: 10; label-anchor: 0.5 0; label-offset: 0 6; mark-label-obstacle: true; label-max-displacement: 90; label-padding: 2; }
现在我们已经清楚地标记了我们的城市,放大到您熟悉的区域,我们可以逐个查看符号的变化。
我们使用前面的表达式来生成适当的标签。表达式也可用于许多其他属性设置。
这个
ne:populated_places
图层提供了几个特定的属性,以使样式更简单:SCALERANK :我们已使用此属性控制显示的详细程度
LABELRANK :用于解决冲突的提示,允许重要城市(如首都)标记,即使它们靠近较大的邻居。
FEATURECLA :用于表示不同类型的城市。我们查一下 Admin-0 capital 城市。
我们要做的第一件事就是计算 mark-size 使用快速表达式:
[10-(SCALERANK/2)]
此表达式的大小应介于5和9之间,并且需要同时应用于 mark-size 和 label-offset .
我们可以手动为geoserver提供标签优先级,而不是解决标签冲突的“先到先服务”默认值。为每个标签计算所提供的表达式,如果发生冲突,则以优先级最高的标签为准。
labelrank属性从1到10,在用作地理服务器标签优先级之前需要翻转:
[10 - LABELRANK]
此表达式将产生介于0和10之间的值,并将用于 label-priority .
* { mark-size: [10-(SCALERANK/2)]; font-fill: black; font-family: "Arial"; font-size: 10; label-anchor: 0.5 0; label-offset: 0 [10-(SCALERANK/2)]; mark-label-obstacle: true; label-max-displacement: 90; label-padding: 2; label-priority: [10 - LABELRANK]; }
接下来我们可以使用
FEATURECLA
检查首都。在文件顶部添加首都城市的选择器:
/* capitals */ [@scale < 70000000] [FEATURECLA = 'Admin-0 capital'] { mark: symbol(star); label: [NAME]; } [@scale > 70000000] [SCALERANK < 2] [FEATURECLA = 'Admin-0 capital'] { mark: symbol(star); label: [NAME]; }
更新人口稠密地区选择器以忽略首都:
/* populated places */ [@scale < 4000000] [FEATURECLA <> 'Admin-0 capital'] { mark: symbol(circle); label: [NAME]; } [@scale > 4000000] [@scale < 8000000] [SCALERANK < 7] [FEATURECLA <> 'Admin-0 capital'] { mark: symbol(circle); label: [NAME]; } [@scale > 8000000] [@scale < 17000000] [SCALERANK < 5] [FEATURECLA <> 'Admin-0 capital'] { mark: symbol(circle); label: [NAME]; } [@scale > 17000000] [@scale < 35000000] [SCALERANK < 4] [FEATURECLA <> 'Admin-0 capital'] { mark: symbol(circle); label: [NAME]; } [@scale > 35000000] [@scale < 70000000][SCALERANK < 3] [FEATURECLA <> 'Admin-0 capital'] { mark: symbol(circle); label: [NAME]; } [@scale > 70000000] [@scale < 140000000][SCALERANK < 2] [FEATURECLA <> 'Admin-0 capital'] { mark: symbol(circle); label: [NAME]; } [@scale > 140000000] [SCALERANK < 1] [FEATURECLA <> 'Admin-0 capital'] { mark: symbol(circle); label: [NAME]; }
最后,我们可以使用选择器和伪选择器的组合来填充首都符号,以检测首都,并提供标记样式。
[FEATURECLA = 'Admin-0 capital'] :mark { fill: black; } :symbol { fill: gray; stroke: black; }
如果您想检查您的工作,最终文件在这里:
point_example.css
3.4.5. 奖金¶
3.4.5.1. 挑战几何位置¶
这个 mark 属性可用于呈现任何几何内容。
挑战: 通过使用 mark 财产。
备注
回答 discussed 在工作簿的末尾。
3.4.5.2. 探索动态符号化¶
我们做了大量的工作来设置选择器来在首都城市的符号(星)和符号(圆)之间进行选择。
这种方法在单独应用时非常简单:
[FEATURECLA = 'Admin-0 capital'] { mark: symbol(star); } [FEATURECLA <> 'Admin-0 capital'] { mark: symbol(circle); }
当与检查另一个属性或检查@scale(如我们的示例中所示)结合使用时,这种方法可能很快导致许多规则难以保持直线。
仔细看两个
symbol()
和url()
实际上可以用字符串表示:[FEATURECLA = 'Admin-0 capital'] { mark: symbol("star"); }
在SLD中表示为:
<sld:PointSymbolizer> <sld:Graphic> <sld:Mark> <sld:WellKnownName>star</sld:WellKnownName> <sld:Fill/> <sld:Stroke/> </sld:Mark> </sld:Graphic> </sld:PointSymbolizer>
GeoServer认识到SLD标记和外部图形的这种局限性,并为动态符号化提供了机会。
这是通过在传递给符号或url的字符串中嵌入一个小的cql表达式来实现的。此子表达式与 ${{ }} 如图所示:
* { mark: symbol( "${if_then_else(equalTo(FEATURECLA,'Admin-0 capital'),'star','circle')}" ); }
在SLD中表示为:
<sld:PointSymbolizer> <sld:Graphic> <sld:Mark> <sld:WellKnownName>${if_then_else(equalTo(FEATURECLA,'Admin-0 capital'),'star','circle')}</sld:WellKnownName> <sld:Fill/> <sld:Stroke/> </sld:Mark> </sld:Graphic> </sld:PointSymbolizer>
挑战: 使用此方法重写 动感造型 例子。
备注
回答 provided 在工作簿的末尾。
3.4.5.3. 挑战层组¶
使用A 图层组 探索符号学如何一起工作以形成地图。
东北:东北1
NE:州政府
NE:人口密集的地方
在这里帮助开始工作的方式是
ne:states_provinces_shp
:* { fill: white,[ recode(mapcolor9, 1,'#8dd3c7', 2,'#ffffb3', 3,'#bebada', 4,'#fb8072', 5,'#80b1d3', 6,'#fdb462', 7,'#b3de69', 8,'#fccde5', 9,'#d9d9d9') ]; fill-opacity: 05%,50%; stroke: black; stroke-width: 0.25; stroke-opacity: 50%; }
这个背景比较繁忙,必须注意确保符号和标签都清晰可见。
挑战: 在这个繁忙的背景下,尽你所能地为居住区设计风格。
下面是一个带有灵感标签的示例:
备注
回答 provided 在工作簿的末尾。
3.4.5.4. 探索真正的字体¶
除了图像格式,geoserver还可以使用其他类型的图形,例如真字体:
* { mark: symbol("ttf://Webdings#0x0064"); } :mark { stroke: blue; }
其他字体已放入
styles
目录可供使用。
3.4.5.5. 浏览自定义图形¶
GeoServer渲染引擎允许Java开发人员勾引额外的符号支持。
geoserver使用此工具提供用于填充图案的形状。社区扩展允许使用简单的自定义形状甚至图表。
使用WKT几何图形表示添加了对自定义图形的支持。
* { mark: symbol("wkt://MULTILINESTRING((-0.25 -0.25, -0.125 -0.25), (0.125 -0.25, 0.25 -0.25), (-0.25 0.25, -0.125 0.25), (0.125 0.25, 0.25 0.25))"); } :mark { stroke: blue; }