    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/crs/configuration/deegree/CRSExporter.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 static org.deegree.crs.projections.ProjectionUtils.EPS11;
    040    import static org.deegree.ogcbase.CommonNamespaces.CRSNS;
    041
    042    import java.io.Writer;
    043    import java.net.MalformedURLException;
    044    import java.util.LinkedList;
    045    import java.util.List;
    046    import java.util.Properties;
    047
    048    import javax.xml.transform.TransformerException;
    049
    050    import org.deegree.crs.Identifiable;
    051    import org.deegree.crs.components.Axis;
    052    import org.deegree.crs.components.Ellipsoid;
    053    import org.deegree.crs.components.GeodeticDatum;
    054    import org.deegree.crs.components.PrimeMeridian;
    055    import org.deegree.crs.components.Unit;
    056    import org.deegree.crs.coordinatesystems.CompoundCRS;
    057    import org.deegree.crs.coordinatesystems.CoordinateSystem;
    058    import org.deegree.crs.coordinatesystems.GeocentricCRS;
    059    import org.deegree.crs.coordinatesystems.GeographicCRS;
    060    import org.deegree.crs.coordinatesystems.ProjectedCRS;
    061    import org.deegree.crs.projections.Projection;
    062    import org.deegree.crs.projections.azimuthal.StereographicAzimuthal;
    063    import org.deegree.crs.projections.conic.LambertConformalConic;
    064    import org.deegree.crs.projections.cylindric.TransverseMercator;
    065    import org.deegree.crs.transformations.helmert.Helmert;
    066    import org.deegree.crs.transformations.polynomial.PolynomialTransformation;
    067    import org.deegree.datatypes.QualifiedName;
    068    import org.deegree.framework.log.ILogger;
    069    import org.deegree.framework.log.LoggerFactory;
    070    import org.deegree.framework.xml.NamespaceContext;
    071    import org.deegree.framework.xml.XMLFragment;
    072    import org.deegree.framework.xml.XMLParsingException;
    073    import org.deegree.framework.xml.XMLTools;
    074    import org.deegree.ogcbase.CommonNamespaces;
    075    import org.w3c.dom.Document;
    076    import org.w3c.dom.Element;
    077
    078    /**
    079     * The <code>CRSExporter</code> exports to the old version format (no version attribute).
    080     *
    081     * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
    082     *
    083     * @author last edited by: $Author: mschneider $
    084     *
    085     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    086     *
    087     */
    088    public class CRSExporter {
    089
    090        private static ILogger LOG = LoggerFactory.getLogger( CRSExporter.class );
    091
    092        /**
    093         * The namespaces used in deegree.
    094         */
    095        private static NamespaceContext nsContext = CommonNamespaces.getNamespaceContext();
    096
    097        /**
    098         * The prefix to use.
    099         */
    100        private final static String PRE = CommonNamespaces.CRS_PREFIX + ":";
    101
    102        /**
    103         *
    104         * @param properties
    105         *            to read configuration from.
    106         */
    107        public CRSExporter( Properties properties ) {
    108            // nothing yet.
    109        }
    110
    111        /**
    112         * Export the given list of CoordinateSystems into the crs-definition format.
    113         *
    114         * @param writer
    115         * @param crsToExport
    116         */
    117        public void export( Writer writer, List<CoordinateSystem> crsToExport ) {
    118            if ( crsToExport != null ) {
    119                if ( crsToExport.size() != 0 ) {
    120                    LOG.logDebug( "Trying to export: " + crsToExport.size() + " coordinate systems." );
    121                    XMLFragment frag = new XMLFragment( new QualifiedName( "crs", "definitions", CommonNamespaces.CRSNS ) );
    122                    Element root = frag.getRootElement();
    123                    LinkedList<String> exportedIDs = new LinkedList<String>();
    124                    for ( CoordinateSystem crs : crsToExport ) {
    125                        if ( crs.getType() == CoordinateSystem.GEOCENTRIC_CRS ) {
    126                            export( (GeocentricCRS) crs, root, exportedIDs );
    127                        } else if ( crs.getType() == CoordinateSystem.GEOGRAPHIC_CRS ) {
    128                            export( (GeographicCRS) crs, root, exportedIDs );
    129                        } else if ( crs.getType() == CoordinateSystem.PROJECTED_CRS ) {
    130                            export( (ProjectedCRS) crs, root, exportedIDs );
    131                        } else if ( crs.getType() == CoordinateSystem.COMPOUND_CRS ) {
    132                            export( (CompoundCRS) crs, root, exportedIDs );
    133                        }
    134                    }
    135                    root.normalize();
    136                    Document validDoc = createValidDocument( root );
    137                    try {
    138                        XMLFragment frag2 = new XMLFragment( validDoc, "http://www.deegree.org/crs" );
    139                        frag2.prettyPrint( writer );
    140                    } catch ( MalformedURLException e ) {
    141                        LOG.logError( "Could not export crs definitions because: " + e.getMessage(), e );
    142                    } catch ( TransformerException e ) {
    143                        LOG.logError( "Could not export crs definitions because: " + e.getMessage(), e );
    144                    }
    145                } else {
    146                    LOG.logWarning( "No coordinate system were given (list.size() == 0)." );
    147                }
    148            } else {
    149                LOG.logError( "No coordinate system were given (list == null)." );
    150            }
    151        }
    152
    153        /**
    154         * Export the projected CRS to it's appropriate deegree-crs-definitions form.
    155         *
    156         * @param projectedCRS
    157         *            to be exported
    158         * @param rootNode
    159         *            to export the projected CRS to.
    160         * @param exportedIds
    161         *            a list of id's already exported.
    162         */
    163        private void export( ProjectedCRS projectedCRS, Element rootNode, List<String> exportedIds ) {
    164            if ( !exportedIds.contains( projectedCRS.getIdentifier() ) ) {
    165                Element crsElement = XMLTools.appendElement( rootNode, CommonNamespaces.CRSNS, PRE + "projectedCRS" );
    166                exportAbstractCRS( projectedCRS, crsElement );
    167                GeographicCRS underLyingCRS = projectedCRS.getGeographicCRS();
    168                export( underLyingCRS, rootNode, exportedIds );
    169
    170                // Add a reference from the geographicCRS element to the projectedCRS element.
    171                XMLTools.appendElement( crsElement, CommonNamespaces.CRSNS, PRE + "usedGeographicCRS",
    172                                        underLyingCRS.getIdentifier() );
    173
    174                export( projectedCRS.getProjection(), crsElement );
    175
    176                // Add the ids to the exportedID list.
    177                for ( String eID : projectedCRS.getIdentifiers() ) {
    178                    exportedIds.add( eID );
    179                }
    180                // finally add the crs node to the rootnode.
    181                rootNode.appendChild( crsElement );
    182            }
    183        }
    184
    185        /**
    186         * Export the geocentric/geographic CRS to it's appropriate deegree-crs-definitions form.
    187         *
    188         * @param geographicCRS
    189         *            to be exported
    190         * @param rootNode
    191         *            to export the geographic CRS to.
    192         * @param exportedIds
    193         *            a list of id's already exported.
    194         */
    195        private void export( GeographicCRS geographicCRS, Element rootNode, List<String> exportedIds ) {
    196            if ( !exportedIds.contains( geographicCRS.getIdentifier() ) ) {
    197                Element crsElement = XMLTools.appendElement( rootNode, CommonNamespaces.CRSNS, PRE + "geographicCRS" );
    198                exportAbstractCRS( geographicCRS, crsElement );
    199
    200                // export the datum.
    201                GeodeticDatum datum = geographicCRS.getGeodeticDatum();
    202                if ( datum != null ) {
    203                    export( datum, rootNode, exportedIds );
    204                    // Add a reference from the datum element to the geographic element.
    205                    XMLTools.appendElement( crsElement, CommonNamespaces.CRSNS, PRE + "usedDatum", datum.getIdentifier() );
    206                } else {
    207                    LOG.logError( "The given datum is not a geodetic one, this mey not be!" );
    208                }
    209                // Add the ids to the exportedID list.
    210                for ( String eID : geographicCRS.getIdentifiers() ) {
    211                    exportedIds.add( eID );
    212                }
    213                // finally add the crs node to the rootnode.
    214                rootNode.appendChild( crsElement );
    215            }
    216        }
    217
    218        /**
    219         * Export the compoundCRS to it's appropriate deegree-crs-definitions form.
    220         *
    221         * @param compoundCRS
    222         *            to be exported
    223         * @param rootNode
    224         *            to export the geographic CRS to.
    225         * @param exportedIds
    226         *            a list of id's already exported.
    227         */
    228        private void export( CompoundCRS compoundCRS, Element rootNode, List<String> exportedIds ) {
    229            if ( !exportedIds.contains( compoundCRS.getIdentifier() ) ) {
    230                Element crsElement = XMLTools.appendElement( rootNode, CommonNamespaces.CRSNS, PRE + "compoundCRS" );
    231                exportIdentifiable( compoundCRS, crsElement );
    232                CoordinateSystem underLyingCRS = compoundCRS.getUnderlyingCRS();
    233                if ( underLyingCRS.getType() == CoordinateSystem.GEOGRAPHIC_CRS ) {
    234                    export( (GeographicCRS) underLyingCRS, rootNode, exportedIds );
    235                } else if ( underLyingCRS.getType() == CoordinateSystem.PROJECTED_CRS ) {
    236                    export( (ProjectedCRS) underLyingCRS, rootNode, exportedIds );
    237                }
    238
    239                // Add a reference from the geographicCRS element to the projectedCRS element.
    240                XMLTools.appendElement( crsElement, CommonNamespaces.CRSNS, PRE + "usedCRS", underLyingCRS.getIdentifier() );
    241                export( compoundCRS.getHeightAxis(), crsElement );
    242
    243                XMLTools.appendElement( crsElement, CommonNamespaces.CRSNS, PRE + "defaultHeight",
    244                                        Double.toString( compoundCRS.getDefaultHeight() ) );
    245
    246                // Add the ids to the exportedID list.
    247                for ( String eID : compoundCRS.getIdentifiers() ) {
    248                    exportedIds.add( eID );
    249                }
    250                // finally add the crs node to the rootnode.
    251                rootNode.appendChild( crsElement );
    252            }
    253        }
    254
    255        /**
    256         * Export the projection to it's appropriate deegree-crs-definitions form.
    257         *
    258         * @param projection
    259         *            to be exported
    260         * @param rootNode
    261         *            to export the projection to.
    262         */
    263        private void export( Projection projection, Element rootNode ) {
    264            Element rootElem = XMLTools.appendElement( rootNode, CommonNamespaces.CRSNS, PRE + "projection" );
    265            String elementName = projection.getImplementationName();
    266            Element projectionElement = XMLTools.appendElement( rootElem, CommonNamespaces.CRSNS, PRE + elementName );
    267            // exportIdentifiable( projection, projectionElement );
    268            Element tmp = XMLTools.appendElement( projectionElement, CommonNamespaces.CRSNS, PRE
    269                                                                                             + "latitudeOfNaturalOrigin",
    270                                                  Double.toString( Math.toDegrees( projection.getProjectionLatitude() ) ) );
    271            tmp.setAttribute( "inDegrees", "true" );
    272            tmp = XMLTools.appendElement( projectionElement, CommonNamespaces.CRSNS, PRE + "longitudeOfNaturalOrigin",
    273                                          Double.toString( Math.toDegrees( projection.getProjectionLongitude() ) ) );
    274            tmp.setAttribute( "inDegrees", "true" );
    275
    276            XMLTools.appendElement( projectionElement, CommonNamespaces.CRSNS, PRE + "scaleFactor",
    277                                    Double.toString( projection.getScale() ) );
    278            XMLTools.appendElement( projectionElement, CommonNamespaces.CRSNS, PRE + "falseEasting",
    279                                    Double.toString( projection.getFalseEasting() ) );
    280            XMLTools.appendElement( projectionElement, CommonNamespaces.CRSNS, PRE + "falseNorthing",
    281                                    Double.toString( projection.getFalseNorthing() ) );
    282            if ( "transverseMercator".equalsIgnoreCase( elementName ) ) {
    283                XMLTools.appendElement( projectionElement, CommonNamespaces.CRSNS, PRE + "northernHemisphere",
    284                                        Boolean.toString( ( (TransverseMercator) projection ).getHemisphere() ) );
    285            } else if ( "lambertConformalConic".equalsIgnoreCase( elementName ) ) {
    286                double paralellLatitude = ( (LambertConformalConic) projection ).getFirstParallelLatitude();
    287                if ( !Double.isNaN( paralellLatitude ) && Math.abs( paralellLatitude ) > EPS11 ) {
    288                    paralellLatitude = Math.toDegrees( paralellLatitude );
    289                    tmp = XMLTools.appendElement( projectionElement, CommonNamespaces.CRSNS, PRE + "firstParallelLatitude",
    290                                                  Double.toString( paralellLatitude ) );
    291                    tmp.setAttribute( "inDegrees", "true" );
    292                }
    293                paralellLatitude = ( (LambertConformalConic) projection ).getSecondParallelLatitude();
    294                if ( !Double.isNaN( paralellLatitude ) && Math.abs( paralellLatitude ) > EPS11 ) {
    295                    paralellLatitude = Math.toDegrees( paralellLatitude );
    296                    tmp = XMLTools.appendElement( projectionElement, CommonNamespaces.CRSNS,
    297                                                  PRE + "secondParallelLatitude", Double.toString( paralellLatitude ) );
    298                    tmp.setAttribute( "inDegrees", "true" );
    299                }
    300            } else if ( "stereographicAzimuthal".equalsIgnoreCase( elementName ) ) {
    301                tmp = XMLTools.appendElement(
    302                                              projectionElement,
    303                                              CommonNamespaces.CRSNS,
    304                                              PRE + "trueScaleLatitude",
    305                                              Double.toString( ( (StereographicAzimuthal) projection ).getTrueScaleLatitude() ) );
    306                tmp.setAttribute( "inDegrees", "true" );
    307            }
    308        }
    309
    310        /**
    311         * Export the confInvo to it's appropriate deegree-crs-definitions form.
    312         *
    313         * @param confInvo
    314         *            to be exported
    315         * @param rootNode
    316         *            to export the confInvo to.
    317         * @param exportedIds
    318         *            a list of id's already exported.
    319         */
    320        private void export( Helmert confInvo, Element rootNode, final List<String> exportedIds ) {
    321            if ( !exportedIds.contains( confInvo.getIdentifier() ) ) {
    322                Element convElement = XMLTools.appendElement( rootNode, CommonNamespaces.CRSNS, PRE + "wgs84Transformation" );
    323                exportIdentifiable( confInvo, convElement );
    324
    325                XMLTools.appendElement( convElement, CommonNamespaces.CRSNS, PRE + "xAxisTranslation",
    326                                        Double.toString( confInvo.dx ) );
    327                XMLTools.appendElement( convElement, CommonNamespaces.CRSNS, PRE + "yAxisTranslation",
    328                                        Double.toString( confInvo.dy ) );
    329                XMLTools.appendElement( convElement, CommonNamespaces.CRSNS, PRE + "zAxisTranslation",
    330                                        Double.toString( confInvo.dz ) );
    331                XMLTools.appendElement( convElement, CommonNamespaces.CRSNS, PRE + "xAxisRotation",
    332                                        Double.toString( confInvo.ex ) );
    333                XMLTools.appendElement( convElement, CommonNamespaces.CRSNS, PRE + "yAxisRotation",
    334                                        Double.toString( confInvo.ey ) );
    335                XMLTools.appendElement( convElement, CommonNamespaces.CRSNS, PRE + "zAxisRotation",
    336                                        Double.toString( confInvo.ez ) );
    337                XMLTools.appendElement( convElement, CommonNamespaces.CRSNS, PRE + "scaleDifference",
    338                                        Double.toString( confInvo.ppm ) );
    339
    340                // Add the ids to the exportedID list.
    341                for ( String eID : confInvo.getIdentifiers() ) {
    342                    exportedIds.add( eID );
    343                }
    344
    345                // finally add the WGS84-Transformation node to the rootnode.
    346                rootNode.appendChild( convElement );
    347            }
    348
    349        }
    350
    351        /**
    352         * Export the PrimeMeridian to it's appropriate deegree-crs-definitions form.
    353         *
    354         * @param pMeridian
    355         *            to be exported
    356         * @param rootNode
    357         *            to export the pMeridian to.
    358         * @param exportedIds
    359         *            a list of id's already exported.
    360         */
    361        private void export( PrimeMeridian pMeridian, Element rootNode, final List<String> exportedIds ) {
    362            if ( !exportedIds.contains( pMeridian.getIdentifier() ) ) {
    363                Element meridianElement = XMLTools.appendElement( rootNode, CommonNamespaces.CRSNS, PRE + "primeMeridian" );
    364                exportIdentifiable( pMeridian, meridianElement );
    365                export( pMeridian.getAngularUnit(), meridianElement );
    366                XMLTools.appendElement( meridianElement, CommonNamespaces.CRSNS, PRE + "longitude",
    367                                        Double.toString( pMeridian.getLongitude() ) );
    368
    369                // Add the ids to the exportedID list.
    370                for ( String eID : pMeridian.getIdentifiers() ) {
    371                    exportedIds.add( eID );
    372                }
    373
    374                // finally add the prime meridian node to the rootnode.
    375                rootNode.appendChild( meridianElement );
    376            }
    377        }
    378
    379        /**
    380         * Export the ellipsoid to it's appropriate deegree-crs-definitions form.
    381         *
    382         * @param ellipsoid
    383         *            to be exported
    384         * @param rootNode
    385         *            to export the ellipsoid to.
    386         * @param exportedIds
    387         *            a list of id's already exported.
    388         */
    389        private void export( Ellipsoid ellipsoid, Element rootNode, final List<String> exportedIds ) {
    390            if ( !exportedIds.contains( ellipsoid.getIdentifier() ) ) {
    391                Element ellipsoidElement = XMLTools.appendElement( rootNode, CommonNamespaces.CRSNS, PRE + "ellipsoid" );
    392                exportIdentifiable( ellipsoid, ellipsoidElement );
    393                XMLTools.appendElement( ellipsoidElement, CommonNamespaces.CRSNS, PRE + "semiMajorAxis",
    394                                        Double.toString( ellipsoid.getSemiMajorAxis() ) );
    395                XMLTools.appendElement( ellipsoidElement, CommonNamespaces.CRSNS, PRE + "inverseFlatting",
    396                                        Double.toString( ellipsoid.getInverseFlattening() ) );
    397                export( ellipsoid.getUnits(), ellipsoidElement );
    398
    399                // Add the ids to the exportedID list.
    400                for ( String eID : ellipsoid.getIdentifiers() ) {
    401                    exportedIds.add( eID );
    402                }
    403                // finally add the ellipsoid node to the rootnode.
    404                rootNode.appendChild( ellipsoidElement );
    405            }
    406        }
    407
    408        /**
    409         * Export the datum to it's appropriate deegree-crs-definitions form.
    410         *
    411         * @param datum
    412         *            to be exported
    413         * @param rootNode
    414         *            to export the datum to.
    415         * @param exportedIds
    416         *            a list of id's already exported.
    417         */
    418        private void export( GeodeticDatum datum, Element rootNode, List<String> exportedIds ) {
    419            if ( !exportedIds.contains( datum.getIdentifier() ) ) {
    420                Element datumElement = XMLTools.appendElement( rootNode, CommonNamespaces.CRSNS, PRE + "geodeticDatum" );
    421                exportIdentifiable( datum, datumElement );
    422                /**
    423                 * EXPORT the ELLIPSOID
    424                 */
    425                Ellipsoid ellipsoid = datum.getEllipsoid();
    426                if ( ellipsoid != null ) {
    427                    export( ellipsoid, rootNode, exportedIds );
    428                    // Add a reference from the ellipsoid element to the datum element.
    429                    XMLTools.appendElement( datumElement, CommonNamespaces.CRSNS, PRE + "usedEllipsoid",
    430                                            ellipsoid.getIdentifier() );
    431                }
    432
    433                /**
    434                 * EXPORT the PRIME_MERIDIAN
    435                 */
    436                PrimeMeridian pMeridian = datum.getPrimeMeridian();
    437                if ( pMeridian != null ) {
    438                    export( pMeridian, rootNode, exportedIds );
    439                    // Add a reference from the prime meridian element to the datum element.
    440                    XMLTools.appendElement( datumElement, CommonNamespaces.CRSNS, PRE + "usedPrimeMeridian",
    441                                            pMeridian.getIdentifier() );
    442                }
    443
    444                /**
    445                 * EXPORT the WGS-84-Conversion INFO
    446                 */
    447                Helmert confInvo = datum.getWGS84Conversion();
    448                if ( confInvo != null ) {
    449                    export( confInvo, rootNode, exportedIds );
    450                    // Add a reference from the prime meridian element to the datum element.
    451                    XMLTools.appendElement( datumElement, CommonNamespaces.CRSNS, PRE + "usedWGS84ConversionInfo",
    452                                            confInvo.getIdentifier() );
    453                }
    454
    455                // Add the ids to the exportedID list.
    456                for ( String eID : datum.getIdentifiers() ) {
    457                    exportedIds.add( eID );
    458                }
    459                // finally add the datum node to the rootnode.
    460                rootNode.appendChild( datumElement );
    461            }
    462        }
    463
    464        /**
    465         * Export toplevel crs features.
    466         *
    467         * @param crs
    468         *            to be exported
    469         * @param crsElement
    470         *            to export to
    471         */
    472        private void exportAbstractCRS( CoordinateSystem crs, Element crsElement ) {
    473            exportIdentifiable( crs, crsElement );
    474            Axis[] axis = crs.getAxis();
    475            StringBuilder axisOrder = new StringBuilder( 200 );
    476            for ( int i = 0; i < axis.length; ++i ) {
    477                Axis a = axis[i];
    478                export( a, crsElement );
    479                axisOrder.append( a.getName() );
    480                if ( ( i + 1 ) < axis.length ) {
    481                    axisOrder.append( ", " );
    482                }
    483            }
    484            XMLTools.appendElement( crsElement, CommonNamespaces.CRSNS, PRE + "axisOrder", axisOrder.toString() );
    485
    486            export( crs.getTransformations(), crsElement );
    487
    488        }
    489
    490        /**
    491         * Export the geocentric CRS to it's appropriate deegree-crs-definitions form.
    492         *
    493         * @param geocentricCRS
    494         *            to be exported
    495         * @param rootNode
    496         *            to export the geocentric CRS to.
    497         * @param exportedIds
    498         *            a list of id's already exported.
    499         */
    500        private void export( GeocentricCRS geocentricCRS, Element rootNode, List<String> exportedIds ) {
    501            if ( !exportedIds.contains( geocentricCRS.getIdentifier() ) ) {
    502                Element crsElement = XMLTools.appendElement( rootNode, CommonNamespaces.CRSNS, PRE + "geocentricCRS" );
    503                exportAbstractCRS( geocentricCRS, crsElement );
    504                // export the datum.
    505                GeodeticDatum datum = geocentricCRS.getGeodeticDatum();
    506                if ( datum != null ) {
    507                    export( datum, rootNode, exportedIds );
    508                    // Add a reference from the datum element to the geocentric element.
    509                    XMLTools.appendElement( crsElement, CommonNamespaces.CRSNS, PRE + "usedDatum", datum.getIdentifier() );
    510                } // Add the ids to the exportedID list.
    511                for ( String eID : geocentricCRS.getIdentifiers() ) {
    512                    exportedIds.add( eID );
    513                }
    514                // finally add the crs node to the rootnode.
    515                rootNode.appendChild( crsElement );
    516            }
    517        }
    518
    519        /**
    520         * Creates the basic nodes of the identifiable object.
    521         *
    522         * @param id
    523         *            object to be exported.
    524         * @param currentNode
    525         *            to expand
    526         */
    527        private void exportIdentifiable( Identifiable id, Element currentNode ) {
    528            for ( String i : id.getIdentifiers() ) {
    529                if ( i != null ) {
    530                    XMLTools.appendElement( currentNode, CommonNamespaces.CRSNS, PRE + "id", i );
    531                }
    532
    533            }
    534            if ( id.getNames() != null && id.getNames().length > 0 ) {
    535                for ( String i : id.getNames() ) {
    536                    if ( i != null ) {
    537                        XMLTools.appendElement( currentNode, CommonNamespaces.CRSNS, PRE + "name", i );
    538                    }
    539                }
    540            }
    541            if ( id.getVersions() != null && id.getVersions().length > 0 ) {
    542                for ( String i : id.getVersions() ) {
    543                    if ( i != null ) {
    544                        XMLTools.appendElement( currentNode, CommonNamespaces.CRSNS, PRE + "version", i );
    545                    }
    546                }
    547            }
    548            if ( id.getDescriptions() != null && id.getDescriptions().length > 0 ) {
    549                for ( String i : id.getDescriptions() ) {
    550                    if ( i != null ) {
    551                        XMLTools.appendElement( currentNode, CommonNamespaces.CRSNS, PRE + "description", i );
    552                    }
    553                }
    554            }
    555            if ( id.getAreasOfUse() != null && id.getAreasOfUse().length > 0 ) {
    556                for ( String i : id.getAreasOfUse() ) {
    557                    if ( i != null ) {
    558                        XMLTools.appendElement( currentNode, CommonNamespaces.CRSNS, PRE + "areaOfUse", i );
    559                    }
    560                }
    561            }
    562        }
    563
    564        /**
    565         * Export an axis to xml in the crs-definitions schema layout.
    566         *
    567         * @param axis
    568         *            to be exported.
    569         * @param currentNode
    570         *            to export to.
    571         */
    572        private void export( Axis axis, Element currentNode ) {
    573            Document doc = currentNode.getOwnerDocument();
    574            Element axisElement = doc.createElementNS( CRSNS.toASCIIString(), PRE + "Axis" );
    575            // The name.
    576            XMLTools.appendElement( axisElement, CommonNamespaces.CRSNS, PRE + "name", axis.getName() );
    577
    578            // the units.
    579            Unit units = axis.getUnits();
    580            export( units, axisElement );
    581
    582            XMLTools.appendElement( axisElement, CommonNamespaces.CRSNS, PRE + "axisOrientation",
    583                                    axis.getOrientationAsString() );
    584            currentNode.appendChild( axisElement );
    585        }
    586
    587        /**
    588         * Export a list of transformations to the crs element to xml with respect to the crs-definitions schema layout.
    589         *
    590         * @param transformations
    591         *            to be exported.
    592         * @param currentNode
    593         *            to export to.
    594         */
    595        private void export( List<PolynomialTransformation> transformations, Element currentNode ) {
    596            for ( PolynomialTransformation transformation : transformations ) {
    597                Element transformationElement = XMLTools.appendElement( currentNode, CRSNS, PRE
    598                                                                                            + "polynomialTransformation" );
    599                if ( !"leastsquare".equals( transformation.getImplementationName().toLowerCase() ) ) {
    600                    transformationElement.setAttribute( "class", transformation.getClass().getCanonicalName() );
    601                }
    602                Element transformElement = XMLTools.appendElement( transformationElement, CRSNS,
    603                                                                   PRE + transformation.getImplementationName() );
    604                XMLTools.appendElement( transformElement, CRSNS, PRE + "polynomialOrder",
    605                                        Integer.toString( transformation.getOrder() ) );
    606                XMLTools.appendElement( transformElement, CRSNS, PRE + "xParameters",
    607                                        transformation.getFirstParams().toString() );
    608                XMLTools.appendElement( transformElement, CRSNS, PRE + "yParameters",
    609                                        transformation.getSecondParams().toString() );
    610                XMLTools.appendElement( transformElement, CRSNS, PRE + "targetCRS",
    611                                        transformation.getTargetCRS().getIdentifier() );
    612            }
    613        }
    614
    615        /**
    616         * Export a unit to xml in the crs-definitions schema layout.
    617         *
    618         * @param units
    619         *            to be exported.
    620         * @param currentNode
    621         *            to export to.
    622         */
    623        private void export( Unit units, Element currentNode ) {
    624            if ( units != null && currentNode != null ) {
    625                XMLTools.appendElement( currentNode, CommonNamespaces.CRSNS, PRE + "units", units.getName() );
    626            }
    627        }
    628
    629        private Document createValidDocument( Element root ) {
    630            // List<Element> lastInput = new LinkedList<Element>( 100 );
    631            try {
    632                List<Element> valid = XMLTools.getElements( root, PRE + "ellipsoid", nsContext );
    633                valid.addAll( XMLTools.getElements( root, PRE + "geodeticDatum", nsContext ) );
    634                valid.addAll( XMLTools.getElements( root, PRE + "projectedCRS", nsContext ) );
    635                valid.addAll( XMLTools.getElements( root, PRE + "geographicCRS", nsContext ) );
    636                valid.addAll( XMLTools.getElements( root, PRE + "compoundCRS", nsContext ) );
    637                valid.addAll( XMLTools.getElements( root, PRE + "geocentricCRS", nsContext ) );
    638                valid.addAll( XMLTools.getElements( root, PRE + "primeMeridian", nsContext ) );
    639                valid.addAll( XMLTools.getElements( root, PRE + "wgs84Transformation", nsContext ) );
    640                Document doc = XMLTools.create();
    641                Element newRoot = doc.createElementNS( CommonNamespaces.CRSNS.toASCIIString(), PRE + "definitions" );
    642                newRoot = (Element) doc.importNode( newRoot, false );
    643                newRoot = (Element) doc.appendChild( newRoot );
    644                for ( int i = 0; i < valid.size(); ++i ) {
    645                    Element el = valid.get( i );
    646                    el = (Element) doc.importNode( el, true );
    647                    newRoot.appendChild( el );
    648                }
    649                XMLTools.appendNSBinding( newRoot, CommonNamespaces.XSI_PREFIX, CommonNamespaces.XSINS );
    650                newRoot.setAttributeNS(
    651                                        CommonNamespaces.XSINS.toASCIIString(),
    652                                        "xsi:schemaLocation",
    653                                        "http://www.deegree.org/crs c:/windows/profiles/rutger/EIGE~VO5/eclipse-projekte/coordinate_systems/resources/schema/crsdefinition.xsd" );
    654                return doc;
    655            } catch ( XMLParsingException xmle ) {
    656                xmle.printStackTrace();
    657            }
    658            return root.getOwnerDocument();
    659        }
    660
    661    }