我使用 geotools GTRenderer 作为 Tileserver 并有一个用于样式的 SLD 文件(取自这里https://docs.geoserver.org/stable/en/user/styling/sld/cookbook/points.html#point-with-styled-标签):
<StyledLayerDescriptor version="1.0.0"
xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/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>WorldCities</Name>
<UserStyle>
<Name>Default Styler</Name>
<FeatureTypeStyle>
<Name>name</Name>
<Rule>
<PointSymbolizer>
<Graphic>
<Mark>
<WellKnownName>circle</WellKnownName>
<Fill>
<CssParameter name="fill">#FF0000</CssParameter>
</Fill>
</Mark>
<Size>6</Size>
</Graphic>
</PointSymbolizer>
<TextSymbolizer>
<Label>
<ogc:PropertyName>nameascii</ogc:PropertyName>
</Label>
<Font>
<CssParameter name="font-family">Arial</CssParameter>
<CssParameter name="font-size">12</CssParameter>
<CssParameter name="font-style">normal</CssParameter>
<CssParameter name="font-weight">bold</CssParameter>
</Font>
<LabelPlacement>
<PointPlacement>
<AnchorPoint>
<AnchorPointX>0.5</AnchorPointX>
<AnchorPointY>0.0</AnchorPointY>
</AnchorPoint>
<Displacement>
<DisplacementX>0</DisplacementX>
<DisplacementY>5</DisplacementY>
</Displacement>
</PointPlacement>
</LabelPlacement>
<Fill>
<CssParameter name="fill">#000000</CssParameter>
</Fill>
</TextSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
PointSymbolizer 有效,我在所需位置得到一个点,但文本符号器会产生数百个标签:
在这个示例输出中,“Southend-on-Sea”是我唯一希望渲染的地方。
知道点和文本符号器之间可能有什么不同吗?
谢谢你的帮助
编辑我使用的代码:
private static Style loadStyleFromXml(String path) throws Exception {
StyleFactory factory = CommonFactoryFinder.getStyleFactory();
URL resource = new File(path).toURI().toURL();
SLDParser stylereader = new SLDParser( factory, resource);
Style styles[] = stylereader.readXML();
return styles[0];
}
private static FeatureSource<SimpleFeatureType, SimpleFeature> readShapefile(String path) throws IOException {
File file = new File(path);
Map<String, Object> filemap = new HashMap<>();
filemap.put("url", file.toURI().toURL());
DataStore dataStore = DataStoreFinder.getDataStore(filemap);
String typeName = dataStore.getTypeNames()[0];
FeatureSource<SimpleFeatureType, SimpleFeature> source = dataStore.getFeatureSource(typeName);
SimpleFeatureType schema = source.getSchema();
return source;
}
平铺渲染方法:
public synchronized byte[] renderRasterTile(int x, int y, int z){
ReferencedEnvelope tileBounds = WebMercatorTileFactory.getExtentFromTileName(new OSMTileIdentifier(x, y, new WebMercatorZoomLevel(z), "custom"));
try {
tileBounds = tileBounds.transform(CRS.decode("EPSG:3857"),true);
} catch (Exception e) {
logger.error("Unable to transfrom coords",e);
throw new RuntimeException(e);
}
BufferedImage image = new BufferedImage(tilePixelSize.width, tilePixelSize.height, BufferedImage.TYPE_INT_RGB);
Graphics2D gr = image.createGraphics();
gr.setPaint(new Color(0,0,0, (float) 0.1));
gr.fill(tilePixelSize);
try {
renderer.paint(gr, tilePixelSize, tileBounds);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write( image, "png", baos );
baos.flush();
byte[] imageInByte = baos.toByteArray();
baos.close();
return imageInByte;
} catch (IOException e) {
logger.error("Unable to render tile",e);
throw new RuntimeException(e);
}
}
public MapContent setupMap(){
MapContent map = new MapContent();
map.setTitle("WorldMap");
FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = readShapefile("cities.shp");
Style style = loadStyleFromXml("cities.sld");
Layer layer = new FeatureLayer(featureSource, style,"cities");
map.addLayer(layer);
return map;
}
我使用的 Shapefile 可以在这里下载:
https://www.naturalearthdata.com/downloads/10m-culture-vectors/10m-populated-places/