Search in sources :

Example 1 with PortrayalException

use of org.geotoolkit.display.PortrayalException in project geotoolkit by Geomatys.

the class RenderingRoutines method optimizeBBox.

public static Envelope optimizeBBox(RenderingContext2D renderingContext, FeatureSet featureSet, double symbolsMargin) throws PortrayalException {
    Envelope bbox = renderingContext.getCanvasObjectiveBounds2D();
    final CoordinateReferenceSystem bboxCRS = bbox.getCoordinateReferenceSystem();
    final CanvasMonitor monitor = renderingContext.getMonitor();
    final CoordinateReferenceSystem layerCRS;
    try {
        layerCRS = FeatureExt.getCRS(featureSet.getType());
    } catch (DataStoreException ex) {
        throw new PortrayalException(ex.getMessage(), ex);
    }
    // expand the search area by the maximum symbol size
    if (symbolsMargin > 0) {
        final GeneralEnvelope env = new GeneralEnvelope(bbox);
        env.setRange(0, env.getMinimum(0) - symbolsMargin, env.getMaximum(0) + symbolsMargin);
        env.setRange(1, env.getMinimum(1) - symbolsMargin, env.getMaximum(1) + symbolsMargin);
        bbox = env;
    }
    // or if the crs is defined only on the feature geometry
    if (layerCRS != null && !Utilities.equalsIgnoreMetadata(layerCRS, bboxCRS)) {
        // BBox and layer bounds have different CRS. reproject bbox bounds
        Envelope env;
        try {
            env = Envelopes.transform(bbox, layerCRS);
            if (GeneralEnvelope.castOrCopy(env).isEmpty()) {
                // possible NaN values or out of crs validity area
                GeneralEnvelope benv = GeneralEnvelope.castOrCopy(bbox);
                benv.normalize();
                env = Envelopes.transform(benv, layerCRS);
            }
        } catch (TransformException ex) {
            // TODO is fixed in geotidy, the result envelope will have infinte values where needed
            // TODO should do something about this, since canvas bounds may be over the crs bounds
            monitor.exceptionOccured(ex, Level.WARNING);
            env = new Envelope2D();
        } catch (IllegalArgumentException ex) {
            // looks like the coordinate of the bbox are outside of the crs valide area.
            // some crs raise this error, other not.
            // if so we should reduce our bbox to the valide extent of the crs.
            monitor.exceptionOccured(ex, Level.WARNING);
            final GeographicBoundingBox gbox = CRS.getGeographicBoundingBox(layerCRS);
            if (gbox == null) {
                env = new GeneralEnvelope(layerCRS);
            } else {
                env = new GeneralEnvelope(gbox);
            }
        } catch (Exception ex) {
            // we should not catch this but we must not block the canvas
            monitor.exceptionOccured(ex, Level.WARNING);
            return null;
        }
        // TODO looks like the envelope after transform operation doesnt have always exactly the same CRS.
        // fix CRS classes method and remove the two next lines.
        env = new GeneralEnvelope(env);
        ((GeneralEnvelope) env).setCoordinateReferenceSystem(layerCRS);
        bbox = env;
    }
    return bbox;
}
Also used : DataStoreException(org.apache.sis.storage.DataStoreException) CanvasMonitor(org.geotoolkit.display.canvas.control.CanvasMonitor) TransformException(org.opengis.referencing.operation.TransformException) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) GeographicBoundingBox(org.opengis.metadata.extent.GeographicBoundingBox) Envelope(org.opengis.geometry.Envelope) GeneralEnvelope(org.apache.sis.geometry.GeneralEnvelope) GeneralEnvelope(org.apache.sis.geometry.GeneralEnvelope) Envelope2D(org.apache.sis.geometry.Envelope2D) PortrayalException(org.geotoolkit.display.PortrayalException) TransformException(org.opengis.referencing.operation.TransformException) MismatchedFeatureException(org.opengis.feature.MismatchedFeatureException) FactoryException(org.opengis.util.FactoryException) DataStoreException(org.apache.sis.storage.DataStoreException) FeatureStoreRuntimeException(org.geotoolkit.storage.feature.FeatureStoreRuntimeException) IOException(java.io.IOException) PropertyNotFoundException(org.opengis.feature.PropertyNotFoundException) PortrayalException(org.geotoolkit.display.PortrayalException)

Example 2 with PortrayalException

use of org.geotoolkit.display.PortrayalException in project geotoolkit by Geomatys.

the class TextSymbolizerRenderer method presentations.

@Override
public Stream<Presentation> presentations(MapLayer layer, Feature feature) {
    // test if the symbol is visible on this feature
    if (!symbol.isVisible(feature))
        return Stream.empty();
    // we adjust coefficient for rendering ------------------------------
    final float coeff;
    if (dispGeom) {
        // symbol is in display unit
        coeff = 1;
    } else {
        // we have a special unit we must adjust the coefficient. We adapt it to the current region of interest,
        // by computin scale difference between objective and display
        final AffineTransform inverse = renderingContext.getObjectiveToDisplay();
        coeff = (float) (this.coeff * Math.abs(AffineTransforms2D.getScale(inverse)));
    }
    // start to extract label parameters---------------------------------
    String label = symbol.getLabel(feature);
    // nothing to paint
    if (label == null)
        return Stream.empty();
    label = label.trim();
    // nothing to paint
    if (label.isEmpty())
        return Stream.empty();
    final CachedHalo halo = symbol.getHalo();
    final CachedLabelPlacement placement = symbol.getPlacement();
    // extract halo parameters
    final float haloWidth;
    final Paint haloPaint;
    if (halo != null) {
        haloWidth = halo.getWidth(feature);
        haloPaint = halo.getJ2DPaint(feature, 0, 0, hints);
    } else {
        haloWidth = 0;
        haloPaint = Color.WHITE;
    }
    /* Extract text parameters.
         * Note:
         * There's an ambiguity in SE encoding. Section 11 defines that any size, including font size, should use
         * defined UOMs. However, text symbology section 11.4.3 states that font size unit is always in pixels.
         * For now, we force no coefficient, to match both:
         *  - Most specific information (11.4.3)
         *  - Most common use-case. Unit of measurement is useful mostly for displacements, to ensure text does not
         *    overlap geometry at given zoom levels. However, for texts, pixel values is often preferred, to ensure
         *    lisibility on screen.
         *
         * TODO: A better way might be to allow expressions suffixed with "px", as defined in SE section 11, last phrase.
         * For now, however, we do not code this solution, because it should be applied on any size in style,
         * and would require a big rework. Sizes should provide Measures instead of numeric values to check if measure
         * has a local uom (expressed as a suffix), or none, in case the context defined uom should be used.
         */
    final Paint fontPaint = symbol.getFontPaint(feature, 0, 0, 1, hints);
    final Font j2dFont = symbol.getJ2dFont(feature, 1);
    // symbolizer doesnt match the featuretype, no geometry found with this name.
    final ProjectedGeometry projectedGeometry = new ProjectedGeometry(renderingContext);
    projectedGeometry.setDataGeometry(GO2Utilities.getGeometry(feature, symbol.getSource().getGeometry()), null);
    if (placement instanceof CachedPointPlacement) {
        final CachedPointPlacement pp = (CachedPointPlacement) placement;
        final float[] anchor = pp.getAnchor(feature, null);
        final float[] disp = pp.getDisplacement(feature, null);
        final float rotation = pp.getRotation(feature);
        final LabelDescriptor descriptor = new DefaultPointLabelDescriptor(label, j2dFont, fontPaint, haloWidth, haloPaint, anchor[0], anchor[1], // SE 11.3.2: displacement is expressed in defined unit of measurement
        disp[0] * coeff, disp[1] * coeff, rotation, renderingContext.getDisplayCRS(), projectedGeometry);
        final TextPresentation tp = new TextPresentation(layer, layer.getData(), feature);
        tp.forGrid(renderingContext);
        tp.labelDesc = descriptor;
        return Stream.of(tp);
    } else if (placement instanceof CachedLinePlacement) {
        final CachedLinePlacement lp = (CachedLinePlacement) placement;
        final LabelDescriptor descriptor = new DefaultLinearLabelDescriptor(label, j2dFont, fontPaint, haloWidth, haloPaint, // SE section 11: Gap and initial gap are defined using UOM.
        lp.getGap(feature) * coeff, lp.getInitialGap(feature) * coeff, // SE 11.1.4 and 11.4.4: Perpendicular offset is in defined unit of measurement
        lp.getOffset(feature) * coeff, lp.isRepeated(), lp.isAligned(), lp.isGeneralizeLine(), projectedGeometry);
        final TextPresentation tp = new TextPresentation(layer, layer.getData(), feature);
        tp.forGrid(renderingContext);
        tp.labelDesc = descriptor;
        return Stream.of(tp);
    } else {
        ExceptionPresentation ep = new ExceptionPresentation(new PortrayalException("Text symbolizer has no label placement, this should not be possible."));
        ep.setLayer(layer);
        ep.setResource(layer.getData());
        return Stream.of(ep);
    }
}
Also used : CachedHalo(org.geotoolkit.display2d.style.CachedHalo) DefaultLinearLabelDescriptor(org.geotoolkit.display2d.style.labeling.DefaultLinearLabelDescriptor) CachedPointPlacement(org.geotoolkit.display2d.style.CachedPointPlacement) DefaultPointLabelDescriptor(org.geotoolkit.display2d.style.labeling.DefaultPointLabelDescriptor) Paint(java.awt.Paint) CachedLabelPlacement(org.geotoolkit.display2d.style.CachedLabelPlacement) Font(java.awt.Font) ProjectedGeometry(org.geotoolkit.display2d.primitive.ProjectedGeometry) ExceptionPresentation(org.apache.sis.internal.map.ExceptionPresentation) AffineTransform(java.awt.geom.AffineTransform) CachedLinePlacement(org.geotoolkit.display2d.style.CachedLinePlacement) DefaultPointLabelDescriptor(org.geotoolkit.display2d.style.labeling.DefaultPointLabelDescriptor) LabelDescriptor(org.geotoolkit.display2d.style.labeling.LabelDescriptor) DefaultLinearLabelDescriptor(org.geotoolkit.display2d.style.labeling.DefaultLinearLabelDescriptor) TextPresentation(org.geotoolkit.display2d.presentation.TextPresentation) PortrayalException(org.geotoolkit.display.PortrayalException)

Example 3 with PortrayalException

use of org.geotoolkit.display.PortrayalException in project geotoolkit by Geomatys.

the class AbstractSymbolizerRenderer method presentations.

/**
 * Obtain the presentation for given resource.Default implementation loops on each feature if resource is a FeatureSet.
 * If resource is an Aggregate, loops on each components and concatenate streams.
 *
 * @param layer
 * @param resource
 * @return Stream never null, can be empty
 * @throws BackingStoreException in stream iteration
 */
@Override
public Stream<Presentation> presentations(MapLayer layer, Resource resource) {
    if (resource instanceof FeatureSet) {
        /*
            Optimise case using envelopes filter and limited propery names.
            */
        final FeatureSet fs = (FeatureSet) resource;
        Set<String> names;
        if (GO2Utilities.mustPreserveAllProperties(getRenderingContext())) {
            names = null;
        } else {
            // extract the used names
            final org.geotoolkit.style.visitor.ListingPropertyVisitor visitor = new org.geotoolkit.style.visitor.ListingPropertyVisitor();
            names = new HashSet<>();
            symbol.getSource().accept(visitor, names);
            if (names.contains("*")) {
                // we need all properties
                names = null;
            }
        }
        // calculate max symbol size, to expand search envelope.
        double symbolsMargin = symbol.getMargin(null, renderingContext);
        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(renderingContext.getDisplayToObjective());
            symbolsMargin = scale * symbolsMargin;
        }
        // optimize
        final Rule rule = GO2Utilities.STYLE_FACTORY.rule(symbol.getSource());
        final Query query;
        try {
            query = RenderingRoutines.prepareQuery(getRenderingContext(), fs, layer, names, Arrays.asList(rule), symbolsMargin);
        } catch (PortrayalException ex) {
            ExceptionPresentation ep = new ExceptionPresentation(ex);
            ep.setLayer(layer);
            ep.setResource(resource);
            return Stream.of(ep);
        }
        final AtomicInteger inc = new AtomicInteger();
        final UndefinedCRSException[] firstException = new UndefinedCRSException[1];
        try {
            return fs.subset(query).features(false).onClose(new Runnable() {

                @Override
                public void run() {
                    final int nb = inc.get();
                    if (nb > 0) {
                        LOGGER.log(Level.INFO, "Several (" + nb + ") undefined crs geometries have been detected on layer : " + layer.getIdentifier() + "/" + layer.getTitle() + " : " + firstException[0].getMessage(), firstException[0]);
                    }
                }
            }).flatMap(new Function<Feature, Stream<Presentation>>() {

                @Override
                public Stream<Presentation> apply(Feature t) {
                    try {
                        return presentations(layer, t);
                    } catch (UndefinedCRSException ex) {
                        inc.incrementAndGet();
                        firstException[0] = ex;
                        return Stream.empty();
                    }
                }
            });
        } catch (DataStoreException ex) {
            ExceptionPresentation ep = new ExceptionPresentation(ex);
            ep.setLayer(layer);
            ep.setResource(resource);
            return Stream.of(ep);
        }
    }
    return SymbolizerRenderer.super.presentations(layer, resource);
}
Also used : Query(org.apache.sis.storage.Query) Feature(org.opengis.feature.Feature) ExceptionPresentation(org.apache.sis.internal.map.ExceptionPresentation) Stream(java.util.stream.Stream) UndefinedCRSException(org.geotoolkit.display2d.primitive.UndefinedCRSException) DataStoreException(org.apache.sis.storage.DataStoreException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) FeatureSet(org.apache.sis.storage.FeatureSet) Rule(org.opengis.style.Rule) PortrayalException(org.geotoolkit.display.PortrayalException)

Example 4 with PortrayalException

use of org.geotoolkit.display.PortrayalException in project geotoolkit by Geomatys.

the class MapFieldRenderer method createValue.

@Override
public Object createValue(final JRField field, final Feature feature) {
    final String name = field.getName();
    final MapDef map = (MapDef) feature.getPropertyValue(name);
    if (map != null && map.getDelegate() == null) {
        // only create delegate if not yet assigned
        final CanvasDef canvasDef = map.getCanvasDef();
        final SceneDef sceneDef = map.getSceneDef();
        // create the canvas
        final CanvasRenderer renderable = new CanvasRenderer(sceneDef.getContext());
        try {
            DefaultPortrayalService.prepareCanvas(renderable, canvasDef, sceneDef);
        } catch (PortrayalException ex) {
            Logger.getLogger("org.geotoolkit.report.graphic.map").log(Level.WARNING, ex.getLocalizedMessage(), ex);
        }
        map.setDelegate(renderable);
    }
    if (map != null && map.getDelegate() == null) {
        map.setDelegate(EmptyRenderable.INSTANCE);
    }
    return map;
}
Also used : SceneDef(org.geotoolkit.display2d.service.SceneDef) CanvasDef(org.geotoolkit.display2d.service.CanvasDef) PortrayalException(org.geotoolkit.display.PortrayalException)

Example 5 with PortrayalException

use of org.geotoolkit.display.PortrayalException in project geotoolkit by Geomatys.

the class DefaultPortrayalService method prepareCanvas.

public static void prepareCanvas(final J2DCanvas canvas, final CanvasDef canvasDef, final SceneDef sceneDef) throws PortrayalException {
    final ContextContainer2D renderer = new ContextContainer2D(canvas);
    canvas.setContainer(renderer);
    final Color bgColor = canvasDef.getBackground();
    if (bgColor != null) {
        canvas.setBackgroundPainter(new SolidColorPainter(bgColor));
    }
    final CanvasMonitor monitor = canvasDef.getMonitor();
    if (monitor != null) {
        canvas.setMonitor(monitor);
    }
    final Hints hints = sceneDef.getHints();
    if (hints != null) {
        for (Entry<?, ?> entry : hints.entrySet()) {
            canvas.setRenderingHint((Key) entry.getKey(), entry.getValue());
        }
    }
    final MapLayers context = sceneDef.getContext();
    renderer.setContext(context);
    GridGeometry gridGeometry = canvasDef.getGridGeometry();
    if (gridGeometry != null) {
        try {
            canvas.setGridGeometry(gridGeometry);
        } catch (FactoryException ex) {
            throw new PortrayalException("Could not set objective crs", ex);
        }
    } else {
        final Envelope contextEnv = canvasDef.getEnvelope();
        final CoordinateReferenceSystem crs = contextEnv.getCoordinateReferenceSystem();
        try {
            canvas.setObjectiveCRS(crs);
        } catch (TransformException | FactoryException ex) {
            throw new PortrayalException("Could not set objective crs", ex);
        }
        // we specifically say to not repect X/Y proportions
        canvas.setAxisProportions(!canvasDef.isStretchImage());
        // setVisibleArea -> setAxisRange -> setRange.
        if (contextEnv != null) {
            try {
                canvas.setGridGeometry(canvasDef.getOrCreateGridGeometry());
            } catch (Exception e) {
                // Rollback to previous behavior
                try {
                    canvas.setVisibleArea(contextEnv);
                    if (canvasDef.getAzimuth() != 0) {
                        canvas.rotate(-Math.toRadians(canvasDef.getAzimuth()));
                    }
                } catch (NoninvertibleTransformException | TransformException ex) {
                    ex.addSuppressed(e);
                    throw new PortrayalException(ex);
                }
            }
        }
    }
    // paints all extensions
    final List<PortrayalExtension> extensions = sceneDef.extensions();
    if (extensions != null) {
        for (final PortrayalExtension extension : extensions) {
            if (extension != null)
                extension.completeCanvas(canvas);
        }
    }
}
Also used : SolidColorPainter(org.geotoolkit.display2d.canvas.painter.SolidColorPainter) GridGeometry(org.apache.sis.coverage.grid.GridGeometry) Hints(org.geotoolkit.factory.Hints) GO2Hints(org.geotoolkit.display2d.GO2Hints) FactoryException(org.opengis.util.FactoryException) ContextContainer2D(org.geotoolkit.display2d.container.ContextContainer2D) Color(java.awt.Color) NoninvertibleTransformException(java.awt.geom.NoninvertibleTransformException) TransformException(org.opengis.referencing.operation.TransformException) Envelope(org.opengis.geometry.Envelope) PortrayalException(org.geotoolkit.display.PortrayalException) FactoryException(org.opengis.util.FactoryException) IIOException(javax.imageio.IIOException) IOException(java.io.IOException) DisjointExtentException(org.apache.sis.coverage.grid.DisjointExtentException) NoninvertibleTransformException(java.awt.geom.NoninvertibleTransformException) TransformException(org.opengis.referencing.operation.TransformException) ProcessException(org.geotoolkit.process.ProcessException) DataStoreException(org.apache.sis.storage.DataStoreException) CanvasMonitor(org.geotoolkit.display.canvas.control.CanvasMonitor) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) MapLayers(org.apache.sis.portrayal.MapLayers) PortrayalException(org.geotoolkit.display.PortrayalException)

Aggregations

PortrayalException (org.geotoolkit.display.PortrayalException)32 TransformException (org.opengis.referencing.operation.TransformException)14 DataStoreException (org.apache.sis.storage.DataStoreException)13 Dimension (java.awt.Dimension)12 Envelope (org.opengis.geometry.Envelope)8 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)8 Graphics2D (java.awt.Graphics2D)7 NoninvertibleTransformException (java.awt.geom.NoninvertibleTransformException)7 IOException (java.io.IOException)7 FactoryException (org.opengis.util.FactoryException)7 Color (java.awt.Color)6 CanvasMonitor (org.geotoolkit.display.canvas.control.CanvasMonitor)6 Rectangle (java.awt.Rectangle)5 BufferedImage (java.awt.image.BufferedImage)5 RenderedImage (java.awt.image.RenderedImage)5 ExceptionPresentation (org.apache.sis.internal.map.ExceptionPresentation)5 Presentation (org.apache.sis.internal.map.Presentation)5 Expression (org.opengis.filter.Expression)5 Font (java.awt.Font)4 AffineTransform (java.awt.geom.AffineTransform)4