001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/crs/configuration/deegree/DeegreeCRSProvider.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 037 package org.deegree.crs.configuration.deegree; 038 039 import java.io.ByteArrayOutputStream; 040 import java.io.PrintWriter; 041 import java.io.UnsupportedEncodingException; 042 import java.lang.reflect.Constructor; 043 import java.lang.reflect.InvocationTargetException; 044 import java.util.LinkedList; 045 import java.util.List; 046 import java.util.Properties; 047 048 import org.deegree.crs.Identifiable; 049 import org.deegree.crs.configuration.AbstractCRSProvider; 050 import org.deegree.crs.coordinatesystems.CoordinateSystem; 051 import org.deegree.crs.exceptions.CRSConfigurationException; 052 import org.deegree.crs.projections.Projection; 053 import org.deegree.crs.transformations.Transformation; 054 import org.deegree.framework.log.ILogger; 055 import org.deegree.framework.log.LoggerFactory; 056 import org.deegree.framework.util.CharsetUtils; 057 import org.deegree.framework.xml.NamespaceContext; 058 import org.deegree.framework.xml.XMLParsingException; 059 import org.deegree.framework.xml.XMLTools; 060 import org.deegree.i18n.Messages; 061 import org.deegree.ogcbase.CommonNamespaces; 062 import org.w3c.dom.Element; 063 064 /** 065 * The <code>DeegreeCRSProvider</code> reads the deegree crs-config (based on it's own xml-schema) and creates the 066 * CRS's (and their datums, conversion info's, ellipsoids and projections) if requested. 067 * <p> 068 * Attention, although urn's are case-sensitive, the deegreeCRSProvider is not. All incoming id's are toLowerCased! 069 * </p> 070 * <h2>Automatic loading of projection/transformation classes</h2> 071 * It is possible to create your own projection/transformation classes, which can be automatically loaded. 072 * <p> 073 * You can achieve this loading by supplying the <b><code>class</code></b> attribute to a 074 * <code>crs:projectedCRS/crs:projection</code> or <code>crs:coordinateSystem/crs:transformation</code> element in 075 * the 'deegree-crs-configuration.xml'. This attribute must contain the full class name (with package), e.g. 076 * <crs:projection class='my.package.and.projection.Implementation'> 077 * </p> 078 * Because the loading is done with reflections your classes must sustain following criteria: 079 * <h3>Projections</h3> 080 * <ol> 081 * <li>It must be a sub class of {@link org.deegree.crs.projections.Projection}</li> 082 * <li>A constructor with following signature must be supplied: <br/> <code> 083 * public MyProjection( <br/> 084 *     {@link org.deegree.crs.coordinatesystems.GeographicCRS} underlyingCRS,<br/> 085 *     double falseNorthing,<br/> 086 *     double falseEasting,<br/> 087 *     javax.vecmath.Point2d naturalOrigin,<br/> 088 *     {@link org.deegree.crs.components.Unit} units,<br/> 089 *     double scale,<br/> 090 *     java.util.List<org.w3c.dom.Element> yourProjectionElements<br/> 091 * );<br/> 092 * </code> 093 * <p> 094 * The first six parameters are common to all projections (for an explanation of their meaning take a look at 095 * {@link Projection}). The last list, will contain all xml-dom elements you supplied in the deegree configuration 096 * (child elements of the crs:projection/crs:MyProjection), thus relieving you of the parsing of the 097 * deegree-crs-configuration.xml document. 098 * </p> 099 * </li> 100 * </ol> 101 * <h3>Transformations</h3> 102 * <ol> 103 * <li>It must be a sub class of {@link org.deegree.crs.transformations.polynomial.PolynomialTransformation}</li> 104 * <li>A constructor with following signature must be supplied: <br/> <code> 105 * public MyTransformation( <br/> 106 *     java.util.list<Double> aValues,<br/> 107 *     java.util.list<Double> bValues,<br/> 108 *     {@link org.deegree.crs.coordinatesystems.CoordinateSystem} targetCRS,<br/> 109 *     java.util.List<org.w3c.dom.Element> yourTransformationElements<br/> 110 * );<br/> 111 * </code> 112 * <p> 113 * The first three parameters are common to all polynomial values (for an explanation of their meaning take a look at 114 * {@link org.deegree.crs.transformations.polynomial.PolynomialTransformation}). Again, the last list, will contain all 115 * xml-dom elements you supplied in the deegree configuration (child elements of the 116 * crs:transformation/crs:MyTransformation), thus relieving you of the parsing of the deegree-crs-configuration.xml 117 * document. 118 * </p> 119 * </li> 120 * </ol> 121 * 122 * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a> 123 * 124 * @author last edited by: $Author: lbuesching $ 125 * 126 * @version $Revision: 27765 $, $Date: 2010-11-04 07:50:32 +0100 (Do, 04 Nov 2010) $ 127 * 128 */ 129 130 public class DeegreeCRSProvider extends AbstractCRSProvider<Element> { 131 132 private static ILogger LOG = LoggerFactory.getLogger( DeegreeCRSProvider.class ); 133 134 private CRSExporter exporter; 135 136 /** 137 * The namespaces used in deegree. 138 */ 139 private static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext(); 140 141 /** 142 * The prefix to use. 143 */ 144 private final static String PRE = CommonNamespaces.CRS_PREFIX + ":"; 145 146 // /** 147 // * The EPSG-Database defines only 48 different ellipsoids, set to 60, will --probably-- result in no collisions. 148 // */ 149 // private final Map<String, Ellipsoid> ellipsoids = new HashMap<String, Ellipsoid>( 60 * 5 ); 150 // 151 // /** 152 // * The EPSG-Database defines over 400 different Geodetic Datums, set to 450, will --probably-- result in no 153 // * collisions. 154 // */ 155 // private final Map<String, GeodeticDatum> datums = new HashMap<String, GeodeticDatum>( 450 * 5 ); 156 // 157 // /** 158 // * The EPSG-Database defines over 1100 different CoordinateTransformations, set to 1200, will --probably-- result 159 // in 160 // * no collisions. 161 // */ 162 // private final Map<String, Helmert> conversionInfos = new HashMap<String, Helmert>( 1200 * 5 ); 163 // 164 // /** 165 // * Theoretically infinite prime meridians could be defined, let's set it to a more practical number of 42. 166 // */ 167 // private final Map<String, PrimeMeridian> primeMeridians = new HashMap<String, PrimeMeridian>( 42 * 5 ); 168 // 169 // /** 170 // * The EPSG-Database defines over 2960 different ProjectedCRS's, set to 3500, will --probably-- result in no 171 // * collisions. 172 // */ 173 // private final Map<String, ProjectedCRS> projectedCRSs = new HashMap<String, ProjectedCRS>( 3500 * 5 ); 174 // 175 // /** 176 // * The EPSG-Database defines over 490 different GeographicCRS's (geodetic), set to 600, will --probably-- result 177 // in 178 // * no collisions. 179 // */ 180 // private final Map<String, GeographicCRS> geographicCRSs = new HashMap<String, GeographicCRS>( 600 * 5 ); 181 // 182 // /** 183 // * The EPSG-Database defines ??? 184 // */ 185 // private final Map<String, CompoundCRS> compoundCRSs = new HashMap<String, CompoundCRS>( 600 * 5 ); 186 // 187 // /** 188 // * The EPSG-Database doesn't define GeocentricCRS's, set to 30, will --probably-- result in no collisions. 189 // */ 190 // private final Map<String, GeocentricCRS> geocentricCRSs = new HashMap<String, GeocentricCRS>( 30 ); 191 // 192 // private final List<GeocentricCRS> cachedGeocentricCRSs = new LinkedList<GeocentricCRS>(); 193 // 194 // private final Map<String, String> doubleGeocentricCRSs = new HashMap<String, String>( 5000 ); 195 // 196 // private final List<CompoundCRS> cachedCompoundCRSs = new LinkedList<CompoundCRS>(); 197 // 198 // private final Map<String, String> doubleCompoundCRSs = new HashMap<String, String>( 5000 ); 199 // 200 // private final List<GeographicCRS> cachedGeoCRSs = new LinkedList<GeographicCRS>(); 201 // 202 // private final Map<String, String> doubleGeos = new HashMap<String, String>( 5000 ); 203 // 204 // private final List<ProjectedCRS> cachedProjCRSs = new LinkedList<ProjectedCRS>(); 205 // 206 // private final Map<String, String> doubleProjCRS = new HashMap<String, String>( 3000 ); 207 // 208 // private final List<GeodeticDatum> cachedDatums = new LinkedList<GeodeticDatum>(); 209 // 210 // private final Map<String, String> doubleDatums = new HashMap<String, String>( 3000 ); 211 // 212 // private final List<Helmert> cachedToWGS = new LinkedList<Helmert>(); 213 // 214 // private final Map<String, String> doubleToWGS = new HashMap<String, String>( 3000 ); 215 // 216 // private final List<Ellipsoid> cachedEllipsoids = new LinkedList<Ellipsoid>(); 217 // 218 // private final Map<String, String> doubleEllipsoids = new HashMap<String, String>( 3000 ); 219 // 220 // private final List<PrimeMeridian> cachedMeridians = new LinkedList<PrimeMeridian>(); 221 // 222 // private final Map<String, String> doubleMeridians = new HashMap<String, String>( 3000 ); 223 // 224 // private final Map<String, String> doubleProjections = new HashMap<String, String>( 3000 ); 225 226 // /** 227 // * The root element of the deegree - crs - configuration. 228 // */ 229 // private Element rootElement; 230 231 // private boolean checkForDoubleDefinition = false; 232 233 /** 234 * @param properties 235 * containing information about the crs resource class and the file location of the crs configuration. If 236 * either is null the default mechanism is using the {@link CRSParser} and the 237 * deegree-crs-configuration.xml 238 * @throws CRSConfigurationException 239 * if the give file or the default-crs-configuration.xml file could not be loaded. 240 */ 241 public DeegreeCRSProvider( Properties properties ) throws CRSConfigurationException { 242 super( properties, CRSParser.class, null ); 243 if ( getResolver() == null ) { 244 CRSParser versionedParser = new CRSParser( this, new Properties( properties ) ); 245 String version = versionedParser.getVersion(); 246 if ( !"".equals( version ) ) { 247 version = version.trim().replaceAll( "\\.", "_" ); 248 String className = "org.deegree.crs.configuration.deegree.CRSParser_" + version; 249 try { 250 Class<?> tClass = Class.forName( className ); 251 tClass.asSubclass( CRSParser.class ); 252 LOG.logDebug( "Trying to load configured CRS provider from classname: " + className ); 253 Constructor<?> constructor = tClass.getConstructor( this.getClass(), Properties.class, 254 Element.class ); 255 if ( constructor == null ) { 256 LOG.logError( "No constructor ( " + this.getClass() + ", Properties.class) found in class:" 257 + className ); 258 } else { 259 versionedParser = (CRSParser) constructor.newInstance( this, new Properties( properties ), 260 versionedParser.getRootElement() ); 261 } 262 className = "org.deegree.crs.configuration.deegree.CRSExporter_" + version; 263 try { 264 tClass = Class.forName( className ); 265 tClass.asSubclass( CRSExporter.class ); 266 constructor = tClass.getConstructor( Properties.class ); 267 LOG.logDebug( "Trying to load configured CRS exporter for version: " + version 268 + " from classname: " + className ); 269 } catch ( ClassNotFoundException e ) { 270 LOG.logDebug( "Could not load the exporter for version 1, using fallback mechanism." ); 271 constructor = null; 272 } 273 274 if ( constructor == null ) { 275 exporter = new CRSExporter( new Properties( properties ) ); 276 LOG.logDebug( "No constructor ( Properties.class ) found in class:" + className ); 277 } else { 278 versionedParser = (CRSParser) constructor.newInstance( new Properties( properties ) ); 279 } 280 } catch ( InstantiationException e ) { 281 LOG.logError( Messages.getMessage( "CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage() ) ); 282 } catch ( IllegalAccessException e ) { 283 LOG.logError( Messages.getMessage( "CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage() ), e ); 284 } catch ( ClassNotFoundException e ) { 285 LOG.logError( Messages.getMessage( "CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage() ), e ); 286 } catch ( SecurityException e ) { 287 LOG.logError( Messages.getMessage( "CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage() ), e ); 288 } catch ( NoSuchMethodException e ) { 289 LOG.logError( Messages.getMessage( "CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage() ), e ); 290 } catch ( IllegalArgumentException e ) { 291 LOG.logError( Messages.getMessage( "CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage() ), e ); 292 } catch ( InvocationTargetException e ) { 293 LOG.logError( Messages.getMessage( "CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage() ), e ); 294 } catch ( Throwable t ) { 295 LOG.logError( Messages.getMessage( "CRS_CONFIG_INSTANTIATION_ERROR", className, t.getMessage() ), t ); 296 } 297 } else { 298 exporter = new CRSExporter( new Properties( properties ) ); 299 } 300 setResolver( versionedParser ); 301 } 302 } 303 304 public boolean canExport() { 305 return exporter != null; 306 } 307 308 public void export( StringBuilder sb, List<CoordinateSystem> crsToExport ) { 309 if ( exporter == null ) { 310 throw new UnsupportedOperationException( "Exporting is not supported for this deegree-crs version" ); 311 } 312 ByteArrayOutputStream out = new ByteArrayOutputStream(); 313 PrintWriter writer = new PrintWriter( out ); 314 exporter.export( writer, crsToExport ); 315 316 try { 317 sb.append( out.toString( CharsetUtils.getSystemCharset() ) ); 318 } catch ( UnsupportedEncodingException e ) { 319 LOG.logError( e ); 320 } 321 322 } 323 324 /** 325 * @return the casted resolver of the super class. 326 */ 327 @Override 328 public CRSParser getResolver() { 329 return (CRSParser) super.getResolver(); 330 } 331 332 public List<String[]> getSortedAvailableCRSIds() 333 throws CRSConfigurationException { 334 List<Element> allCRSs = new LinkedList<Element>(); 335 List<String[]> result = new LinkedList<String[]>(); 336 337 try { 338 allCRSs.addAll( XMLTools.getElements( getResolver().getRootElement(), "//" + PRE + "geographicCRS", 339 nsContext ) ); 340 allCRSs.addAll( XMLTools.getElements( getResolver().getRootElement(), "//" + PRE + "projectedCRS", 341 nsContext ) ); 342 allCRSs.addAll( XMLTools.getElements( getResolver().getRootElement(), "//" + PRE + "geocentricCRS", 343 nsContext ) ); 344 allCRSs.addAll( XMLTools.getElements( getResolver().getRootElement(), "//" + PRE + "compoundCRS", nsContext ) ); 345 for ( Element crs : allCRSs ) { 346 if ( crs != null ) { 347 result.add( XMLTools.getNodesAsStrings( crs, PRE + "id", nsContext ) ); 348 } 349 } 350 } catch ( XMLParsingException e ) { 351 throw new CRSConfigurationException( 352 Messages.getMessage( "CRS_CONFIG_GET_ALL_ELEMENT_IDS", e.getMessage() ), 353 e ); 354 } 355 return result; 356 } 357 358 public List<String> getAvailableCRSIds() 359 throws CRSConfigurationException { 360 List<Element> allCRSIDs = new LinkedList<Element>(); 361 362 try { 363 allCRSIDs.addAll( XMLTools.getElements( getResolver().getRootElement(), "//" + PRE + "geographicCRS/" + PRE 364 + "id", nsContext ) ); 365 allCRSIDs.addAll( XMLTools.getElements( getResolver().getRootElement(), "//" + PRE + "projectedCRS/" + PRE 366 + "id", nsContext ) ); 367 allCRSIDs.addAll( XMLTools.getElements( getResolver().getRootElement(), "//" + PRE + "geocentricCRS/" + PRE 368 + "id", nsContext ) ); 369 allCRSIDs.addAll( XMLTools.getElements( getResolver().getRootElement(), "//" + PRE + "compoundCRS/" + PRE 370 + "id", nsContext ) ); 371 } catch ( XMLParsingException e ) { 372 throw new CRSConfigurationException( 373 Messages.getMessage( "CRS_CONFIG_GET_ALL_ELEMENT_IDS", e.getMessage() ), 374 e ); 375 } 376 List<String> result = new LinkedList<String>(); 377 for ( Element crs : allCRSIDs ) { 378 if ( crs != null ) { 379 result.add( XMLTools.getStringValue( crs ) ); 380 } 381 } 382 return result; 383 } 384 385 public List<CoordinateSystem> getAvailableCRSs() 386 throws CRSConfigurationException { 387 List<CoordinateSystem> allSystems = new LinkedList<CoordinateSystem>(); 388 if ( getResolver().getRootElement() != null ) { 389 List<Element> allCRSIDs = new LinkedList<Element>(); 390 391 try { 392 allCRSIDs.addAll( XMLTools.getElements( getResolver().getRootElement(), "//" + PRE + "geographicCRS/" 393 + PRE + "id", nsContext ) ); 394 allCRSIDs.addAll( XMLTools.getElements( getResolver().getRootElement(), "//" + PRE + "projectedCRS/" 395 + PRE + "id", nsContext ) ); 396 allCRSIDs.addAll( XMLTools.getElements( getResolver().getRootElement(), "//" + PRE + "geocentricCRS/" 397 + PRE + "id", nsContext ) ); 398 allCRSIDs.addAll( XMLTools.getElements( getResolver().getRootElement(), "//" + PRE + "compoundCRS/" 399 + PRE + "id", nsContext ) ); 400 } catch ( XMLParsingException e ) { 401 throw new CRSConfigurationException( Messages.getMessage( "CRS_CONFIG_GET_ALL_ELEMENT_IDS", 402 e.getMessage() ), e ); 403 } 404 final int total = allCRSIDs.size(); 405 int count = 0; 406 int percentage = (int) Math.round( total / 100.d ); 407 int number = 0; 408 System.out.println( "Trying to create a total of " + total + " coordinate systems." ); 409 for ( Element crsID : allCRSIDs ) { 410 if ( crsID != null ) { 411 String id = crsID.getTextContent(); 412 if ( id != null && !"".equals( id.trim() ) ) { 413 if ( count++ % percentage == 0 ) { 414 System.out.print( "\r" + ( number ) + ( ( number++ < 10 ) ? " " : " " ) + "% created" ); 415 } 416 allSystems.add( getCRSByID( id ) ); 417 } 418 } 419 } 420 System.out.println(); 421 // if ( checkForDoubleDefinition ) { 422 // allSystems.addAll( cachedGeoCRSs ); 423 // allSystems.addAll( cachedProjCRSs ); 424 // allSystems.addAll( cachedGeocentricCRSs ); 425 // allSystems.addAll( cachedCompoundCRSs ); 426 // StringBuilder cachedGeos = new StringBuilder( "Cached Geographic coordinatesystems (" ); 427 // cachedGeos.append( cachedGeoCRSs.size() ).append( "):\n" ); 428 // for ( GeographicCRS geo : cachedGeoCRSs ) { 429 // cachedGeos.append( geo.getIdentifier() ).append( "\n" ); 430 // } 431 // System.out.println( cachedGeos.toString() ); 432 // if ( !doubleGeos.isEmpty() ) { 433 // Set<String> keys = doubleGeos.keySet(); 434 // LOG.logInfo( "Following geographic crs's could probably be mapped on eachother" ); 435 // for ( String key : keys ) { 436 // LOG.logInfo( key + " : " + doubleGeos.get( key ) ); 437 // } 438 // } 439 // if ( !doubleProjCRS.isEmpty() ) { 440 // Set<String> keys = doubleProjCRS.keySet(); 441 // LOG.logInfo( "Following projected crs's could probably be mapped on eachother" ); 442 // for ( String key : keys ) { 443 // LOG.logInfo( key + " : " + doubleProjCRS.get( key ) ); 444 // } 445 // 446 // } 447 // if ( !doubleGeocentricCRSs.isEmpty() ) { 448 // Set<String> keys = doubleGeocentricCRSs.keySet(); 449 // LOG.logInfo( "Following geocentric crs's could probably be mapped on eachother" ); 450 // for ( String key : keys ) { 451 // LOG.logInfo( key + " : " + doubleGeocentricCRSs.get( key ) ); 452 // } 453 // } 454 // 455 // if ( !doubleProjections.isEmpty() ) { 456 // Set<String> keys = doubleProjections.keySet(); 457 // LOG.logInfo( "Following projections could probably be mapped on eachother" ); 458 // for ( String key : keys ) { 459 // LOG.logInfo( key + " : " + doubleProjections.get( key ) ); 460 // } 461 // } 462 // if ( !doubleDatums.isEmpty() ) { 463 // Set<String> keys = doubleDatums.keySet(); 464 // LOG.logInfo( "Following datums could probably be mapped on eachother" ); 465 // for ( String key : keys ) { 466 // LOG.logInfo( key + " : " + doubleDatums.get( key ) ); 467 // } 468 // } 469 // if ( !doubleToWGS.isEmpty() ) { 470 // Set<String> keys = doubleToWGS.keySet(); 471 // LOG.logInfo( "Following wgs conversion infos could probably be mapped on eachother" ); 472 // for ( String key : keys ) { 473 // LOG.logInfo( key + " : " + doubleToWGS.get( key ) ); 474 // } 475 // } 476 // if ( !doubleEllipsoids.isEmpty() ) { 477 // Set<String> keys = doubleEllipsoids.keySet(); 478 // LOG.logInfo( "Following ellipsoids could probably be mapped on eachother" ); 479 // for ( String key : keys ) { 480 // LOG.logInfo( key + " : " + doubleEllipsoids.get( key ) ); 481 // } 482 // } 483 // if ( !doubleMeridians.isEmpty() ) { 484 // Set<String> keys = doubleEllipsoids.keySet(); 485 // LOG.logInfo( "Following prime meridians could probably be mapped on eachother" ); 486 // for ( String key : keys ) { 487 // LOG.logInfo( key + " : " + doubleMeridians.get( key ) ); 488 // } 489 // } 490 // } else { 491 // Collection<CompoundCRS> cCRSs = compoundCRSs.values(); 492 // for ( String key : compoundCRSs.keySet() ) { 493 // CompoundCRS crs = compoundCRSs.get( key ); 494 // if ( !allSystems.contains( crs ) ) { 495 // allSystems.add( crs ); 496 // } 497 // } 498 // for ( String key : geographicCRSs.keySet() ) { 499 // GeographicCRS crs = geographicCRSs.get( key ); 500 // if ( !allSystems.contains( crs ) ) { 501 // allSystems.add( crs ); 502 // } 503 // } 504 // for ( String key : geocentricCRSs.keySet() ) { 505 // GeocentricCRS crs = geocentricCRSs.get( key ); 506 // if ( !allSystems.contains( crs ) ) { 507 // allSystems.add( crs ); 508 // } 509 // } 510 // for ( String key : projectedCRSs.keySet() ) { 511 // ProjectedCRS crs = projectedCRSs.get( key ); 512 // if ( !allSystems.contains( crs ) ) { 513 // allSystems.add( crs ); 514 // } 515 // } 516 // } 517 518 } else { 519 LOG.logDebug( "The root element is null, is this correct behaviour?" ); 520 } 521 return allSystems; 522 } 523 524 public Identifiable getIdentifiable( String id ) 525 throws CRSConfigurationException { 526 Identifiable result = getCachedIdentifiable( id ); 527 if ( result == null ) { 528 result = getResolver().parseIdentifiableObject( id ); 529 } 530 return result; 531 } 532 533 @Override 534 protected CoordinateSystem parseCoordinateSystem( Element crsDefinition ) 535 throws CRSConfigurationException { 536 return getResolver().parseCoordinateSystem( crsDefinition ); 537 } 538 539 @Override 540 public Transformation parseTransformation( Element transformationDefinition ) 541 throws CRSConfigurationException { 542 return getResolver().parseTransformation( transformationDefinition ); 543 544 } 545 546 public Transformation getTransformation( CoordinateSystem sourceCRS, CoordinateSystem targetCRS ) 547 throws CRSConfigurationException { 548 return getResolver().getTransformation( sourceCRS, targetCRS ); 549 } 550 551 public List<Transformation> getTransformations() { 552 throw new UnsupportedOperationException( 553 "Parsing of transformations is not applicable for deegree configuration files yet." ); 554 } 555 }