最近用geotools写了一个基于b/s的sld样式编辑器,支持点线面和注记样式配置,可嵌入web或单独使用。前台可以配置、预览样式效果(wms)和导出样式,在使用上比udig灵活。
前台布局如下:
前台基于mvvm,利用自定义的json传到后台解析,我重点说样式生成。
如ogc wms规范可从后台获取bbox范围内的图层,后台写入图片时可渲染样式,产生视觉良好的图。日前配图层sld样式主要还是手写、udig和lyr文件转换,这些都是借助第三方工具,比较繁琐。阅style 文档时和geotools 部分源码时,写了这个,话不多说,这里借用一张图片(感谢制作者,找不到源出处了):
图中关系体现样式结构,FeatureTypeStyle标签是Style部分的根节点,可包含多个Rule,Rule可含Filter、具体的Symbolizer和TextSymbolizer(文本)。前台传来的点线面具有自己特殊属性,json会标记出,这里我们用指定常量来做演示。
先定义几个常量:
//默认常量
private static final Color LINE_COLOUR = Color.BLUE;
private static final Color FILL_COLOUR = Color.CYAN;
private static final float OPACITY = 1.0f;
private static final float LINE_WIDTH = 1.0f;
private static final float POINT_SIZE = 10.0f;
成员用于生成标签元素、expression和filter:
private StyleFactory sf = CommonFactoryFinder.getStyleFactory();
private FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
private SLDTransformer transformer = new SLDTransformer(); //导出文本用
生成一个FeatureTypeStyle:
FeatureTypeStyle fts = sf.createFeatureTypeStyle();
添加填充颜色、和边线,加入到FeatureTypeStyle:
Stroke stroke = sf.createStroke(ff.literal(LINE_COLOUR),ff.literal(LINE_WIDTH),ff.literal(OPACITY));
Fill fill = sf.createFill(ff.literal(FILL_COLOUR),ff.literal(OPACITY));
Symbolizer symbolizer = sf.createPolygonSymbolizer(stroke, fill, "the_geom");
Rule rule = sf.createRule();
rule.setName("rule_name");
rule.symbolizers().add(symbolizer);
fts.rules().add(rule);
过滤条件(可选),可以通过它给wms图片上不同颜色,加入到相应的Rule中:
Filter filter = ECQL.toFilter("Layer='A'");
rule.setFilter(filter);
生成style,style对应UserStyle标签:
Style style = sf.createStyle();
style.setName("style_name");
style.featureTypeStyles().add(fts);
生成StyledLayerDescriptor,顶级sld:
StyledLayerDescriptorImpl sld = new StyledLayerDescriptorImpl();
UserLayer userLayer = new UserLayerImpl();
userLayer.setUserStyles(new Style[]{style}); //传入数组
sld.addStyledLayer(userLayer);
最后产生样式文本:
System.out.println(transformer.transform(sld));
只需将polygon的换成PointSymbolizer,其他的和polygon相似。子标签Graphic,通过Mark来设置边线和填充:
Mark mark = sf.getSquareMark();
mark.setFill(fill);
mark.setStroke(stroke);
Graphic graphic = sf.createDefaultGraphic();
graphic.graphicalSymbols().clear();
graphic.graphicalSymbols().add(mark);
graphic.setSize(ff.literal(POINT_SIZE));
Symbolizer symbolizer = sf.createPointSymbolizer(graphic, "the_geom");
linestring只是没有Fill,其他和polygon一致。
总结:当然具体的设置还有其他的内容或相关标签,这里只介绍了一个流程,如填充还可以图案等。下一回说说文本注记的生成。