Geotools:将不同样式的点添加到同一地图层
Geotools: Add points with different styles to same map layer
我在我的 java 项目中使用 GeoTools 将不同大小、颜色和不透明度的点绘制到地图中。
由于它们有很多不同的样式,我最终在我的地图中有 千层 。目前每个添加的点都有自己的层因为我没能把它们添加到一个层中。
我正在从我的实体对象中获取积分。来自同一实体的每个点都具有相同的颜色。具有相同 name/color.
的实体更多
这是在地图上绘制一个实体的方式:
点的大小是在以下代码段中动态计算的:
public class Whosebug {
private final MapContent mapContent;
public Whosebug() {
this.mapContent = new MapContent();
}
public void addPoints(final HashMap<String, Color> colorsForEntities, final List<Entity> toDraw){
final GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
// Create SimpleFeatureType for Point
final SimpleFeatureTypeBuilder pointTb = new SimpleFeatureTypeBuilder();
pointTb.setName("points");
pointTb.setCRS(DefaultGeographicCRS.WGS84);
pointTb.add("point", Point.class);
final SimpleFeatureBuilder pointFeatureBuilder = new SimpleFeatureBuilder(pointTb.buildFeatureType());
for (final Entity entity : toDraw) {
final List<Point2D> pathPoints = entity.getPoints();
Color color = colorsForEntities.get(entity.getName());
Layer layerPoints;
Style pointStyle;
final float maxOpacity = MyProperties.getFloat(Constants.POINT_STYLE_OPACITY);
final float maxSize = MyProperties.getFloat(Constants.POINT_STYLE_SIZE);
final int NumPoints = pathPoints.size();
float opacity = maxOpacity;
float size = maxSize;
final float deltaOpacity = maxOpacity / NumPoints;
final float deltaSize = maxSize / NumPoints;
for (final Point2D point2D : pathPoints) {
final Point point = geometryFactory.createPoint(new Coordinate(point2D.getX(), point2D.getY()));
pointFeatureBuilder.add(point);
final SimpleFeature feature = pointFeatureBuilder.buildFeature(null);
final DefaultFeatureCollection pointCollection = new DefaultFeatureCollection();
pointCollection.add(feature);
pointStyle = SLD.createPointStyle("Circle", color, color, opacity, size);
opacity = opacity - deltaOpacity;
size = size - deltaSize;
layerPoints = new FeatureLayer(pointCollection, pointStyle);
mapContent.addLayer(layerPoints);
}
}
}
}
是否可以将点添加到一个图层或至少获得更少的图层?
它可以更有效地完成 :-) 我认为最简单的方法是从 entity
构建您的 SimpleFeature
,以便它们包含所需的颜色、大小和不透明度。类似于:
final SimpleFeatureTypeBuilder pointTb = new SimpleFeatureTypeBuilder();
pointTb.setName("points");
pointTb.setCRS(DefaultGeographicCRS.WGS84);
pointTb.add("point", Point.class);
pointTb.add("color", String.class);
pointTb.add("size", Integer.class);
pointTb.add("opacity", Float.class);
final SimpleFeatureBuilder pointFeatureBuilder = new SimpleFeatureBuilder(pointTb.buildFeatureType());
然后您可以创建一个 Style
,它采用这些属性并使用它们来设置每个点的样式。像(未经测试):
StyleBuilder sb = new StyleBuilder();
FilterFactory2 ff = sb.getFilterFactory();
Mark testMark = sb.createMark(sb.literalExpression("Circle"),
sb.createFill(sb.attributeExpression("color"),sb.attributeExpression("opacity")),
null);
Graphic graph = sb.createGraphic(null, // An external graphics if needed
new Mark[] { testMark }, // a Mark if not an external graphics
null, // aSymbol
ff.literal(sb.attributeExpression("opacity")), // opacity
ff.property("size"), // read from feature "size" attribute
ff.literal(0)); // rotation, here read into the feature
PointSymbolizer aPointSymbolizer = sb.createPointSymbolizer(graph);
// creation of the style
org.geotools.styling.Style style = sb.createStyle(aPointSymbolizer);
由于 SLD 不提供任何循环支持,我认为没有任何方法可以避免将每个 entity
分成一组具有自己样式的单独点,除非您想要写一个 custom mark factory.
我在我的 java 项目中使用 GeoTools 将不同大小、颜色和不透明度的点绘制到地图中。 由于它们有很多不同的样式,我最终在我的地图中有 千层 。目前每个添加的点都有自己的层因为我没能把它们添加到一个层中。
我正在从我的实体对象中获取积分。来自同一实体的每个点都具有相同的颜色。具有相同 name/color.
的实体更多这是在地图上绘制一个实体的方式:
点的大小是在以下代码段中动态计算的:
public class Whosebug {
private final MapContent mapContent;
public Whosebug() {
this.mapContent = new MapContent();
}
public void addPoints(final HashMap<String, Color> colorsForEntities, final List<Entity> toDraw){
final GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
// Create SimpleFeatureType for Point
final SimpleFeatureTypeBuilder pointTb = new SimpleFeatureTypeBuilder();
pointTb.setName("points");
pointTb.setCRS(DefaultGeographicCRS.WGS84);
pointTb.add("point", Point.class);
final SimpleFeatureBuilder pointFeatureBuilder = new SimpleFeatureBuilder(pointTb.buildFeatureType());
for (final Entity entity : toDraw) {
final List<Point2D> pathPoints = entity.getPoints();
Color color = colorsForEntities.get(entity.getName());
Layer layerPoints;
Style pointStyle;
final float maxOpacity = MyProperties.getFloat(Constants.POINT_STYLE_OPACITY);
final float maxSize = MyProperties.getFloat(Constants.POINT_STYLE_SIZE);
final int NumPoints = pathPoints.size();
float opacity = maxOpacity;
float size = maxSize;
final float deltaOpacity = maxOpacity / NumPoints;
final float deltaSize = maxSize / NumPoints;
for (final Point2D point2D : pathPoints) {
final Point point = geometryFactory.createPoint(new Coordinate(point2D.getX(), point2D.getY()));
pointFeatureBuilder.add(point);
final SimpleFeature feature = pointFeatureBuilder.buildFeature(null);
final DefaultFeatureCollection pointCollection = new DefaultFeatureCollection();
pointCollection.add(feature);
pointStyle = SLD.createPointStyle("Circle", color, color, opacity, size);
opacity = opacity - deltaOpacity;
size = size - deltaSize;
layerPoints = new FeatureLayer(pointCollection, pointStyle);
mapContent.addLayer(layerPoints);
}
}
}
}
是否可以将点添加到一个图层或至少获得更少的图层?
它可以更有效地完成 :-) 我认为最简单的方法是从 entity
构建您的 SimpleFeature
,以便它们包含所需的颜色、大小和不透明度。类似于:
final SimpleFeatureTypeBuilder pointTb = new SimpleFeatureTypeBuilder();
pointTb.setName("points");
pointTb.setCRS(DefaultGeographicCRS.WGS84);
pointTb.add("point", Point.class);
pointTb.add("color", String.class);
pointTb.add("size", Integer.class);
pointTb.add("opacity", Float.class);
final SimpleFeatureBuilder pointFeatureBuilder = new SimpleFeatureBuilder(pointTb.buildFeatureType());
然后您可以创建一个 Style
,它采用这些属性并使用它们来设置每个点的样式。像(未经测试):
StyleBuilder sb = new StyleBuilder();
FilterFactory2 ff = sb.getFilterFactory();
Mark testMark = sb.createMark(sb.literalExpression("Circle"),
sb.createFill(sb.attributeExpression("color"),sb.attributeExpression("opacity")),
null);
Graphic graph = sb.createGraphic(null, // An external graphics if needed
new Mark[] { testMark }, // a Mark if not an external graphics
null, // aSymbol
ff.literal(sb.attributeExpression("opacity")), // opacity
ff.property("size"), // read from feature "size" attribute
ff.literal(0)); // rotation, here read into the feature
PointSymbolizer aPointSymbolizer = sb.createPointSymbolizer(graph);
// creation of the style
org.geotools.styling.Style style = sb.createStyle(aPointSymbolizer);
由于 SLD 不提供任何循环支持,我认为没有任何方法可以避免将每个 entity
分成一组具有自己样式的单独点,除非您想要写一个 custom mark factory.