001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/model/coverage/grid/GMLGridCoverageWriter.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003    
004     This file is part of deegree.
005     Copyright (C) 2001-2006 by:
006     EXSE, Department of Geography, University of Bonn
007     http://www.giub.uni-bonn.de/deegree/
008     lat/lon GmbH
009     http://www.lat-lon.de
010    
011     This library is free software; you can redistribute it and/or
012     modify it under the terms of the GNU Lesser General Public
013     License as published by the Free Software Foundation; either
014     version 2.1 of the License, or (at your option) any later version.
015    
016     This library is distributed in the hope that it will be useful,
017     but WITHOUT ANY WARRANTY; without even the implied warranty of
018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
019     Lesser General Public License for more details.
020    
021     You should have received a copy of the GNU Lesser General Public
022     License along with this library; if not, write to the Free Software
023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
024    
025     Contact:
026    
027     Andreas Poth
028     lat/lon GmbH
029     Aennchenstr. 19
030     53115 Bonn
031     Germany
032     E-Mail: poth@lat-lon.de
033    
034     Prof. Dr. Klaus Greve
035     Department of Geography
036     University of Bonn
037     Meckenheimer Allee 166
038     53115 Bonn
039     Germany
040     E-Mail: greve@giub.uni-bonn.de
041    
042     
043     ---------------------------------------------------------------------------*/
044    package org.deegree.model.coverage.grid;
045    
046    import java.io.IOException;
047    import java.io.OutputStream;
048    import java.net.URL;
049    import java.util.List;
050    import java.util.Map;
051    
052    import org.deegree.datatypes.parameter.GeneralParameterValueIm;
053    import org.deegree.datatypes.parameter.InvalidParameterNameException;
054    import org.deegree.datatypes.parameter.InvalidParameterValueException;
055    import org.deegree.datatypes.parameter.OperationParameterIm;
056    import org.deegree.datatypes.parameter.ParameterNotFoundException;
057    import org.deegree.framework.log.ILogger;
058    import org.deegree.framework.log.LoggerFactory;
059    import org.deegree.framework.xml.NamespaceContext;
060    import org.deegree.framework.xml.XMLFragment;
061    import org.deegree.framework.xml.XMLParsingException;
062    import org.deegree.framework.xml.XMLTools;
063    import org.deegree.ogcbase.CommonNamespaces;
064    import org.w3c.dom.Element;
065    import org.w3c.dom.Node;
066    
067    /**
068     * Implementation of {@link "org.opengis.coverage.grid.GridCoverageWriter"} for writing a
069     * GridCoverage as GML document to a defined destioation
070     * 
071     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
072     * @author last edited by: $Author: apoth $
073     * 
074     * @version $Revision: 6585 $, $Date: 2007-04-11 15:18:40 +0200 (Mi, 11 Apr 2007) $
075     */
076    public class GMLGridCoverageWriter extends AbstractGridCoverageWriter {
077    
078        private static ILogger LOG = LoggerFactory.getLogger( GMLGridCoverageWriter.class );
079    
080        private URL template = GMLGridCoverageWriter.class.getResource( "gml_rectifiedgrid_template.xml" );
081    
082        /**
083         * 
084         * @param destination
085         * @param metadata
086         * @param subNames
087         * @param currentSubname
088         * @param format
089         */
090        public GMLGridCoverageWriter( Object destination, Map<String, Object> metadata, String[] subNames,
091                                      String currentSubname, Format format ) {
092            super( destination, metadata, subNames, currentSubname, format );
093    
094        }
095    
096        /**
097         * disposes all resources assigned to a GMLGridCoverageWriter instance. For most cases this will
098         * be IO-resources
099         * 
100         * @throws IOException
101         */
102        public void dispose()
103                                throws IOException {
104    
105        }
106    
107        /**
108         * @param coverage
109         * @param parameters
110         *            must contain the servlet URL within the first field; all other fields must contain
111         *            the required parameters for a valid GetCoverage request
112         * @throws InvalidParameterNameException
113         * @throws InvalidParameterValueException
114         * @throws ParameterNotFoundException
115         * @throws IOException
116         */
117        public void write( GridCoverage coverage, GeneralParameterValueIm[] parameters )
118                                throws InvalidParameterNameException, InvalidParameterValueException,
119                                ParameterNotFoundException, IOException {
120            XMLFragment xml = new XMLFragment();
121            try {
122                xml.load( template );
123                Element root = xml.getRootElement();
124                NamespaceContext nsc = CommonNamespaces.getNamespaceContext();
125    
126                String xpath = "gml:rectifiedGridDomain/gml:RectifiedGrid/gml:limits/gml:GridEnvelope/gml:low";
127                Element element = (Element) XMLTools.getNode( root, xpath, nsc );
128                double x = coverage.getEnvelope().minCP.ord[0];
129                double y = coverage.getEnvelope().minCP.ord[1];
130                Node node = root.getOwnerDocument().createTextNode(
131                                                                    Double.toString( x )
132                                                                                            + ' '
133                                                                                            + Double.toString( y ) );
134                element.appendChild( node );
135    
136                xpath = "gml:rectifiedGridDomain/gml:RectifiedGrid/gml:limits/gml:GridEnvelope/gml:high";
137                element = (Element) XMLTools.getNode( root, xpath, nsc );
138                x = coverage.getEnvelope().maxCP.ord[0];
139                y = coverage.getEnvelope().maxCP.ord[1];
140                node = root.getOwnerDocument().createTextNode(
141                                                               Double.toString( x )
142                                                                                       + ' '
143                                                                                       + Double.toString( y ) );
144                element.appendChild( node );
145    
146                xpath = "gml:rectifiedGridDomain/gml:RectifiedGrid/gml:origin/gml:Point";
147                element = (Element) XMLTools.getNode( root, xpath, nsc );
148                element.setAttribute( "srsName", coverage.getCoordinateReferenceSystem().getName() );
149    
150                xpath = "gml:rectifiedGridDomain/gml:RectifiedGrid/gml:origin/gml:Point/gml:pos";
151                element = (Element) XMLTools.getNode( root, xpath, nsc );
152                x = coverage.getEnvelope().minCP.ord[0];
153                y = coverage.getEnvelope().minCP.ord[1];
154                node = root.getOwnerDocument().createTextNode(
155                                                               Double.toString( x )
156                                                                                       + ' '
157                                                                                       + Double.toString( y ) );
158                element.appendChild( node );
159    
160                double[] res = calcGridResolution( coverage, parameters );
161    
162                xpath = "gml:rectifiedGridDomain/gml:RectifiedGrid/gml:offsetVector";
163                List list = XMLTools.getNodes( root, xpath, nsc );
164                for ( int i = 0; i < list.size(); i++ ) {
165                    element = (Element) list.get( i );
166                    element.setAttribute( "srsName", coverage.getCoordinateReferenceSystem().getName() );
167                    if ( i == 0 ) {
168                        node = root.getOwnerDocument().createTextNode( res[i] + " 0" );
169                        element.appendChild( node );
170                    } else if ( i == 1 ) {
171                        node = root.getOwnerDocument().createTextNode( "0 " + res[i] );
172                        element.appendChild( node );
173                    } else if ( i == 2 ) {
174                        node = root.getOwnerDocument().createTextNode( "0 0 " + res[i] );
175                        element.appendChild( node );
176                    }
177                }
178    
179                xpath = "gml:rangeSet/gml:File/gml:fileName";
180                element = (Element) XMLTools.getNode( root, xpath, nsc );
181                StringBuffer sb = new StringBuffer( 300 );
182                OperationParameterIm op = (OperationParameterIm) parameters[0].getDescriptor();
183                sb.append( op.getDefaultValue() ).append( '?' );
184                for ( int i = 1; i < parameters.length; i++ ) {
185                    // OperationParameter
186                    op = (OperationParameterIm) parameters[i].getDescriptor();
187                    sb.append( op.getName() );
188                    sb.append( '=' ).append( op.getDefaultValue() );
189                    if ( i < parameters.length - 1 ) {
190                        sb.append( '&' );
191                    }
192                }
193                node = root.getOwnerDocument().createCDATASection( sb.toString() );
194                element.appendChild( node );
195            } catch ( XMLParsingException e ) {
196                LOG.logError( "could not parse GMLGridCoverage response template", e );
197                throw new InvalidParameterValueException( "", e.getMessage(), "" );
198            } catch ( Exception e ) {
199                LOG.logError( "could not write GMLGridCoverage", e );
200                throw new InvalidParameterValueException( "", e.getMessage(), "" );
201            }
202            xml.write( ( (OutputStream) destination ) );
203    
204        }
205    
206        /**
207         * returns the resolution of the grid in x- and y- directory
208         * 
209         * @param coverage
210         * @param parameters
211         * @return the resolution of the grid in x- and y- directory
212         */
213        private double[] calcGridResolution( GridCoverage coverage, GeneralParameterValueIm[] parameters ) {
214            double wx = coverage.getEnvelope().maxCP.ord[0] - coverage.getEnvelope().minCP.ord[0];
215            double wy = coverage.getEnvelope().maxCP.ord[1] - coverage.getEnvelope().minCP.ord[1];
216            Integer width = (Integer) getNamedParameter( parameters, "width" ).getDefaultValue();
217            Integer height = (Integer) getNamedParameter( parameters, "height" ).getDefaultValue();
218            double dx = wx / width.doubleValue();
219            double dy = wy / height.doubleValue();
220            double[] res = new double[] { dx, dy };
221            return res;
222        }
223    
224        /**
225         * selects the parameter matching the passed name from the passed array
226         * 
227         * @param parameters
228         * @param name
229         * @return
230         */
231        private OperationParameterIm getNamedParameter( GeneralParameterValueIm[] parameters,
232                                                        String name ) {
233            for ( int i = 0; i < parameters.length; i++ ) {
234                // OperationParameter
235                OperationParameterIm op = (OperationParameterIm) parameters[i].getDescriptor();
236                if ( op.getName().equals( name ) ) {
237                    return op;
238                }
239            }
240            return null;
241        }
242    
243    }
244    /***************************************************************************************************
245     * <code> 
246     Changes to this class. What the people have been up to: 
247     
248     $Log$
249     Revision 1.15  2007/03/06 14:55:16  wanhoff
250     Fixed Javadoc (@throws, changed @see to @link)
251    
252     Revision 1.14  2007/02/09 17:28:00  poth
253     *** empty log message ***
254    
255     Revision 1.13  2007/02/02 07:59:14  wanhoff
256     fixed Javadoc @return tag and footer
257    
258     Revision 1.12  2006/12/27 13:44:37  poth
259     useless method removed
260    
261     Revision 1.11  2006/07/05 12:58:09  poth
262     bug fix - creating offSetVectors for rectified grid corrected
263    
264     Revision 1.10  2006/06/12 08:09:54  poth
265     calculation of rectified grid completed
266    
267     </code>
268     **************************************************************************************************/