001: /*
002: * Geotools2 - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package org.geotools.renderer.shape;
018:
019: import java.awt.Color;
020: import java.awt.Frame;
021: import java.awt.Graphics;
022: import java.awt.Graphics2D;
023: import java.awt.GraphicsEnvironment;
024: import java.awt.Panel;
025: import java.awt.Rectangle;
026: import java.awt.event.WindowAdapter;
027: import java.awt.event.WindowEvent;
028: import java.awt.image.BufferedImage;
029: import java.io.IOException;
030: import java.net.URL;
031:
032: import junit.framework.TestCase;
033:
034: import org.geotools.TestData;
035: import org.geotools.data.shapefile.indexed.IndexedShapefileDataStore;
036: import org.geotools.data.shapefile.indexed.IndexedShapefileDataStoreFactory;
037: import org.geotools.feature.Feature;
038: import org.geotools.filter.FilterFactory;
039: import org.geotools.filter.FilterFactoryFinder;
040: import org.geotools.filter.IllegalFilterException;
041: import org.geotools.renderer.GTRenderer;
042: import org.geotools.renderer.RenderListener;
043: import org.geotools.styling.FeatureTypeStyle;
044: import org.geotools.styling.Fill;
045: import org.geotools.styling.LineSymbolizer;
046: import org.geotools.styling.PointSymbolizer;
047: import org.geotools.styling.PolygonSymbolizer;
048: import org.geotools.styling.Rule;
049: import org.geotools.styling.Stroke;
050: import org.geotools.styling.Style;
051: import org.geotools.styling.StyleFactory;
052: import org.geotools.styling.StyleFactoryFinder;
053: import org.geotools.styling.Symbolizer;
054:
055: import com.vividsolutions.jts.geom.Envelope;
056:
057: /**
058: * Utitility methods for unit tests
059: *
060: * @author jeichar
061: *
062: * @since 2.1.x
063: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/extension/shapefile-renderer/src/test/java/org/geotools/renderer/shape/TestUtilites.java $
064: */
065: public class TestUtilites {
066: static final FilterFactory filterFactory = FilterFactoryFinder
067: .createFilterFactory();
068: public static boolean INTERACTIVE = false;
069:
070: public static IndexedShapefileDataStore getPolygons()
071: throws IOException {
072: return TestUtilites.getDataStore("lakes.shp");
073: }
074:
075: public static IndexedShapefileDataStore getDataStore(String filename)
076: throws IOException {
077: URL url = TestData.url(Rendering2DTest.class, filename);
078: IndexedShapefileDataStoreFactory factory = new IndexedShapefileDataStoreFactory();
079:
080: return (IndexedShapefileDataStore) factory.createDataStore(url);
081: }
082:
083: public static IndexedShapefileDataStore getLines()
084: throws IOException {
085: return getDataStore("streams.shp");
086: }
087:
088: public static IndexedShapefileDataStore getPoints()
089: throws IOException {
090: URL url = TestData.url("shapes/pointtest.shp");
091: //IndexedShapefileDataStoreFactory factory = new IndexedShapefileDataStoreFactory();
092: //return (IndexedShapefileDataStore) factory.createDataStore(url);
093:
094: return new IndexedShapefileDataStore(url);
095: }
096:
097: public static Style createTestStyle(String polyName, String lineName)
098: throws IllegalFilterException {
099: return createTestStyle(polyName, lineName, null);
100: }
101:
102: public static Style createTestStyle(String polyName,
103: String lineName, String pointName)
104: throws IllegalFilterException {
105: if (polyName == null) {
106: polyName = "lakes";
107: }
108:
109: if (lineName == null) {
110: lineName = "streams";
111: }
112:
113: if (pointName == null) {
114: pointName = "pointtest";
115: }
116:
117: StyleFactory sFac = StyleFactoryFinder.createStyleFactory();
118:
119: // The following is complex, and should be built from
120: // an SLD document and not by hand
121: PointSymbolizer pointsym = sFac.createPointSymbolizer();
122: pointsym.setGraphic(sFac.getDefaultGraphic());
123:
124: LineSymbolizer linesym = sFac.createLineSymbolizer();
125: Stroke myStroke = sFac.getDefaultStroke();
126: myStroke.setColor(TestUtilites.filterFactory
127: .createLiteralExpression("#0000ff"));
128: myStroke.setWidth(TestUtilites.filterFactory
129: .createLiteralExpression(new Integer(5)));
130: Rendering2DTest.LOGGER.info("got new Stroke " + myStroke);
131: linesym.setStroke(myStroke);
132:
133: PolygonSymbolizer polysym = sFac.createPolygonSymbolizer();
134: Fill myFill = sFac.getDefaultFill();
135: myFill.setColor(TestUtilites.filterFactory
136: .createLiteralExpression("#ff0000"));
137: polysym.setFill(myFill);
138: myStroke = sFac.getDefaultStroke();
139: myStroke.setColor(TestUtilites.filterFactory
140: .createLiteralExpression("#0000ff"));
141: myStroke.setWidth(TestUtilites.filterFactory
142: .createLiteralExpression(new Integer(2)));
143: polysym.setStroke(myStroke);
144:
145: Rule rule = sFac.createRule();
146: rule.setSymbolizers(new Symbolizer[] { polysym });
147:
148: FeatureTypeStyle fts = sFac
149: .createFeatureTypeStyle(new Rule[] { rule });
150: fts.setFeatureTypeName(polyName);
151:
152: Rule rule2 = sFac.createRule();
153: rule2.setSymbolizers(new Symbolizer[] { linesym });
154:
155: FeatureTypeStyle fts2 = sFac.createFeatureTypeStyle();
156: fts2.setRules(new Rule[] { rule2 });
157: fts2.setFeatureTypeName(lineName);
158:
159: Rule rule3 = sFac.createRule();
160: rule3.setSymbolizers(new Symbolizer[] { pointsym });
161:
162: FeatureTypeStyle fts3 = sFac.createFeatureTypeStyle();
163: fts3.setRules(new Rule[] { rule3 });
164: fts3.setFeatureTypeName(pointName);
165:
166: Style style = sFac.createStyle();
167: style.setFeatureTypeStyles(new FeatureTypeStyle[] { fts, fts2,
168: fts3 });
169:
170: return style;
171: }
172:
173: /**
174: * bounds may be null
175: *
176: * @param testName DOCUMENT ME!
177: * @param renderer DOCUMENT ME!
178: * @param timeOut DOCUMENT ME!
179: * @param bounds DOCUMENT ME!
180: *
181: * @throws Exception DOCUMENT ME!
182: */
183: public static BufferedImage showRender(String testName,
184: GTRenderer renderer, long timeOut, Envelope bounds)
185: throws Exception {
186: return showRender(testName, renderer, timeOut, bounds, -1);
187: }
188:
189: /**
190: * bounds may be null
191: *
192: * @param testName DOCUMENT ME!
193: * @param renderer DOCUMENT ME!
194: * @param timeOut DOCUMENT ME!
195: * @param bounds DOCUMENT ME!
196: * @param expectedFeatureCount DOCUMENT ME!
197: * @return
198: *
199: * @throws Exception DOCUMENT ME!
200: */
201: public static BufferedImage showRender(String testName,
202: GTRenderer renderer, long timeOut, Envelope bounds,
203: int expectedFeatureCount) throws Exception {
204: CountingRenderListener listener = new CountingRenderListener();
205:
206: if (expectedFeatureCount > -1) {
207: renderer.addRenderListener(listener);
208: }
209:
210: int w = 300;
211: int h = 300;
212: final BufferedImage image = new BufferedImage(w, h,
213: BufferedImage.TYPE_INT_ARGB);
214: Graphics g = image.getGraphics();
215: g.setColor(Color.white);
216: g.fillRect(0, 0, w, h);
217: TestUtilites.render(renderer, g, new Rectangle(w, h), bounds);
218:
219: g.dispose();
220: if (!GraphicsEnvironment.isHeadless()
221: && TestUtilites.INTERACTIVE) {
222: Frame frame = new Frame(testName);
223: frame.addWindowListener(new WindowAdapter() {
224: public void windowClosing(WindowEvent e) {
225: e.getWindow().dispose();
226: }
227: });
228:
229: Panel p = new Panel() {
230: /** <code>serialVersionUID</code> field */
231: private static final long serialVersionUID = 1L;
232:
233: public void paint(Graphics g) {
234: g.drawImage(image, 0, 0, this );
235: }
236: };
237:
238: frame.add(p);
239: frame.setSize(w, h);
240: frame.setVisible(true);
241:
242: Thread.sleep(timeOut);
243: frame.dispose();
244:
245: }
246:
247: boolean hasData = false; //All I can seem to check reliably.
248:
249: for (int y = 0; y < h; y++) {
250: for (int x = 0; x < w; x++) {
251: if (image.getRGB(x, y) != -1) {
252: hasData = true;
253: }
254: }
255: }
256:
257: TestCase
258: .assertTrue("image is blank and should not be", hasData);
259:
260: if (expectedFeatureCount > -1) {
261: renderer.removeRenderListener(listener);
262: TestCase.assertEquals(expectedFeatureCount, listener.count);
263: }
264:
265: return image;
266: }
267:
268: /**
269: * responsible for actually rendering.
270: *
271: * @param obj DOCUMENT ME!
272: * @param g
273: * @param rect DOCUMENT ME!
274: * @param bounds
275: *
276: * @throws IOException
277: */
278: private static void render(Object obj, Graphics g, Rectangle rect,
279: Envelope bounds) throws IOException {
280: if (obj instanceof GTRenderer) {
281: GTRenderer renderer = (GTRenderer) obj;
282:
283: if (bounds == null) {
284: bounds = renderer.getContext().getLayerBounds();
285: }
286:
287: renderer.paint((Graphics2D) g, rect, bounds);
288: }
289: }
290:
291: public static class CountingRenderListener implements
292: RenderListener {
293: public int count = 0;
294:
295: /* (non-Javadoc)
296: * @see org.geotools.renderer.lite.RenderListener#featureRenderer(org.geotools.feature.Feature)
297: */
298: public void featureRenderer(Feature feature) {
299: count++;
300: }
301:
302: /* (non-Javadoc)
303: * @see org.geotools.renderer.lite.RenderListener#errorOccurred(java.lang.Exception)
304: */
305: public void errorOccurred(Exception e) {
306: // TODO Auto-generated method stub
307: }
308: }
309: }
|