/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2009-2010, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.display2d.style.labeling.decimate; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Point; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.geom.Rectangle2D; import java.awt.geom.RoundRectangle2D; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import org.geotoolkit.display2d.GO2Utilities; import org.geotoolkit.display2d.canvas.RenderingContext2D; import org.geotoolkit.display2d.style.labeling.PointLabelDescriptor; import org.geotoolkit.display2d.style.labeling.candidate.Candidate; import org.geotoolkit.display2d.style.labeling.candidate.PointCandidate; import org.opengis.referencing.operation.TransformException; import org.apache.sis.util.logging.Logging; /** * * @author Johann Sorel (Geomatys) * @module */ public class PointLabelCandidateRenderer implements LabelCandidateRenderer<PointLabelDescriptor>{ private static final Candidate[] EMPTY = new Candidate[0]; private final RenderingContext2D context; private final Graphics2D g2; public PointLabelCandidateRenderer(final RenderingContext2D context) { this.context = context; g2 = context.getGraphics(); } @Override public Candidate[] generateCandidat(final PointLabelDescriptor label) { Geometry[] shapes = null; try { shapes = label.getGeometry().getDisplayGeometryJTS(); } catch (TransformException ex) { Logging.getLogger("org.geotoolkit.display2d.style.labeling.decimate").log(Level.WARNING, null, ex); } if(shapes == null) return null; final List<Candidate> candidates = new ArrayList<>(shapes.length); for(int i=0; i<shapes.length; i++){ final Geometry shape = shapes[i]; final Point pt = GO2Utilities.getBestPoint(shape); if(pt==null || pt.isEmpty()) continue; final Coordinate point = pt.getCoordinate(); final FontMetrics metric = context.getFontMetrics(label.getTextFont()); final int textUpper = metric.getAscent(); final int textLower = metric.getDescent(); final int textWidth = metric.stringWidth(label.getText()); float refX = (float) point.x; float refY = (float) point.y; refX = refX + label.getDisplacementX(); refY = refY - label.getDisplacementY(); refX = refX - (label.getAnchorX()*textWidth); //text is draw above reference point so use + refY = refY + (label.getAnchorY()*(textUpper)); candidates.add(new PointCandidate(label, textWidth, textUpper, textLower, refX,refY )); } return candidates.toArray(EMPTY); } @Override public void render(final Candidate candidate) { if(!(candidate instanceof PointCandidate)) return; final PointCandidate pointCandidate = (PointCandidate) candidate; final PointLabelDescriptor label = pointCandidate.getDescriptor(); final double rotation = Math.toRadians(label.getRotation()); context.switchToDisplayCRS(); ////////////////////////////BBOX FOR TEST/////////////////////////////// // g2.setStroke(new BasicStroke(1)); // g2.setColor(Color.BLACK); // g2.rotate(rotation, pointCandidate.getCorrectedX(), pointCandidate.getCorrectedY()); // g2.drawRect((int)pointCandidate.getCorrectedX(), // (int)pointCandidate.getCorrectedY()-pointCandidate.upper, // pointCandidate.width, // pointCandidate.upper+pointCandidate.lower); // g2.rotate(-rotation, pointCandidate.getCorrectedX(), pointCandidate.getCorrectedY()); //////////////////////////////////////////////////////////////////////// //TODO draw a nice line if correction is important---------------------- // g2.setColor(Color.RED); // g2.setStroke(new BasicStroke(1)); // g2.drawLine((int)pointCandidate.x, // (int)pointCandidate.y, // (int)pointCandidate.getCorrectedX(), // (int)pointCandidate.getCorrectedY()); //rotation-------------------------------------------------------------- if(rotation != 0){ g2.rotate(rotation, pointCandidate.getCorrectedX(), pointCandidate.getCorrectedY()); } g2.setFont(label.getTextFont()); //paint halo------------------------------------------------------------ final float haloWidth = label.getHaloWidth(); if(haloWidth > 0){ final float haloWidth2 = haloWidth+haloWidth; FontMetrics metric = g2.getFontMetrics(); final Rectangle2D bounds = metric.getStringBounds(label.getText(), g2); Shape shape = new RoundRectangle2D.Double( bounds.getMinX() + pointCandidate.getCorrectedX() - haloWidth, bounds.getMinY() + pointCandidate.getCorrectedY() - haloWidth, bounds.getWidth() + haloWidth2, bounds.getHeight()+ haloWidth2, 2+haloWidth2, 2+haloWidth2); g2.setPaint(label.getHaloPaint()); g2.fill(shape); } //paint text------------------------------------------------------------ g2.setPaint(label.getTextPaint()); g2.drawString(label.getText(), pointCandidate.getCorrectedX(), pointCandidate.getCorrectedY()); //reset rotation if(rotation != 0){ g2.rotate(-rotation, pointCandidate.getCorrectedX(), pointCandidate.getCorrectedY()); } } }