001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/graphics/sld/LinePlacement.java $
002    /*----------------    FILE HEADER  ------------------------------------------
003     
004     This file is part of deegree.
005     Copyright (C) 2001-2008 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    package org.deegree.graphics.sld;
044    
045    import org.deegree.framework.xml.Marshallable;
046    import org.deegree.model.feature.Feature;
047    import org.deegree.model.filterencoding.FilterEvaluationException;
048    
049    /**
050     * Incarnation of an sld:LinePlacement-element.
051     * <p>
052     * Contains some deegree-specific extensions:
053     * <ul>
054     * <li>PerpendicularOffset: may be used as defined by the OGC, but it can also be set to one of the
055     * special values 'center', 'above', 'below', 'auto'
056     * <li>Gap: defines the distance between two captions on the line string
057     * <li>LineWidth: provides the thickness of the styled line (needed as information for the correct
058     * positioning of labels above and below the line string)
059     * </ul>
060     * <p>
061     * 
062     * @author <a href="mailto:mschneider@lat-lon.de">Markus Schneider</a>
063     * @version $Revision: 9340 $ $Date: 2007-12-27 13:32:12 +0100 (Do, 27 Dez 2007) $
064     */
065    
066    public class LinePlacement implements Marshallable {
067    
068        public final static int TYPE_ABSOLUTE = 0;
069    
070        public final static int TYPE_ABOVE = 1;
071    
072        public final static int TYPE_BELOW = 2;
073    
074        public final static int TYPE_CENTER = 3;
075    
076        public final static int TYPE_AUTO = 4;
077    
078        private ParameterValueType perpendicularOffset = null;
079    
080        private ParameterValueType lineWidth = null;
081    
082        private ParameterValueType gap = null;
083    
084        public LinePlacement( ParameterValueType perpendicularOffset, ParameterValueType lineWidth, ParameterValueType gap ) {
085            this.perpendicularOffset = perpendicularOffset;
086            this.lineWidth = lineWidth;
087            this.gap = gap;
088        }
089    
090        /**
091         * returns the gap as
092         * 
093         * @see ParameterValueType
094         * @return
095         */
096        public ParameterValueType getGap() {
097            return gap;
098        }
099    
100        /**
101         * returns the line width as
102         * 
103         * @see ParameterValueType
104         * @return
105         */
106        public ParameterValueType getLineWidth() {
107            return lineWidth;
108        }
109    
110        /**
111         * returns the perpendicular offset as
112         * 
113         * @see ParameterValueType
114         * @return
115         */
116        public ParameterValueType getPerpendicularOffset() {
117            return perpendicularOffset;
118        }
119    
120        /**
121         * The PerpendicularOffset element of a LinePlacement gives the perpendicular distance away from
122         * a line to draw a label. The distance is in pixels and is positive to the left-hand side of
123         * the line string. Negative numbers mean right. The default offset is 0.
124         * <p>
125         * deegree-specific extension: if the element has one of the values: 'center', 'above', 'below',
126         * 'auto', the return value is invalid
127         * <p>
128         * 
129         * @param feature
130         *            specifies the <tt>Feature</tt> to be used for evaluation of the underlying
131         *            'sld:ParameterValueType'
132         * @return the offset (only valid if type is TYPE_ABSOLUTE)
133         * @throws FilterEvaluationException
134         *             if the evaluation fails
135         */
136        public double getPerpendicularOffset( Feature feature )
137                                throws FilterEvaluationException {
138    
139            double pValue = 0.0;
140    
141            if ( perpendicularOffset != null ) {
142                String stringValue = perpendicularOffset.evaluate( feature );
143                if ( ( !stringValue.equals( "center" ) ) && ( !stringValue.equals( "above" ) )
144                     && ( !stringValue.equals( "below" ) ) && ( !stringValue.equals( "auto" ) ) ) {
145                    try {
146                        pValue = Double.parseDouble( stringValue );
147                    } catch ( NumberFormatException e ) {
148                        throw new FilterEvaluationException(
149                                                             "Element 'PerpendicularOffset' "
150                                                                                     + "must be equal to 'center', 'above', 'below' or 'auto' or it "
151                                                                                     + "must denote a valid double value!" );
152                    }
153    
154                }
155            }
156            return pValue;
157        }
158    
159        /**
160         * @see org.deegree.graphics.sld.LinePlacement#getPerpendicularOffset(Feature)
161         *      <p>
162         * @param perpendicularOffset
163         */
164        public void setPerpendicularOffset( double perpendicularOffset ) {
165            ParameterValueType pvt = StyleFactory.createParameterValueType( "" + perpendicularOffset );
166            this.perpendicularOffset = pvt;
167        }
168    
169        /**
170         * Returns the placement type (one of the constants defined in <tt>LinePlacement</tt>).
171         * <p>
172         * 
173         * @param feature
174         * @return
175         * @throws FilterEvaluationException
176         */
177        public int getPlacementType( Feature feature )
178                                throws FilterEvaluationException {
179            int type = TYPE_ABSOLUTE;
180    
181            if ( perpendicularOffset != null ) {
182                String stringValue = perpendicularOffset.evaluate( feature );
183                if ( stringValue.equals( "center" ) ) {
184                    type = TYPE_CENTER;
185                } else if ( stringValue.equals( "above" ) ) {
186                    type = TYPE_ABOVE;
187                } else if ( stringValue.equals( "below" ) ) {
188                    type = TYPE_BELOW;
189                } else if ( stringValue.equals( "auto" ) ) {
190                    type = TYPE_AUTO;
191                }
192            }
193            return type;
194        }
195    
196        /**
197         * Sets the placement type (one of the constants defined in <tt>LinePlacement</tt>).
198         * <p>
199         * 
200         * @param placementType
201         */
202        public void setPlacementType( int placementType ) {
203            ParameterValueType pvt = null;
204            String type = null;
205            if ( placementType == 1 ) {
206                type = "above";
207            } else if ( placementType == 2 ) {
208                type = "below";
209            } else if ( placementType == 3 ) {
210                type = "center";
211            } else if ( placementType == 4 ) {
212                type = "auto";
213            }
214            pvt = StyleFactory.createParameterValueType( "" + type );
215            this.perpendicularOffset = pvt;
216        }
217    
218        /**
219         * Provides the thickness of the styled line (needed as information for the correct positioning
220         * of labels above and below the line string).
221         * <p>
222         * 
223         * @param feature
224         * @return
225         * @throws FilterEvaluationException
226         */
227        public double getLineWidth( Feature feature )
228                                throws FilterEvaluationException {
229            double width = 3;
230    
231            if ( lineWidth != null ) {
232                width = Double.parseDouble( lineWidth.evaluate( feature ) );
233            }
234            return width;
235        }
236    
237        /**
238         * Provides the thickness of the styled line (needed as information for the correct positioning
239         * of labels above and below the line string).
240         * <p>
241         * 
242         * @param lineWidth
243         *            the lineWidth to be set
244         */
245        public void setLineWidth( double lineWidth ) {
246            ParameterValueType pvt = StyleFactory.createParameterValueType( "" + lineWidth );
247            this.lineWidth = pvt;
248        }
249    
250        /**
251         * Defines the distance between two captions on the line string. One unit is the width of the
252         * label caption.
253         * <p>
254         * 
255         * @param feature
256         * @return
257         * @throws FilterEvaluationException
258         */
259        public int getGap( Feature feature )
260                                throws FilterEvaluationException {
261            int gapValue = 6;
262    
263            if ( gap != null ) {
264                gapValue = Integer.parseInt( gap.evaluate( feature ) );
265            }
266            return gapValue;
267        }
268    
269        /**
270         * Defines the distance between two captions on the line string. One unit is the width of the
271         * label caption.
272         * <p>
273         * 
274         * @param gap
275         *            the gap to be set
276         */
277        public void setGap( int gap ) {
278            ParameterValueType pvt = StyleFactory.createParameterValueType( "" + gap );
279            this.gap = pvt;
280        }
281    
282        /**
283         * exports the content of the Font as XML formated String
284         * 
285         * @return xml representation of the Font
286         */
287        public String exportAsXML() {
288    
289            StringBuffer sb = new StringBuffer( 1000 );
290            sb.append( "<LinePlacement>" );
291            if ( perpendicularOffset != null ) {
292                sb.append( "<PerpendicularOffset>" );
293                sb.append( ( (Marshallable) perpendicularOffset ).exportAsXML() );
294                sb.append( "</PerpendicularOffset>" );
295            }
296            if ( lineWidth != null ) {
297                sb.append( "<LineWidth>" );
298                sb.append( ( (Marshallable) lineWidth ).exportAsXML() );
299                sb.append( "</LineWidth>" );
300            }
301            if ( gap != null ) {
302                sb.append( "<Gap>" );
303                sb.append( ( (Marshallable) gap ).exportAsXML() );
304                sb.append( "</Gap>" );
305            }
306            sb.append( "</LinePlacement>" );
307    
308            return sb.toString();
309        }
310    }