001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/model/coverage/grid/GridCoverageExchange.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 package org.deegree.model.coverage.grid; 037 038 import java.io.IOException; 039 import java.io.InputStream; 040 import java.net.URI; 041 import java.util.ArrayList; 042 import java.util.HashMap; 043 import java.util.List; 044 import java.util.Map; 045 046 import org.deegree.datatypes.CodeList; 047 import org.deegree.datatypes.QualifiedName; 048 import org.deegree.framework.log.ILogger; 049 import org.deegree.framework.log.LoggerFactory; 050 import org.deegree.framework.util.ConvenienceFileFilter; 051 import org.deegree.framework.util.StringTools; 052 import org.deegree.io.shpapi.ShapeFile; 053 import org.deegree.model.crs.CRSFactory; 054 import org.deegree.model.crs.CoordinateSystem; 055 import org.deegree.model.crs.UnknownCRSException; 056 import org.deegree.model.feature.Feature; 057 import org.deegree.model.spatialschema.Envelope; 058 import org.deegree.model.spatialschema.Geometry; 059 import org.deegree.model.spatialschema.GeometryFactory; 060 import org.deegree.ogcbase.CommonNamespaces; 061 import org.deegree.ogcwebservices.InvalidParameterValueException; 062 import org.deegree.ogcwebservices.wcs.configuration.Directory; 063 import org.deegree.ogcwebservices.wcs.configuration.Extension; 064 import org.deegree.ogcwebservices.wcs.configuration.File; 065 import org.deegree.ogcwebservices.wcs.configuration.GridDirectory; 066 import org.deegree.ogcwebservices.wcs.configuration.Shape; 067 import org.deegree.ogcwebservices.wcs.describecoverage.CoverageOffering; 068 069 /** 070 * Support for creation of grid coverages from persistent formats as well as exporting a grid 071 * coverage to a persistent formats. For example, it allows for creation of grid coverages from the 072 * GeoTIFF Well-known binary format and exporting to the GeoTIFF file format. Basic implementations 073 * only require creation of grid coverages from a file format or resource. More sophesticated 074 * implementations may extract the grid coverages from a database. In such case, a 075 * <code>GridCoverageExchange</code> instance will hold a connection to a specific database and 076 * the dispose method will need to be invoked in order to close this connection. 077 * <p> 078 * 079 * @author Andreas Poth 080 * @version 1.0 081 * @since 2.0 082 */ 083 public class GridCoverageExchange { 084 085 private static final ILogger LOG = LoggerFactory.getLogger( GridCoverageExchange.class ); 086 087 private static final URI DEEGREEAPP = CommonNamespaces.buildNSURI( "http://www.deegree.org/app" ); 088 089 private static final String APP_PREFIX = "app"; 090 091 /** 092 * 093 */ 094 public static final String SHAPE_IMAGE_FILENAME = "FILENAME"; 095 096 /** 097 * 098 */ 099 public static final String SHAPE_DIR_NAME = "FOLDER"; 100 101 private CoverageOffering coverageOffering; 102 103 /** 104 * @param coverageOffering 105 */ 106 public GridCoverageExchange( CoverageOffering coverageOffering ) { 107 this.coverageOffering = coverageOffering; 108 } 109 110 /** 111 * Returns a grid coverage reader that can manage the specified source 112 * 113 * @param source 114 * An object that specifies somehow the data source. Can be a 115 * {@link java.lang.String}, an {@link java.io.InputStream}, a 116 * {@link java.nio.channels.FileChannel}, whatever. It's up to the associated grid 117 * coverage reader to make meaningful use of it. 118 * @return The grid coverage reader. 119 * @throws IOException 120 * if an error occurs during reading. 121 * 122 * @revisit We need a mechanism to allow the right GridCoverageReader Something like an SPI. 123 * What if we can't find a GridCoverageReader? Do we return null or throw an Exception? 124 */ 125 public GridCoverageReader getReader( Object source ) 126 throws IOException { 127 if ( !( source instanceof InputStream ) ) { 128 throw new IOException( "source parameter must be an instance of InputStream" ); 129 } 130 return null; 131 } 132 133 /** 134 * This method is a deegree specific enhancement of the <tt>GridCoverageExchange</tt> 135 * class/interface as defined by GeoAPI. Returns a grid coverage reader that can manage the 136 * specified source 137 * 138 * @param source 139 * An object that specifies somehow the data source. 140 * @param description 141 * an object describing the grid coverage and the access to avaiable metadata 142 * @param envelope 143 * @param format 144 * @return The grid coverage reader. 145 * @throws IOException 146 * if an error occurs during reading. 147 * 148 * @revisit We need a mechanism to allow the right GridCoverageReader Something like an SPI. 149 * What if we can't find a GridCoverageReader? Do we return null or throw an Exception? 150 */ 151 public GridCoverageReader getReader( InputStream source, CoverageOffering description, Envelope envelope, 152 Format format ) 153 throws IOException { 154 GridCoverageReader gcr = null; 155 Extension ext = description.getExtension(); 156 String type = ext.getType(); 157 if ( type.equals( Extension.FILEBASED ) || type.equals( Extension.SCRIPTBASED ) ) { 158 if ( format.getName().toUpperCase().indexOf( "GEOTIFF" ) > -1 ) { 159 gcr = new GeoTIFFGridCoverageReader( source, description, envelope, format ); 160 } else if ( isImageFormat( format ) ) { 161 gcr = new ImageGridCoverageReader( source, description, envelope, format ); 162 } else { 163 throw new IOException( "not supported file format: " + format.getName() ); 164 } 165 } else { 166 throw new IOException( "coverage storage type: " + type 167 + " is not supported with method: getReader(InputStream, " 168 + "CoverageOffering, Envelope, Format )" ); 169 } 170 return gcr; 171 } 172 173 /** 174 * This method is a deegree specific enhancement of the <tt>GridCoverageExchange</tt> 175 * class/interface as defined by GeoAPI. Returns a grid coverage reader that can manage the 176 * specified source 177 * 178 * @param resource 179 * a string that specifies somehow the data source (e.g. a file). 180 * @param description 181 * an object describing the grid coverage and the access to avaiable metadata 182 * @param envelope 183 * @param format 184 * 185 * @return The grid coverage reader. 186 * @throws IOException 187 * if an error occurs during reading. 188 * @throws InvalidParameterValueException 189 * 190 * @revisit We need a mechanism to allow the right GridCoverageReader Something like an SPI. 191 * What if we can't find a GridCoverageReader? Do we return null or throw an Exception? 192 */ 193 public GridCoverageReader getReader( Object resource, CoverageOffering description, Envelope envelope, Format format ) 194 throws IOException, InvalidParameterValueException { 195 GridCoverageReader gcr = null; 196 Extension ext = description.getExtension(); 197 String type = ext.getType(); 198 if ( type.equals( Extension.FILEBASED ) || type.equals( Extension.SCRIPTBASED )) { 199 File file = new File( null, (String) resource, envelope ); 200 if ( format.getName().toUpperCase().indexOf( "GEOTIFF" ) > -1 ) { 201 LOG.logDebug( "creating GeoTIFFGridCoverageReader" ); 202 gcr = new GeoTIFFGridCoverageReader( file, description, envelope, format ); 203 } else if ( isImageFormat( format ) ) { 204 LOG.logDebug( "creating ImageGridCoverageReader" ); 205 gcr = new ImageGridCoverageReader( file, description, envelope, format ); 206 } else { 207 throw new IOException( "not supported file format: " + format.getName() ); 208 } 209 } else if ( type.equals( Extension.NAMEINDEXED ) ) { 210 LOG.logDebug( "creating nameIndexed CompoundGridCoverageReader" ); 211 Directory[] dirs = new Directory[] { (Directory) resource }; 212 gcr = getReader( dirs, description, envelope, format ); 213 } else if ( type.equals( Extension.SHAPEINDEXED ) ) { 214 LOG.logDebug( "creating shapeIndexed CompoundGridCoverageReader" ); 215 File[] files = null; 216 try { 217 files = getFilesFromShape( (Shape) resource, envelope, description ); 218 } catch ( UnknownCRSException e ) { 219 throw new InvalidParameterValueException( e ); 220 } 221 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 222 for ( int i = 0; i < files.length; i++ ) { 223 LOG.logDebug( "matching tile: ", files[i].getName() ); 224 } 225 } 226 gcr = getReader( files, description, envelope, format ); 227 } else if ( type.equals( Extension.ORACLEGEORASTER ) ) { 228 LOG.logDebug( "creating OracleGeoRasterGridCoverageReader" ); 229 Class<?> clzz; 230 try { 231 clzz = Class.forName( "org.deegree.model.coverage.grid.oracle.GeoRasterReaderAccess" ); 232 } catch ( ClassNotFoundException e ) { 233 LOG.logError( e.getMessage(), e ); 234 throw new InvalidParameterValueException( e ); 235 } 236 GCReaderAccess acc; 237 try { 238 acc = (GCReaderAccess) clzz.newInstance(); 239 } catch ( InstantiationException e ) { 240 LOG.logError( e.getMessage(), e ); 241 throw new InvalidParameterValueException( e ); 242 } catch ( IllegalAccessException e ) { 243 LOG.logError( e.getMessage(), e ); 244 throw new InvalidParameterValueException( e ); 245 } 246 gcr = acc.createGridCoverageReader( resource, description, envelope, format ); 247 } else if ( type.equals( Extension.DATABASEINDEXED ) ) { 248 LOG.logDebug( "creating databaseIndexed CompoundGridCoverageReader" ); 249 File[] files = null; 250 try { 251 files = getFilesFromDatabase( (DatabaseIndexedGCMetadata) resource, envelope, description ); 252 } catch ( UnknownCRSException e ) { 253 LOG.logError( e.getMessage(), e ); 254 throw new InvalidParameterValueException( e ); 255 } 256 if ( LOG.getLevel() == ILogger.LOG_DEBUG ) { 257 for ( int i = 0; i < files.length; i++ ) { 258 LOG.logDebug( "matching tile: ", files[i].getName() ); 259 } 260 } 261 gcr = new CompoundGridCoverageReader( files, description, envelope, format ); 262 } else { 263 throw new IOException( "coverage storage type: " + type + " is not supported" ); 264 } 265 return gcr; 266 } 267 268 /** 269 * reads the names of the grid coverage files intersecting the requested region from the passed 270 * database. 271 * 272 * @param dbigcmd 273 * @param envelope 274 * @param description 275 * @return file list 276 * @throws UnknownCRSException 277 * @throws InvalidParameterValueException 278 */ 279 private File[] getFilesFromDatabase( DatabaseIndexedGCMetadata dbigcmd, Envelope envelope, 280 CoverageOffering description ) 281 throws UnknownCRSException, InvalidParameterValueException { 282 283 CoordinateSystem crs = createNativeCRS( description ); 284 285 String className = null; 286 if ( dbigcmd.getJDBCConnection().getDriver().toUpperCase().indexOf( "ORACLE" ) > -1 ) { 287 className = DatabaseIndexAccessMessages.getString( "oracle" ); 288 } else if ( dbigcmd.getJDBCConnection().getDriver().toUpperCase().indexOf( "POSTGRES" ) > -1 ) { 289 className = DatabaseIndexAccessMessages.getString( "postgres" ); 290 } 291 Class<?> clzz; 292 try { 293 clzz = Class.forName( className ); 294 } catch ( ClassNotFoundException e ) { 295 LOG.logError( e.getMessage(), e ); 296 throw new InvalidParameterValueException( className, e ); 297 } 298 DatabaseIndexAccess dbia; 299 try { 300 dbia = (DatabaseIndexAccess) clzz.newInstance(); 301 } catch ( InstantiationException e ) { 302 LOG.logError( e.getMessage(), e ); 303 throw new InvalidParameterValueException( className, e ); 304 } catch ( IllegalAccessException e ) { 305 LOG.logError( e.getMessage(), e ); 306 throw new InvalidParameterValueException( className, e ); 307 } 308 309 return dbia.getFiles( dbigcmd, envelope, crs ); 310 } 311 312 /** 313 * This method is a deegree specific enhancement of the <tt>GridCoverageExchange</tt> 314 * class/interface as defined by GeoAPI. Returns a grid coverage reader that can manage the 315 * specified source 316 * 317 * @param resources 318 * an array strings that specifies somehow the data sources (e.g. some files). 319 * @param description 320 * an object describing the grid coverage and the access to avaiable metadata 321 * @param envelope 322 * @param format 323 * @return The grid coverage reader. 324 * @throws IOException 325 * if an error occurs during reading. 326 * @throws InvalidParameterValueException 327 * 328 * @revisit We need a mechanism to allow the right GridCoverageReader Something like an SPI. 329 * What if we can't find a GridCoverageReader? Do we return null or throw an Exception? 330 */ 331 public GridCoverageReader getReader( Object[] resources, CoverageOffering description, Envelope envelope, 332 Format format ) 333 throws IOException, InvalidParameterValueException { 334 335 // CS_CoordinateSystem crs = createNativeCRS( description ); 336 GridCoverageReader gcr = null; 337 Extension ext = description.getExtension(); 338 String type = ext.getType(); 339 File[] files = null; 340 if ( type.equals( Extension.FILEBASED ) || type.equals( Extension.SCRIPTBASED ) ) { 341 LOG.logDebug( "creating filebased CompoundGridCoverageReader" ); 342 files = (File[]) resources; 343 gcr = new CompoundGridCoverageReader( files, description, envelope, format ); 344 } else if ( type.equals( Extension.NAMEINDEXED ) ) { 345 LOG.logDebug( "creating nameIndexed CompoundGridCoverageReader" ); 346 try { 347 files = getFilesFromDirectories( (Directory[]) resources, envelope, description ); 348 } catch ( UnknownCRSException e ) { 349 throw new InvalidParameterValueException( e ); 350 } 351 gcr = new CompoundGridCoverageReader( files, description, envelope, format ); 352 } else if ( type.equals( Extension.SHAPEINDEXED ) ) { 353 LOG.logDebug( "creating shapeIndexed CompoundGridCoverageReader" ); 354 files = (File[]) resources; 355 gcr = new CompoundGridCoverageReader( files, description, envelope, format ); 356 } else if ( type.equals( Extension.ORACLEGEORASTER ) ) { 357 LOG.logDebug( "creating OracleGeoRasterGridCoverageReader" ); 358 Class<?> clzz; 359 try { 360 clzz = Class.forName( "org.deegree.model.coverage.grid.oracle.GeoRasterReaderAccess" ); 361 } catch ( ClassNotFoundException e ) { 362 LOG.logError( e.getMessage(), e ); 363 throw new InvalidParameterValueException( e ); 364 } 365 GCReaderAccess acc; 366 try { 367 acc = (GCReaderAccess) clzz.newInstance(); 368 } catch ( InstantiationException e ) { 369 LOG.logError( e.getMessage(), e ); 370 throw new InvalidParameterValueException( e ); 371 } catch ( IllegalAccessException e ) { 372 LOG.logError( e.getMessage(), e ); 373 throw new InvalidParameterValueException( e ); 374 } 375 gcr = acc.createGridCoverageReader( resources[0], description, envelope, format ); 376 } else { 377 throw new IOException( "coverage storage type: " + type + " is not supported" ); 378 } 379 380 return gcr; 381 } 382 383 /** 384 * returns true if the passed format is an image format 385 * 386 * @param format 387 * @return <code>true</code> if the passed format is an image format 388 */ 389 private boolean isImageFormat( Format format ) { 390 String frmt = format.getName().toUpperCase(); 391 return frmt.equalsIgnoreCase( "png" ) || frmt.equalsIgnoreCase( "bmp" ) || frmt.equalsIgnoreCase( "tif" ) 392 || frmt.equalsIgnoreCase( "tiff" ) || frmt.equalsIgnoreCase( "gif" ) || frmt.equalsIgnoreCase( "jpg" ) 393 || frmt.equalsIgnoreCase( "jpeg" ) || frmt.indexOf( "ECW" ) > -1; 394 } 395 396 /** 397 * reads the names of the grid coverage files intersecting the requested region from the passed 398 * shape (name). 399 * 400 * @param shape 401 * @param envelope 402 * requested envelope 403 * @param description 404 * description (metadata) of the source coverage 405 * @return file list 406 * @throws IOException 407 * @throws UnknownCRSException 408 */ 409 private File[] getFilesFromShape( Shape shape, Envelope envelope, CoverageOffering description ) 410 throws IOException, UnknownCRSException { 411 412 CoordinateSystem crs = createNativeCRS( description ); 413 414 String shapeBaseName = StringTools.replace( shape.getRootFileName(), "\\", "/", true ); 415 String shapeDir = shapeBaseName.substring( 0, shapeBaseName.lastIndexOf( "/" ) + 1 ); 416 417 ShapeFile shp = new ShapeFile( shapeBaseName ); 418 File[] files = null; 419 int[] idx = shp.getGeoNumbersByRect( envelope ); 420 if ( idx != null ) { 421 files = new File[idx.length]; 422 try { 423 for ( int i = 0; i < files.length; i++ ) { 424 Feature feature = shp.getFeatureByRecNo( idx[i] ); 425 QualifiedName qn = new QualifiedName( APP_PREFIX, SHAPE_IMAGE_FILENAME, DEEGREEAPP ); 426 String img = (String) feature.getDefaultProperty( qn ).getValue(); 427 qn = new QualifiedName( APP_PREFIX, SHAPE_DIR_NAME, DEEGREEAPP ); 428 String dir = (String) feature.getDefaultProperty( qn ).getValue(); 429 if ( !( new java.io.File( dir ).isAbsolute() ) ) { 430 // solve relative path; it is assumed that the tile directories 431 // are located in the same directory as the shape file 432 dir = shapeDir + dir; 433 } 434 Geometry geom = feature.getGeometryPropertyValues()[0]; 435 Envelope env = geom.getEnvelope(); 436 env = GeometryFactory.createEnvelope( env.getMin(), env.getMax(), crs ); 437 files[i] = new File( crs, dir.concat( "/".concat( img ) ), env ); 438 } 439 } catch ( Exception e ) { 440 shp.close(); 441 LOG.logError( e.getMessage(), e ); 442 throw new IOException( e.getMessage() ); 443 } 444 } else { 445 files = new File[0]; 446 } 447 shp.close(); 448 449 return files; 450 451 } 452 453 /** 454 * reads the names of the grid coverage files intersecting the requested region from raster data 455 * files contained in the passed directories 456 * 457 * @param directories 458 * list of directories searched for matching raster files 459 * @param envelope 460 * requested envelope 461 * @param description 462 * description (metadata) of the source coverage 463 * @return list of files intersecting the requested envelope 464 * @throws UnknownCRSException 465 */ 466 private File[] getFilesFromDirectories( Directory[] directories, Envelope envelope, CoverageOffering description ) 467 throws UnknownCRSException { 468 469 CoordinateSystem crs = createNativeCRS( description ); 470 471 List<File> list = new ArrayList<File>( 1000 ); 472 473 for ( int i = 0; i < directories.length; i++ ) { 474 475 double widthCRS = ( (GridDirectory) directories[i] ).getTileWidth(); 476 double heightCRS = ( (GridDirectory) directories[i] ).getTileHeight(); 477 String[] extensions = directories[i].getFileExtensions(); 478 String dirName = directories[i].getName(); 479 480 ConvenienceFileFilter fileFilter = new ConvenienceFileFilter( false, extensions ); 481 java.io.File iofile = new java.io.File( dirName ); 482 String[] tiles = iofile.list( fileFilter ); 483 for ( int j = 0; j < tiles.length; j++ ) { 484 int pos1 = tiles[j].indexOf( '_' ); 485 int pos2 = tiles[j].lastIndexOf( '.' ); 486 String tmp = tiles[j].substring( 0, pos1 ); 487 double x1 = Double.parseDouble( tmp ) / 1000d; 488 tmp = tiles[j].substring( pos1 + 1, pos2 ); 489 double y1 = Double.parseDouble( tmp ) / 1000d; 490 Envelope env = GeometryFactory.createEnvelope( x1, y1, x1 + widthCRS, y1 + heightCRS, crs ); 491 if ( env.intersects( envelope ) ) { 492 File file = new File( crs, dirName + '/' + tiles[j], env ); 493 list.add( file ); 494 } 495 } 496 497 } 498 499 File[] files = list.toArray( new File[list.size()] ); 500 501 return files; 502 } 503 504 /** 505 * creates an instance of <tt>CS_CoordinateSystem</tt> from the name of the native CRS of the 506 * grid coverage 507 * 508 * @param description 509 * @return the crs 510 * @throws UnknownCRSException 511 */ 512 private CoordinateSystem createNativeCRS( CoverageOffering description ) 513 throws UnknownCRSException { 514 String srs = description.getSupportedCRSs().getNativeSRSs()[0].getCodes()[0]; 515 516 return CRSFactory.create( srs ); 517 } 518 519 /** 520 * Returns a GridCoverageWriter that can write the specified format. The file format name is 521 * determined from the {@link Format} interface. Sample file formats include: 522 * 523 * <blockquote><table> 524 * <tr> 525 * <td>"GeoTIFF"</td> 526 * <td> - GeoTIFF</td> 527 * </tr> 528 * <tr> 529 * <td>"PIX"</td> 530 * <td> - PCI Geomatics PIX</td> 531 * </tr> 532 * <tr> 533 * <td>"HDF-EOS"</td> 534 * <td> - NASA HDF-EOS</td> 535 * </tr> 536 * <tr> 537 * <td>"NITF"</td> 538 * <td> - National Image Transfer Format</td> 539 * </tr> 540 * <tr> 541 * <td>"STDS-DEM"</td> 542 * <td> - Standard Transfer Data Standard</td> 543 * </tr> 544 * </table></blockquote> 545 * 546 * @param destination 547 * An object that specifies somehow the data destination. Can be a 548 * {@link java.lang.String}, an {@link java.io.OutputStream}, a 549 * {@link java.nio.channels.FileChannel}, whatever. It's up to the associated grid 550 * coverage writer to make meaningful use of it. 551 * @param format 552 * the output format. 553 * @return The grid coverage writer. 554 * @throws IOException 555 * if an error occurs during reading. 556 */ 557 public GridCoverageWriter getWriter( Object destination, Format format ) 558 throws IOException { 559 560 LOG.logDebug( "requested format: ", format.getName() ); 561 562 GridCoverageWriter gcw = null; 563 564 if ( !isKnownFormat( format ) ) { 565 throw new IOException( "not supported Format: " + format ); 566 } 567 568 Map<String, Object> metadata = new HashMap<String, Object>(); 569 metadata.put( "offset", coverageOffering.getExtension().getOffset() ); 570 metadata.put( "scaleFactor", coverageOffering.getExtension().getScaleFactor() ); 571 if ( format.getName().equalsIgnoreCase( "GEOTIFF" ) ) { 572 gcw = new GeoTIFFGridCoverageWriter( destination, metadata, null, null, format ); 573 } else if ( isImageFormat( format ) ) { 574 gcw = new ImageGridCoverageWriter( destination, metadata, null, null, format ); 575 } else if ( format.getName().equalsIgnoreCase( "GML" ) || format.getName().equalsIgnoreCase( "GML2" ) 576 || format.getName().equalsIgnoreCase( "GML3" ) ) { 577 gcw = new GMLGridCoverageWriter( destination, metadata, null, null, format ); 578 } else if ( format.getName().equalsIgnoreCase( "XYZ" ) ) { 579 gcw = new XYZGridCoverageWriter( destination, metadata, null, null, format ); 580 } else { 581 throw new IOException( "not supported Format: " + format ); 582 } 583 584 return gcw; 585 } 586 587 /** 588 * validates if a passed format is known to an instance of <tt>GridCoverageExchange</tt> 589 * 590 * @param format 591 * @return <code>true</code> if the format is known, <code>false</code> otherwise. 592 */ 593 private boolean isKnownFormat( Format format ) { 594 CodeList[] codeList = coverageOffering.getSupportedFormats().getFormats(); 595 for ( int i = 0; i < codeList.length; i++ ) { 596 String[] codes = codeList[i].getCodes(); 597 for ( int j = 0; j < codes.length; j++ ) { 598 if ( format.getName().equalsIgnoreCase( codes[j] ) ) { 599 return true; 600 } 601 } 602 } 603 LOG.logDebug( format.getName() + " not supported" ); 604 return false; 605 } 606 607 }