001    //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/ogcwebservices/wms/operation/DimensionValues.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.ogcwebservices.wms.operation;
038    
039    import static java.lang.Float.parseFloat;
040    import static java.lang.Math.abs;
041    
042    import java.util.LinkedList;
043    
044    /**
045     * <code>DimensionValues</code>
046     * 
047     * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a>
048     * @author last edited by: $Author: apoth $
049     * 
050     * @version $Revision: 31591 $, $Date: 2011-08-18 16:08:43 +0200 (Do, 18 Aug 2011) $
051     */
052    public class DimensionValues {
053    
054        /**
055         * original value used for initializing
056         */
057        private String originalValue;
058    
059        /**
060         * The actual values.
061         */
062        public LinkedList<DimensionValue> values;
063    
064        /**
065         * @param val
066         */
067        public DimensionValues( String val ) {
068            this.originalValue = val;
069            values = new LinkedList<DimensionValue>();
070            String[] vals = val.split( "," );
071            for ( String v : vals ) {
072                values.add( new DimensionValue( v ) );
073            }
074        }
075    
076        /**
077         * @return the originalValue
078         */
079        public String getOriginalValue() {
080            return originalValue;
081        }
082    
083        /**
084         * @return if multiple values are contained
085         */
086        public boolean hasMultipleValues() {
087            return values.size() > 1;
088        }
089    
090        /**
091         * @param value
092         * @return true, if the given single value is contained
093         */
094        public boolean includesValue( String value ) {
095            for ( DimensionValue val : values ) {
096                if ( val.value == null ) {
097                    // TODO use the resolution
098                    if ( val.low.compareTo( value ) <= 0 && val.high.compareTo( value ) >= 0 ) {
099                        return true;
100                    }
101                } else {
102                    if ( val.value.equals( value ) ) {
103                        return true;
104                    }
105                }
106            }
107    
108            return false;
109        }
110    
111        /**
112         * @param value
113         * @return true, if the given single value is contained
114         */
115        public boolean includesValue( float value ) {
116            for ( DimensionValue val : values ) {
117                if ( val.value == null ) {
118                    // TODO use resolution
119                    if ( val.lowf <= value && val.highf >= value ) {
120                        return true;
121                    }
122                } else {
123                    if ( abs( val.valuef - value ) <= 0.0000001 ) {
124                        return true;
125                    }
126                }
127            }
128    
129            return false;
130        }
131    
132        /**
133         * @param elev
134         * @return true, if the value(s) are valid
135         */
136        public boolean includes( DimensionValues elev ) {
137            for ( DimensionValue val : elev.values ) {
138                if ( val.value != null ) {
139                    if ( !includesValue( parseFloat( val.value ) ) ) {
140                        return false;
141                    }
142                } else {
143                    if ( !includesValue( parseFloat( val.high ) ) || !includesValue( parseFloat( val.low ) ) ) {
144                        return false;
145                    }
146                }
147            }
148    
149            return true;
150        }
151    
152        /**
153         * @param value
154         * @return the nearest value
155         */
156        public String getNearestValue( String value ) {
157            String nearestHigh = null, nearestLow = null;
158            for ( DimensionValue val : values ) {
159                if ( val.value == null ) {
160                    // TODO check it for ranges
161                } else {
162                    if ( nearestHigh != null && nearestHigh.compareTo( val.value ) > 0 && val.value.compareTo( value ) > 0 ) {
163                        nearestHigh = val.value;
164                        continue;
165                    }
166                    if ( nearestLow != null && nearestLow.compareTo( val.value ) < 0 && val.value.compareTo( value ) < 0 ) {
167                        nearestLow = val.value;
168                        continue;
169                    }
170                    if ( nearestHigh == null && val.value.compareTo( value ) > 0 ) {
171                        nearestHigh = val.value;
172                        continue;
173                    }
174                    if ( nearestLow == null && val.value.compareTo( value ) < 0 ) {
175                        nearestLow = val.value;
176                        continue;
177                    }
178                }
179            }
180    
181            if ( nearestHigh == null ) {
182                return nearestLow;
183            }
184            if ( nearestLow == null ) {
185                return nearestHigh;
186            }
187            try {
188                float low = parseFloat( nearestLow );
189                float high = parseFloat( nearestHigh );
190                float val = parseFloat( value );
191                if ( abs( val - low ) > abs( val - high ) ) {
192                    return nearestHigh;
193                }
194                return nearestLow;
195            } catch ( NumberFormatException nfe ) {
196                // TODO for time
197            }
198            return null; // TODO check which bound is nearer
199        }
200    
201        /**
202         * <code>DimensionValue</code>
203         * 
204         * @author <a href="mailto:schmitz@lat-lon.de">Andreas Schmitz</a>
205         * @author last edited by: $Author: apoth $
206         * 
207         * @version $Revision: 31591 $, $Date: 2011-08-18 16:08:43 +0200 (Do, 18 Aug 2011) $
208         */
209        public class DimensionValue {
210            /**
211             *
212             */
213            public String value;
214    
215            /**
216             *
217             */
218            public float valuef;
219    
220            /**
221             *
222             */
223            public String low;
224    
225            /**
226             *
227             */
228            public float lowf;
229    
230            /**
231             *
232             */
233            public String high;
234    
235            /**
236             *
237             */
238            public float highf;
239    
240            /**
241             *
242             */
243            public String res;
244    
245            /**
246             *
247             */
248            public float resf;
249    
250            DimensionValue( String val ) {
251                if ( val.indexOf( "/" ) != -1 ) {
252                    String[] vs = val.split( "/" );
253                    low = vs[0];
254                    high = vs[1];
255                    try {
256                        lowf = parseFloat( low );
257                        highf = parseFloat( high );
258                    } catch ( NumberFormatException nfe ) {
259                        // no float values then
260                    }
261                    if ( vs.length > 2 ) {
262                        res = vs[2];
263                        try {
264                            resf = parseFloat( res );
265                        } catch ( NumberFormatException nfe ) {
266                            // no float value then
267                        }
268                    }
269                } else {
270                    value = val;
271                    try {
272                        valuef = parseFloat( value );
273                    } catch ( NumberFormatException nfe ) {
274                        // no float value then
275                    }
276                }
277            }
278        }
279    }