    001    /*----------------------------------------------------------------------------
    002     This file is part of deegree, http://deegree.org/
    003     Copyright (C) 2001-2009 by:
    004       Department of Geography, University of Bonn
    005     and
    006       lat/lon GmbH
    007
    008     This library is free software; you can redistribute it and/or modify it under
    009     the terms of the GNU Lesser General Public License as published by the Free
    010     Software Foundation; either version 2.1 of the License, or (at your option)
    011     any later version.
    012     This library is distributed in the hope that it will be useful, but WITHOUT
    013     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    014     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    015     details.
    016     You should have received a copy of the GNU Lesser General Public License
    017     along with this library; if not, write to the Free Software Foundation, Inc.,
    018     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    019
    020     Contact information:
    021
    022     lat/lon GmbH
    023     Aennchenstr. 19, 53177 Bonn
    024     Germany
    025     http://lat-lon.de/
    026
    027     Department of Geography, University of Bonn
    028     Prof. Dr. Klaus Greve
    029     Postfach 1147, 53001 Bonn
    030     Germany
    031     http://www.geographie.uni-bonn.de/deegree/
    032
    033     e-mail: info@deegree.org
    034    ----------------------------------------------------------------------------*/
    035
    036    package org.deegree.ogcwebservices.wpvs.operation;
    037
    038    import javax.media.j3d.PickShape;
    039    import javax.media.j3d.Transform3D;
    040    import javax.vecmath.AxisAngle4d;
    041    import javax.vecmath.Point3d;
    042    import javax.vecmath.Vector3d;
    043
    044    import org.deegree.model.crs.CoordinateSystem;
    045    import org.deegree.model.spatialschema.Geometry;
    046    import org.deegree.model.spatialschema.GeometryException;
    047    import org.deegree.ogcwebservices.wpvs.j3d.ViewPoint;
    048
    049    /**
    050     * This abstract class represents a geometry needed for Get3DFeatureInfoRequest. It contains the 3d geometry and its 2d
    051     * projektion. The 2d geometry is required for WFS request, the 3d geometry for the final test of intersection.
    052     *
    053     * @version $Revision: $
    054     * @author <a href="mailto:cordes@lat-lon.de">Lyn Buesching</a>
    055     * @author last edited by: $Author: $
    056     *
    057     * @version 1.0. $Revision: $, $Date: $
    058     *
    059     */
    060    public abstract class RequestGeometry {
    061
    062        /**
    063         * The the feature info request
    064         */
    065        protected Get3DFeatureInfo request;
    066
    067        // begin point of the view ray
    068        private Point3d beginPointLine;
    069
    070        private CoordinateSystem crs;
    071
    072        /**
    073         *  geometry for wfs query
    074         */
    075        protected Geometry wfsReqGeom;
    076
    077        /**
    078         *  3d geometry: needed for final testing
    079         */
    080        protected PickShape pickshape;
    081
    082        /**
    083         * Constructor to initialize the attributes needed for all geometries
    084         *
    085         * @param request
    086         *            the Get3DFeatureInfoRequest
    087         */
    088        public RequestGeometry( Get3DFeatureInfo request ) {
    089            this.request = request;
    090            crs = request.getGetViewRequestCopy().getCrs();
    091            beginPointLine = new ViewPoint( request.getGetViewRequestCopy() ).getObserverPosition();
    092        }
    093
    094        /**
    095         *
    096         * @return the pickshape or <code>null</code> if it was not set.
    097         */
    098        public PickShape getPickshape() {
    099            return pickshape;
    100        }
    101
    102        /**
    103         * @return the geometry repsonse from the wfs-request or <code>null</code> if it was not set.
    104         */
    105        public Geometry getWfsReqGeom() {
    106            return wfsReqGeom;
    107        }
    108
    109        /**
    110         * @return the starting point of the line.
    111         */
    112        public Point3d getBeginPointLine() {
    113            return beginPointLine;
    114        }
    115
    116        /**
    117         * @return the crs of the request.
    118         */
    119        public CoordinateSystem getCrs() {
    120            return crs;
    121        }
    122
    123        /**
    124         * @return the request.
    125         */
    126        public Get3DFeatureInfo getRequest() {
    127            return request;
    128        }
    129
    130        // abstract methods
    131        /**
    132         * sets the geometry needed for WFS request
    133         *
    134         * @throws GeometryException
    135         *             if something went wrong.
    136         */
    137        public abstract void setWfsReqGeom()
    138                                            throws GeometryException;
    139
    140        /**
    141         * Sets the geometry needed for final test of intersection
    142         */
    143        public abstract void setPickshape();
    144
    145        /**
    146         * Calculates a ray through the ViewPoint and the ClickPoint.
    147         *
    148         * @param viewPoint
    149         *            position of the request
    150         * @param depth
    151         *            far clipping plane
    152         * @param width
    153         *            of the request
    154         * @param height
    155         *            of the request
    156         * @param clickI
    157         *            x-axis
    158         * @param clickJ
    159         *            y-axis
    160         * @return The end point of the requestGeometry.
    161         */
    162        protected Point3d calcEndPoint( ViewPoint viewPoint, double depth, int width, int height, int clickI, int clickJ ) {
    163            // sets extension of the ray
    164            double extension = viewPoint.getFarClippingPlane();
    165            if ( depth > 0 && depth < extension ) {
    166                extension = depth;
    167            }
    168            GetView getView = request.getGetViewRequestCopy();
    169
    170            // rotates the cklickpoint to the roll-angle
    171            double roll = getView.getRoll();
    172            double deltaI = -( width / 2 ) + clickI;
    173            double deltaJ = ( height / 2 ) - clickJ;
    174
    175            double x = deltaI * Math.cos( roll ) + deltaJ * Math.sin( roll );
    176            double y = -deltaI * Math.sin( roll ) + deltaJ * Math.cos( roll );
    177
    178            // calculates the angles to rotate the vector (vp-poi)
    179            double aov = viewPoint.getAngleOfView();
    180            double distProj = ( width / 2 ) / Math.tan( aov / 2 );
    181
    182            double angleI = Math.atan( x / distProj );
    183            double angleJ = Math.atan( y / distProj );
    184
    185            Point3d vp = viewPoint.getObserverPosition();
    186            Point3d poi = viewPoint.getPointOfInterest();
    187            Vector3d vectorVPtoPOI = new Vector3d();
    188            vectorVPtoPOI.sub( poi, vp );
    189
    190            Transform3D trans = new Transform3D();
    191
    192            // rotation at angleJ (vertikal)
    193            Vector3d rotJ = new Vector3d();
    194            Vector3d eZ = new Vector3d( 0, 0, 1 );
    195            rotJ.cross( vectorVPtoPOI, eZ );
    196            AxisAngle4d axisAngleJ = new AxisAngle4d( rotJ, angleJ );
    197            trans.set( axisAngleJ );
    198            trans.transform( vectorVPtoPOI );
    199
    200            // rotation at angleI (horizontal)
    201            Vector3d rotI = new Vector3d();
    202            rotI.cross( vectorVPtoPOI, rotJ );
    203            AxisAngle4d axisAngleI = new AxisAngle4d( rotI, angleI );
    204            trans.set( axisAngleI );
    205            trans.transform( vectorVPtoPOI );
    206
    207            // scale to extension
    208            vectorVPtoPOI.normalize();
    209            vectorVPtoPOI.scale( extension );
    210            Point3d endPoint = new Point3d();
    211
    212            // add to the viewpoint
    213            endPoint.add( vp, vectorVPtoPOI );
    214            return endPoint;
    215        }
    216    }