Source Code Cross Referenced for ArcGridWriter.java in  » GIS » GeoTools-2.4.1 » org » geotools » gce » arcgrid » 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 » GeoTools 2.4.1 » org.geotools.gce.arcgrid 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.gce.arcgrid;
018:
019:        import it.geosolutions.imageio.plugins.arcgrid.AsciiGridsImageMetadata;
020:        import it.geosolutions.imageio.plugins.arcgrid.AsciiGridsImageWriter;
021:        import it.geosolutions.imageio.plugins.arcgrid.spi.AsciiGridsImageWriterSpi;
022:
023:        import java.awt.geom.AffineTransform;
024:        import java.awt.image.RenderedImage;
025:        import java.io.BufferedWriter;
026:        import java.io.File;
027:        import java.io.FileWriter;
028:        import java.io.IOException;
029:        import java.io.OutputStream;
030:        import java.io.UnsupportedEncodingException;
031:        import java.net.URL;
032:        import java.net.URLDecoder;
033:        import java.util.Iterator;
034:        import java.util.List;
035:        import java.util.logging.Level;
036:        import java.util.logging.Logger;
037:
038:        import javax.imageio.IIOImage;
039:        import javax.imageio.ImageIO;
040:        import javax.imageio.stream.ImageOutputStream;
041:        import javax.media.jai.Interpolation;
042:
043:        import org.geotools.coverage.Category;
044:        import org.geotools.coverage.GridSampleDimension;
045:        import org.geotools.coverage.grid.GeneralGridRange;
046:        import org.geotools.coverage.grid.GridCoverage2D;
047:        import org.geotools.coverage.grid.GridGeometry2D;
048:        import org.geotools.coverage.grid.io.AbstractGridCoverageWriter;
049:        import org.geotools.coverage.grid.io.AbstractGridFormat;
050:        import org.geotools.coverage.grid.io.imageio.GeoToolsWriteParams;
051:        import org.geotools.coverage.processing.DefaultProcessor;
052:        import org.geotools.coverage.processing.operation.Resample;
053:        import org.geotools.coverage.processing.operation.SelectSampleDimension;
054:        import org.geotools.data.DataSourceException;
055:        import org.geotools.factory.Hints;
056:        import org.geotools.geometry.GeneralEnvelope;
057:        import org.geotools.parameter.Parameter;
058:        import org.geotools.referencing.operation.matrix.XAffineTransform;
059:        import org.geotools.resources.coverage.CoverageUtilities;
060:        import org.geotools.resources.i18n.Vocabulary;
061:        import org.geotools.resources.i18n.VocabularyKeys;
062:        import org.opengis.coverage.grid.Format;
063:        import org.opengis.coverage.grid.GridCoverage;
064:        import org.opengis.coverage.grid.GridCoverageWriter;
065:        import org.opengis.geometry.Envelope;
066:        import org.opengis.parameter.GeneralParameterValue;
067:        import org.opengis.parameter.ParameterValueGroup;
068:        import org.opengis.referencing.crs.CoordinateReferenceSystem;
069:        import org.opengis.referencing.cs.AxisDirection;
070:
071:        /**
072:         * {@link ArcGridWriter} supports writing of an ArcGrid GridCoverage to a
073:         * Desination object
074:         * 
075:         * XXX We cannot write a rotated grid coverage, we have to enforce that!
076:         * 
077:         * @author Daniele Romagnoli
078:         * @author Simone Giannecchini (simboss)
079:         */
080:        public final class ArcGridWriter extends AbstractGridCoverageWriter
081:                implements  GridCoverageWriter {
082:            /** Logger. */
083:            private final static Logger LOGGER = org.geotools.util.logging.Logging
084:                    .getLogger("org.geotools.gce.arcgrid");
085:
086:            /** Imageio {@link AsciiGridsImageWriter} we will use to write out. */
087:            private AsciiGridsImageWriter mWriter = new AsciiGridsImageWriter(
088:                    new AsciiGridsImageWriterSpi());
089:
090:            /** Default {@link ParameterValueGroup} for doing a bandselect. */
091:            private final static ParameterValueGroup bandSelectParams;
092:
093:            /** Default {@link ParameterValueGroup} for doing a reshape. */
094:            private final static ParameterValueGroup reShapeParams;
095:
096:            /** Caching a {@link Resample} operation. */
097:            private static final Resample resampleFactory = new Resample();
098:
099:            /** Caching a {@link SelectSampleDimension} operation. */
100:            private static final SelectSampleDimension bandSelectFactory = new SelectSampleDimension();
101:            static {
102:                DefaultProcessor processor = new DefaultProcessor(new Hints(
103:                        Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE));
104:                bandSelectParams = (ParameterValueGroup) processor
105:                        .getOperation("SelectSampleDimension").getParameters();
106:
107:                reShapeParams = (ParameterValueGroup) processor.getOperation(
108:                        "Resample").getParameters();
109:            }
110:
111:            /** Small number for comparisons of angles in this pugin. */
112:            private static final double ROTATION_EPS = 1E-3;
113:
114:            /** The band of the provided coverage that we want to write down. */
115:            private int writeBand = -1;
116:
117:            /**
118:             * Takes either a URL or a String that points to an ArcGridCoverage file and
119:             * converts it to a URL that can then be written to.
120:             * 
121:             * @param destination
122:             *            the URL or String pointing to the file to load the ArcGrid
123:             * @throws DataSourceException
124:             */
125:            public ArcGridWriter(Object destination) throws DataSourceException {
126:                this (destination, null);
127:            }
128:
129:            /**
130:             * Takes either a URL or a String that points to an ArcGridCoverage file and
131:             * converts it to a URL that can then be written to.
132:             * 
133:             * @param destination
134:             *            the URL or String pointing to the file to load the ArcGrid
135:             * @throws DataSourceException
136:             */
137:            public ArcGridWriter(Object destination, Hints hints)
138:                    throws DataSourceException {
139:                this .destination = destination;
140:                if (destination instanceof  File)
141:                    try {
142:                        super .outStream = ImageIO
143:                                .createImageOutputStream(destination);
144:                    } catch (IOException e) {
145:                        if (LOGGER.isLoggable(Level.SEVERE))
146:                            LOGGER
147:                                    .log(Level.SEVERE, e.getLocalizedMessage(),
148:                                            e);
149:                        throw new DataSourceException(e);
150:                    }
151:                else if (destination instanceof  URL) {
152:                    final URL dest = (URL) destination;
153:                    if (dest.getProtocol().equalsIgnoreCase("file")) {
154:                        File destFile;
155:                        try {
156:                            destFile = new File(URLDecoder.decode(dest
157:                                    .getFile(), "UTF-8"));
158:                        } catch (UnsupportedEncodingException e) {
159:                            if (LOGGER.isLoggable(Level.SEVERE))
160:                                LOGGER.log(Level.SEVERE, e
161:                                        .getLocalizedMessage(), e);
162:                            throw new DataSourceException(e);
163:                        }
164:                        try {
165:                            super .outStream = ImageIO
166:                                    .createImageOutputStream(destFile);
167:                        } catch (IOException e) {
168:                            if (LOGGER.isLoggable(Level.SEVERE))
169:                                LOGGER.log(Level.SEVERE, e
170:                                        .getLocalizedMessage(), e);
171:                            throw new DataSourceException(e);
172:                        }
173:                    }
174:
175:                } else if (destination instanceof  OutputStream) {
176:
177:                    try {
178:                        super .outStream = ImageIO
179:                                .createImageOutputStream((OutputStream) destination);
180:                    } catch (IOException e) {
181:                        if (LOGGER.isLoggable(Level.SEVERE))
182:                            LOGGER
183:                                    .log(Level.SEVERE, e.getLocalizedMessage(),
184:                                            e);
185:                        throw new DataSourceException(e);
186:                    }
187:
188:                } else if (destination instanceof  ImageOutputStream)
189:                    this .destination = outStream = (ImageOutputStream) destination;
190:                else
191:                    throw new DataSourceException(
192:                            "The provided destination cannot be used!");
193:                // //
194:                //
195:                // managing hints
196:                //
197:                // //
198:                if (hints != null) {
199:                    if (this .hints == null) {
200:                        this .hints = new Hints(Hints.LENIENT_DATUM_SHIFT,
201:                                Boolean.TRUE);
202:                    }
203:                    this .hints.add(hints);
204:                }
205:            }
206:
207:            /**
208:             * Creates a Format object describing the Arc Grid Format
209:             * 
210:             * @return the format of the data source we will write to. (ArcGridFormat in
211:             *         this case)
212:             * 
213:             * @see org.opengis.coverage.grid.GridCoverageWriter#getFormat()
214:             */
215:            public Format getFormat() {
216:                return new ArcGridFormat();
217:            }
218:
219:            /**
220:             * This method was copied from ArcGridData source
221:             * 
222:             * @param gc
223:             *            the grid coverage that will be written to the destination
224:             * @param parameters
225:             *            to control this writing process
226:             * @param grass
227:             *            tells me whether to write this coverage in the grass format.
228:             * 
229:             * @throws DataSourceException
230:             *             indicates an unexpected exception
231:             */
232:            private void writeGridCoverage(GridCoverage2D gc,
233:                    GeneralParameterValue[] parameters)
234:                    throws DataSourceException {
235:                try {
236:                    // /////////////////////////////////////////////////////////////////////
237:                    //
238:                    // Checking writing params
239:                    //
240:                    // /////////////////////////////////////////////////////////////////////
241:                    GeoToolsWriteParams gtParams = null;
242:                    boolean grass = false;
243:                    boolean forceCellSize = false;
244:                    final String grassParam = ArcGridFormat.GRASS.getName()
245:                            .getCode().toString();
246:                    final String cellSizeParam = ArcGridFormat.FORCE_CELLSIZE
247:                            .getName().getCode().toString();
248:                    if (parameters != null) {
249:                        for (int i = 0; i < parameters.length; i++) {
250:                            Parameter param = (Parameter) parameters[i];
251:                            String name = param.getDescriptor().getName()
252:                                    .toString();
253:                            if (param
254:                                    .getDescriptor()
255:                                    .getName()
256:                                    .getCode()
257:                                    .equals(
258:                                            AbstractGridFormat.GEOTOOLS_WRITE_PARAMS
259:                                                    .getName().toString())) {
260:                                gtParams = (GeoToolsWriteParams) param
261:                                        .getValue();
262:                            }
263:                            if (name.equalsIgnoreCase(grassParam))
264:                                grass = param.booleanValue();
265:                            if (name.equalsIgnoreCase(cellSizeParam))
266:                                forceCellSize = param.booleanValue();
267:                        }
268:                    }
269:                    if (gtParams == null)
270:                        gtParams = new ArcGridWriteParams();
271:                    // write band
272:                    int[] writeBands = gtParams.getSourceBands();
273:                    writeBand = CoverageUtilities.getVisibleBand(gc
274:                            .getRenderedImage());
275:                    if ((writeBands == null || writeBands.length == 0 || writeBands.length > 1)
276:                            && (writeBand < 0 || writeBand > gc
277:                                    .getNumSampleDimensions()))
278:                        throw new IllegalArgumentException(
279:                                "You need to supply a valid index for deciding which band to write.");
280:                    if (!((writeBands == null || writeBands.length == 0 || writeBands.length > 1)))
281:                        writeBand = writeBands[0];
282:
283:                    // /////////////////////////////////////////////////////////////////
284:                    //
285:                    // Getting CRS and envelope information
286:                    //
287:                    // /////////////////////////////////////////////////////////////////
288:                    final CoordinateReferenceSystem crs = gc
289:                            .getCoordinateReferenceSystem2D();
290:
291:                    // /////////////////////////////////////////////////////////////////
292:                    //
293:                    // getting visible band, if needed
294:                    // /////////////////////////////////////////////////////////////////
295:                    final int numBands = gc.getNumSampleDimensions();
296:                    if (numBands > 1) {
297:                        final int visibleBand;
298:                        if (writeBand > 0 && writeBand < numBands)
299:                            visibleBand = writeBand;
300:                        else
301:                            visibleBand = CoverageUtilities.getVisibleBand(gc);
302:
303:                        final ParameterValueGroup param = (ParameterValueGroup) ArcGridWriter.bandSelectParams
304:                                .clone();
305:                        param.parameter("source").setValue(gc);
306:                        param.parameter("SampleDimensions").setValue(
307:                                new int[] { visibleBand });
308:                        gc = (GridCoverage2D) bandSelectFactory.doOperation(
309:                                param, null);
310:                    }
311:                    // /////////////////////////////////////////////////////////////////
312:                    //
313:                    // checking if the coverage needs to be resampled in order to have
314:                    // square pixels for the esri format
315:                    //
316:                    // /////////////////////////////////////////////////////////////////
317:                    if (!grass && forceCellSize)
318:                        gc = reShapeData(gc);
319:
320:                    // /////////////////////////////////////////////////////////////////
321:                    //
322:                    // Preparing to write header information
323:                    //
324:                    // /////////////////////////////////////////////////////////////////
325:                    // getting the new envelope after the reshaping
326:                    final Envelope newEnv = gc.getEnvelope2D();
327:
328:                    // trying to prepare the header
329:                    final AffineTransform gridToWorld = (AffineTransform) ((GridGeometry2D) gc
330:                            .getGridGeometry()).getGridToCRS2D();
331:                    final double xl = newEnv.getLowerCorner().getOrdinate(0);
332:                    final double yl = newEnv.getLowerCorner().getOrdinate(1);
333:                    final double cellsizeX = Math.abs(gridToWorld.getScaleX());
334:                    final double cellsizeY = Math.abs(gridToWorld.getScaleY());
335:
336:                    // /////////////////////////////////////////////////////////////////
337:                    //	
338:                    // Preparing source image and metadata
339:                    //
340:                    // /////////////////////////////////////////////////////////////////
341:                    final RenderedImage source = gc.getRenderedImage();
342:                    final int cols = source.getWidth();
343:                    final int rows = source.getHeight();
344:
345:                    // Preparing main parameters for JAI imageWrite Operation
346:                    // //
347:                    // Setting Output
348:                    // //
349:                    //mWriter.reset();
350:                    mWriter.setOutput(outStream);
351:
352:                    // //
353:                    // no data management
354:                    // //
355:                    double inNoData = getCandidateNoData(gc);
356:
357:                    // //
358:                    // Construct a proper asciiGridRaster which supports metadata
359:                    // setting
360:                    // //
361:
362:                    // Setting the source for the image write operation
363:                    mWriter.write(null, new IIOImage(source, null,
364:                            new AsciiGridsImageMetadata(cols, rows, cellsizeX,
365:                                    cellsizeY, xl, yl, true, grass, inNoData)),
366:                            null);
367:
368:                    // writing crs info
369:                    writeCRSInfo(crs);
370:
371:                    // /////////////////////////////////////////////////////////////////
372:                    //
373:                    // Creating the imageWrite Operation
374:                    //
375:                    // /////////////////////////////////////////////////////////////////
376:                    mWriter.dispose();
377:                    // TODO: Auto-dispose. Maybe I need to allow a manual dispose call?
378:                } catch (IOException e) {
379:                    if (LOGGER.isLoggable(Level.SEVERE))
380:                        LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
381:                    throw new DataSourceException(e);
382:                }
383:            }
384:
385:            /**
386:             * Resampling the raster in order to have square pixels instead of
387:             * rectangular which are not suitable for an Esrii ascii grid.
388:             * 
389:             * @param gc
390:             *            Input coverage.
391:             * @return A new coverage with square pixels.
392:             */
393:            private GridCoverage2D reShapeData(GridCoverage2D gc) {
394:
395:                // /////////////////////////////////////////////////////////////////////
396:                //
397:                // Getting the dx and dy for this coverage and checking if they differ
398:                // so much that we need to reshape in order to have square pixels
399:                //
400:                // /////////////////////////////////////////////////////////////////////
401:                final AffineTransform gridToWorld = (AffineTransform) ((GridGeometry2D) gc
402:                        .getGridGeometry()).getGridToCRS2D();
403:                final double dx = XAffineTransform.getScaleX0(gridToWorld);
404:                final double dy = XAffineTransform.getScaleY0(gridToWorld);
405:                if (AsciiGridsImageWriter.resolutionCheck(dx, dy,
406:                        AsciiGridsImageWriter.EPS)) {
407:                    return gc;
408:                }
409:
410:                // /////////////////////////////////////////////////////////////////////
411:                //
412:                // Getting info about the original image in order to create the new
413:                // gridgeometry
414:                //
415:                // /////////////////////////////////////////////////////////////////////
416:                final RenderedImage image = gc.getRenderedImage();
417:                int Nx = image.getWidth();
418:                int Ny = image.getHeight();
419:                final double _Nx;
420:                final double _Ny;
421:
422:                // /////////////////////////////////////////////////////////////////////
423:                //
424:                // Getting info about the original evelope n order to create the new
425:                // gridgeometry
426:                //
427:                // /////////////////////////////////////////////////////////////////////
428:                final Envelope oldEnv = gc.getEnvelope2D();
429:                final double W = oldEnv.getLength(0);
430:                final double H = oldEnv.getLength(1);
431:                if ((dx - dy) > ArcGridWriter.ROTATION_EPS) {
432:                    /**
433:                     * we have higher resolution on the Y axis we have to increase it on
434:                     * the X axis as well.
435:                     */
436:
437:                    // new number of columns
438:                    _Nx = W / dy;
439:                    Nx = (int) (_Nx + 0.5);
440:                } else {
441:                    /**
442:                     * we have higher resolution on the X axis we have to increase it on
443:                     * the Y axis as well.
444:                     */
445:
446:                    // new number of rows
447:                    _Ny = H / dx;
448:                    Ny = (int) (_Ny + 0.5);
449:                }
450:
451:                // new grid range
452:                final GeneralGridRange newGridrange = new GeneralGridRange(
453:                        new int[] { 0, 0 }, new int[] { Nx, Ny });
454:                final GridGeometry2D newGridGeometry = new GridGeometry2D(
455:                        newGridrange, new GeneralEnvelope(gc.getEnvelope()));
456:
457:                // /////////////////////////////////////////////////////////////////////
458:                //
459:                // Reshaping using the resample operation for having best precision.
460:                //
461:                // /////////////////////////////////////////////////////////////////////
462:                final ParameterValueGroup param = (ParameterValueGroup) reShapeParams
463:                        .clone();
464:                param.parameter("source").setValue(gc);
465:                param.parameter("CoordinateReferenceSystem").setValue(
466:                        gc.getCoordinateReferenceSystem2D());
467:                param.parameter("GridGeometry").setValue(newGridGeometry);
468:                param
469:                        .parameter("InterpolationType")
470:                        .setValue(
471:                                Interpolation
472:                                        .getInstance(Interpolation.INTERP_NEAREST));
473:                return (GridCoverage2D) resampleFactory.doOperation(param,
474:                        hints);
475:            }
476:
477:            /**
478:             * Writing {@link CoordinateReferenceSystem} WKT representation on a prj
479:             * file.
480:             * 
481:             * @param crs
482:             *            the {@link CoordinateReferenceSystem} to be written out.
483:             * 
484:             * @throws IOException
485:             */
486:            private void writeCRSInfo(CoordinateReferenceSystem crs)
487:                    throws IOException {
488:                // is it null?
489:                if (crs == null) {
490:                    throw new IllegalArgumentException("CRS cannot be null!");
491:                }
492:
493:                // get the destination path
494:                // getting the path of this object and the name
495:                URL url = null;
496:                String pathname = null;
497:                String name = null;
498:
499:                if (this .destination instanceof  String) {
500:                    url = (new File((String) this .destination)).toURL();
501:                    pathname = url.getPath().substring(0,
502:                            url.getPath().lastIndexOf("/") + 1);
503:                    name = url.getPath().substring(
504:                            url.getPath().lastIndexOf("/") + 1,
505:                            url.getPath().length());
506:                } else if (this .destination instanceof  File) {
507:                    url = ((File) this .destination).toURL();
508:                    pathname = url.getPath().substring(0,
509:                            url.getPath().lastIndexOf("/") + 1);
510:                    name = url.getPath().substring(
511:                            url.getPath().lastIndexOf("/") + 1,
512:                            url.getPath().length());
513:                } else if (this .destination instanceof  URL) {
514:                    url = (URL) this .destination;
515:                    pathname = url.getPath().substring(0,
516:                            url.getPath().lastIndexOf("/") + 1);
517:                    name = url.getPath().substring(
518:                            url.getPath().lastIndexOf("/") + 1,
519:                            url.getPath().length());
520:                } else {
521:                    // do nothing for the moment
522:                    return;
523:                }
524:
525:                // build up the name
526:                name = new StringBuffer(pathname).append(
527:                        ((name.indexOf(".") > 0) ? name.substring(0, name
528:                                .indexOf(".")) : name)).append(".prj")
529:                        .toString();
530:
531:                // create the file
532:                final BufferedWriter fileWriter = new BufferedWriter(
533:                        new FileWriter(name));
534:
535:                // write information on crs
536:                fileWriter.write(crs.toWKT());
537:                fileWriter.close();
538:            }
539:
540:            /**
541:             * Note: The geotools GridCoverage class does not implement the geoAPI
542:             * GridCoverage Interface so this method shows an error. All other methods
543:             * are using the geotools GridCoverage class
544:             * 
545:             * @see org.opengis.coverage.grid.GridCoverageWriter#write(org.opengis.coverage.grid.GridCoverage,
546:             *      org.opengis.parameter.GeneralParameterValue[])
547:             */
548:            public void write(GridCoverage coverage,
549:                    GeneralParameterValue[] parameters)
550:                    throws IllegalArgumentException, IOException {
551:                ensureWeCanWrite(coverage, parameters);
552:                writeGridCoverage((GridCoverage2D) coverage, parameters);
553:
554:            }
555:
556:            /**
557:             * Ascii grids have a few limitations.
558:             * 
559:             * <ol>
560:             * <li>The gridcoverage they contain must have a gridToWorld transform
561:             * which is a compositions of scale and translate, no skew, no rotation.</li>
562:             * <li>The PRJ must be lon-lat (this is an assumption form real world).</li>
563:             * </ol>
564:             * 
565:             * @param coverage
566:             *            to check for the possibility to be written b this writer.
567:             * @param parameters
568:             *            to control the writing process.
569:             * @throws IOException
570:             */
571:            private void ensureWeCanWrite(GridCoverage coverage,
572:                    GeneralParameterValue[] parameters) throws IOException {
573:                // /////////////////////////////////////////////////////////////////////
574:                //
575:                // RULE 1
576:                //
577:                // Checking the grid to world transform for having only scale and
578:                // translate.
579:                //
580:                // /////////////////////////////////////////////////////////////////////
581:                final AffineTransform gridToWorldTransform = new AffineTransform(
582:                        (AffineTransform) ((GridGeometry2D) coverage
583:                                .getGridGeometry()).getGridToCRS2D());
584:
585:                final int swapXY = XAffineTransform
586:                        .getSwapXY(gridToWorldTransform);
587:                XAffineTransform.round(gridToWorldTransform, ROTATION_EPS);
588:                final double rotation = XAffineTransform
589:                        .getRotation(gridToWorldTransform);
590:                if (swapXY == -1)
591:                    throw new DataSourceException(
592:                            "Impossible to encode this coverage as an ascii grid since its"
593:                                    + "transformation is not a simple scale and translate");
594:                if (rotation != 0)
595:                    throw new DataSourceException(
596:                            "Impossible to encode this coverage as an ascii grid since its"
597:                                    + "transformation is not a simple scale and translate");
598:
599:                // /////////////////////////////////////////////////////////////////////
600:                //
601:                // RULE 2
602:                //
603:                // Checking the CRS to have flip only at first axis
604:                //
605:                // /////////////////////////////////////////////////////////////////////
606:                final int flip = XAffineTransform.getFlip(gridToWorldTransform);
607:                final CoordinateReferenceSystem crs2D = ((GridCoverage2D) coverage)
608:                        .getCoordinateReferenceSystem2D();
609:                // flip==-1 means there is a flip.
610:                if (flip > 0)
611:                    throw new DataSourceException(
612:                            "Impossible to encode this coverage as an ascii grid since its"
613:                                    + "coordinate reference system has strange axes orientation");
614:                // let's check that its the Y axis that's flipped
615:                if (!AxisDirection.NORTH.equals(crs2D.getCoordinateSystem()
616:                        .getAxis(1).getDirection()))
617:                    throw new DataSourceException(
618:                            "Impossible to encode this coverage as an ascii grid since its"
619:                                    + "coordinate reference system has strange axes orientation");
620:                if (!AxisDirection.EAST.equals(crs2D.getCoordinateSystem()
621:                        .getAxis(0).getDirection()))
622:                    throw new DataSourceException(
623:                            "Impossible to encode this coverage as an ascii grid since its"
624:                                    + "coordinate reference system has strange axes orientation");
625:
626:                // /////////////////////////////////////////////////////////////////////
627:                //
628:                // RULE 3
629:                //
630:                // Check that we are actually writing a GridCoverage2D
631:                //
632:                // /////////////////////////////////////////////////////////////////////
633:                if (coverage instanceof  GridCoverage2D
634:                        && !(coverage.getGridGeometry() instanceof  GridGeometry2D))
635:                    throw new DataSourceException(
636:                            "The provided coverage is not a GridCoverage2D");
637:            }
638:
639:            /**
640:             * @see org.opengis.coverage.grid.GridCoverageWriter#dispose()
641:             */
642:            public void dispose() {
643:
644:                if (mWriter != null) {
645:                    mWriter.dispose();
646:                    mWriter = null;
647:                }
648:            }
649:
650:            static double getCandidateNoData(GridCoverage2D gc) {
651:                // no data management
652:                final GridSampleDimension sd = (GridSampleDimension) gc
653:                        .getSampleDimension(0);
654:                final List categories = sd.getCategories();
655:                final Iterator it = categories.iterator();
656:                Category candidate;
657:                double inNoData = Double.NaN;
658:                final String noDataName = Vocabulary
659:                        .format(VocabularyKeys.NODATA);
660:                while (it.hasNext()) {
661:                    candidate = (Category) it.next();
662:                    final String name = candidate.getName().toString();
663:                    if (name.equalsIgnoreCase("No Data")
664:                            || name.equalsIgnoreCase(noDataName)) {
665:                        inNoData = candidate.getRange().getMaximum();
666:                    }
667:                }
668:
669:                return inNoData;
670:            }
671:
672:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.