/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2009-2015, 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 java.awt.Graphics2D; import java.awt.RenderingHints; import java.util.ArrayList; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import org.geotoolkit.display2d.canvas.RenderingContext2D; import org.geotoolkit.display2d.style.labeling.DefaultLabelRenderer; import org.geotoolkit.display2d.style.labeling.LabelDescriptor; import org.geotoolkit.display2d.style.labeling.LabelLayer; import org.geotoolkit.display2d.style.labeling.LinearLabelDescriptor; import org.geotoolkit.display2d.style.labeling.PointLabelDescriptor; import org.geotoolkit.display2d.style.labeling.candidate.Candidate; import org.geotoolkit.display2d.style.labeling.candidate.LabelingUtilities; import org.geotoolkit.display2d.style.labeling.candidate.LinearCandidate; import org.geotoolkit.display2d.style.labeling.candidate.PointCandidate; /** * Label renderer that apply a simple decimation on labels to remove all * overlaping labels and labels partly visible on the map edges. * * @author Johann Sorel (Geomatys) * @module */ public class DecimationLabelRenderer extends DefaultLabelRenderer{ private final SortedSet<Candidate> candidates = new TreeSet<Candidate>(LabelingUtilities.XY_COMPARATOR); private final List<LabelLayer> layers = new ArrayList<LabelLayer>(); private PointLabelCandidateRenderer pointRenderer; private LinearLabelCandidateRenderer LinearRenderer; public DecimationLabelRenderer() { } @Override public LabelLayer createLabelLayer() { return new DecimateLabelLayer(false, true); } /** * {@inheritDoc } */ @Override public void setRenderingContext(final RenderingContext2D context){ super.setRenderingContext(context); LinearRenderer = new LinearLabelCandidateRenderer(context); pointRenderer = new PointLabelCandidateRenderer(context); } /** * {@inheritDoc } */ @Override public RenderingContext2D getRenderingContext() { return context; } /** * {@inheritDoc } */ @Override public void append(final LabelLayer layer) { layers.add(layer); } /** * {@inheritDoc } */ @Override public void portrayLabels(){ final Graphics2D g2 = context.getGraphics(); //enable antialiasing for labels g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //paint the remaining candidates for(Candidate candidate : candidates){ if(candidate instanceof PointCandidate){ pointRenderer.render(candidate); }else if(candidate instanceof LinearCandidate){ LinearRenderer.render(candidate); } } layers.clear(); } private List<Candidate> optimize(List<Candidate> candidates){ candidates = LabelingUtilities.clipOutofBounds(context,candidates); candidates = LabelingUtilities.sortByXY(candidates); return candidates; } private class DecimateLabelLayer implements LabelLayer{ private final List<LabelDescriptor> labels = new ArrayList<LabelDescriptor>(){ @Override public boolean add(LabelDescriptor label) { if(label instanceof PointLabelDescriptor){ final Candidate[] pcs = pointRenderer.generateCandidat((PointLabelDescriptor) label); if(pcs == null) return true; for(Candidate c : pcs){ final PointCandidate pc = (PointCandidate) c; pc.setPriority(1); synchronized(candidates){ if(!LabelingUtilities.intersects(pc,candidates)){ candidates.add(pc); }else{ } } } }else if(label instanceof LinearLabelDescriptor){ final Candidate[] lcs = LinearRenderer.generateCandidat((LinearLabelDescriptor) label); for(Candidate c : lcs){ final LinearCandidate lc = (LinearCandidate) c; lc.setPriority(1); synchronized(candidates){ candidates.add(lc); } } } return true; } }; private final boolean obstacle; private final boolean labelled; public DecimateLabelLayer(final boolean isObstacle, final boolean isLabelled) { this.labelled = isLabelled; this.obstacle = isObstacle; } @Override public boolean isObstacle() { return obstacle; } @Override public boolean isLabelled() { return labelled; } @Override public List<LabelDescriptor> labels() { return labels; } } }