001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/model/coverage/grid/GMLGridCoverageWriter.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.OutputStream;
040    import java.net.URL;
041    import java.util.List;
042    import java.util.Map;
043    
044    import org.deegree.datatypes.parameter.GeneralParameterValueIm;
045    import org.deegree.datatypes.parameter.InvalidParameterNameException;
046    import org.deegree.datatypes.parameter.InvalidParameterValueException;
047    import org.deegree.datatypes.parameter.OperationParameterIm;
048    import org.deegree.datatypes.parameter.ParameterNotFoundException;
049    import org.deegree.framework.log.ILogger;
050    import org.deegree.framework.log.LoggerFactory;
051    import org.deegree.framework.xml.NamespaceContext;
052    import org.deegree.framework.xml.XMLFragment;
053    import org.deegree.framework.xml.XMLParsingException;
054    import org.deegree.framework.xml.XMLTools;
055    import org.deegree.ogcbase.CommonNamespaces;
056    import org.w3c.dom.Element;
057    import org.w3c.dom.Node;
058    
059    /**
060     * Implementation of {@link "org.opengis.coverage.grid.GridCoverageWriter"} for writing a GridCoverage as GML document
061     * to a defined destioation
062     *
063     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
064     * @author last edited by: $Author: mschneider $
065     *
066     * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $
067     */
068    public class GMLGridCoverageWriter extends AbstractGridCoverageWriter {
069    
070        private static ILogger LOG = LoggerFactory.getLogger( GMLGridCoverageWriter.class );
071    
072        private URL template = GMLGridCoverageWriter.class.getResource( "gml_rectifiedgrid_template.xml" );
073    
074        /**
075         *
076         * @param destination
077         * @param metadata
078         * @param subNames
079         * @param currentSubname
080         * @param format
081         */
082        public GMLGridCoverageWriter( Object destination, Map<String, Object> metadata, String[] subNames,
083                                      String currentSubname, Format format ) {
084            super( destination, metadata, subNames, currentSubname, format );
085    
086        }
087    
088        /**
089         * disposes all resources assigned to a GMLGridCoverageWriter instance. For most cases this will be IO-resources
090         *
091         * @throws IOException
092         */
093        public void dispose()
094                                throws IOException {
095            // nothing here, why does it exist?
096        }
097    
098        /**
099         * @param coverage
100         * @param parameters
101         *            must contain the servlet URL within the first field; all other fields must contain the required
102         *            parameters for a valid GetCoverage request
103         * @throws InvalidParameterNameException
104         * @throws InvalidParameterValueException
105         * @throws ParameterNotFoundException
106         * @throws IOException
107         */
108        public void write( GridCoverage coverage, GeneralParameterValueIm[] parameters )
109                                throws InvalidParameterNameException, InvalidParameterValueException,
110                                ParameterNotFoundException, IOException {
111            XMLFragment xml = new XMLFragment();
112            try {
113                xml.load( template );
114                Element root = xml.getRootElement();
115                NamespaceContext nsc = CommonNamespaces.getNamespaceContext();
116    
117                String xpath = "gml:rectifiedGridDomain/gml:RectifiedGrid/gml:limits/gml:GridEnvelope/gml:low";
118                Element element = (Element) XMLTools.getNode( root, xpath, nsc );
119                double x = coverage.getEnvelope().getMin().getX();
120                double y = coverage.getEnvelope().getMin().getY();
121                Node node = root.getOwnerDocument().createTextNode( Double.toString( x ) + ' ' + Double.toString( y ) );
122                element.appendChild( node );
123    
124                xpath = "gml:rectifiedGridDomain/gml:RectifiedGrid/gml:limits/gml:GridEnvelope/gml:high";
125                element = (Element) XMLTools.getNode( root, xpath, nsc );
126                x = coverage.getEnvelope().getMax().getX();
127                y = coverage.getEnvelope().getMax().getY();
128                node = root.getOwnerDocument().createTextNode( Double.toString( x ) + ' ' + Double.toString( y ) );
129                element.appendChild( node );
130    
131                xpath = "gml:rectifiedGridDomain/gml:RectifiedGrid/gml:origin/gml:Point";
132                element = (Element) XMLTools.getNode( root, xpath, nsc );
133                element.setAttribute( "srsName", coverage.getCoordinateReferenceSystem().getIdentifier() );
134    
135                xpath = "gml:rectifiedGridDomain/gml:RectifiedGrid/gml:origin/gml:Point/gml:pos";
136                element = (Element) XMLTools.getNode( root, xpath, nsc );
137                x = coverage.getEnvelope().getMin().getX();
138                y = coverage.getEnvelope().getMin().getY();
139                node = root.getOwnerDocument().createTextNode( Double.toString( x ) + ' ' + Double.toString( y ) );
140                element.appendChild( node );
141    
142                double[] res = calcGridResolution( coverage, parameters );
143    
144                xpath = "gml:rectifiedGridDomain/gml:RectifiedGrid/gml:offsetVector";
145                List<Element> list = XMLTools.getElements( root, xpath, nsc );
146                for ( int i = 0; i < list.size(); i++ ) {
147                    element = list.get( i );
148                    element.setAttribute( "srsName", coverage.getCoordinateReferenceSystem().getIdentifier() );
149                    if ( i == 0 ) {
150                        node = root.getOwnerDocument().createTextNode( res[i] + " 0" );
151                        element.appendChild( node );
152                    } else if ( i == 1 ) {
153                        node = root.getOwnerDocument().createTextNode( "0 " + res[i] );
154                        element.appendChild( node );
155                    } else if ( i == 2 ) {
156                        node = root.getOwnerDocument().createTextNode( "0 0 " + res[i] );
157                        element.appendChild( node );
158                    }
159                }
160    
161                xpath = "gml:rangeSet/gml:File/gml:fileName";
162                element = (Element) XMLTools.getNode( root, xpath, nsc );
163                StringBuffer sb = new StringBuffer( 300 );
164                OperationParameterIm op = (OperationParameterIm) parameters[0].getDescriptor();
165                sb.append( op.getDefaultValue() ).append( '?' );
166                for ( int i = 1; i < parameters.length; i++ ) {
167                    // OperationParameter
168                    op = (OperationParameterIm) parameters[i].getDescriptor();
169                    sb.append( op.getName() );
170                    sb.append( '=' ).append( op.getDefaultValue() );
171                    if ( i < parameters.length - 1 ) {
172                        sb.append( '&' );
173                    }
174                }
175                node = root.getOwnerDocument().createCDATASection( sb.toString() );
176                element.appendChild( node );
177            } catch ( XMLParsingException e ) {
178                LOG.logError( "could not parse GMLGridCoverage response template", e );
179                throw new InvalidParameterValueException( "", e.getMessage(), "" );
180            } catch ( Exception e ) {
181                LOG.logError( "could not write GMLGridCoverage", e );
182                throw new InvalidParameterValueException( "", e.getMessage(), "" );
183            }
184            xml.write( ( (OutputStream) destination ) );
185    
186        }
187    
188        /**
189         * returns the resolution of the grid in x- and y- directory
190         *
191         * @param coverage
192         * @param parameters
193         * @return the resolution of the grid in x- and y- directory
194         */
195        private double[] calcGridResolution( GridCoverage coverage, GeneralParameterValueIm[] parameters ) {
196            double wx = coverage.getEnvelope().getMax().getX() - coverage.getEnvelope().getMin().getX();
197            double wy = coverage.getEnvelope().getMax().getY() - coverage.getEnvelope().getMin().getY();
198            Integer width = (Integer) getNamedParameter( parameters, "width" ).getDefaultValue();
199            Integer height = (Integer) getNamedParameter( parameters, "height" ).getDefaultValue();
200            double dx = wx / width.doubleValue();
201            double dy = wy / height.doubleValue();
202            double[] res = new double[] { dx, dy };
203            return res;
204        }
205    
206        /**
207         * selects the parameter matching the passed name from the passed array
208         *
209         * @param parameters
210         * @param name
211         * @return the parameter
212         */
213        private OperationParameterIm getNamedParameter( GeneralParameterValueIm[] parameters, String name ) {
214            for ( int i = 0; i < parameters.length; i++ ) {
215                // OperationParameter
216                OperationParameterIm op = (OperationParameterIm) parameters[i].getDescriptor();
217                if ( op.getName().equals( name ) ) {
218                    return op;
219                }
220            }
221            return null;
222        }
223    
224    }