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