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);
}
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;
}
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);
}
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);
}
}
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;
}
Aggregations