Search in sources :

Example 1 with TransformedShape

use of org.geotoolkit.display.shape.TransformedShape in project geotoolkit by Geomatys.

the class LineSymbolizerRendererService method glyph.

/**
 * {@inheritDoc }
 */
@Override
public void glyph(final Graphics2D g, final Rectangle2D rectangle, final CachedLineSymbolizer symbol, final MapLayer layer) {
    final AffineTransform affine = new AffineTransform(rectangle.getWidth(), 0, 0, rectangle.getHeight(), rectangle.getX(), rectangle.getY());
    g.setClip(rectangle);
    final TransformedShape shape = new TransformedShape();
    shape.setOriginalShape(GO2Utilities.GLYPH_LINE);
    shape.setTransform(affine);
    GO2Utilities.renderStroke(shape, symbol.getSource().getStroke(), symbol.getSource().getUnitOfMeasure(), g);
}
Also used : TransformedShape(org.geotoolkit.display.shape.TransformedShape) AffineTransform(java.awt.geom.AffineTransform)

Example 2 with TransformedShape

use of org.geotoolkit.display.shape.TransformedShape in project geotoolkit by Geomatys.

the class CachedGraphic method getMargin.

/**
 * @return margin of this style for the given feature
 */
public float getMargin(final Object candidate, final float coeff) {
    evaluate();
    final boolean noFeature = (candidate == null);
    // //we have a cachedImage, we return it's bigest attribut
    // BufferedImage img = (BufferedImage)cachedValues.get(ID_BUFFER);
    // if(img != null){
    // return (img.getHeight()*coeff > img.getWidth()*coeff) ? img.getHeight()*coeff : img.getWidth()*coeff;
    // }
    // get the displacement margin
    final float maxDisplacement = cachedDisplacement.getMargin(candidate, coeff);
    if (Float.isNaN(maxDisplacement))
        return Float.NaN;
    // get anchor margin
    final float anchorRatio = cachedAnchor.getMarginRatio(candidate, coeff);
    if (Float.isNaN(anchorRatio))
        return Float.NaN;
    float candidateOpacity = cachedOpacity;
    float candidateRotation = cachedRotation;
    float candidateSize = cachedSize;
    if (Float.isNaN(candidateOpacity)) {
        final Expression expOpacity = styleElement.getOpacity();
        if (noFeature) {
            // can not evaluate
            return Float.NaN;
        } else {
            candidateOpacity = GO2Utilities.evaluate(expOpacity, candidate, 1f, 0f, 1f);
        }
    }
    if (candidateOpacity <= 0)
        return 0;
    if (Float.isNaN(candidateRotation)) {
        final Expression expRotation = styleElement.getRotation();
        final Number rot = GO2Utilities.evaluate(expRotation, candidate, Number.class, 0f);
        candidateRotation = (float) Math.toRadians(rot.doubleValue());
    }
    if (Float.isNaN(candidateSize)) {
        final Expression expSize = styleElement.getSize();
        if (noFeature) {
            // can not evaluate
            return Float.NaN;
        } else {
            candidateSize = GO2Utilities.evaluate(expSize, candidate, Number.class, 16f).floatValue();
        }
    }
    if (candidateSize <= 0)
        return 0;
    // the subbuffer image
    BufferedImage subBuffer = null;
    // we have a cached mark ------------------------------------------------------------------
    if (cachedMark != null) {
        if (noFeature) {
            if (cachedMark.isStatic()) {
                subBuffer = cachedMark.getImage(candidate, candidateSize * coeff, null);
            }
        } else {
            subBuffer = cachedMark.getImage(candidate, candidateSize * coeff, null);
        }
    }
    // we have a cached external --------------------------------------------------------------
    if (cachedExternal != null) {
        if (noFeature) {
            if (cachedExternal.isStatic()) {
                subBuffer = cachedExternal.getImage(candidateSize, coeff, null);
            }
        } else {
            subBuffer = cachedExternal.getImage(candidateSize, coeff, null);
        }
    }
    if (subBuffer == null)
        return 0;
    // we must change size according to rotation ---------------------------------------------
    final int maxSizeX;
    final int maxSizeY;
    if (candidateRotation == 0) {
        maxSizeX = subBuffer.getWidth();
        maxSizeY = subBuffer.getHeight();
    } else {
        Rectangle rect = new Rectangle(subBuffer.getWidth(), subBuffer.getHeight());
        TransformedShape trs = new TransformedShape();
        trs.setOriginalShape(rect);
        trs.rotate(candidateRotation);
        maxSizeX = (int) trs.getBounds2D().getWidth();
        maxSizeY = (int) trs.getBounds2D().getHeight();
    }
    // consider the anchor value and displacement
    // max margin is : iconSize/2 + iconSize-0.5 + maxDisplacement
    final float iconSize = Math.max(maxSizeX, maxSizeY);
    return (iconSize / 2f + (Math.abs(anchorRatio - 0.5f) * iconSize) + maxDisplacement) * coeff;
}
Also used : TransformedShape(org.geotoolkit.display.shape.TransformedShape) Expression(org.opengis.filter.Expression) Rectangle(java.awt.Rectangle) BufferedImage(java.awt.image.BufferedImage)

Example 3 with TransformedShape

use of org.geotoolkit.display.shape.TransformedShape in project geotoolkit by Geomatys.

the class J2DGridUtilities method paint.

public static void paint(final RenderingContext2D context, final GridTemplate template) {
    CoordinateReferenceSystem gridCRS = template.getCRS();
    // use context crs if gridcrs is not defined
    if (gridCRS == null)
        gridCRS = context.getObjectiveCRS();
    final Graphics2D g = context.getGraphics();
    context.switchToDisplayCRS();
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g.setComposite(GO2Utilities.ALPHA_COMPOSITE_1F);
    // calculate the cliping zone for texts
    final float xTextOffset = template.getXTextOffset();
    final float yTextOffset = template.getYTextOffset();
    final Rectangle clip = new Rectangle(context.getCanvasDisplayBounds());
    clip.x += xTextOffset;
    clip.height -= yTextOffset;
    final Shape shp = new TransformedShape(clip, context.getDisplayToObjective());
    final List<Coordinate> coords = new ArrayList<>();
    final PathIterator ite = shp.getPathIterator(null);
    final double[] vals = new double[3];
    while (!ite.isDone()) {
        ite.currentSegment(vals);
        coords.add(new Coordinate(vals[0], vals[1]));
        ite.next();
    }
    final GeometryFactory fact = JTS.getFactory();
    final LinearRing ring = fact.createLinearRing(coords.toArray(new Coordinate[coords.size()]));
    final Polygon bounds = fact.createPolygon(ring, new LinearRing[0]);
    final LabelRenderer renderer = context.getLabelRenderer(true);
    final LabelLayer layer = new DefaultLabelLayer(false, true);
    final RenderingHints tickHint = new RenderingHints(null);
    tickHint.put(Graduation.VISUAL_AXIS_LENGTH, context.getCanvasDisplayBounds().width);
    tickHint.put(Graduation.VISUAL_TICK_SPACING, 200);
    // number of point by line
    final int nbPoint = 20;
    final CoordinateReferenceSystem objectiveCRS = context.getObjectiveCRS2D();
    try {
        // reduce grid bounds to validity area
        Envelope gridBounds = Envelopes.transform(context.getCanvasObjectiveBounds2D(), gridCRS);
        if (new GeneralEnvelope(gridBounds).isEmpty()) {
            // envelope likely contains NaN values
            gridBounds = CRS.getDomainOfValidity(gridCRS);
            if (gridBounds == null) {
                // try to convert target CRS validity to grid crs
                gridBounds = CRS.getDomainOfValidity(objectiveCRS);
                if (gridBounds == null) {
                    // nothing we can do
                    return;
                }
                gridBounds = Envelopes.transform(gridBounds, gridCRS);
            }
        }
        if (Math.abs(gridBounds.getSpan(0)) < MIN || Math.abs(gridBounds.getSpan(1)) < MIN) {
            return;
        }
        Envelope validity = CRS.getDomainOfValidity(gridCRS);
        if (validity != null) {
            GeneralEnvelope env = new GeneralEnvelope(gridBounds);
            env.intersect(validity);
            gridBounds = env;
        }
        final MathTransform gridToObj = CRS.findOperation(gridCRS, objectiveCRS, null).getMathTransform();
        final MathTransform objToGrid = gridToObj.inverse();
        // grid on X axis ---------------------------------------------------
        final NumberGraduation graduationX = new NumberGraduation(null);
        graduationX.setRange(gridBounds.getMinimum(0), gridBounds.getMaximum(0), gridBounds.getCoordinateReferenceSystem().getCoordinateSystem().getAxis(0).getUnit());
        TickIterator tickIte = graduationX.getTickIterator(tickHint, null);
        while (!tickIte.isDone()) {
            tickIte.next();
            final String label = tickIte.currentLabel();
            final double d = tickIte.currentPosition();
            if (d > gridBounds.getMaximum(0))
                continue;
            final ArrayList<Coordinate> lineCoords = new ArrayList<>();
            final double maxY = gridBounds.getMaximum(1);
            final double step = gridBounds.getSpan(1) / nbPoint;
            for (double k = Math.nextUp(gridBounds.getMinimum(1)); k < maxY; k += step) {
                lineCoords.add(new Coordinate(d, k));
            }
            lineCoords.add(new Coordinate(d, Math.nextAfter(maxY, Double.NEGATIVE_INFINITY)));
            Geometry geom = fact.createLineString(lineCoords.toArray(new Coordinate[lineCoords.size()]));
            if (geom == null)
                continue;
            final ProjectedGeometry pg = new ProjectedGeometry(context);
            pg.setDataGeometry(geom, gridCRS);
            // draw line
            if (tickIte.isMajorTick()) {
                g.setPaint(template.getMainLinePaint());
                g.setStroke(template.getMainLineStroke());
            } else {
                g.setPaint(template.getLinePaint());
                g.setStroke(template.getLineStroke());
            }
            for (Shape ds : pg.getDisplayShape()) g.draw(ds);
            // clip geometry to avoid text outside visible area
            geom = org.apache.sis.internal.feature.jts.JTS.transform(geom, gridToObj);
            if (geom == null)
                continue;
            geom = geom.intersection(bounds);
            pg.setDataGeometry(geom, objectiveCRS);
            // draw text
            final LinearLabelDescriptor desc;
            if (tickIte.isMajorTick()) {
                desc = new DefaultLinearLabelDescriptor(label, template.getMainLabelFont(), template.getMainLabelPaint(), template.getMainHaloWidth(), template.getMainHaloPaint(), 0, 10, 3, false, false, false, pg);
            } else {
                desc = new DefaultLinearLabelDescriptor(label, template.getLabelFont(), template.getLabelPaint(), template.getHaloWidth(), template.getHaloPaint(), 0, 10, 3, false, false, false, pg);
            }
            layer.labels().add(desc);
        }
        // grid on Y axis ---------------------------------------------------
        final NumberGraduation graduationY = new NumberGraduation(null);
        graduationY.setRange(gridBounds.getMinimum(1), gridBounds.getMaximum(1), gridBounds.getCoordinateReferenceSystem().getCoordinateSystem().getAxis(1).getUnit());
        tickIte = graduationY.getTickIterator(tickHint, null);
        while (!tickIte.isDone()) {
            tickIte.next();
            final String label = tickIte.currentLabel();
            final double d = tickIte.currentPosition();
            if (d > gridBounds.getMaximum(1))
                continue;
            final ArrayList<Coordinate> lineCoords = new ArrayList<>();
            final double maxX = gridBounds.getMaximum(0);
            final double step = gridBounds.getSpan(0) / nbPoint;
            for (double k = Math.nextUp(gridBounds.getMinimum(0)); k < maxX; k += step) {
                lineCoords.add(new Coordinate(k, d));
            }
            lineCoords.add(new Coordinate(Math.nextAfter(maxX, Double.NEGATIVE_INFINITY), d));
            Geometry geom = fact.createLineString(lineCoords.toArray(new Coordinate[lineCoords.size()]));
            final ProjectedGeometry pg = new ProjectedGeometry(context);
            pg.setDataGeometry(geom, gridCRS);
            // draw line
            if (tickIte.isMajorTick()) {
                g.setPaint(template.getMainLinePaint());
                g.setStroke(template.getMainLineStroke());
            } else {
                g.setPaint(template.getLinePaint());
                g.setStroke(template.getLineStroke());
            }
            for (Shape ds : pg.getDisplayShape()) g.draw(ds);
            // clip geometry to avoid text outside visible area
            geom = org.apache.sis.internal.feature.jts.JTS.transform(geom, gridToObj);
            if (geom == null)
                continue;
            geom = geom.intersection(bounds);
            pg.setDataGeometry(geom, objectiveCRS);
            // draw text
            final LinearLabelDescriptor desc;
            if (tickIte.isMajorTick()) {
                desc = new DefaultLinearLabelDescriptor(label, template.getMainLabelFont(), template.getMainLabelPaint(), template.getMainHaloWidth(), template.getMainHaloPaint(), 0, 10, 3, false, false, false, pg);
            } else {
                desc = new DefaultLinearLabelDescriptor(label, template.getLabelFont(), template.getLabelPaint(), template.getHaloWidth(), template.getHaloPaint(), 0, 10, 3, false, false, false, pg);
            }
            layer.labels().add(desc);
        }
    } catch (Exception ex) {
        // TODO: NO!!
        ex.printStackTrace();
    }
    renderer.portrayImmidiately(layer);
}
Also used : LabelRenderer(org.geotoolkit.display2d.style.labeling.LabelRenderer) TransformedShape(org.geotoolkit.display.shape.TransformedShape) Shape(java.awt.Shape) GeometryFactory(org.locationtech.jts.geom.GeometryFactory) LinearLabelDescriptor(org.geotoolkit.display2d.style.labeling.LinearLabelDescriptor) DefaultLinearLabelDescriptor(org.geotoolkit.display2d.style.labeling.DefaultLinearLabelDescriptor) MathTransform(org.opengis.referencing.operation.MathTransform) PathIterator(java.awt.geom.PathIterator) Rectangle(java.awt.Rectangle) ArrayList(java.util.ArrayList) Envelope(org.opengis.geometry.Envelope) GeneralEnvelope(org.apache.sis.geometry.GeneralEnvelope) RenderingHints(java.awt.RenderingHints) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem) Polygon(org.locationtech.jts.geom.Polygon) DefaultLinearLabelDescriptor(org.geotoolkit.display2d.style.labeling.DefaultLinearLabelDescriptor) TickIterator(org.geotoolkit.display.axis.TickIterator) Graphics2D(java.awt.Graphics2D) ProjectedGeometry(org.geotoolkit.display2d.primitive.ProjectedGeometry) Geometry(org.locationtech.jts.geom.Geometry) LabelLayer(org.geotoolkit.display2d.style.labeling.LabelLayer) DefaultLabelLayer(org.geotoolkit.display2d.style.labeling.DefaultLabelLayer) TransformedShape(org.geotoolkit.display.shape.TransformedShape) Coordinate(org.locationtech.jts.geom.Coordinate) ProjectedGeometry(org.geotoolkit.display2d.primitive.ProjectedGeometry) LinearRing(org.locationtech.jts.geom.LinearRing) DefaultLabelLayer(org.geotoolkit.display2d.style.labeling.DefaultLabelLayer) GeneralEnvelope(org.apache.sis.geometry.GeneralEnvelope) NumberGraduation(org.geotoolkit.display.axis.NumberGraduation)

Example 4 with TransformedShape

use of org.geotoolkit.display.shape.TransformedShape in project geotoolkit by Geomatys.

the class GO2Utilities method renderGraphic.

// //////////////////////////////////////////////////////////////////////////
// Glyph utils /////////////////////////////////////////////////////////////
// //////////////////////////////////////////////////////////////////////////
/**
 * Paint a mark.
 *
 * @param mark : mark to paint
 * @param size : expected mark size
 * @param target : Graphics2D
 */
public static void renderGraphic(final Mark mark, final float size, final Graphics2D target) {
    final Expression wkn = mark.getWellKnownName();
    final Shape shape;
    if (StyleConstants.MARK_CIRCLE.equals(wkn)) {
        shape = WKMMarkFactory.CIRCLE;
    } else if (StyleConstants.MARK_CROSS.equals(wkn)) {
        shape = WKMMarkFactory.CROSS;
    } else if (StyleConstants.MARK_SQUARE.equals(wkn)) {
        shape = WKMMarkFactory.SQUARE;
    } else if (StyleConstants.MARK_STAR.equals(wkn)) {
        shape = WKMMarkFactory.STAR;
    } else if (StyleConstants.MARK_TRIANGLE.equals(wkn)) {
        shape = WKMMarkFactory.TRIANGLE;
    } else if (StyleConstants.MARK_X.equals(wkn)) {
        shape = WKMMarkFactory.X;
    } else {
        shape = null;
    }
    if (shape != null) {
        final TransformedShape trs = new TransformedShape();
        trs.setOriginalShape(shape);
        trs.scale(size, size);
        renderFill(trs, mark.getFill(), target);
        renderStroke(trs, mark.getStroke(), Units.METRE, target);
    }
}
Also used : Shape(java.awt.Shape) TransformedShape(org.geotoolkit.display.shape.TransformedShape) TransformedShape(org.geotoolkit.display.shape.TransformedShape) Expression(org.opengis.filter.Expression)

Example 5 with TransformedShape

use of org.geotoolkit.display.shape.TransformedShape in project geotoolkit by Geomatys.

the class CachedGraphic method getImage.

/**
 * @return BufferedImage for a feature
 */
public BufferedImage getImage(final Object candidate, final Float forcedSize, final float coeff, boolean withRotation, final RenderingHints hints) {
    evaluate();
    // //we have a cached buffer ---------------------------------------------------------------
    // if(cachedValues.containsKey(ID_BUFFER)){
    // return (BufferedImage) cachedValues.get(ID_BUFFER);
    // }
    // -------- grab the cached parameters ----------------------------------------------------
    float candidateOpacity = cachedOpacity;
    float candidateRotation = cachedRotation;
    Float candidateSize = (forcedSize != null) ? forcedSize : cachedSize;
    if (Float.isNaN(candidateOpacity)) {
        final Expression expOpacity = styleElement.getOpacity();
        candidateOpacity = GO2Utilities.evaluate(expOpacity, candidate, 1f, 0f, 1);
    }
    if (Float.isNaN(candidateRotation)) {
        final Expression expRotation = styleElement.getRotation();
        final Number rot = GO2Utilities.evaluate(expRotation, candidate, Number.class, 0f);
        candidateRotation = (float) Math.toRadians(rot.doubleValue());
    }
    if (candidateSize.isNaN()) {
        final Expression expSize = styleElement.getSize();
        candidateSize = GO2Utilities.evaluate(expSize, candidate, Number.class, Float.NaN).floatValue();
    }
    // the subbuffer image
    BufferedImage subBuffer = null;
    // we have a cached mark ------------------------------------------------------------------
    if (cachedMark != null) {
        if (candidateSize.isNaN()) {
            subBuffer = cachedMark.getImage(candidate, 16 * coeff, hints);
        } else {
            subBuffer = cachedMark.getImage(candidate, candidateSize * coeff, hints);
        }
    }
    // we have a cached external --------------------------------------------------------------
    if (cachedExternal != null) {
        subBuffer = cachedExternal.getImage(candidateSize, coeff, hints);
    }
    if (subBuffer == null) {
        // may happen if image is too small
        return null;
    }
    final boolean skipRotation = candidateRotation == 0 || !withRotation;
    // no operation to append to image, return the buffer directly ----------------------------
    if (skipRotation && candidateOpacity == 1)
        return subBuffer;
    // we must change opacity or rotation ----------------------------------------------------
    final int maxSizeX;
    final int maxSizeY;
    if (skipRotation) {
        maxSizeX = subBuffer.getWidth();
        maxSizeY = subBuffer.getHeight();
    } else {
        Rectangle rect = new Rectangle(subBuffer.getWidth(), subBuffer.getHeight());
        TransformedShape trs = new TransformedShape();
        trs.setOriginalShape(rect);
        trs.rotate(candidateRotation);
        final Rectangle2D rotatedRect = trs.getBounds2D();
        maxSizeX = (int) rotatedRect.getWidth();
        maxSizeY = (int) rotatedRect.getHeight();
    }
    if (maxSizeX <= 0 || maxSizeY <= 0) {
        return null;
    }
    final BufferedImage buffer = new BufferedImage(maxSizeX, maxSizeY, BufferedImage.TYPE_INT_ARGB);
    final Graphics2D g2 = (Graphics2D) buffer.getGraphics();
    if (hints != null) {
        g2.setRenderingHints(hints);
    }
    final Composite j2dComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, candidateOpacity);
    g2.setComposite(j2dComposite);
    if (!skipRotation)
        g2.rotate(candidateRotation, maxSizeX / 2f, maxSizeY / 2f);
    final int translateX = (maxSizeX - subBuffer.getWidth()) / 2;
    final int translateY = (maxSizeY - subBuffer.getHeight()) / 2;
    g2.drawImage(subBuffer, translateX, translateY, null);
    g2.dispose();
    return buffer;
}
Also used : TransformedShape(org.geotoolkit.display.shape.TransformedShape) Composite(java.awt.Composite) AlphaComposite(java.awt.AlphaComposite) Expression(org.opengis.filter.Expression) Rectangle(java.awt.Rectangle) Rectangle2D(java.awt.geom.Rectangle2D) BufferedImage(java.awt.image.BufferedImage) Graphics2D(java.awt.Graphics2D)

Aggregations

TransformedShape (org.geotoolkit.display.shape.TransformedShape)7 Expression (org.opengis.filter.Expression)4 Graphics2D (java.awt.Graphics2D)3 Rectangle (java.awt.Rectangle)3 Shape (java.awt.Shape)3 BufferedImage (java.awt.image.BufferedImage)3 AffineTransform (java.awt.geom.AffineTransform)2 AlphaComposite (java.awt.AlphaComposite)1 Composite (java.awt.Composite)1 RenderingHints (java.awt.RenderingHints)1 PathIterator (java.awt.geom.PathIterator)1 Rectangle2D (java.awt.geom.Rectangle2D)1 ArrayList (java.util.ArrayList)1 GeneralEnvelope (org.apache.sis.geometry.GeneralEnvelope)1 NumberGraduation (org.geotoolkit.display.axis.NumberGraduation)1 TickIterator (org.geotoolkit.display.axis.TickIterator)1 ProjectedGeometry (org.geotoolkit.display2d.primitive.ProjectedGeometry)1 DefaultLabelLayer (org.geotoolkit.display2d.style.labeling.DefaultLabelLayer)1 DefaultLinearLabelDescriptor (org.geotoolkit.display2d.style.labeling.DefaultLinearLabelDescriptor)1 LabelLayer (org.geotoolkit.display2d.style.labeling.LabelLayer)1