Search in sources :

Example 1 with FeatureTypeStyle

use of org.opengis.style.FeatureTypeStyle in project geotoolkit by Geomatys.

the class CategoryStyleBuilder method analyze.

public void analyze(final MapLayer layer) {
    Resource resource = layer.getData();
    if (!(resource instanceof FeatureSet)) {
        throw new IllegalArgumentException("Layer resource must be a FeatureSet");
    }
    this.layer = layer;
    fts.rules().clear();
    properties.clear();
    if (layer != null) {
        FeatureType schema;
        try {
            schema = ((FeatureSet) resource).getType();
        } catch (DataStoreException ex) {
            throw new FeatureStoreRuntimeException(ex.getMessage(), ex);
        }
        for (PropertyType desc : schema.getProperties(true)) {
            if (desc instanceof AttributeType) {
                Class<?> type = ((AttributeType) desc).getValueClass();
                if (!Geometry.class.isAssignableFrom(type)) {
                    properties.add(ff.property(desc.getName().tip().toString()));
                }
            }
        }
        // find the geometry class for template
        Class<?> geoClass = null;
        try {
            PropertyType geo = FeatureExt.getDefaultGeometry(schema);
            geoClass = Features.toAttribute(geo).map(AttributeType::getValueClass).orElse(null);
        } catch (PropertyNotFoundException ex) {
            LOGGER.log(Level.FINE, "No sis:geometry property found", ex);
        }
        if (geoClass == null) {
            return;
        }
        if (Polygon.class.isAssignableFrom(geoClass) || MultiPolygon.class.isAssignableFrom(geoClass)) {
            Stroke stroke = sf.stroke(Color.BLACK, 1);
            Fill fill = sf.fill(Color.BLUE);
            template = sf.polygonSymbolizer(stroke, fill, null);
            expectedType = PolygonSymbolizer.class;
        } else if (LineString.class.isAssignableFrom(geoClass) || MultiLineString.class.isAssignableFrom(geoClass)) {
            Stroke stroke = sf.stroke(Color.BLUE, 2);
            template = sf.lineSymbolizer(stroke, null);
            expectedType = LineSymbolizer.class;
        } else {
            Stroke stroke = sf.stroke(Color.BLACK, 1);
            Fill fill = sf.fill(Color.BLUE);
            List<GraphicalSymbol> symbols = new ArrayList<>();
            symbols.add(sf.mark(StyleConstants.MARK_CIRCLE, fill, stroke));
            Graphic gra = sf.graphic(symbols, ff.literal(1), ff.literal(12), ff.literal(0), sf.anchorPoint(), sf.displacement());
            template = sf.pointSymbolizer(gra, null);
            expectedType = PointSymbolizer.class;
        }
        // try to rebuild the previous analyze if it was one
        List<? extends FeatureTypeStyle> ftss = layer.getStyle().featureTypeStyles();
        if (ftss.size() == 1) {
            FeatureTypeStyle fts = ftss.get(0);
            // defensive copy avoid synchronization
            List<? extends Rule> candidateRules = new ArrayList<>(fts.rules());
            for (Rule r : candidateRules) {
                // defensive copy avoid synchronization
                List<? extends Symbolizer> candidateSymbols = new ArrayList<>(r.symbolizers());
                if (candidateSymbols.size() != 1)
                    break;
                Symbolizer symbol = candidateSymbols.get(0);
                if (expectedType.isInstance(symbol)) {
                    if (r.isElseFilter()) {
                        // it looks like it's a valid classification "other" rule
                        this.fts.rules().add((MutableRule) r);
                        template = symbol;
                        other = true;
                    } else {
                        Filter f = r.getFilter();
                        if (f != null && f.getOperatorType() == ComparisonOperatorName.PROPERTY_IS_EQUAL_TO) {
                            BinaryComparisonOperator equal = (BinaryComparisonOperator) f;
                            Expression exp1 = equal.getOperand1();
                            Expression exp2 = equal.getOperand2();
                            if (exp1 instanceof ValueReference && exp2 instanceof Literal) {
                                if (properties.contains(exp1)) {
                                    // it looks like it's a valid classification property rule
                                    this.fts.rules().add((MutableRule) r);
                                    template = symbol;
                                    currentProperty = (ValueReference) exp1;
                                } else {
                                    // property is not in the schema
                                    break;
                                }
                            } else if (exp2 instanceof ValueReference && exp1 instanceof Literal) {
                                if (properties.contains(exp2)) {
                                    // it looks like it's a valid classification property rule
                                    this.fts.rules().add((MutableRule) r);
                                    template = symbol;
                                    currentProperty = (ValueReference) exp2;
                                } else {
                                    // property is not in the schema
                                    break;
                                }
                            } else {
                                // mismatch analyze structure
                                break;
                            }
                        }
                    }
                } else {
                    break;
                }
            }
        }
    }
}
Also used : FeatureType(org.opengis.feature.FeatureType) Fill(org.opengis.style.Fill) PropertyNotFoundException(org.opengis.feature.PropertyNotFoundException) ArrayList(java.util.ArrayList) PropertyType(org.opengis.feature.PropertyType) AttributeType(org.opengis.feature.AttributeType) Literal(org.opengis.filter.Literal) List(java.util.List) ArrayList(java.util.ArrayList) Polygon(org.locationtech.jts.geom.Polygon) MultiPolygon(org.locationtech.jts.geom.MultiPolygon) ValueReference(org.opengis.filter.ValueReference) PointSymbolizer(org.opengis.style.PointSymbolizer) DataStoreException(org.apache.sis.storage.DataStoreException) Stroke(org.opengis.style.Stroke) Graphic(org.opengis.style.Graphic) Resource(org.apache.sis.storage.Resource) PointSymbolizer(org.opengis.style.PointSymbolizer) PolygonSymbolizer(org.opengis.style.PolygonSymbolizer) LineSymbolizer(org.opengis.style.LineSymbolizer) Symbolizer(org.opengis.style.Symbolizer) Geometry(org.locationtech.jts.geom.Geometry) MutableRule(org.geotoolkit.style.MutableRule) MultiPolygon(org.locationtech.jts.geom.MultiPolygon) Filter(org.opengis.filter.Filter) Expression(org.opengis.filter.Expression) LineSymbolizer(org.opengis.style.LineSymbolizer) FeatureStoreRuntimeException(org.geotoolkit.storage.feature.FeatureStoreRuntimeException) FeatureSet(org.apache.sis.storage.FeatureSet) MutableFeatureTypeStyle(org.geotoolkit.style.MutableFeatureTypeStyle) FeatureTypeStyle(org.opengis.style.FeatureTypeStyle) Rule(org.opengis.style.Rule) MutableRule(org.geotoolkit.style.MutableRule) BinaryComparisonOperator(org.opengis.filter.BinaryComparisonOperator)

Example 2 with FeatureTypeStyle

use of org.opengis.style.FeatureTypeStyle in project geotoolkit by Geomatys.

the class DefaultStyleFactory method style.

@Override
public MutableStyle style(final String name, final Description description, final boolean isDefault, final List<FeatureTypeStyle> featureTypeStyles, final Symbolizer defaultSymbolizer) {
    final MutableStyle style = new DefaultMutableStyle();
    style.setName(name);
    style.setDescription(description);
    style.setDefault(isDefault);
    for (FeatureTypeStyle fts : featureTypeStyles) {
        if (fts instanceof MutableFeatureTypeStyle) {
            style.featureTypeStyles().add((MutableFeatureTypeStyle) fts);
        } else {
            throw new IllegalArgumentException("This factory implementation requiere a list of MutableFeatureTypeStyle");
        }
    }
    style.setDefaultSpecification(defaultSymbolizer);
    return style;
}
Also used : FeatureTypeStyle(org.opengis.style.FeatureTypeStyle)

Example 3 with FeatureTypeStyle

use of org.opengis.style.FeatureTypeStyle in project geotoolkit by Geomatys.

the class J2DLegendUtilities method paintWithTemplate.

/**
 * Draw legend using given {@link LegendTemplate} as rendering hint. At the
 * end of the drawning, input {@link Graphics2D} origin is reset at the origin
 * it was when given as parameter.
 * @param item The map item to draw legend for.
 * @param g2d The graphic object to draw legend in.
 * @param bounds Drawing authorized rectangle.
 * @param template Rendering hints.
 * @param legendResults useless. Store drawn images for each coverage layer
 * @return The number of lines which have been drawn on y axis
 */
private static int paintWithTemplate(final MapItem item, final Graphics2D g2d, final Rectangle bounds, final LegendTemplate template, final Map<GenericName, BufferedImage> legendResults) {
    final AffineTransform origin = g2d.getTransform();
    final FontMetrics layerFontMetric = g2d.getFontMetrics(template.getLayerFont());
    final FontMetrics ruleFontMetric = g2d.getFontMetrics(template.getRuleFont());
    final int ruleFontHeight = ruleFontMetric.getHeight();
    final float gapSize = template.getGapSize();
    final Dimension glyphSize = template.getGlyphSize();
    final Rectangle2D rectangle = new Rectangle2D.Float();
    float moveY = 0;
    final List<MapItem> layers = (item instanceof MapLayers) ? ((MapLayers) item).getComponents() : Collections.EMPTY_LIST;
    for (int l = 0, n = layers.size(); l < n; l++) {
        final MapItem currentItem = layers.get(l);
        // check if the given layer is visible, and if we should display invisible layers.
        if (template.displayOnlyVisibleLayers() && !isVisible(currentItem)) {
            continue;
        }
        // Check for current item title.
        if (template.isLayerVisible()) {
            if (l != 0) {
                moveY += gapSize;
            }
            String title = "";
            final CharSequence titleTmp = currentItem.getTitle();
            if (titleTmp != null) {
                title = titleTmp.toString().replace("{}", "");
            }
            if (title.isEmpty()) {
                title = currentItem.getIdentifier();
            }
            if (title != null && !title.isEmpty()) {
                moveY += layerFontMetric.getLeading() + layerFontMetric.getAscent();
                g2d.setFont(template.getLayerFont());
                Color layerFontColor = template.getLayerFontColor();
                if (layerFontColor != null) {
                    if (template.getLayerFontOpacity() != null) {
                        layerFontColor = new Color(layerFontColor.getRed(), layerFontColor.getGreen(), layerFontColor.getBlue(), template.getLayerFontOpacity());
                    }
                } else {
                    layerFontColor = Color.BLACK;
                }
                g2d.setColor(layerFontColor);
                g2d.drawString(title, 0, moveY);
                moveY += layerFontMetric.getDescent();
                moveY += gapSize;
            }
        }
        // If we're not on a leaf, try to display this node children.
        if (!(currentItem instanceof MapLayer)) {
            // Using doubles allows current position relative translation.
            final double nodeInset = template.getBackground().getBackgroundInsets().left;
            g2d.translate(nodeInset, moveY);
            final int itemDim = paintWithTemplate(currentItem, g2d, bounds, template, legendResults);
            g2d.translate(-nodeInset, -moveY);
            // Previous function reset graphic position at the top of drawn map item. We Add its size to vertical offset, so next item knows how much pixels it should jump.
            moveY += itemDim;
            continue;
        }
        final MapLayer layer = (MapLayer) layers.get(l);
        // default style defined on the WMS service for this layer
        wmscase: if (layer.getData() instanceof GridCoverageResource) {
            // Get the image from the ones previously stored, to not resend a get legend graphic request.
            BufferedImage image = null;
            try {
                image = legendResults.get(layer.getData().getIdentifier().get());
            } catch (DataStoreException ex) {
            // do nothing
            }
            if (image == null) {
                break wmscase;
            }
            if (l != 0) {
                moveY += gapSize;
            }
            g2d.drawImage(image, null, 0, Math.round(moveY));
            moveY += image.getHeight();
            continue;
        }
        final Style style = layer.getStyle();
        if (style == null) {
            continue;
        }
        int numElement = 0;
        for (final FeatureTypeStyle fts : style.featureTypeStyles()) {
            for (final Rule rule : fts.rules()) {
                if (numElement != 0) {
                    moveY += gapSize;
                }
                // calculate the rule text displacement with the glyph size
                final float stepRuleTitle;
                final float glyphHeight;
                final float glyphWidth;
                final Dimension preferred = DefaultGlyphService.glyphPreferredSize(rule, null, layer);
                if (glyphSize == null) {
                    // find the best size
                    glyphHeight = preferred.height;
                    glyphWidth = preferred.width;
                } else {
                    // Use the biggest size between preferred one and default one.
                    glyphHeight = Math.max(glyphSize.height, preferred.height);
                    glyphWidth = Math.max(glyphSize.width, preferred.width);
                }
                if (glyphHeight > ruleFontHeight) {
                    stepRuleTitle = ruleFontMetric.getLeading() + ruleFontMetric.getAscent() + (glyphHeight - ruleFontHeight) / 2;
                } else {
                    stepRuleTitle = ruleFontMetric.getLeading() + ruleFontMetric.getAscent();
                }
                rectangle.setRect(0, moveY, glyphWidth, glyphHeight);
                DefaultGlyphService.render(rule, rectangle, g2d, layer);
                String title = "";
                final Description description = rule.getDescription();
                if (description != null) {
                    final InternationalString titleTmp = description.getTitle();
                    if (titleTmp != null) {
                        title = titleTmp.toString();
                    }
                }
                if (title.isEmpty()) {
                    moveY += glyphHeight;
                } else {
                    g2d.setFont(template.getRuleFont());
                    g2d.setColor(Color.BLACK);
                    g2d.drawString(title, glyphWidth + GLYPH_SPACE, moveY + stepRuleTitle);
                    moveY += (glyphHeight > ruleFontHeight) ? glyphHeight : ruleFontHeight;
                }
                numElement++;
            }
        }
    }
    g2d.setTransform(origin);
    return (int) moveY;
}
Also used : DataStoreException(org.apache.sis.storage.DataStoreException) Description(org.opengis.style.Description) Color(java.awt.Color) MapLayer(org.apache.sis.portrayal.MapLayer) Rectangle2D(java.awt.geom.Rectangle2D) Dimension(java.awt.Dimension) InternationalString(org.opengis.util.InternationalString) BufferedImage(java.awt.image.BufferedImage) InternationalString(org.opengis.util.InternationalString) FontMetrics(java.awt.FontMetrics) GridCoverageResource(org.apache.sis.storage.GridCoverageResource) AffineTransform(java.awt.geom.AffineTransform) FeatureTypeStyle(org.opengis.style.FeatureTypeStyle) Style(org.opengis.style.Style) FeatureTypeStyle(org.opengis.style.FeatureTypeStyle) Rule(org.opengis.style.Rule) MapItem(org.apache.sis.portrayal.MapItem) MapLayers(org.apache.sis.portrayal.MapLayers)

Example 4 with FeatureTypeStyle

use of org.opengis.style.FeatureTypeStyle in project geotoolkit by Geomatys.

the class CopyStyleVisitor method visit.

@Override
public MutableStyle visit(Style style, Object data) {
    final MutableStyle copy = SF.style();
    copy.setDefault(style.isDefault());
    copy.setDefaultSpecification(style.getDefaultSpecification());
    copy.setDescription(style.getDescription());
    copy.setName(style.getName());
    for (FeatureTypeStyle fts : style.featureTypeStyles()) {
        copy.featureTypeStyles().add((MutableFeatureTypeStyle) fts.accept(this, data));
    }
    return copy;
}
Also used : MutableStyle(org.geotoolkit.style.MutableStyle) MutableFeatureTypeStyle(org.geotoolkit.style.MutableFeatureTypeStyle) FeatureTypeStyle(org.opengis.style.FeatureTypeStyle)

Example 5 with FeatureTypeStyle

use of org.opengis.style.FeatureTypeStyle in project geotoolkit by Geomatys.

the class DefaultStyleVisitor method visit.

@Override
public Object visit(final Style style, Object data) {
    final List<? extends FeatureTypeStyle> ftss = style.featureTypeStyles();
    if (ftss != null) {
        for (FeatureTypeStyle fts : ftss) {
            data = fts.accept(this, data);
        }
    }
    final Symbolizer def = style.getDefaultSpecification();
    if (def != null) {
        data = def.accept(this, data);
    }
    return data;
}
Also used : FeatureTypeStyle(org.opengis.style.FeatureTypeStyle) ExtensionSymbolizer(org.opengis.style.ExtensionSymbolizer) RasterSymbolizer(org.opengis.style.RasterSymbolizer) TextSymbolizer(org.opengis.style.TextSymbolizer) PointSymbolizer(org.opengis.style.PointSymbolizer) PolygonSymbolizer(org.opengis.style.PolygonSymbolizer) LineSymbolizer(org.opengis.style.LineSymbolizer) Symbolizer(org.opengis.style.Symbolizer)

Aggregations

FeatureTypeStyle (org.opengis.style.FeatureTypeStyle)13 Rule (org.opengis.style.Rule)6 Symbolizer (org.opengis.style.Symbolizer)5 DataStoreException (org.apache.sis.storage.DataStoreException)4 MutableFeatureTypeStyle (org.geotoolkit.style.MutableFeatureTypeStyle)4 PolygonSymbolizer (org.opengis.style.PolygonSymbolizer)4 Style (org.opengis.style.Style)4 MapLayer (org.apache.sis.portrayal.MapLayer)3 MapLayers (org.apache.sis.portrayal.MapLayers)3 LineSymbolizer (org.opengis.style.LineSymbolizer)3 PointSymbolizer (org.opengis.style.PointSymbolizer)3 Dimension (java.awt.Dimension)2 FontMetrics (java.awt.FontMetrics)2 MapItem (org.apache.sis.portrayal.MapItem)2 FeatureSet (org.apache.sis.storage.FeatureSet)2 GridCoverageResource (org.apache.sis.storage.GridCoverageResource)2 Resource (org.apache.sis.storage.Resource)2 PortrayalException (org.geotoolkit.display.PortrayalException)2 Expression (org.opengis.filter.Expression)2 Filter (org.opengis.filter.Filter)2