Search in sources :

Example 6 with FeatureTypeStyle

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

the class MapContextTileGenerator method generate.

@Override
public void generate(TileMatrixSet pyramid, Envelope env, NumberRange resolutions, ProcessListener listener) throws DataStoreException, InterruptedException {
    // check if we can optimize tiles generation
    boolean rasterOptimisation = true;
    search: for (MapLayer layer : MapBuilder.getLayers(sceneDef.getContext())) {
        final Style style = layer.getStyle();
        for (FeatureTypeStyle fts : style.featureTypeStyles()) {
            for (Rule rule : fts.rules()) {
                double scaleMin = rule.getMinScaleDenominator();
                double scaleMax = rule.getMaxScaleDenominator();
                // CanvasUtilities.computeSEScale
                if (scaleMin != 0.0 || scaleMax < 5.0E9) {
                    rasterOptimisation = false;
                    break search;
                }
                for (Symbolizer symbolizer : rule.symbolizers()) {
                    if (symbolizer instanceof RasterSymbolizer || symbolizer instanceof DynamicRangeSymbolizer) {
                    // ok
                    } else if (symbolizer instanceof PolygonSymbolizer) {
                        PolygonSymbolizer ps = (PolygonSymbolizer) symbolizer;
                        // check if we have a plain fill
                        Displacement displacement = ps.getDisplacement();
                        Fill fill = ps.getFill();
                        Stroke stroke = ps.getStroke();
                        Expression perpendicularOffset = ps.getPerpendicularOffset();
                        if (displacement != null) {
                            Double dx = doubleValue(displacement.getDisplacementX());
                            Double dy = doubleValue(displacement.getDisplacementX());
                            if ((dx != null && dx != 0.0) || (dy != null && dy != 0.0)) {
                                rasterOptimisation = false;
                                break search;
                            }
                        }
                        if (perpendicularOffset != null) {
                            Double off = doubleValue(perpendicularOffset);
                            if (off != null && off != 0.0) {
                                rasterOptimisation = false;
                                break search;
                            }
                        }
                        if (stroke != null) {
                            Double op = doubleValue(stroke.getOpacity());
                            Double wd = doubleValue(stroke.getWidth());
                            if ((op == null || op == 0.0) || (wd == null || wd == 0.0)) {
                            // not visible
                            } else {
                                rasterOptimisation = false;
                                break search;
                            }
                        }
                        if (fill != null) {
                            if (fill.getGraphicFill() != null) {
                                rasterOptimisation = false;
                                break search;
                            }
                        }
                    } else {
                        rasterOptimisation = false;
                        break search;
                    }
                }
            }
        }
    }
    if (rasterOptimisation) {
        /*
            We can generate the pyramid starting from the lowest level then going up
            using the previously generated level.
            */
        if (env != null) {
            try {
                CoordinateReferenceSystem targetCrs = pyramid.getCoordinateReferenceSystem();
                Envelope baseEnv = env;
                env = Envelopes.transform(env, targetCrs);
                double[] minres = new double[] { resolutions.getMinDouble(), resolutions.getMinDouble() };
                double[] maxres = new double[] { resolutions.getMaxDouble(), resolutions.getMaxDouble() };
                minres = ReferencingUtilities.convertResolution(baseEnv, minres, targetCrs, null);
                maxres = ReferencingUtilities.convertResolution(baseEnv, maxres, targetCrs, null);
                resolutions = NumberRange.create(minres[0], true, maxres[0], true);
            } catch (TransformException ex) {
                throw new DataStoreException(ex.getMessage(), ex);
            }
        }
        // generate lower level from data
        final TileMatrix[] mosaics = pyramid.getTileMatrices().toArray(new TileMatrix[0]);
        Arrays.sort(mosaics, (TileMatrix o1, TileMatrix o2) -> Double.compare(o1.getScale(), o2.getScale()));
        MapLayers parent = sceneDef.getContext();
        Hints hints = sceneDef.getHints();
        final long total = TileMatrices.countTiles(pyramid, env, resolutions);
        final AtomicLong al = new AtomicLong();
        // send an event only every few seconds
        final AtomicLong tempo = new AtomicLong(System.currentTimeMillis());
        final String msg = " / " + NumberFormat.getIntegerInstance(Locale.FRANCE).format(total);
        for (final TileMatrix mosaic : mosaics) {
            if (resolutions == null || resolutions.contains(mosaic.getScale())) {
                final Rectangle rect;
                try {
                    rect = TileMatrices.getTilesInEnvelope(mosaic, env);
                } catch (NoSuchDataException ex) {
                    continue;
                }
                final CanvasDef canvasDef = new CanvasDef();
                canvasDef.setBackground(this.canvasDef.getBackground());
                canvasDef.setEnvelope(mosaic.getEnvelope());
                final SceneDef sceneDef = new SceneDef(parent, hints);
                // one thread per line, the progressive image generates multiple tiles when drawing
                // this approach is more efficient from profiling result then using tile by tile
                // generation
                Stream<Tile> stream = LongStream.range(rect.y, rect.y + rect.height).parallel().boxed().flatMap((Long y) -> {
                    try {
                        final ProgressiveImage img = new ProgressiveImage(canvasDef, sceneDef, mosaic.getGridSize(), mosaic.getTileSize(), mosaic.getScale(), 0);
                        return img.generate(rect.x, rect.x + rect.width, y.intValue(), skipEmptyTiles);
                    } catch (Exception ex) {
                        LOGGER.log(Level.INFO, "Failed to generate a tile {0}", ex.getMessage());
                        LOGGER.log(Level.FINER, "Failed to generate a tile ", ex);
                        return Stream.empty();
                    }
                });
                if (listener != null) {
                    final NumberFormat format = NumberFormat.getIntegerInstance(Locale.FRANCE);
                    stream = stream.map((Tile t) -> {
                        long n = al.incrementAndGet();
                        if (n % 1000 == 0) {
                            final long time = System.currentTimeMillis();
                            if (tempo.updateAndGet((long operand) -> ((time - operand) > 3000) ? time : operand) == time) {
                                listener.progressing(new ProcessEvent(DUMMY, format.format(n) + msg, (float) ((((double) n) / ((double) total)) * 100.0)));
                            }
                        }
                        return t;
                    });
                }
                mosaic.writeTiles(stream, null);
                // last level event
                final NumberFormat format = NumberFormat.getIntegerInstance(Locale.FRANCE);
                long v = al.get();
                if (listener != null) {
                    listener.progressing(new ProcessEvent(DUMMY, format.format(v) + msg, (float) ((((double) v) / ((double) total)) * 100.0)));
                }
                // modify context
                final DefaultTileMatrixSet pm = new DefaultTileMatrixSet(pyramid.getCoordinateReferenceSystem());
                pm.getMosaicsInternal().add(mosaic);
                final InMemoryTiledGridCoverageResource r = new InMemoryTiledGridCoverageResource(NamesExt.create("test"));
                r.setSampleDimensions(sampleDimensions);
                r.getTileMatrixSets().add(pm);
                final MapLayers mc = MapBuilder.createContext();
                mc.getComponents().add(MapBuilder.createLayer(r));
                parent = mc;
                hints = new Hints(hints);
                hints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
                hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
            }
        }
    } else {
        super.generate(pyramid, env, resolutions, listener);
    }
}
Also used : InMemoryTiledGridCoverageResource(org.geotoolkit.storage.memory.InMemoryTiledGridCoverageResource) Fill(org.opengis.style.Fill) Hints(org.geotoolkit.factory.Hints) RenderingHints(java.awt.RenderingHints) PolygonSymbolizer(org.opengis.style.PolygonSymbolizer) MapLayer(org.apache.sis.portrayal.MapLayer) Rectangle(java.awt.Rectangle) Envelope(org.opengis.geometry.Envelope) DefaultTileMatrixSet(org.geotoolkit.storage.multires.DefaultTileMatrixSet) DynamicRangeSymbolizer(org.geotoolkit.display2d.ext.dynamicrange.DynamicRangeSymbolizer) FeatureTypeStyle(org.opengis.style.FeatureTypeStyle) Style(org.opengis.style.Style) SceneDef(org.geotoolkit.display2d.service.SceneDef) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) TileMatrix(org.geotoolkit.storage.multires.TileMatrix) Stroke(org.opengis.style.Stroke) DataStoreException(org.apache.sis.storage.DataStoreException) ProcessEvent(org.geotoolkit.process.ProcessEvent) TransformException(org.opengis.referencing.operation.TransformException) Tile(org.geotoolkit.storage.multires.Tile) DefaultImageTile(org.geotoolkit.storage.coverage.DefaultImageTile) ImageTile(org.geotoolkit.storage.coverage.ImageTile) NoSuchDataException(org.apache.sis.storage.NoSuchDataException) PolygonSymbolizer(org.opengis.style.PolygonSymbolizer) RasterSymbolizer(org.opengis.style.RasterSymbolizer) DynamicRangeSymbolizer(org.geotoolkit.display2d.ext.dynamicrange.DynamicRangeSymbolizer) Symbolizer(org.opengis.style.Symbolizer) Displacement(org.opengis.style.Displacement) PortrayalException(org.geotoolkit.display.PortrayalException) TransformException(org.opengis.referencing.operation.TransformException) NoSuchDataException(org.apache.sis.storage.NoSuchDataException) DataStoreException(org.apache.sis.storage.DataStoreException) IOException(java.io.IOException) RasterSymbolizer(org.opengis.style.RasterSymbolizer) AtomicLong(java.util.concurrent.atomic.AtomicLong) Expression(org.opengis.filter.Expression) AtomicLong(java.util.concurrent.atomic.AtomicLong) FeatureTypeStyle(org.opengis.style.FeatureTypeStyle) Rule(org.opengis.style.Rule) CanvasDef(org.geotoolkit.display2d.service.CanvasDef) MapLayers(org.apache.sis.portrayal.MapLayers) NumberFormat(java.text.NumberFormat)

Example 7 with FeatureTypeStyle

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

the class DefaultPortrayalService method present.

public static Stream<Presentation> present(MapLayer layer, Resource resource, RenderingContext2D renderContext) {
    final Style style = layer.getStyle();
    Stream<Presentation> stream = Stream.empty();
    FeatureType type = null;
    if (resource instanceof FeatureSet) {
        try {
            type = ((FeatureSet) resource).getType();
        } catch (DataStoreException ex) {
            ExceptionPresentation ep = new ExceptionPresentation(ex);
            ep.setLayer(layer);
            ep.setResource(resource);
            return Stream.of(ep);
        }
    } else if (resource instanceof GridCoverageResource || resource instanceof BandedCoverageResource) {
        type = null;
    } else if (resource instanceof Aggregate) {
        try {
            // combine each component resource in the stream
            for (Resource r : ((Aggregate) resource).components()) {
                stream = Stream.concat(stream, present(layer, r, renderContext));
            }
        } catch (DataStoreException ex) {
            ExceptionPresentation ep = new ExceptionPresentation(ex);
            ep.setLayer(layer);
            ep.setResource(resource);
            return Stream.of(ep);
        }
        return stream;
    } else {
        // unknown type
        return Stream.empty();
    }
    final boolean keepAllProperties = GO2Utilities.mustPreserveAllProperties(renderContext);
    for (FeatureTypeStyle fts : style.featureTypeStyles()) {
        final List<Rule> rules = GO2Utilities.getValidRules(fts, renderContext.getSEScale(), type);
        if (rules.isEmpty())
            continue;
        // prepare the renderers
        final CachedRule[] cachedRules = toCachedRules(rules, type);
        final RenderingRules renderers = new RenderingRules(cachedRules, renderContext);
        {
            // special case for group symbolizers
            // group symbolizers must be alone in a FTS
            SymbolizerRenderer groupRenderer = null;
            int count = 0;
            for (int i = 0; i < renderers.renderers.length; i++) {
                for (int k = 0; k < renderers.renderers[i].length; k++) {
                    count++;
                    if (renderers.renderers[i][k].getService().isGroupSymbolizer()) {
                        groupRenderer = renderers.renderers[i][k];
                    }
                }
            }
            if (groupRenderer != null) {
                if (count > 1) {
                    ExceptionPresentation ep = new ExceptionPresentation(new PortrayalException("Group symbolizer (" + groupRenderer.getService().getSymbolizerClass().getSimpleName() + ") must be alone in a FeatureTypeStyle element."));
                    ep.setLayer(layer);
                    ep.setResource(resource);
                    stream = Stream.concat(stream, Stream.of(ep));
                } else {
                    stream = Stream.concat(stream, groupRenderer.presentations(layer, resource));
                }
                continue;
            }
        }
        // extract the used names
        Set<String> names;
        if (keepAllProperties) {
            names = null;
        } else {
            names = GO2Utilities.propertiesNames(rules);
            if (names.contains("*")) {
                // we need all properties
                names = null;
            }
        }
        // performance routine, only one symbol to render
        if (renderers.rules.length == 1 && (renderers.rules[0].getFilter() == null || renderers.rules[0].getFilter() == Filter.include()) && renderers.rules[0].symbolizers().length == 1) {
            stream = Stream.concat(stream, renderers.renderers[0][0].presentations(layer, resource));
            continue;
        }
        if (resource instanceof GridCoverageResource) {
            boolean painted = false;
            for (int i = 0; i < renderers.elseRuleIndex; i++) {
                final CachedRule rule = renderers.rules[i];
                final Filter ruleFilter = rule.getFilter();
                // test if the rule is valid for this feature
                if (ruleFilter == null || ruleFilter.test(resource)) {
                    painted = true;
                    for (final SymbolizerRenderer renderer : renderers.renderers[i]) {
                        stream = Stream.concat(stream, renderer.presentations(layer, resource));
                    }
                }
            }
            // the data hasn't been painted, paint it with the 'else' rules
            if (!painted) {
                for (int i = renderers.elseRuleIndex; i < renderers.rules.length; i++) {
                    final CachedRule rule = renderers.rules[i];
                    final Filter ruleFilter = rule.getFilter();
                    // test if the rule is valid for this feature
                    if (ruleFilter == null || ruleFilter.test(resource)) {
                        for (final SymbolizerRenderer renderer : renderers.renderers[i]) {
                            stream = Stream.concat(stream, renderer.presentations(layer, resource));
                        }
                    }
                }
            }
        } else if (resource instanceof FeatureSet) {
            final FeatureSet fs = (FeatureSet) resource;
            // calculate max symbol size, to expand search envelope.
            double symbolsMargin = 0.0;
            for (CachedRule rule : cachedRules) {
                for (CachedSymbolizer cs : rule.symbolizers()) {
                    symbolsMargin = Math.max(symbolsMargin, cs.getMargin(null, renderContext));
                }
            }
            if (Double.isNaN(symbolsMargin) || Double.isInfinite(symbolsMargin)) {
                // symbol margin can not be pre calculated, expect a max of 300pixels
                symbolsMargin = 300f;
            }
            if (symbolsMargin > 0) {
                final double scale = AffineTransforms2D.getScale(renderContext.getDisplayToObjective());
                symbolsMargin = scale * symbolsMargin;
            }
            // optimize
            final Query query;
            try {
                query = RenderingRoutines.prepareQuery(renderContext, fs, layer, names, rules, symbolsMargin);
                final Stream<Presentation> s = fs.subset(query).features(false).flatMap(new Function<Feature, Stream<Presentation>>() {

                    @Override
                    public Stream<Presentation> apply(Feature feature) {
                        Stream<Presentation> stream = Stream.empty();
                        boolean painted = false;
                        for (int i = 0; i < renderers.elseRuleIndex; i++) {
                            final CachedRule rule = renderers.rules[i];
                            final Filter ruleFilter = rule.getFilter();
                            // test if the rule is valid for this feature
                            if (ruleFilter == null || ruleFilter.test(feature)) {
                                painted = true;
                                for (final SymbolizerRenderer renderer : renderers.renderers[i]) {
                                    stream = Stream.concat(stream, renderer.presentations(layer, feature));
                                }
                            }
                        }
                        // the feature hasn't been painted, paint it with the 'else' rules
                        if (!painted) {
                            for (int i = renderers.elseRuleIndex; i < renderers.rules.length; i++) {
                                final CachedRule rule = renderers.rules[i];
                                final Filter ruleFilter = rule.getFilter();
                                // test if the rule is valid for this feature
                                if (ruleFilter == null || ruleFilter.test(feature)) {
                                    for (final SymbolizerRenderer renderer : renderers.renderers[i]) {
                                        stream = Stream.concat(stream, renderer.presentations(layer, feature));
                                    }
                                }
                            }
                        }
                        return stream;
                    }
                });
                stream = Stream.concat(stream, s);
            } catch (PortrayalException | DataStoreException ex) {
                ExceptionPresentation ep = new ExceptionPresentation(ex);
                ep.setLayer(layer);
                ep.setResource(resource);
                return Stream.of(ep);
            }
        }
    }
    return stream;
}
Also used : FeatureType(org.opengis.feature.FeatureType) Query(org.apache.sis.storage.Query) RenderingRules(org.geotoolkit.display2d.container.RenderingRules) Feature(org.opengis.feature.Feature) Function(java.util.function.Function) ExceptionPresentation(org.apache.sis.internal.map.ExceptionPresentation) GridCoverageResource(org.apache.sis.storage.GridCoverageResource) FeatureTypeStyle(org.opengis.style.FeatureTypeStyle) Style(org.opengis.style.Style) CachedRule(org.geotoolkit.display2d.style.CachedRule) Stream(java.util.stream.Stream) OutputStream(java.io.OutputStream) DataStoreException(org.apache.sis.storage.DataStoreException) BandedCoverageResource(org.geotoolkit.storage.coverage.BandedCoverageResource) Resource(org.apache.sis.storage.Resource) GridCoverageResource(org.apache.sis.storage.GridCoverageResource) BandedCoverageResource(org.geotoolkit.storage.coverage.BandedCoverageResource) Presentation(org.apache.sis.internal.map.Presentation) ExceptionPresentation(org.apache.sis.internal.map.ExceptionPresentation) CachedSymbolizer(org.geotoolkit.display2d.style.CachedSymbolizer) SymbolizerRenderer(org.geotoolkit.display2d.style.renderer.SymbolizerRenderer) Filter(org.opengis.filter.Filter) FeatureSet(org.apache.sis.storage.FeatureSet) FeatureTypeStyle(org.opengis.style.FeatureTypeStyle) Rule(org.opengis.style.Rule) CachedRule(org.geotoolkit.display2d.style.CachedRule) Aggregate(org.apache.sis.storage.Aggregate) PortrayalException(org.geotoolkit.display.PortrayalException)

Example 8 with FeatureTypeStyle

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

the class ListingPropertyVisitor 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)

Example 9 with FeatureTypeStyle

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

the class J2DLegendUtilities method estimateWithTemplate.

/**
 * Estimate the size (pixels) needed to render the given {@link MapItem} legend
 * using the input rendering hint (see {@link LegendTemplate}).
 * @param g2d The {@link Graphics2D} to paint legend into.
 * @param source The source map item to render.
 * @param toSet The {@link Dimension} to store estimation result into.
 * @param template the {@link LegendTemplate} to use as rendering hint.
 * @param images A map in which we'll store eventual legend we generated
 * during the process (key = layer name, value = layer legend). Can be null.
 * @param considerBackground A boolean to specify if we must count input
 * {@link LegendTemplate} background margins in the result size (true) or
 * not (false).
 */
private static void estimateWithTemplate(final Graphics2D g2d, final MapItem source, final Dimension toSet, final LegendTemplate template, final Map<GenericName, BufferedImage> images, final boolean considerBackground) {
    final FontMetrics layerFontMetric = g2d.getFontMetrics(template.getLayerFont());
    final FontMetrics ruleFontMetric = g2d.getFontMetrics(template.getRuleFont());
    final int ruleFontHeight = ruleFontMetric.getHeight();
    final Dimension glyphSize = template.getGlyphSize();
    final List<MapItem> childItems = (source instanceof MapLayers) ? ((MapLayers) source).getComponents() : Collections.EMPTY_LIST;
    for (int l = 0, n = childItems.size(); l < n; l++) {
        /* If legend template asks for visible items only, we have to proceed
             * in two steps, because we cannot just check item visibility.
             * If we are on a container (not a layer), it must be considered as
             * invisible if none of its children is visible.
             */
        final MapItem currentItem = childItems.get(l);
        if (template.displayOnlyVisibleLayers() && !isVisible(currentItem)) {
            continue;
        }
        if (template.isLayerVisible()) {
            if (l != 0) {
                toSet.height += template.getGapSize();
            }
            // Determines space to reserve for title.
            final Dimension titleDim = estimateTitle(currentItem, layerFontMetric);
            toSet.height += titleDim.height;
            if (toSet.width < titleDim.width) {
                toSet.width = titleDim.width;
            }
            if (titleDim.height > 0) {
                toSet.height += template.getGapSize();
            }
        }
        if (!(currentItem instanceof MapLayer)) {
            estimateWithTemplate(g2d, currentItem, toSet, template, images, considerBackground);
            continue;
        }
        final MapLayer layer = (MapLayer) currentItem;
        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) {
                    toSet.height += template.getGapSize();
                }
                // calculate the text length
                int textLenght = 0;
                final Description description = rule.getDescription();
                if (description != null) {
                    final InternationalString titleTmp = description.getTitle();
                    if (titleTmp != null) {
                        final String title = titleTmp.toString();
                        textLenght = ruleFontMetric.stringWidth(title);
                    }
                }
                // calculate the glyph size
                final int glyphHeight;
                final int 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 defined size
                    glyphHeight = glyphSize.height > preferred.height ? glyphSize.height : preferred.height;
                    glyphWidth = glyphSize.width > preferred.width ? glyphSize.width : preferred.width;
                }
                final int totalWidth = glyphWidth + ((textLenght == 0) ? 0 : (GLYPH_SPACE + textLenght));
                final int fh = (textLenght > 0) ? ruleFontHeight : 0;
                final int totalHeight = (glyphHeight > fh) ? glyphHeight : fh;
                toSet.height += totalHeight;
                if (toSet.width < totalWidth) {
                    toSet.width = totalWidth;
                }
                numElement++;
            }
        }
    }
    if (considerBackground && template.getBackground() != null) {
        final Insets insets = template.getBackground().getBackgroundInsets();
        toSet.width += insets.left + insets.right;
        toSet.height += insets.bottom + insets.top;
    }
}
Also used : Description(org.opengis.style.Description) Insets(java.awt.Insets) MapLayer(org.apache.sis.portrayal.MapLayer) Dimension(java.awt.Dimension) InternationalString(org.opengis.util.InternationalString) InternationalString(org.opengis.util.InternationalString) FontMetrics(java.awt.FontMetrics) 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 10 with FeatureTypeStyle

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

the class RenderingRoutines method mergeStyles.

/**
 * Merge a layer style with a selection style.
 * The selection style fts elements will be placed after those of the default style.
 */
public static MutableStyle mergeStyles(MutableStyle style, Filter selectionFilter, MutableStyle selectionStyle) {
    if (selectionFilter == null || Filter.exclude().equals(selectionFilter) || selectionStyle == null) {
        // unmodified
        return style;
    }
    final Filter exclusionFilter = FILTER_FACTORY.not(selectionFilter);
    final MutableStyle result = GO2Utilities.STYLE_FACTORY.style();
    for (FeatureTypeStyle fts : style.featureTypeStyles()) {
        final MutableFeatureTypeStyle resultfts = GO2Utilities.STYLE_FACTORY.featureTypeStyle();
        resultfts.setDescription(fts.getDescription());
        resultfts.setFeatureInstanceIDs(fts.getFeatureInstanceIDs());
        resultfts.setName(fts.getName());
        resultfts.setOnlineResource(fts.getOnlineResource());
        result.featureTypeStyles().add(resultfts);
        for (Rule rule : fts.rules()) {
            final MutableRule modifiedRule = STYLE_FACTORY.rule(rule.symbolizers().toArray(new Symbolizer[0]));
            Filter f = rule.getFilter();
            if (f == null) {
                f = exclusionFilter;
            } else {
                f = FILTER_FACTORY.and(f, exclusionFilter);
            }
            modifiedRule.setFilter(f);
            resultfts.rules().add(modifiedRule);
        }
    }
    if (selectionStyle != null) {
        for (FeatureTypeStyle fts : selectionStyle.featureTypeStyles()) {
            final MutableFeatureTypeStyle resultfts = GO2Utilities.STYLE_FACTORY.featureTypeStyle();
            resultfts.setDescription(fts.getDescription());
            resultfts.setFeatureInstanceIDs(fts.getFeatureInstanceIDs());
            resultfts.setName(fts.getName());
            resultfts.setOnlineResource(fts.getOnlineResource());
            result.featureTypeStyles().add(resultfts);
            for (Rule rule : fts.rules()) {
                final MutableRule modifiedRule = STYLE_FACTORY.rule(rule.symbolizers().toArray(new Symbolizer[0]));
                Filter f = rule.getFilter();
                if (f == null) {
                    f = selectionFilter;
                } else {
                    f = FILTER_FACTORY.and(f, selectionFilter);
                }
                modifiedRule.setFilter(f);
                resultfts.rules().add(modifiedRule);
            }
        }
    }
    return result;
}
Also used : MutableRule(org.geotoolkit.style.MutableRule) MutableStyle(org.geotoolkit.style.MutableStyle) Filter(org.opengis.filter.Filter) MutableFeatureTypeStyle(org.geotoolkit.style.MutableFeatureTypeStyle) MutableFeatureTypeStyle(org.geotoolkit.style.MutableFeatureTypeStyle) FeatureTypeStyle(org.opengis.style.FeatureTypeStyle) Rule(org.opengis.style.Rule) MutableRule(org.geotoolkit.style.MutableRule) 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