【Java+GS】GeoServer,通过配置自定义样式,实现不同图斑展示不同颜色。附java实现方法

写在前面,在配置geoserver图层时,需要了如下需求:

  1. 每个不同的图层要求配置不同的样式
  2. 一个图层内,根据不同条件的也要展示不同的颜色

所以为了方便知识整理,将把简单的样式发布和一些实际的样式配置结合做一个整理。

思路整理如下:

  1. 掌握sld文件发布样式(客户端)
  2. 掌握使用java api 发布样式
  3. 设计从数据库字段自定义样式

客户端发布样式

一、GeoServer中使用SLD样式

SLD是风格化图层描述器(Styled Layer Descriptor)的简称,是2005年OGC提出的一个标准,这个标准在一定条件下允许WMS服务器对地图可视化的表现形式进行扩展。在没有SLD之前,只能使用一些已经在服务器上规定好的样式来对地图进行可视化。而当使用了实现了SLD标准之后,它允许我们从客户端来对地图进行定义自己的样式,分级显示等操作,极大的扩展了地图可视化的灵活性。

  • 简单来说,sld就是用于描述图层样式的一个xml格式的文本
  • SLD文档的元素架构如下:

img

关于详细的解释可以看博客[GeoServer中使用SLD样式]

  • 根据需求,这里着重提到的是《3.4 分属性渲染》

二、分属性渲染

各标签含义

标签名含义
……Rule声明一个规则
………Filter过滤器
………PolygonSymbolizer样式
………TextSymbolizer注记

格式如下

image-20230506093452902

三、客户端操作发布图层

  1. 新建样式

    image-20230506093848417

  2. 输入样式名称,输入sld文本,点击验证

    image-20230506094009742

  3. 图层展示测试,进入图层编辑界面,进入layer preview标签下即可预览。效果如下

    image-20230506094439656

掌握使用java api 发布样式

一、前置准备

以我本地的环境为例

  1. 导入依赖 geoserver-manager
<!--图层发布-->
<dependency>
    <groupId>nl.pdok</groupId>
    <artifactId>geoserver-manager</artifactId>
    <version>1.7.0-pdok2</version>
</dependency>
  1. 获取manager对象 —— 比较简单,配置一些必要的参数即可

二、发布图层

发布图层有以下几个常用的方法:

image-20230506095110818

分别是使用file文件发布,和使用string文件发布

三、发布工具类

    /**
     *  创建样式
     *   逻辑修改
     * @param manager geoserver图层管理类
     * @param styleName 样式名称  
     * @param geoStylePath 从配置文件获取的
     * @return
     */
    public static boolean createStyle(GeoServerRESTManager manager, String styleName, String geoStylePath) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        boolean existsStyle = manager.getReader().existsStyle(styleName);
        if (!existsStyle) {
			String style = FileUtils.readFileToString(new File(geoStylePath));
            //创建样式
            existsStyle = manager.getPublisher().publishStyle(style,styleName);
        }
        return existsStyle;
  • 从指定路径读取sld文件文本,在进行发布
  • 为什么使用后string字符串进行发布 —— 为了便于后期进行数据库配置后进行发布

设计从数据库字段自定义样式

一、数据库设计

目标:根据数据库动态生成发布所需的sld文件。

其实就是需要6个核心参数:条件x2, stroke x2 , fill x2

  • property_name 字段名
  • literal 条件
  • fill_color 填充颜色
  • fill_opacity 不透明度
  • stroke_color 线条颜色
  • stroke_width 线宽

给出初版表结构如下

CREATE TABLE "public"."geoserver_publish_style" (
  "id" int8 NOT NULL DEFAULT nextval('geoserver_publish_style_id_seq'::regclass),
  "property_name" varchar(255) COLLATE "pg_catalog"."default",
  "literal" varchar(255) COLLATE "pg_catalog"."default",
  "fill_color" varchar(255) COLLATE "pg_catalog"."default",
  "fill_opacity" varchar(255) COLLATE "pg_catalog"."default",
  "stroke_color" varchar(255) COLLATE "pg_catalog"."default",
  "stroke_width" varchar(53) COLLATE "pg_catalog"."default",
  "parent_id" int8,
  "created_id" int8,
  "created_time" timestamp(6) DEFAULT now(),
  "last_modify_id" int8,
  "last_modify_time" timestamp(6) DEFAULT now(),
  "is_valid" int2,
  "bsm" varchar(255) COLLATE "pg_catalog"."default",
  "table_name" varchar(255) COLLATE "pg_catalog"."default",
  "is_sm" varchar(255) COLLATE "pg_catalog"."default",
  "name" varchar(255) COLLATE "pg_catalog"."default",
  "sorting" int4,
  CONSTRAINT "geoserver_publish_style_pkey" PRIMARY KEY ("id")
)
;

ALTER TABLE "public"."geoserver_publish_style" 
  OWNER TO "postgres";

COMMENT ON COLUMN "public"."geoserver_publish_style"."property_name" IS '字段名';

COMMENT ON COLUMN "public"."geoserver_publish_style"."literal" IS '条件';

COMMENT ON COLUMN "public"."geoserver_publish_style"."fill_color" IS '填充颜色';

COMMENT ON COLUMN "public"."geoserver_publish_style"."fill_opacity" IS '不透明度';

COMMENT ON COLUMN "public"."geoserver_publish_style"."stroke_color" IS '线条颜色';

COMMENT ON COLUMN "public"."geoserver_publish_style"."stroke_width" IS '线宽';

COMMENT ON COLUMN "public"."geoserver_publish_style"."parent_id" IS '父类id';

COMMENT ON COLUMN "public"."geoserver_publish_style"."table_name" IS '所属表名';

COMMENT ON COLUMN "public"."geoserver_publish_style"."is_sm" IS '是否为多色(1为单色;2为多色)';

COMMENT ON COLUMN "public"."geoserver_publish_style"."name" IS '名称(如是根节点的话,代表样式名称,子节点泽表示图例名称)';

COMMENT ON COLUMN "public"."geoserver_publish_style"."sorting" IS '排序';

COMMENT ON TABLE "public"."geoserver_publish_style" IS '图层样式';

二、业务逻辑分享

初版,测试可行

逻辑其实以拼接出所需要的sld文档为主,逻辑思路如下:

  1. 构建出一个sld文件雏形(string
  2. 从数据库获取自定义的字段结构
  3. 将每个数据库实体拼接成一个单独的rule标签
  4. 将所有rule标签拼接后,存入1.中的sld文件中
  5. 返回结果即可
 /**
     * 根据样式名称name 查询出对应的整个实体列表
     */
    public RestResult<List<GeoserverPublishStyleResponse>> getListByName(String name) {
        LambdaQueryWrapper<GeoserverPublishStyle> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(GeoserverPublishStyle::getName , name);
        List<GeoserverPublishStyle> list = this.list(wrapper);
        List<GeoserverPublishStyleResponse> responses = new ArrayList<>();
        for (GeoserverPublishStyle geoserverPublishStyle : list) {
            GeoserverPublishStyleResponse response = GeoserverPublishStyleConvert.INSTANCE.toResponse(geoserverPublishStyle);
            responses.add(response);
        }

        return RestResultUtils.success(responses);
    }



    @Override
    public String composeSldText(String name) {
        List<GeoserverPublishStyleResponse> styleResponses = this.getListByName(name).getData();
        // 获取初始sld文本
        StringBuffer sld = new StringBuffer(SLD_ORIGIN_TEXT);
        StringBuffer rules = new StringBuffer();
        // 循环生成rule文本
        for (GeoserverPublishStyleResponse style : styleResponses) {
            StringBuffer str = new StringBuffer(SLD_RULE_HEAD);
            // 存title
            str.append(style.getPropertyName() + "=" + style.getLiteral());
            // 存条件名PropertyName
            str.append(SLD_RULE_2);
            str.append(style.getPropertyName());
            // 存属性值
            str.append(SLD_RULE_3);
            str.append(style.getLiteral());
            str.append(SLD_RULE_4);
            // 存填充颜色
            str.append("<Fill><CssParameter name=\"fill\">");
            str.append(style.getFillColor() != null ?
                    style.getFillColor() :
                    "#DDDDDD");
            // 存填充颜色的透明度
            str.append("</CssParameter> <CssParameter name=\"fill-opacity\">");
            str.append(style.getFillOpacity() != null ? style.getFillOpacity() : "0.7");
            str.append("</CssParameter></Fill><Stroke>");
             存线条信息
            String strokeColor = style.getStrokeColor();
            String strokeWidth = style.getStrokeWidth();
            if (StringUtils.hasText(strokeColor) ) {
                str.append("<CssParameter name=\"stroke\">");
                str.append(strokeColor);
                str.append("</CssParameter>");
            }
            if(StringUtils.hasText(strokeWidth)){
                str.append("<CssParameter name=\"stroke-width\">");
                str.append(strokeWidth);
                str.append("</CssParameter>");
            }
            str.append("</Stroke>");
            // 存结尾
            str.append(SLD_RULE_END);

            /// 插入rules中
            rules.append(str);
        }
        // 将rule替换掉sld的文本
        sld.replace(684,689 , rules.toString());

        return sld.toString();
    }

使用到的静态变量

    String SLD_ORIGIN_TEXT = "<?xml version=\"1.0\" encoding=\"GBK\"?><StyledLayerDescriptor version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/sld StyledLayerDescriptor.xsd\" xmlns=\"http://www.opengis.net/sld\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><NamedLayer><Name>name</Name><UserStyle><FeatureTypeStyle><Rule><Title>default</Title><PolygonSymbolizer><Fill><CssParameter name=\"fill\">#DDDDDD</CssParameter><CssParameter name=\"fill-opacity\">0.7</CssParameter></Fill><Stroke><CssParameter name=\"stroke\">#808080</CssParameter><CssParameter name=\"stroke-width\">0.3</CssParameter></Stroke></PolygonSymbolizer></Rule>" +
            "@rule" +
            "</FeatureTypeStyle></UserStyle></NamedLayer></StyledLayerDescriptor>";

    String SLD_RULE_HEAD = "<Rule><Title>";
    String SLD_RULE_2 = "</Title><ogc:Filter><ogc:PropertyIsEqualTo><ogc:PropertyName>";
    String SLD_RULE_3 = "</ogc:PropertyName><ogc:Literal>";
    String SLD_RULE_4 = "</ogc:Literal></ogc:PropertyIsEqualTo></ogc:Filter><PolygonSymbolizer>";
    String SLD_RULE_END = "</PolygonSymbolizer></Rule>";

来看看测试代码 ,获取最终数据

@SpringBootTest
class GeoserverPublishStyleServiceTest {
    @Resource
    IGeoserverPublishStyleService geoserverPublishStyleService;

    @Test
    void composeSLDStirng(){
        String s = geoserverPublishStyleService.composeSldText(null);
        System.out.println(s);
    }

}

image-20230508092127651

结果是符合预期的,测试通过

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Xcong_Zhu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值