3.4.

CSS样式教程的下一站是点的表示。

../../../_images/PointSymbology.svg

点符号学回顾:

  • 点仅用于表示位置,不形成形状。线条的视觉宽度不会随比例而变化。

  • SLD使用 PointSymbolizer 记录如何绘制线条形状。

  • 点的标签定位到点位置。

由于点本身没有固有的形状,因此重点放在用适当的符号标记位置上。

参考文献:

这个练习利用了 ne:populated_places 层。

  1. 导航到 风格 页。

  2. 点击 Add a new style 并选择以下选项:

    姓名:

    point_example

    工作区:

    No workspace

    格式:

    CSS

  3. 将初始CSS定义替换为以下内容并单击 apply

    * {
      mark: symbol(circle);
    }
    
  4. 并使用 Layer Preview 选项卡以预览结果。

    ../../../_images/point_03_map.png

3.4.1. 作记号

点用强制属性表示 mark .

../../../_images/PointSymbology.svg

SLD标准提供了与点符号一起使用的“众所周知”符号: circlesquaretrianglearrowcrossstarx .

  1. 作为一个 密钥属性 存在 mark 触发生成适当的点符号。

    * {
     mark: symbol(square);
    }
    
  2. 地图预览:

    ../../../_images/point_mark_1.png
  3. 在继续之前,我们将使用选择器将显示的数据量减少到合理的水平。

    [ SCALERANK < 1 ] {
      mark: symbol(square);
    }
    
  4. 使图像更加清晰:

    ../../../_images/point_mark_2.png
  5. 其他属性可用于控制标记的演示文稿:

    这个 mark-size 属性用于控制符号大小。

    这个 mark-rotation 属性控制方向,接受以度为单位的输入。

    同时尝试这两种设置:

    [ SCALERANK < 1 ] {
      mark: symbol(square);
      mark-size: 8;
      mark-rotation: 45;
    }
    
  6. 结果在每个位置用菱形标记:

    ../../../_images/point_mark_3.png
  7. 现在我们已经为点位置分配了一个符号,我们可以使用 pseudo-selector 设置结果形状的样式。

    :符号 -为CSS文档中的所有符号提供样式。

    :标记 -为CSS文档中的所有标记符号提供样式。

    这种形式的伪选择器用于所有标记:

    [ SCALERANK < 1 ] {
      mark: symbol(square);
      mark-size: 8;
      mark-rotation: 45;
    }
    :mark{
       fill: white;
       stroke: black;
    }
    
  8. 将标记更新为带黑色轮廓的白色正方形。

    ../../../_images/point_mark_4.png
  9. 第二种方法用于在同一文档中单独配置符号。

    :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;
    }
    
  10. 产生有趣的复合符号效果:

    ../../../_images/point_mark_5.png

3.4.2. 图解的

符号也可以由外部图形提供,

../../../_images/Point_Graphic_CSS.svg

这项技术显示在初始文件中:“airport.svg”css示例。

  1. 要使用外部图形,需要两条信息。

    mark 属性定义为 url 对图像的引用。

    mark-mime 属性用于告诉呈现引擎期望的文件格式

    此技术用于引用放置在Styles目录中的文件。

    [ SCALERANK < 1 ] {
      mark: url(port.svg);
      mark-mime: "image/svg";
    }
    
  2. 在每个位置绘制所提供的形状:

    ../../../_images/point_graphic_1.png
  3. 这个 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;
    }
    
  4. 如地图预览所示。

    ../../../_images/point_graphic_2.png

3.4.3. 标签

标签现在已经熟悉我们的经验线串和多边形。

../../../_images/Point_Label_CSS.svg

关键属性 mark标签 需要标记点位置。

  1. 替换 point_example 包括以下内容:

    [ SCALERANK < 1 ] {
      mark: symbol(circle);
      label: [NAME];
    }
    
  2. 确认结果 Map 预览。

    ../../../_images/point_label_1.png
  3. 每个标签都是从提供的点开始绘制的——这是不幸的,因为它确保每个标签将与使用的符号重叠。为了解决这个限制,我们将使用SLD控件来放置标签:

    label-anchor 提供两个值,表示标签相对于起始标签位置的对齐方式。

    label-offset 用于提供使用和X和Y偏移的初始位移。对于点,建议使用此偏移调整符号所用区域的标签位置。

    备注

    财产 label-anchor 定义相对于由结果标签形成的边界框的定位点位置。定位点位置将捕捉到由点位置和位移偏移生成的标签位置。

  4. 同时使用这两个工具,我们可以将标签置于符号下方的中心,注意所用的位移提供了符号尺寸所需区域之外的偏移量。

    [ SCALERANK < 1 ] {
      mark: symbol(circle);
      mark-size: 10;
    
      label: [NAME];
      label-offset: 0 -12;
      label-anchor: 0.5 1.0;
    
      font-fill: black;
    }
    
  5. 每个标签现在都放在标记下面。

    ../../../_images/point_label_2.png
  6. 剩下的一个问题是标签和符号之间的重叠。

    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;
    }
    
  7. 使图像更加清晰:

    ../../../_images/point_label_3.png

3.4.4. 动感造型

  1. 我们会很快使用 标尺 根据@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;
    }
    
  2. 点击 Submit 更新 Map 在每一步之后。

    ../../../_images/point_04_scale.png
  3. 要添加标签,我们必须同时使用 密钥属性 在每个比例选择器中标记和标签,使用规则级联定义一次标记大小和字体信息。

    [@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;
    }
    
    ../../../_images/point_05_label.png
  4. 我们将使用 label-offsetlabel-anchor 将标签放置在每个符号的上方。

    将以下两行添加到 * 选择器:

    * {
      mark-size: 6;
    
      font-fill: black;
      font-family: "Arial";
      font-size: 10;
    
      label-anchor: 0.5 0;
      label-offset: 0 6;
    }
    
    ../../../_images/point_05_align.png
  5. 对特定于供应商的参数进行一点处理,可以防止标签与每个符号发生冲突,同时使渲染引擎在允许重新定位标签的范围内具有一定的灵活性。

    将以下供应商选项添加到 * 选择器:

    * {
      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;
    }
    
    ../../../_images/point_06_relocate.png
  6. 现在我们已经清楚地标记了我们的城市,放大到您熟悉的区域,我们可以逐个查看符号的变化。

    我们使用前面的表达式来生成适当的标签。表达式也可用于许多其他属性设置。

    这个 ne:populated_places 图层提供了几个特定的属性,以使样式更简单:

    • SCALERANK :我们已使用此属性控制显示的详细程度

    • LABELRANK :用于解决冲突的提示,允许重要城市(如首都)标记,即使它们靠近较大的邻居。

    • FEATURECLA :用于表示不同类型的城市。我们查一下 Admin-0 capital 城市。

    我们要做的第一件事就是计算 mark-size 使用快速表达式:

    [10-(SCALERANK/2)]
    

    此表达式的大小应介于5和9之间,并且需要同时应用于 mark-sizelabel-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];
    }
    
    ../../../_images/point_07_expression.png
  7. 接下来我们可以使用 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];
    }
    
    ../../../_images/point_08_symbol.png
  8. 最后,我们可以使用选择器和伪选择器的组合来填充首都符号,以检测首都,并提供标记样式。

    [FEATURECLA = 'Admin-0 capital'] :mark {
      fill: black;
    }
    
    :symbol {
      fill: gray;
      stroke: black;
    }
    
    ../../../_images/point_09_fill.png
  9. 如果您想检查您的工作,最终文件在这里: point_example.css

3.4.5. 奖金

3.4.5.1. 挑战几何位置

  1. 这个 mark 属性可用于呈现任何几何内容。

  2. 挑战: 通过使用 mark 财产。

    备注

    回答 discussed 在工作簿的末尾。

3.4.5.2. 探索动态符号化

  1. 我们做了大量的工作来设置选择器来在首都城市的符号(星)和符号(圆)之间进行选择。

    这种方法在单独应用时非常简单:

    [FEATURECLA = 'Admin-0 capital'] {
       mark: symbol(star);
    }
    [FEATURECLA <> 'Admin-0 capital'] {
       mark: symbol(circle);
    }
    

    当与检查另一个属性或检查@scale(如我们的示例中所示)结合使用时,这种方法可能很快导致许多规则难以保持直线。

  2. 仔细看两个 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>
    
  3. 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>
    
  4. 挑战: 使用此方法重写 动感造型 例子。

    备注

    回答 provided 在工作簿的末尾。

3.4.5.3. 挑战层组

  1. 使用A 图层组 探索符号学如何一起工作以形成地图。

    • 东北:东北1

    • NE:州政府

    • NE:人口密集的地方

  2. 在这里帮助开始工作的方式是 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%;
    }
    
  3. 这个背景比较繁忙,必须注意确保符号和标签都清晰可见。

  4. 挑战: 在这个繁忙的背景下,尽你所能地为居住区设计风格。

    下面是一个带有灵感标签的示例:

    ../../../_images/point_challenge_1.png

    备注

    回答 provided 在工作簿的末尾。

3.4.5.4. 探索真正的字体

  1. 除了图像格式,geoserver还可以使用其他类型的图形,例如真字体:

    * {
       mark: symbol("ttf://Webdings#0x0064");
    }
    :mark {
       stroke: blue;
    }
    
  2. 其他字体已放入 styles 目录可供使用。

3.4.5.5. 浏览自定义图形

  1. GeoServer渲染引擎允许Java开发人员勾引额外的符号支持。

    geoserver使用此工具提供用于填充图案的形状。社区扩展允许使用简单的自定义形状甚至图表。

  2. 使用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;
    }
    
Previous: 3.3. 多边形