package org.geotools.renderer.label; import static org.junit.Assert.*; import java.awt.Color; import java.awt.Rectangle; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.atomic.AtomicReference; import org.geotools.feature.simple.SimpleFeatureBuilder; import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.geotools.geometry.jts.LiteShape2; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.geotools.renderer.RenderListener; import org.geotools.styling.Font; import org.geotools.styling.StyleBuilder; import org.geotools.styling.TextSymbolizer; import org.geotools.test.TestGraphics; import org.geotools.util.NumberRange; import org.junit.Before; import org.junit.Test; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.io.ParseException; import com.vividsolutions.jts.io.WKTReader; public class LabelCacheImplTest { private static final Geometry L3 = geometry("LINESTRING(20 20, 30 30)"); private static final Geometry L2 = geometry("LINESTRING(10 10, 20 20)"); private static final Geometry L1 = geometry("LINESTRING(0 0, 10 10)"); private static final String LAYER_ID = "layerId"; SimpleFeatureType schema; SimpleFeatureBuilder fb; LabelCacheImpl cache; StyleBuilder sb; NumberRange<Double> ALL_SCALES = new NumberRange<Double>(Double.class, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY); @Before public void setupSchema() { SimpleFeatureTypeBuilder tb = new SimpleFeatureTypeBuilder(); tb.setName("test"); tb.add("name", String.class); tb.add("geom", LineString.class, DefaultGeographicCRS.WGS84); schema = tb.buildFeatureType(); fb = new SimpleFeatureBuilder(schema); cache = new LabelCacheImpl(); cache.startLayer(LAYER_ID); sb = new StyleBuilder(); } @Test public void testSimpleGrouping() throws Exception { TextSymbolizer ts = sb.createTextSymbolizer(Color.BLACK, (Font) null, "name"); ts.getOptions().put(TextSymbolizer.GROUP_KEY, "true"); SimpleFeature f1 = createFeature("label1", L1); SimpleFeature f2 = createFeature("label1", L2); cache.put(LAYER_ID, ts, f1, new LiteShape2((Geometry) f1.getDefaultGeometry(), null, null, false), ALL_SCALES); cache.put(LAYER_ID, ts, f2, new LiteShape2((Geometry) f2.getDefaultGeometry(), null, null, false), ALL_SCALES); // we have just one List<LabelCacheItem> labels = cache.getActiveLabels(); assertEquals(1, labels.size()); LabelCacheItem item = labels.get(0); assertEquals("label1", item.getLabel()); assertEquals(2, item.getGeoms().size()); } @Test public void testGroupDifferentSymbolizers() throws Exception { TextSymbolizer ts1 = sb.createTextSymbolizer(Color.BLACK, (Font) null, "name"); ts1.getOptions().put(TextSymbolizer.GROUP_KEY, "true"); TextSymbolizer ts2 = sb.createTextSymbolizer(Color.YELLOW, (Font) null, "name"); ts2.getOptions().put(TextSymbolizer.GROUP_KEY, "true"); SimpleFeature f1 = createFeature("label1", L1); SimpleFeature f2 = createFeature("label1", L2); cache.put(LAYER_ID, ts1, f1, new LiteShape2((Geometry) f1.getDefaultGeometry(), null, null, false), ALL_SCALES); cache.put(LAYER_ID, ts2, f2, new LiteShape2((Geometry) f2.getDefaultGeometry(), null, null, false), ALL_SCALES); // two different symbolizers, we should have two List<LabelCacheItem> labels = cache.getActiveLabels(); assertEquals(2, labels.size()); } @Test public void testMinNonGrouped() throws Exception { TextSymbolizer ts = sb.createTextSymbolizer(Color.BLACK, (Font) null, "name"); TextSymbolizer tsGroup = sb.createTextSymbolizer(Color.YELLOW, (Font) null, "name"); tsGroup.getOptions().put(TextSymbolizer.GROUP_KEY, "true"); SimpleFeature f1 = createFeature("label1", L1); SimpleFeature f2 = createFeature("label1", L2); SimpleFeature f3 = createFeature("label1", L3); cache.put(LAYER_ID, tsGroup, f1, new LiteShape2((Geometry) f1.getDefaultGeometry(), null, null, false), ALL_SCALES); cache.put(LAYER_ID, ts, f2, new LiteShape2((Geometry) f2.getDefaultGeometry(), null, null, false), ALL_SCALES); cache.put(LAYER_ID, tsGroup, f3, new LiteShape2((Geometry) f3.getDefaultGeometry(), null, null, false), ALL_SCALES); // two different symbolizers, we should have two (the first grouped with the third) List<LabelCacheItem> labels = cache.getActiveLabels(); assertEquals(2, labels.size()); LabelCacheItem item1 = labels.get(0); assertEquals("label1", item1.getLabel()); assertEquals(Arrays.asList(L1, L3), item1.getGeoms()); LabelCacheItem item2 = labels.get(1); assertEquals("label1", item2.getLabel()); assertEquals(Arrays.asList(L2), item2.getGeoms()); } @Test public void testRendererListener() throws Exception { TextSymbolizer ts = sb.createTextSymbolizer(Color.BLACK, (Font) null, "name"); AtomicReference<Exception> exception = new AtomicReference<Exception>(null); RenderListener listener = new RenderListener() { @Override public void featureRenderer(SimpleFeature feature) { // TODO Auto-generated method stub } @Override public void errorOccurred(Exception e) { exception.set(e); } }; cache.addRenderListener(listener); SimpleFeature f1 = createFeature("label1", L1); cache.put(LAYER_ID, ts, f1, new LiteShape2((Geometry) f1.getDefaultGeometry(), null, null, false), ALL_SCALES); cache.endLayer("layerId", null, null); TestGraphics testGraphics = new TestGraphics(); testGraphics.setRenderingHints(Collections.emptyMap()); cache.end(testGraphics, new Rectangle(0, 0, 10, 10)); // got here, did we get the exception assertNotNull(exception.get()); } private SimpleFeature createFeature(String label, Geometry geom) { fb.add(label); fb.add(geom); return fb.buildFeature(null); } private static Geometry geometry(String wkt) { try { return new WKTReader().read(wkt); } catch (ParseException e) { throw new RuntimeException(e); } } }