Геоинструменты: добавляйте точки с разными стилями на один и тот же слой карты.

Я использую GeoTools в своем java-проекте для рисования точек разных размеров, цветов и прозрачности на карте. Поскольку для них существует множество разных стилей, в итоге я получил тысячи слоев на своей карте. В настоящее время каждая добавленная точка имеет свой собственный слой, потому что мне не удалось добавить их в один слой.

Я получаю очки от моего объекта Entity. Каждая точка одного и того же объекта имеет одинаковый цвет. Есть больше объектов с тем же именем/цветом.

Вот как один объект должен быть нарисован на карте:

введите здесь описание изображения

Размер точек рассчитывается динамически в следующем фрагменте кода:

public class Stackoverflow {

private final MapContent mapContent;

public Stackoverflow() {
    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);
        }

    }
}

}

Можно ли добавить точки в один слой или, по крайней мере, получить гораздо меньшее количество слоев?


person HelloWorld0815    schedule 18.06.2016    source источник


Ответы (1)


Это можно сделать более эффективно :-) Я думаю, что самым простым способом было бы построить ваши SimpleFeature из entity так, чтобы они содержали требуемый цвет, размер и непрозрачность. Что-то вроде:

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 на набор отдельных точек с их собственным стилем, если только вы не хотите писать фабрика пользовательских меток.

person Ian Turton    schedule 20.06.2016
comment
Ссылка не работает. Можем ли мы применить стиль к карте без перезагрузки карты? - person code_poetry; 23.01.2021