001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/ogcwebservices/wpvs/operation/GetView.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2001-2006 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: rbezema $
077 *
078 * @version 2.0, $Revision: 7960 $, $Date: 2007-08-09 12:01:43 +0200 (Do, 09 Aug 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 if ( datasetsString.length() == 0 ) {
476 throw new InconsistentRequestException(
477 "'DATASETS' cannot contain space characters only or be empty" );
478 }
479
480 String[] datasets = datasetsString.split( "," );
481 if ( datasetsString.length() == 0 ) {
482 throw new InconsistentRequestException(
483 "'DATASETS' must contain at least one dataset name" );
484 }
485 List<String> datasetList = new ArrayList<String>( datasets.length );
486 for ( String dataset : datasets ) {
487 datasetList.add( dataset.trim() );
488 }
489
490 String boxstring = requestParams.remove( "BOUNDINGBOX" );
491 Envelope boundingBox = null;
492 if ( boxstring == null ) {
493 throw new InconsistentRequestException( "BOUNDINGBOX value must be set" );
494 }
495
496 try {
497 boxstring = URLDecoder.decode( boxstring, CharsetUtils.getSystemCharset() );
498 } catch ( UnsupportedEncodingException e ) {
499 LOG.logError( e.getLocalizedMessage(), e );
500 throw new InconsistentRequestException(
501 StringTools.concat(
502 100,
503 "Cannot decode BOUNDINGBOX: '",
504 boxstring,
505 " using ",
506 CharsetUtils.getSystemCharset() ) );
507 }
508
509 String[] tokens = boxstring.split( "," );
510 if ( tokens.length != 4 ) {
511 throw new InconsistentRequestException(
512 "BOUNDINGBOX value must have a value such as xmin,ymin,xmax,ymax" );
513 }
514
515 double minx;
516 double maxx;
517 double miny;
518 double maxy;
519 try {
520 minx = Double.parseDouble( tokens[0] );
521 miny = Double.parseDouble( tokens[1] );
522 maxx = Double.parseDouble( tokens[2] );
523 maxy = Double.parseDouble( tokens[3] );
524 } catch ( NumberFormatException e ) {
525 LOG.logError( e.getLocalizedMessage(), e );
526 throw new InconsistentRequestException( "BOUNDINGBOX has an illegal value: "
527 + e.getMessage() );
528 }
529
530 if ( minx >= maxx ) {
531 throw new InvalidParameterValueException( "minx must be less than maxx" );
532 }
533
534 if ( miny >= maxy ) {
535 throw new InvalidParameterValueException( "miny must be less than maxy" );
536 }
537
538 boundingBox = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, crs );
539
540 /**
541 * Doing some checking of the given request parameters.
542 */
543
544 if ( !boundingBox.contains( poi ) ) {
545 throw new InconsistentRequestException( "POI (" + poi
546 + " )must be inside the Bounding box ("
547 + boundingBox + ")" );
548 }
549
550 tmp = requestParams.remove( "FARCLIPPINGPLANE" );
551 double farClippingPlane = 150000;
552 if ( tmp != null ) {
553 try {
554 farClippingPlane = Double.parseDouble( tmp );
555 } catch ( NumberFormatException e ) {
556 LOG.logError( e.getLocalizedMessage(), e );
557 throw new InvalidParameterValueException( "FarClippingPlane must be a number" );
558 }
559 }
560
561 tmp = requestParams.remove( "QUALITY" );
562 double quality = 1f;
563 if ( tmp != null ) {
564 try {
565 quality = Double.parseDouble( tmp );
566 } catch ( NumberFormatException e ) {
567 LOG.logError( e.getLocalizedMessage(), e );
568 throw new InvalidParameterValueException( "QUALITY must have a value between [0,1]" );
569 }
570 }
571
572 String exceptions = requestParams.remove( "EXCEPTIONFORMAT" );
573 if ( exceptions == null ) {
574 exceptions = "XML";
575 }
576
577 // Shouldn't this be checked for the right value ???
578 tmp = requestParams.remove( "DATETIME" );
579 if ( tmp == null ) {
580 // when the moon is in the second house,
581 // and jupiter aligns with mars.
582 // -> dawning of the age of the wpvs
583 tmp = "2007-03-21T12:00:00";
584 } else {
585 try {
586 TimeTools.createCalendar( tmp );
587 } catch ( NumberFormatException nfe ) {
588 throw new InvalidParameterValueException(
589 Messages.getMessage( "WPVS_GETVIEW_ILLEGAL_DATETIME", tmp) );
590 }
591 }
592
593 // org.deegree.framework.util.TimeTools.createCalendar( tmp );
594
595 requestParams.put( "DATETIME", tmp );
596
597 tmp = requestParams.remove( "SCALE" );
598 if ( tmp != null ) {
599 try {
600 Double.parseDouble( tmp );
601 requestParams.put( "SCALE", tmp );
602 } catch ( NumberFormatException e ) {
603 LOG.logError( e.getLocalizedMessage(), e );
604 throw new InvalidParameterValueException( e );
605 }
606 }
607
608 return new GetView( version, id, datasetList, elevModel, quality, poi, boundingBox, crs,
609 pitch, yaw, roll, distance, aov, format, bgColor, transparency,
610 imgDimension, exceptions, farClippingPlane, requestParams );
611 }
612
613 /**
614 * @return the requested angleOfView
615 */
616 public double getAngleOfView() {
617 return angleOfView;
618 }
619
620 /**
621 * @return the requested distance to the poi
622 */
623 public double getDistance() {
624 return distance;
625 }
626
627 /**
628 * @return the requested dimension of the resultimage
629 */
630 public Dimension getImageDimension() {
631 return imageDimension;
632 }
633
634 /**
635 * @return the requested pitch (rotation around the x-axis)
636 */
637 public double getPitch() {
638 return pitch;
639 }
640
641 /**
642 *
643 * @return the point of interest as Point3d
644 */
645 public Point3d getPointOfInterest() {
646 return pointOfInterest;
647 }
648
649 /**
650 * @return the quality of the textures
651 */
652 public double getQuality() {
653 return quality;
654 }
655
656 /**
657 * @return the requested roll (rotation around the y-axis)
658 */
659 public double getRoll() {
660 return roll;
661 }
662
663 /**
664 * @return if the resultimage should be transparent
665 */
666 public boolean isTransparent() {
667 return transparent;
668 }
669
670 /**
671 * @return the requested yaw (rotation around the z-axis)
672 */
673 public double getYaw() {
674 return yaw;
675 }
676
677 /**
678 * @return the requested datasets (e.g. layers or features etc.)
679 */
680 public List<String> getDatasets() {
681 return datasets;
682 }
683
684 /**
685 * @return the requested color of the background
686 */
687 public Color getBackgroundColor() {
688 return backgroundColor;
689 }
690
691 /**
692 * @return the requested format of thrown exceptions
693 */
694 public String getExceptionFormat() {
695 return exceptionFormat;
696 }
697
698 /**
699 * @return the mimetype of the resultimage
700 */
701 public String getOutputFormat() {
702 return outputFormat;
703 }
704
705 /**
706 * @return the boundingbox of the request
707 */
708 public Envelope getBoundingBox() {
709 return boundingBox;
710 }
711
712 /**
713 * @return the Coordinate System of the request
714 */
715 public CoordinateSystem getCrs() {
716 return crs;
717 }
718
719 /**
720 * @return the elevationmodel to be used.
721 */
722 public String getElevationModel() {
723 return elevationModel;
724 }
725
726 /**
727 * @return Returns the farClippingPlane.
728 */
729 public double getFarClippingPlane() {
730 return farClippingPlane;
731 }
732
733 /**
734 * @param farClippingPlane
735 * another clippingPlane distance.
736 */
737 public void setFarClippingPlane( double farClippingPlane ) {
738 this.farClippingPlane = farClippingPlane;
739 }
740
741 /**
742 * @param pitch
743 * a new pitch value
744 */
745 public void setPitch( double pitch ) {
746 this.pitch = pitch;
747 }
748
749 /**
750 * @param distance
751 * An other distance value.
752 */
753 public void setDistance( double distance ) {
754 this.distance = distance;
755 }
756
757 /**
758 * @param yaw
759 * An other yaw value.
760 */
761 public void setYaw( double yaw ) {
762 this.yaw = yaw;
763 }
764
765 /**
766 * @param angleOfView
767 * An other angleOfView value.
768 */
769 public void setAngleOfView( double angleOfView ) {
770 this.angleOfView = angleOfView;
771 }
772 }