001    //$HeadURL: $
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.ogcwebservices.wcts.data;
038    
039    import java.util.ArrayList;
040    import java.util.List;
041    
042    import javax.vecmath.Point3d;
043    
044    import org.deegree.crs.transformations.Transformation;
045    import org.deegree.framework.log.ILogger;
046    import org.deegree.framework.log.LoggerFactory;
047    import org.deegree.i18n.Messages;
048    import org.deegree.model.crs.CRSFactory;
049    import org.deegree.model.crs.CRSTransformationException;
050    import org.deegree.model.crs.CoordinateSystem;
051    import org.deegree.model.crs.GeoTransformer;
052    import org.deegree.ogcwebservices.OGCWebServiceException;
053    
054    /**
055     * <code>SimpleData</code> takes a list of points which will be transformed.
056     *
057     * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
058     *
059     * @author last edited by: $Author:$
060     *
061     * @version $Revision:$, $Date:$
062     *
063     */
064    public class SimpleData extends TransformableData<Point3d> {
065        private static ILogger LOG = LoggerFactory.getLogger( SimpleData.class );
066    
067        /**
068         * The coordinate separator, default to ','
069         */
070        private final String cs;
071    
072        /**
073         * The tuple separator, default to ' '
074         */
075        private final String ts;
076    
077        private List<Point3d> sourcePoints;
078    
079        /**
080         * Creates a simple data instance.
081         *
082         * @param transformableData
083         * @param cs
084         *            the coordinate separator
085         * @param ts
086         *            the tuple separator
087         * @throws IllegalArgumentException
088         *             if either one of the crs's are <code>null</code>.
089         */
090        public SimpleData( List<Point3d> transformableData, String cs, String ts ) throws IllegalArgumentException {
091            if ( transformableData == null ) {
092                transformableData = new ArrayList<Point3d>();
093            }
094            this.sourcePoints = transformableData;
095            if ( cs == null || "".equals( cs ) ) {
096                cs = ",";
097            }
098            this.cs = cs;
099    
100            if ( ts == null || "".equals( ts ) ) {
101                ts = " ";
102            }
103            this.ts = ts;
104        }
105    
106        /**
107         * using default values, cs="," and ts='space'
108         */
109        public SimpleData() {
110            this( new ArrayList<Point3d>(), null, null );
111        }
112    
113        @Override
114        public void doTransform( CoordinateSystem sourceCRS, CoordinateSystem targetCRS, boolean enableLogging ) {
115            GeoTransformer transformer = getGeotransformer( targetCRS );
116            try {
117                sourcePoints = transformer.transform( sourceCRS, sourcePoints );
118            } catch ( IllegalArgumentException e ) {
119                LOG.logError( e.getMessage(), e );
120            } catch ( CRSTransformationException e ) {
121                LOG.logError( e.getMessage(), e );
122            }
123        }
124    
125        @Override
126        public void doTransform( Transformation transformation, boolean enableLogging )
127                                throws OGCWebServiceException {
128            GeoTransformer transformer = getGeotransformer( transformation );
129            try {
130                sourcePoints = transformer.transform( CRSFactory.create( transformation.getSourceCRS() ), sourcePoints );
131            } catch ( IllegalArgumentException e ) {
132                LOG.logError( e.getMessage(), e );
133            } catch ( CRSTransformationException e ) {
134                LOG.logError( e.getMessage(), e );
135            }
136    
137        }
138    
139        /**
140         * @return true if this simpleData has sourcePoints.
141         */
142        public boolean hasData() {
143            return ( sourcePoints != null && sourcePoints.size() > 0 );
144        }
145    
146        @Override
147        public List<Point3d> getTransformedData() {
148            return sourcePoints;
149        }
150    
151        /**
152         * @return the value for the ts attribute, defaults to a single space character.
153         */
154        public final String getTupleSeparator() {
155            return ts;
156        }
157    
158        /**
159         * @return the value for the cs attribute, defaults to a single comma character.
160         */
161        public final String getCoordinateSeparator() {
162            return cs;
163        }
164    
165        /**
166         * Parses a String of data into the appropriate Point3d, according to the given cs, ts and coordinate dimension.
167         *
168         * @param simpleData
169         *            a String containing the data
170         * @param sourceDim
171         *            the dimension of the source coordinate system, in which the points are defined.
172         * @param cs
173         *            the coordinate separator.
174         * @param ts
175         *            the tuple separator.
176         * @param ds
177         *            the decimal separator currently not evaluated.
178         * @return a list containing the parsed points or an empty list if the points could not be retrieved, never
179         *         <code>null</code>
180         */
181        public static List<Point3d> parseData( String simpleData, int sourceDim, String cs, String ts, String ds ) {
182            if ( simpleData == null || "".equals( simpleData.trim() ) ) {
183                return new ArrayList<Point3d>();
184            }
185            List<Point3d> result = new ArrayList<Point3d>();
186            simpleData = simpleData.trim();
187            String[] tuples = simpleData.split( ts );
188    
189            int count = 0;
190            for ( String tuple : tuples ) {
191                count++;
192                if ( tuple != null ) {
193                    tuple = tuple.trim();
194                    String[] coords = tuple.split( cs );
195                    if ( coords.length != sourceDim ) {
196                        LOG.logError( Messages.getMessage( "WCTS_DIM_COORDS_NOT_CONGRUENT", sourceDim, cs ) );
197                    } else {
198                        String first = coords[0];
199                        String second = coords[1];
200                        String third = null;
201                        if ( sourceDim == 3 ) {
202                            third = coords[2];
203                        }
204                        double x = 0;
205                        double y = 0;
206                        double z = 0;
207                        try {
208                            x = Double.parseDouble( first );
209                        } catch ( NumberFormatException e ) {
210                            LOG.logError( "Unparsable x value: " + x + " at coord " + count );
211                            x = Double.NaN;
212                        }
213                        try {
214                            y = Double.parseDouble( second );
215                        } catch ( NumberFormatException e ) {
216                            LOG.logError( "Unparsable y value: " + y + " at coord " + count );
217                            y = Double.NaN;
218                        }
219                        if ( sourceDim == 3 ) {
220                            try {
221                                z = Double.parseDouble( third );
222                            } catch ( NumberFormatException e ) {
223                                LOG.logError( "Unparsable z value: " + z + " at coord " + count );
224                                z = Double.NaN;
225                            }
226                        }
227                        if ( !( Double.isNaN( x ) || Double.isNaN( y ) || Double.isNaN( z ) ) ) {
228                            result.add( new Point3d( x, y, z ) );
229                        }
230                    }
231                }
232            }
233            return result;
234        }
235    
236    }