Source Code Cross Referenced for EncodeKML.java in  » GIS » GeoServer » org » vfny » geoserver » wms » responses » map » kml » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeoServer » org.vfny.geoserver.wms.responses.map.kml 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org.  All rights reserved.
002:         * This code is licensed under the GPL 2.0 license, availible at the root
003:         * application directory.
004:         */
005:        package org.vfny.geoserver.wms.responses.map.kml;
006:
007:        import com.vividsolutions.jts.geom.Envelope;
008:        import org.geotools.data.DataUtilities;
009:        import org.geotools.data.DefaultQuery;
010:        import org.geotools.data.FeatureSource;
011:        import org.geotools.data.Query;
012:        import org.geotools.factory.CommonFactoryFinder;
013:        import org.geotools.factory.GeoTools;
014:        import org.geotools.feature.AttributeType;
015:        import org.geotools.feature.FeatureCollection;
016:        import org.geotools.feature.FeatureType;
017:        import org.geotools.feature.GeometryAttributeType;
018:        import org.geotools.filter.IllegalFilterException;
019:        import org.geotools.geometry.jts.ReferencedEnvelope;
020:        import org.geotools.image.ImageWorker;
021:        import org.geotools.map.MapContext;
022:        import org.geotools.map.MapLayer;
023:        import org.geotools.referencing.CRS;
024:        import org.geotools.renderer.lite.RendererUtilities;
025:        import org.geotools.renderer.lite.StreamingRenderer;
026:        import org.opengis.filter.Filter;
027:        import org.opengis.filter.FilterFactory;
028:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
029:        import org.vfny.geoserver.wms.WMSMapContext;
030:        import java.awt.AlphaComposite;
031:        import java.awt.Color;
032:        import java.awt.Graphics2D;
033:        import java.awt.Rectangle;
034:        import java.awt.RenderingHints;
035:        import java.awt.geom.AffineTransform;
036:        import java.awt.image.BufferedImage;
037:        import java.io.IOException;
038:        import java.io.OutputStream;
039:        import java.util.ArrayList;
040:        import java.util.HashMap;
041:        import java.util.List;
042:        import java.util.Map;
043:        import java.util.logging.Level;
044:        import java.util.logging.Logger;
045:        import java.util.zip.ZipEntry;
046:        import java.util.zip.ZipOutputStream;
047:        import javax.media.jai.GraphicsJAI;
048:
049:        /**
050:         * @deprecated use {@link KMLTransformer}.
051:         */
052:        public class EncodeKML {
053:            /** Standard Logger */
054:            private static final Logger LOGGER = org.geotools.util.logging.Logging
055:                    .getLogger("org.vfny.geoserver.responses.wms.map.kml");
056:
057:            /** Filter factory for creating bounding box filters */
058:            //private FilterFactory filterFactory = FilterFactoryFinder.createFilterFactory();
059:            /** the XML and KML header */
060:            private static final String KML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\t"
061:                    + "<kml xmlns=\"http://earth.google.com/kml/2.0\">\n";
062:
063:            /** the KML closing element */
064:            private static final String KML_FOOTER = "</kml>\n";
065:
066:            /**
067:             * Map context document - layers, styles aoi etc.
068:             *
069:             * @uml.property name="mapContext"
070:             * @uml.associationEnd multiplicity="(1 1)"
071:             */
072:            private WMSMapContext mapContext;
073:
074:            /**
075:             * Actualy writes the KML out
076:             *
077:             * @uml.property name="writer"
078:             * @uml.associationEnd multiplicity="(0 1)"
079:             */
080:            private KMLWriter writer;
081:
082:            /** Filter factory for creating bounding box filters */
083:            private FilterFactory filterFactory = CommonFactoryFinder
084:                    .getFilterFactory2(GeoTools.getDefaultHints());
085:
086:            /** Flag to be monotored by writer loops */
087:            private boolean abortProcess;
088:
089:            /**
090:             * Creates a new EncodeKML object.
091:             *
092:             * @param mapContext A full description of the map to be encoded.
093:             */
094:            public EncodeKML(WMSMapContext mapContext) {
095:                this .mapContext = mapContext;
096:            }
097:
098:            /**
099:             * Sets the abort flag.  Active encoding may be halted, but this is not garanteed.
100:             */
101:            public void abort() {
102:                abortProcess = true;
103:            }
104:
105:            /**
106:             * Perform the actual encoding.  May return early if abort it called.
107:             *
108:             * @param out Ouput stream to send the data to.
109:             *
110:             * @throws IOException Thrown if anything goes wrong whilst writing
111:             */
112:            public void encodeKML(final OutputStream out) throws IOException {
113:                this .writer = new KMLWriter(out, mapContext);
114:                //once KML supports bbox queries against WMS this can be used to 
115:                //decimate the geometries based on zoom level.
116:                //writer.setMinCoordDistance(env.getWidth() / 1000);
117:                abortProcess = false;
118:
119:                long t = System.currentTimeMillis();
120:
121:                try {
122:                    writeHeader();
123:
124:                    ArrayList layerRenderList = new ArrayList(); // not used in straight KML generation
125:                    writeLayers(false, layerRenderList);
126:                    writeFooter();
127:
128:                    this .writer.flush();
129:                    t = System.currentTimeMillis() - t;
130:                    LOGGER.fine(new StringBuffer("KML generated, it took")
131:                            .append(t).append(" ms").toString());
132:                } catch (IOException ioe) {
133:                    if (abortProcess) {
134:                        LOGGER.fine("KML encoding aborted");
135:
136:                        return;
137:                    } else {
138:                        throw ioe;
139:                    }
140:                } catch (AbortedException ex) {
141:                    return;
142:                }
143:            }
144:
145:            /**
146:             * This method is used to encode kml + images and put all the stuff into a KMZ
147:             * file.
148:             *
149:             * @param out the response is a Zipped output stream
150:             * @throws IOException
151:             */
152:            public void encodeKMZ(final ZipOutputStream out) throws IOException {
153:                this .writer = new KMLWriter(out, mapContext);
154:
155:                abortProcess = false;
156:
157:                long t = System.currentTimeMillis();
158:
159:                try {
160:                    // first we produce the KML file containing the code and the PlaceMarks
161:                    final ZipEntry e = new ZipEntry("wms.kml");
162:                    out.putNextEntry(e);
163:                    writeHeader();
164:
165:                    ArrayList layerRenderList = new ArrayList();
166:                    writeLayers(true, layerRenderList);
167:                    writeFooter();
168:                    this .writer.flush();
169:                    out.closeEntry();
170:
171:                    // then we produce and store all the layer images
172:                    writeImages(out, layerRenderList);
173:
174:                    t = System.currentTimeMillis() - t;
175:                    LOGGER.fine(new StringBuffer("KMZ generated, it took")
176:                            .append(t).append(" ms").toString());
177:                } catch (IOException ioe) {
178:                    if (abortProcess) {
179:                        LOGGER.fine("KMZ encoding aborted");
180:
181:                        return;
182:                    } else {
183:                        throw ioe;
184:                    }
185:                } catch (AbortedException ex) {
186:                    return;
187:                }
188:            }
189:
190:            /**
191:             * Determines whether to return a vector (KML) result of the data or to
192:             * return an image instead.
193:             * If the kmscore is 100, then the output should always be vector. If
194:             * the kmscore is 0, it should always be raster. In between, the number of
195:             * features is weighed against the kmscore value.
196:             * kmscore determines whether to return the features as vectors, or as one
197:             * raster image. It is the point, determined by the user, where X number of
198:             * features is "too many" and the result should be returned as an image instead.
199:             *
200:             * kmscore is logarithmic. The higher the value, the more features it takes
201:             * to make the algorithm return an image. The lower the kmscore, the fewer
202:             * features it takes to force an image to be returned.
203:             * (in use, the formula is exponential: as you increase the KMScore value,
204:             * the number of features required increases exponentially).
205:             *
206:             * @param kmscore the score, between 0 and 100, use to determine what output to use
207:             * @param numFeatures how many features are being rendered
208:             * @return true: use just kml vectors, false: use raster result
209:             */
210:            private boolean useVectorOutput(int kmscore, int numFeatures) {
211:                if (kmscore == 100) {
212:                    return true; // vector KML
213:                }
214:
215:                if (kmscore == 0) {
216:                    return false; // raster KMZ
217:                }
218:
219:                // For numbers in between, determine exponentionally based on kmscore value:
220:                // 10^(kmscore/15)
221:                // This results in exponential growth.
222:                // The lowest bound is 1 feature and the highest bound is 3.98 million features
223:                // The most useful kmscore values are between 20 and 70 (21 and 46000 features respectively)
224:                // A good default kmscore value is around 40 (464 features)
225:                double magic = Math.pow(10, kmscore / 15);
226:
227:                if (numFeatures > magic) {
228:                    return false; // return raster
229:                } else {
230:                    return true; // return vector
231:                }
232:            }
233:
234:            /**
235:             * writes out standard KML header
236:             *
237:             * @throws IOException
238:             */
239:            private void writeHeader() throws IOException {
240:                writer.write(KML_HEADER);
241:            }
242:
243:            /**
244:             * writes out standard KML footer
245:             *
246:             * @throws IOException DOCUMENT ME!
247:             */
248:            private void writeFooter() throws IOException {
249:                writer.write(KML_FOOTER);
250:            }
251:
252:            /**
253:             * Processes each of the layers within the current mapContext in turn.
254:             *
255:             * writeLayers must be called before writeImages in order for the kmScore
256:             * algorithm to work.
257:             *
258:             * @throws IOException
259:             * @throws AbortedException
260:             *
261:             */
262:            private void writeLayers(final boolean kmz,
263:                    ArrayList layerRenderList) throws IOException,
264:                    AbortedException {
265:                MapLayer[] layers = mapContext.getLayers();
266:                int nLayers = layers.length;
267:
268:                final int imageWidth = this .mapContext.getMapWidth();
269:                final int imageHeight = this .mapContext.getMapHeight();
270:
271:                //final CoordinateReferenceSystem requestedCrs = mapContext.getCoordinateReferenceSystem();
272:                //writer.setRequestedCRS(requestedCrs);
273:                //writer.setScreenSize(new Rectangle(imageWidth, imageHeight));
274:                if (nLayers > 1) { // if we have more than one layer, use the name "GeoServer" to group them
275:                    writer.startDocument("GeoServer", null);
276:                }
277:
278:                for (int i = 0; i < nLayers; i++) { // for every layer specified in the request
279:
280:                    MapLayer layer = layers[i];
281:                    writer.startDocument(layer.getTitle(), null);
282:
283:                    //FeatureReader featureReader = null;
284:                    FeatureSource fSource = layer.getFeatureSource();
285:                    FeatureType schema = fSource.getSchema();
286:
287:                    //GeometryAttributeType geometryAttribute = schema.getDefaultGeometry();
288:                    //CoordinateReferenceSystem sourceCrs = geometryAttribute.getCoordinateSystem();
289:                    Rectangle paintArea = new Rectangle(imageWidth, imageHeight);
290:                    AffineTransform worldToScreen = RendererUtilities
291:                            .worldToScreenTransform(mapContext
292:                                    .getAreaOfInterest(), paintArea);
293:                    double scaleDenominator = 1;
294:
295:                    try {
296:                        scaleDenominator = RendererUtilities.calculateScale(
297:                                mapContext.getAreaOfInterest(), mapContext
298:                                        .getCoordinateReferenceSystem(),
299:                                paintArea.width, paintArea.height, 90); // 90 = OGC standard DPI (see SLD spec page 37)
300:                    } catch (Exception e) // probably either (1) no CRS (2) error xforming
301:                    {
302:                        scaleDenominator = 1 / worldToScreen.getScaleX(); //DJB old method - the best we can do
303:                    }
304:
305:                    writer.setRequestedScale(scaleDenominator);
306:
307:                    String[] attributes;
308:                    boolean isRaster = false;
309:
310:                    AttributeType[] ats = schema.getAttributeTypes();
311:                    final int length = ats.length;
312:                    attributes = new String[length];
313:
314:                    for (int t = 0; t < length; t++) {
315:                        attributes[t] = ats[t].getName();
316:
317:                        if (attributes[t].equals("grid")) {
318:                            isRaster = true;
319:                        }
320:                    }
321:
322:                    try {
323:                        CoordinateReferenceSystem sourceCrs = schema
324:                                .getDefaultGeometry().getCoordinateSystem();
325:                        writer.setSourceCrs(sourceCrs); // it seems to work better getting it from the schema, here
326:
327:                        Envelope envelope = mapContext.getAreaOfInterest();
328:                        ReferencedEnvelope aoi = new ReferencedEnvelope(
329:                                envelope, mapContext
330:                                        .getCoordinateReferenceSystem());
331:
332:                        Filter filter = null;
333:
334:                        //ReferencedEnvelope aoi = mapContext.getAreaOfInterest();
335:                        if (!CRS.equalsIgnoreMetadata(aoi
336:                                .getCoordinateReferenceSystem(), schema
337:                                .getDefaultGeometry().getCoordinateSystem())) {
338:                            aoi = aoi.transform(schema.getDefaultGeometry()
339:                                    .getCoordinateSystem(), true);
340:                        }
341:
342:                        filter = createBBoxFilters(schema, attributes, aoi);
343:
344:                        // now build the query using only the attributes and the bounding
345:                        // box needed
346:                        DefaultQuery q = new DefaultQuery(schema.getTypeName());
347:                        q.setFilter(filter);
348:                        q.setPropertyNames(attributes);
349:
350:                        // now, if a definition query has been established for this layer, be
351:                        // sure to respect it by combining it with the bounding box one.
352:                        Query definitionQuery = layer.getQuery();
353:
354:                        if (definitionQuery != Query.ALL) {
355:                            if (q == Query.ALL) {
356:                                q = (DefaultQuery) definitionQuery;
357:                            } else {
358:                                q = (DefaultQuery) DataUtilities.mixQueries(
359:                                        definitionQuery, q, "KMLEncoder");
360:                            }
361:                        }
362:
363:                        q.setCoordinateSystem(layer.getFeatureSource()
364:                                .getSchema().getDefaultGeometry()
365:                                .getCoordinateSystem());
366:
367:                        FeatureCollection fc = fSource.getFeatures(q);
368:
369:                        int kmscore = mapContext.getRequest().getKMScore(); //KMZ score value
370:                        boolean useVector = useVectorOutput(kmscore, fc.size()); // kmscore = render vector/raster
371:
372:                        if (useVector || !kmz) {
373:                            LOGGER.info("Layer (" + layer.getTitle()
374:                                    + ") rendered with KML vector output.");
375:                            layerRenderList.add(new Integer(i)); // save layer number so it won't be rendered
376:
377:                            if (!isRaster) {
378:                                writer.writeFeaturesAsVectors(fc, layer); // vector
379:                            } else {
380:                                writer.writeCoverages(fc, layer); // coverage
381:                            }
382:                        } else {
383:                            // user requested KMZ and kmscore says render raster
384:                            LOGGER.info("Layer (" + layer.getTitle()
385:                                    + ") rendered with KMZ raster output.");
386:                            // layer order is only needed for raster results. In the <GroundOverlay> tag 
387:                            // you need to point to a raster image, this image has the layer number as
388:                            // part of the name. The kml will then reference the image via the layer number
389:                            writer.writeFeaturesAsRaster(fc, layer, i); // raster
390:                        }
391:
392:                        LOGGER.fine("finished writing");
393:                    } catch (IOException ex) {
394:                        LOGGER.info(new StringBuffer("process failed: ")
395:                                .append(ex.getMessage()).toString());
396:                        throw ex;
397:                    } catch (AbortedException ae) {
398:                        LOGGER.info(new StringBuffer("process aborted: ")
399:                                .append(ae.getMessage()).toString());
400:                        throw ae;
401:                    } catch (Throwable t) {
402:                        LOGGER.warning(new StringBuffer("UNCAUGHT exception: ")
403:                                .append(t.getMessage()).toString());
404:
405:                        IOException ioe = new IOException(new StringBuffer(
406:                                "UNCAUGHT exception: ").append(t.getMessage())
407:                                .toString());
408:                        ioe.setStackTrace(t.getStackTrace());
409:                        throw ioe;
410:                    } finally {
411:                        /*if (featureReader != null) {
412:                            try{
413:                                featureReader.close();
414:                            }catch(IOException ioe){
415:                                //featureReader was probably closed already.
416:                            }
417:                        }*/
418:                    }
419:
420:                    writer.endDocument();
421:                }
422:
423:                if (nLayers > 1) {
424:                    writer.endDocument();
425:                }
426:            }
427:
428:            /**
429:             * This method produces and stores PNG images of all map layers using the StreamingRenderer and JAI Encoder.
430:             *
431:             * @param outZ
432:             * @throws IOException
433:             * @throws AbortedException
434:             */
435:            private void writeImages(final ZipOutputStream outZ,
436:                    ArrayList layerRenderList) throws IOException,
437:                    AbortedException {
438:                MapLayer[] layers = this .mapContext.getLayers();
439:                int nLayers = layers.length;
440:
441:                for (int i = 0; i < nLayers; i++) {
442:                    if (layerRenderList.size() > 0) {
443:                        int num = ((Integer) layerRenderList.get(0)).intValue();
444:
445:                        if (num == i) { // if this layer is a layer that doesn't need to be rendered, move to next layer
446:                            layerRenderList.remove(0);
447:
448:                            continue;
449:                        }
450:                    }
451:
452:                    final MapLayer layer = layers[i];
453:                    MapContext map = this .mapContext;
454:                    map.clearLayerList();
455:                    map.addLayer(layer);
456:
457:                    final int width = this .mapContext.getMapWidth();
458:                    final int height = this .mapContext.getMapHeight();
459:
460:                    LOGGER.fine(new StringBuffer("setting up ").append(width)
461:                            .append("x").append(height).append(" image")
462:                            .toString());
463:
464:                    // simone: ARGB should be much better
465:                    BufferedImage curImage = new BufferedImage(width, height,
466:                            BufferedImage.TYPE_4BYTE_ABGR);
467:
468:                    // simboss: this should help out with coverages
469:                    final Graphics2D graphic = GraphicsJAI.createGraphicsJAI(
470:                            curImage.createGraphics(), null);
471:
472:                    LOGGER.fine("setting to transparent");
473:
474:                    int type = AlphaComposite.SRC;
475:                    graphic.setComposite(AlphaComposite.getInstance(type));
476:
477:                    Color c = new Color(this .mapContext.getBgColor().getRed(),
478:                            this .mapContext.getBgColor().getGreen(),
479:                            this .mapContext.getBgColor().getBlue(), 0);
480:
481:                    //LOGGER.info("****** bg color: "+c.getRed()+","+c.getGreen()+","+c.getBlue()+","+c.getAlpha()+", trans: "+c.getTransparency());
482:                    graphic.setBackground(this .mapContext.getBgColor());
483:                    graphic.setColor(c);
484:                    graphic.fillRect(0, 0, width, height);
485:
486:                    type = AlphaComposite.SRC_OVER;
487:                    graphic.setComposite(AlphaComposite.getInstance(type));
488:
489:                    Rectangle paintArea = new Rectangle(width, height);
490:
491:                    final StreamingRenderer renderer = new StreamingRenderer();
492:                    renderer.setContext(map);
493:
494:                    RenderingHints hints = new RenderingHints(
495:                            RenderingHints.KEY_ANTIALIASING,
496:                            RenderingHints.VALUE_ANTIALIAS_ON);
497:                    renderer.setJava2DHints(hints);
498:
499:                    // we already do everything that the optimized data loading does...
500:                    // if we set it to true then it does it all twice...
501:                    Map rendererParams = new HashMap();
502:                    rendererParams.put("optimizedDataLoadingEnabled",
503:                            Boolean.TRUE);
504:                    rendererParams.put("renderingBuffer", new Integer(
505:                            mapContext.getBuffer()));
506:                    renderer.setRendererHints(rendererParams);
507:
508:                    Envelope dataArea = map.getAreaOfInterest();
509:                    AffineTransform at = RendererUtilities
510:                            .worldToScreenTransform(dataArea, paintArea);
511:                    renderer.paint(graphic, paintArea, dataArea, at);
512:                    graphic.dispose();
513:
514:                    // /////////////////////////////////////////////////////////////////
515:                    //
516:                    // Storing Image ...
517:                    //
518:                    // /////////////////////////////////////////////////////////////////
519:                    final ZipEntry e = new ZipEntry("layer_" + (i) + ".png");
520:                    outZ.putNextEntry(e);
521:                    new ImageWorker(curImage).writePNG(outZ, "FILTERED", 0.75f,
522:                            false, false);
523:                    //final MemoryCacheImageOutputStream memOutStream = new MemoryCacheImageOutputStream(outZ);
524:                    /*final PlanarImage encodedImage = PlanarImage
525:                                    .wrapRenderedImage(curImage);
526:                    //final PlanarImage finalImage = encodedImage.getColorModel() instanceof DirectColorModel?ImageUtilities
527:                    //                .reformatColorModel2ComponentColorModel(encodedImage):encodedImage;
528:                    final PlanarImage finalImage = encodedImage;
529:                    final Iterator it = ImageIO.getImageWritersByMIMEType("image/png");
530:                    ImageWriter imgWriter = null;
531:                    if (!it.hasNext()) {
532:                            LOGGER.warning("No PNG ImageWriter found");
533:                            throw new IllegalStateException("No PNG ImageWriter found");
534:                    } else
535:                            imgWriter = (ImageWriter) it.next();
536:                     */
537:
538:                    //---------------------- bo- new
539:                    //			PngEncoderB png = new PngEncoderB(curImage, PngEncoder.ENCODE_ALPHA, 0, 1);
540:                    //			byte[] pngbytes = png.pngEncode();
541:                    //			memOutStream.write(pngbytes);
542:                    //----------------------
543:                    //imgWriter.setOutput(memOutStream);
544:                    //imgWriter.write(null, new IIOImage(finalImage, null, null), null);
545:                    //memOutStream.flush();
546:                    //memOutStream.close();
547:                    //imgWriter.dispose();
548:                    outZ.closeEntry();
549:                }
550:            }
551:
552:            /**
553:             * Creates the bounding box filters (one for each geometric attribute) needed to query a
554:             * <code>MapLayer</code>'s feature source to return just the features for the target
555:             * rendering extent
556:             *
557:             * @param schema the layer's feature source schema
558:             * @param attributes set of needed attributes
559:             * @param bbox the rendering bounding box
560:             * @return an or'ed list of bbox filters, one for each geometric attribute in
561:             *         <code>attributes</code>. If there are just one geometric attribute, just returns
562:             *         its corresponding <code>GeometryFilter</code>.
563:             * @throws IllegalFilterException if something goes wrong creating the filter
564:             */
565:            private Filter createBBoxFilters(FeatureType schema,
566:                    String[] attributes, Envelope bbox)
567:                    throws IllegalFilterException {
568:                List filters = new ArrayList();
569:                final int length = attributes.length;
570:                for (int j = 0; j < length; j++) {
571:                    AttributeType attType = schema
572:                            .getAttributeType(attributes[j]);
573:
574:                    //DJB: added this for better error messages!
575:                    if (attType == null) {
576:                        if (LOGGER.isLoggable(Level.FINE)) {
577:                            LOGGER.fine(new StringBuffer("Could not find '")
578:                                    .append(attributes[j]).append(
579:                                            "' in the FeatureType (").append(
580:                                            schema.getTypeName()).append(")")
581:                                    .toString());
582:                        }
583:
584:                        throw new IllegalFilterException(new StringBuffer(
585:                                "Could not find '").append(
586:                                attributes[j] + "' in the FeatureType (")
587:                                .append(schema.getTypeName()).append(")")
588:                                .toString());
589:                    }
590:
591:                    if (attType instanceof  GeometryAttributeType) {
592:                        Filter gfilter = filterFactory.bbox(attType
593:                                .getLocalName(), bbox.getMinX(),
594:                                bbox.getMinY(), bbox.getMaxX(), bbox.getMaxY(),
595:                                null);
596:                        filters.add(gfilter);
597:                    }
598:                }
599:
600:                if (filters.size() == 0)
601:                    return Filter.INCLUDE;
602:                else if (filters.size() == 1)
603:                    return (Filter) filters.get(0);
604:                else
605:                    return filterFactory.or(filters);
606:            }
607:        }
w__w_w___._j___a__v___a___2_s__.__c___o___m__ | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.