001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/ogcwebservices/wpvs/operation/GetView.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     Aennchenstraße 19
030     53177 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.ogcwebservices.wpvs.operation;
045    
046    import java.awt.Color;
047    import java.awt.Dimension;
048    import java.io.UnsupportedEncodingException;
049    import java.net.URLDecoder;
050    import java.util.ArrayList;
051    import java.util.List;
052    import java.util.Map;
053    
054    import javax.vecmath.Point3d;
055    
056    import org.deegree.framework.log.ILogger;
057    import org.deegree.framework.log.LoggerFactory;
058    import org.deegree.framework.util.CharsetUtils;
059    import org.deegree.framework.util.MimeTypeMapper;
060    import org.deegree.framework.util.StringTools;
061    import org.deegree.framework.util.TimeTools;
062    import org.deegree.i18n.Messages;
063    import org.deegree.model.crs.CRSFactory;
064    import org.deegree.model.crs.CoordinateSystem;
065    import org.deegree.model.crs.UnknownCRSException;
066    import org.deegree.model.spatialschema.Envelope;
067    import org.deegree.model.spatialschema.GeometryFactory;
068    import org.deegree.model.spatialschema.Position;
069    import org.deegree.ogcwebservices.InconsistentRequestException;
070    import org.deegree.ogcwebservices.InvalidParameterValueException;
071    
072    /**
073     * This Class handles a kvp request from a client and stores it's values.
074     * 
075     * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a>
076     * @author last edited by: $Author: apoth $
077     * 
078     * @version 2.0, $Revision: 9345 $, $Date: 2007-12-27 17:22:25 +0100 (Do, 27 Dez 2007) $
079     * 
080     * @since 2.0
081     */
082    public class GetView extends WPVSRequestBase {
083    
084        /**
085         * 
086         */
087        private static final long serialVersionUID = 3147456903146907261L;
088    
089        private static final ILogger LOG = LoggerFactory.getLogger( GetView.class );
090    
091        private final List<String> datasets;
092    
093        private double quality;
094    
095        /**
096         * using deegree's Position
097         */
098        private final Point3d pointOfInterest;
099    
100        private double pitch;
101    
102        private double yaw;
103    
104        private double roll;
105    
106        private double distance;
107    
108        private double angleOfView;
109    
110        private final boolean transparent;
111    
112        private final Dimension imageDimension;
113    
114        private final String outputFormat;
115    
116        private final Color backgroundColor;
117    
118        private final String exceptionFormat;
119    
120        private final String elevationModel;
121    
122        private final Envelope boundingBox;
123    
124        private final CoordinateSystem crs;
125    
126        private double farClippingPlane;
127    
128        private GetView( String version, String id, List<String> datasets, String elevationModel,
129                         double quality, Position pointOfInterest, Envelope bbox, CoordinateSystem crs,
130                         double pitch, double yaw, double roll, double distance, double angleOfView,
131                         String outputFormat, Color backgroundColor, boolean transparent,
132                         Dimension imageDimension, String exceptionFormat, double farClippingPlane,
133                         Map<String, String> vendorSpecificParameter ) {
134            this(
135                  version,
136                  id,
137                  datasets,
138                  elevationModel,
139                  quality,
140                  new Point3d( pointOfInterest.getX(), pointOfInterest.getY(), pointOfInterest.getZ() ),
141                  bbox, crs, pitch, yaw, roll, distance, angleOfView, outputFormat, backgroundColor,
142                  transparent, imageDimension, exceptionFormat, farClippingPlane,
143                  vendorSpecificParameter );
144        }
145    
146        /**
147         * Trusted constructor. No parameter validity is performed. This is delegated to the factory
148         * method createGeMap.
149         * 
150         * TODO the list of pars is too long, should break up into smaller classes, e.g. pars for
151         * perspective output, etc.
152         * 
153         * @param version
154         * @param id
155         * @param datasets
156         * @param elevationModel
157         * @param quality
158         * @param pointOfInterest
159         * @param bbox
160         * @param crs
161         * @param pitch
162         * @param yaw
163         * @param roll
164         * @param distance
165         * @param angleOfView
166         * @param outputFormat
167         * @param backgroundColor
168         * @param transparent
169         * @param imageDimension
170         * @param exceptionFormat
171         * @param farClippingPlane
172         * @param vendorSpecificParameter
173         */
174        private GetView( String version, String id, List<String> datasets, String elevationModel,
175                         double quality, Point3d pointOfInterest, Envelope bbox, CoordinateSystem crs,
176                         double pitch, double yaw, double roll, double distance, double angleOfView,
177                         String outputFormat, Color backgroundColor, boolean transparent,
178                         Dimension imageDimension, String exceptionFormat, double farClippingPlane,
179                         Map<String, String> vendorSpecificParameter ) {
180            super( version, id, vendorSpecificParameter );
181            this.datasets = datasets;
182            this.elevationModel = elevationModel;
183    
184            this.quality = quality;
185            this.pointOfInterest = pointOfInterest;
186            this.boundingBox = bbox;
187            this.crs = crs;
188            this.pitch = pitch;
189            this.yaw = yaw;
190            this.roll = roll;
191            this.distance = distance;
192            this.angleOfView = angleOfView;
193            this.outputFormat = outputFormat;
194            this.backgroundColor = backgroundColor;
195            this.transparent = transparent;
196            this.imageDimension = imageDimension;
197            this.exceptionFormat = exceptionFormat;
198            this.farClippingPlane = farClippingPlane;
199    
200        }
201    
202        /**
203         * Factory method to create an instance of GetView from teh parameters in <code>model</code>
204         * 
205         * @param requestParams
206         *            a map containing request parameters and values
207         * @return a new instance of GetView
208         * @throws InconsistentRequestException
209         *             if a mandatory parameter is missing
210         * @throws InvalidParameterValueException
211         *             if a parameter has an illegal value
212         */
213        public static GetView create( Map<String, String> requestParams )
214                                throws InconsistentRequestException, InvalidParameterValueException {
215    
216            // TODO throw a proper exception, the InconsistentRequestException doesn't cover all cases
217    
218            // not needed anymore
219            requestParams.remove( "REQUEST" );
220    
221            String id = requestParams.remove( "ID" );
222    
223            /*
224             * TODO check if this is right WPVSConfiguration configuration = (WPVSConfiguration)
225             * model.remove( "CAPABILITIES" ); if ( configuration == null ){ throw new RuntimeException (
226             * "Working site: you forgot to add config to model -> " + "see how this is done in wms" ); }
227             */
228    
229            String version = requestParams.remove( "VERSION" );
230            if ( version == null ) {
231                throw new InconsistentRequestException( "'VERSION' value must be set" );
232            }
233    
234            // FORMAT
235            String format = requestParams.remove( "OUTPUTFORMAT" );
236            if ( format == null ) {
237                throw new InconsistentRequestException( "OUTPUTFORMAT value must be set" );
238            }
239            try {
240                format = URLDecoder.decode( format, CharsetUtils.getSystemCharset() );
241            } catch ( UnsupportedEncodingException e1 ) {
242                LOG.logError( e1.getLocalizedMessage(), e1 );
243            }
244            if ( !MimeTypeMapper.isKnownImageType( format ) ) {
245                throw new InvalidParameterValueException(
246                                                          StringTools.concat( 50, format,
247                                                                              " is not a valid image/result format" ) );
248            }
249    
250            // TRANSPARENCY
251            boolean transparency = false;
252            String tp = requestParams.remove( "TRANSPARENT" );
253            if ( tp != null ) {
254                transparency = tp.toUpperCase().trim().equals( "TRUE" );
255            }
256    
257            if ( transparency
258                 && ( format.equals( "image/jpg" ) || format.equals( "image/jpeg" )
259                      || format.equals( "image/bmp" ) || format.equals( "image/tif" ) || format.equals( "image/tiff" ) ) ) {
260    
261                throw new InconsistentRequestException(
262                                                        StringTools.concat(
263                                                                            100,
264                                                                            "TRANSPARENCY=true is inconsistent with OUTPUTFORMAT=",
265                                                                            format,
266                                                                            ".Valid transparent formats are 'image/gif' ",
267                                                                            "and 'image/png'." ) );
268            }
269    
270            // width
271            String tmp = requestParams.remove( "WIDTH" );
272            if ( tmp == null ) {
273                throw new InconsistentRequestException( "'WIDTH' value must be set" );
274            }
275            int width = 0;
276            try {
277                width = Integer.parseInt( tmp );
278            } catch ( NumberFormatException e ) {
279                throw new InconsistentRequestException( "WIDTH must be a valid integer number" );
280            }
281    
282            tmp = requestParams.remove( "HEIGHT" );
283            if ( tmp == null ) {
284                throw new InconsistentRequestException( "'HEIGHT' value must be set" );
285            }
286            int height = 0;
287            try {
288                height = Integer.parseInt( tmp );
289            } catch ( NumberFormatException e ) {
290                throw new InconsistentRequestException( "HEIGHT must be a valid integer number" );
291            }
292    
293            if ( width < 0 || height < 0 ) {
294                throw new InconsistentRequestException( "WIDTH and HEIGHT must be >= 0" );
295            }
296            Dimension imgDimension = new Dimension( width, height );
297    
298            Color bgColor = Color.white;
299    
300            tmp = requestParams.remove( "BACKGROUNDCOLOR" );
301            if ( tmp != null ) {
302                try {
303                    bgColor = Color.decode( tmp );
304                } catch ( NumberFormatException e ) {
305                    throw new InconsistentRequestException(
306                                                            StringTools.concat(
307                                                                                100,
308                                                                                "The BACKGROUNDCOLOR '",
309                                                                                tmp,
310                                                                                "' does not denote a valid hexadecimal color." ) );
311                }
312            }
313    
314            String elevModel = requestParams.remove( "ELEVATIONMODEL" );
315            /*
316             * if ( elevModel == null ) { throw new InconsistentRequestException( "'ELEVATIONMODEL'
317             * value must be set" ); }
318             */
319            if ( elevModel != null ) {
320                elevModel = elevModel.trim();
321                if ( elevModel.length() == 0 ) {
322                    throw new InconsistentRequestException(
323                                                            "ELEVATIONMODEL cannot contain space characters only or be empty" );
324                }
325            }
326    
327            tmp = requestParams.remove( "AOV" );
328            if ( tmp == null ) {
329                throw new InconsistentRequestException( "'AOV' value must be set" );
330            }
331    
332            double aov = 0;
333            try {
334                aov = Math.toRadians( Double.parseDouble( tmp ) );
335                /**
336                 * checking for > 0 || < 90
337                 */
338                if ( ( aov <= 0 ) || ( aov >= 1.5707963265 ) ) {
339                    throw new InvalidParameterValueException(
340                                                              "AOV value must be a number between 0° and 180°" );
341                }
342            } catch ( NumberFormatException e ) {
343                LOG.logError( e.getLocalizedMessage(), e );
344                throw new InvalidParameterValueException( "AOV couldn't parse the aov value" );
345            }
346    
347            tmp = requestParams.remove( "ROLL" );
348            if ( tmp == null ) {
349                throw new InconsistentRequestException( "'ROLL' value must be set" );
350            }
351            double roll;
352            try {
353                /**
354                 * checking for > 360 && < 360
355                 */
356                roll = Double.parseDouble( tmp ) % 360;
357                if ( roll < 0 )
358                    roll += 360;
359                roll = Math.toRadians( roll );
360            } catch ( NumberFormatException e ) {
361                LOG.logError( e.getLocalizedMessage(), e );
362                throw new InvalidParameterValueException( "ROLL value must be a number" );
363            }
364    
365            tmp = requestParams.remove( "DISTANCE" );
366            if ( tmp == null ) {
367                throw new InconsistentRequestException( "'DISTANCE' value must be set." );
368            }
369    
370            double distance;
371            String mesg = "DISTANCE must be a number >= 0.";
372            try {
373                distance = Double.parseDouble( tmp );
374                if ( distance < 0 ) {
375                    throw new InvalidParameterValueException( mesg );
376                }
377            } catch ( NumberFormatException e ) {
378                LOG.logError( e.getLocalizedMessage(), e );
379                throw new InvalidParameterValueException( mesg );
380            }
381    
382            tmp = requestParams.remove( "PITCH" );
383            if ( tmp == null ) {
384                throw new InconsistentRequestException( "'PITCH' value must be set." );
385            }
386            double pitch = 0;
387            try {
388                pitch = Math.toRadians( Double.parseDouble( tmp ) );
389                if ( ( pitch < -1.570796327 ) || ( pitch > 1.570796327 ) ) {
390                    throw new InvalidParameterValueException(
391                                                              "PITCH value must be a number between -90° and 90°" );
392                }
393            } catch ( NumberFormatException e ) {
394                LOG.logError( e.getLocalizedMessage(), e );
395                throw new InvalidParameterValueException(
396                                                          "PITCH value must be a number between -90° and 90°" );
397            }
398    
399            tmp = requestParams.remove( "YAW" );
400            if ( tmp == null ) {
401                throw new InconsistentRequestException( "'YAW' value must be set." );
402            }
403            double yaw;
404            try {
405                double tmpYaw = Double.parseDouble( tmp ) % 360;
406                if ( tmpYaw < 0 )
407                    tmpYaw += 360;
408                // YAW == 270 -> OutOfMem Error
409                // if ( tmpYaw > 89.5 && tmpYaw < 90.5 ) {
410                // tmpYaw = 91;
411                // } else if ( tmpYaw > 269.5 && tmpYaw < 270.5 ) {
412                // tmpYaw = 271;
413                // }
414                // [UT] 06.06.2005 splitter doesn't work fine for 0 (or 360) and 180
415                // if ( tmpYaw % 180 == 0 ) {
416                // tmpYaw += 0.5;
417                // }
418                yaw = Math.toRadians( tmpYaw );
419    
420            } catch ( NumberFormatException e ) {
421                LOG.logError( e.getLocalizedMessage(), e );
422                throw new InvalidParameterValueException( "YAW value must be a number" );
423            }
424    
425            tmp = requestParams.remove( "POI" );
426            if ( tmp == null ) {
427                throw new InconsistentRequestException( "POI value is missing." );
428            }
429            mesg = "POI value must denote a number tuple with valid x,y,z values, for example '123.45,678.90,456.123'";
430    
431            try {
432                tmp = URLDecoder.decode( tmp, CharsetUtils.getSystemCharset() );
433            } catch ( UnsupportedEncodingException e ) {
434                LOG.logError( e.getLocalizedMessage(), e );
435                throw new InconsistentRequestException( e.getLocalizedMessage() );
436            }
437            String[] xyz = tmp.split( "," );
438            if ( xyz.length != 3 ) {
439                throw new InvalidParameterValueException( mesg );
440            }
441            Position poi;
442            double[] p = new double[3];
443            try {
444                p[0] = Double.parseDouble( xyz[0] );
445                p[1] = Double.parseDouble( xyz[1] );
446                p[2] = Double.parseDouble( xyz[2] );
447    
448            } catch ( NumberFormatException e ) {
449                LOG.logError( e.getLocalizedMessage(), e );
450                throw new InvalidParameterValueException( mesg );
451            }
452            poi = GeometryFactory.createPosition( p );
453    
454            String crsString = requestParams.remove( "CRS" );
455            CoordinateSystem crs = null;
456            if ( crsString == null ) {
457                throw new InconsistentRequestException( "CRS parameter is missing." );
458            }
459            try {
460                crsString = URLDecoder.decode( crsString, CharsetUtils.getSystemCharset() );
461                crs = CRSFactory.create( crsString );
462            } catch ( UnsupportedEncodingException e ) {
463                LOG.logError( e.getLocalizedMessage(), e );
464            } catch ( UnknownCRSException ucrse ) {
465                LOG.logError( ucrse.getLocalizedMessage(), ucrse );
466                throw new InvalidParameterValueException( ucrse.getMessage() );
467            }
468    
469            String datasetsString = requestParams.remove( "DATASETS" );
470            if ( datasetsString == null ) {
471                throw new InconsistentRequestException( "'DATASETS' value must be set" );
472            }
473    
474            datasetsString = datasetsString.trim();
475    
476            String[] datasets = datasetsString.split( "," );
477            if ( "".equals( datasetsString )  || datasets.length == 0 ) {
478                throw new InconsistentRequestException(
479                                                        "'DATASETS' must contain at least one dataset name, and cannot be empty (i.e. only have spaces)" );
480            }
481            List<String> datasetList = new ArrayList<String>( datasets.length );
482            for ( String dataset : datasets ) {
483                datasetList.add( dataset.trim() );
484            }
485    
486            String boxstring = requestParams.remove( "BOUNDINGBOX" );
487            Envelope boundingBox = null;
488            if ( boxstring == null ) {
489                throw new InconsistentRequestException( "BOUNDINGBOX value must be set" );
490            }
491    
492            try {
493                boxstring = URLDecoder.decode( boxstring, CharsetUtils.getSystemCharset() );
494            } catch ( UnsupportedEncodingException e ) {
495                LOG.logError( e.getLocalizedMessage(), e );
496                throw new InconsistentRequestException(
497                                                        StringTools.concat(
498                                                                            100,
499                                                                            "Cannot decode BOUNDINGBOX: '",
500                                                                            boxstring,
501                                                                            " using ",
502                                                                            CharsetUtils.getSystemCharset() ) );
503            }
504    
505            String[] tokens = boxstring.split( "," );
506            if ( tokens.length != 4 ) {
507                throw new InconsistentRequestException(
508                                                        "BOUNDINGBOX value must have a value such as xmin,ymin,xmax,ymax" );
509            }
510    
511            double minx;
512            double maxx;
513            double miny;
514            double maxy;
515            try {
516                minx = Double.parseDouble( tokens[0] );
517                miny = Double.parseDouble( tokens[1] );
518                maxx = Double.parseDouble( tokens[2] );
519                maxy = Double.parseDouble( tokens[3] );
520            } catch ( NumberFormatException e ) {
521                LOG.logError( e.getLocalizedMessage(), e );
522                throw new InconsistentRequestException( "BOUNDINGBOX has an illegal value: "
523                                                        + e.getMessage() );
524            }
525    
526            if ( minx >= maxx ) {
527                throw new InvalidParameterValueException( "minx must be less than maxx" );
528            }
529    
530            if ( miny >= maxy ) {
531                throw new InvalidParameterValueException( "miny must be less than maxy" );
532            }
533    
534            boundingBox = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, crs );
535    
536            /**
537             * Doing some checking of the given request parameters.
538             */
539    
540            if ( !boundingBox.contains( poi ) ) {
541                throw new InconsistentRequestException( "POI (" + poi
542                                                        + " )must be inside the Bounding box ("
543                                                        + boundingBox + ")" );
544            }
545    
546            tmp = requestParams.remove( "FARCLIPPINGPLANE" );
547            double farClippingPlane = 150000;
548            if ( tmp != null ) {
549                try {
550                    farClippingPlane = Double.parseDouble( tmp );
551                } catch ( NumberFormatException e ) {
552                    LOG.logError( e.getLocalizedMessage(), e );
553                    throw new InvalidParameterValueException( "FarClippingPlane must be a number" );
554                }
555            }
556    
557            tmp = requestParams.remove( "QUALITY" );
558            double quality = 1f;
559            if ( tmp != null ) {
560                try {
561                    quality = Double.parseDouble( tmp );
562                } catch ( NumberFormatException e ) {
563                    LOG.logError( e.getLocalizedMessage(), e );
564                    throw new InvalidParameterValueException( "QUALITY must have a value between [0,1]" );
565                }
566            }
567    
568            String exceptions = requestParams.remove( "EXCEPTIONFORMAT" );
569            if ( exceptions == null ) {
570                exceptions = "XML";
571            }
572    
573            // Shouldn't this be checked for the right value ???
574            tmp = requestParams.remove( "DATETIME" );
575            if ( tmp == null ) {
576                // when the moon is in the second house,
577                // and jupiter aligns with mars.
578                // -> dawning of the age of the wpvs
579                tmp = "2007-03-21T12:00:00";
580            } else {
581                try {
582                    TimeTools.createCalendar( tmp );
583                } catch ( NumberFormatException nfe ) {
584                    throw new InvalidParameterValueException(
585                                                              Messages.getMessage( "WPVS_GETVIEW_ILLEGAL_DATETIME", tmp)  );
586                }
587            }
588    
589            // org.deegree.framework.util.TimeTools.createCalendar( tmp );
590    
591            requestParams.put( "DATETIME", tmp );
592    
593            tmp = requestParams.remove( "SCALE" );
594            if ( tmp != null ) {
595                try {
596                    Double.parseDouble( tmp );
597                    requestParams.put( "SCALE", tmp );
598                } catch ( NumberFormatException e ) {
599                    LOG.logError( e.getLocalizedMessage(), e );
600                    throw new InvalidParameterValueException( e );
601                }
602            }
603    
604            return new GetView( version, id, datasetList, elevModel, quality, poi, boundingBox, crs,
605                                pitch, yaw, roll, distance, aov, format, bgColor, transparency,
606                                imgDimension, exceptions, farClippingPlane, requestParams );
607        }
608    
609        /**
610         * @return the requested angleOfView
611         */
612        public double getAngleOfView() {
613            return angleOfView;
614        }
615    
616        /**
617         * @return the requested distance to the poi
618         */
619        public double getDistance() {
620            return distance;
621        }
622    
623        /**
624         * @return the requested dimension of the resultimage
625         */
626        public Dimension getImageDimension() {
627            return imageDimension;
628        }
629    
630        /**
631         * @return the requested pitch (rotation around the x-axis)
632         */
633        public double getPitch() {
634            return pitch;
635        }
636    
637        /**
638         * 
639         * @return the point of interest as Point3d
640         */
641        public Point3d getPointOfInterest() {
642            return pointOfInterest;
643        }
644    
645        /**
646         * @return the quality of the textures
647         */
648        public double getQuality() {
649            return quality;
650        }
651    
652        /**
653         * @return the requested roll (rotation around the y-axis)
654         */
655        public double getRoll() {
656            return roll;
657        }
658    
659        /**
660         * @return if the resultimage should be transparent
661         */
662        public boolean isTransparent() {
663            return transparent;
664        }
665    
666        /**
667         * @return the requested yaw (rotation around the z-axis)
668         */
669        public double getYaw() {
670            return yaw;
671        }
672    
673        /**
674         * @return the requested datasets (e.g. layers or features etc.)
675         */
676        public List<String> getDatasets() {
677            return datasets;
678        }
679    
680        /**
681         * @return the requested color of the background
682         */
683        public Color getBackgroundColor() {
684            return backgroundColor;
685        }
686    
687        /**
688         * @return the requested format of thrown exceptions
689         */
690        public String getExceptionFormat() {
691            return exceptionFormat;
692        }
693    
694        /**
695         * @return the mimetype of the resultimage
696         */
697        public String getOutputFormat() {
698            return outputFormat;
699        }
700    
701        /**
702         * @return the boundingbox of the request
703         */
704        public Envelope getBoundingBox() {
705            return boundingBox;
706        }
707    
708        /**
709         * @return the Coordinate System of the request
710         */
711        public CoordinateSystem getCrs() {
712            return crs;
713        }
714    
715        /**
716         * @return the elevationmodel to be used.
717         */
718        public String getElevationModel() {
719            return elevationModel;
720        }
721    
722        /**
723         * @return Returns the farClippingPlane.
724         */
725        public double getFarClippingPlane() {
726            return farClippingPlane;
727        }
728    
729        /**
730         * @param farClippingPlane
731         *            another clippingPlane distance.
732         */
733        public void setFarClippingPlane( double farClippingPlane ) {
734            this.farClippingPlane = farClippingPlane;
735        }
736    
737        /**
738         * @param pitch
739         *            a new pitch value
740         */
741        public void setPitch( double pitch ) {
742            this.pitch = pitch;
743        }
744    
745        /**
746         * @param distance
747         *            An other distance value.
748         */
749        public void setDistance( double distance ) {
750            this.distance = distance;
751        }
752    
753        /**
754         * @param yaw
755         *            An other yaw value.
756         */
757        public void setYaw( double yaw ) {
758            this.yaw = yaw;
759        }
760    
761        /**
762         * @param angleOfView
763         *            An other angleOfView value.
764         */
765        public void setAngleOfView( double angleOfView ) {
766            this.angleOfView = angleOfView;
767        }
768    }