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