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 java.awt.geom.Point2D;
039    
040    import javax.media.j3d.PickConeSegment;
041    import javax.vecmath.Point3d;
042    import javax.vecmath.Vector3d;
043    
044    import org.deegree.model.spatialschema.GeometryException;
045    import org.deegree.model.spatialschema.GeometryFactory;
046    import org.deegree.model.spatialschema.Position;
047    import org.deegree.model.spatialschema.SurfaceInterpolation;
048    import org.deegree.model.spatialschema.SurfaceInterpolationImpl;
049    import org.deegree.ogcwebservices.wpvs.j3d.ViewPoint;
050    
051    /**
052     * This class represents the geometry needed for a request cone.
053     *
054     * @version $Revision: $
055     * @author <a href="mailto:cordes@lat-lon.de">Lyn Buesching</a>
056     * @author last edited by: $Author: $
057     *
058     * @version 1.0. $Revision: $, $Date: $
059     *
060     */
061    public class ConeRequest extends RequestGeometry {
062    
063        // end point of the view ray
064        private Point3d endPointLine;
065    
066        /**
067         * Initializes the two Geometries for the request with a cone.
068         *
069         * @param request
070         */
071            public ConeRequest(Get3DFeatureInfo request) {
072                    super( request );
073            endPointLine = new Point3d (calcEndPoint( new ViewPoint( request.getGetViewRequestCopy() ),
074                          (int)request.getDepth(),
075                          (int)request.getGetViewRequestCopy().getImageDimension().getWidth(),
076                          (int)request.getGetViewRequestCopy().getImageDimension().getHeight(),
077                          request.getClickPoint().x, request.getClickPoint().y ) );
078            }
079    
080            @Override
081            public void setPickshape() {
082                    pickshape = new PickConeSegment( getBeginPointLine(), endPointLine, getRequest().getApexAngle() );
083            }
084    
085            @Override
086            public void setWfsReqGeom() throws GeometryException {
087    
088            Position[] pos = new Position[4];
089            int i = 0;
090            pos[i++] = GeometryFactory.createPosition(getBeginPointLine().x, getBeginPointLine().y, 0);
091    
092            Vector3d tmp = new Vector3d();
093            tmp.sub(getBeginPointLine(), endPointLine);
094            double length = tmp.length();
095            double r = Math.tan( getRequest().getApexAngle() ) * length;
096    
097            double dX = endPointLine.x - getBeginPointLine().x;
098            double dY = endPointLine.y - getBeginPointLine().y;
099            double lengthGround = Math.sqrt(Math.pow( dX, 2 ) + Math.pow( dY, 2 ));
100    
101            double dif = Math.tan( getRequest().getApexAngle() ) * (lengthGround + r);
102            double rot = Math.toRadians(90);
103            if ( dY == 0 && dX > 0 ) {
104                rot = Math.toRadians(270);
105            }else if ( dX != dY ) {
106                rot = Math.atan( dX / dY );
107            }
108            if ( dY < 0 ) {
109                rot = ( rot + Math.toRadians(180) );
110            } else {
111                rot = ( rot + Math.toRadians(360) );
112            }
113            rot = Math.toRadians( 360 ) - (rot  % Math.toRadians( 360 ));
114    
115            // transformation
116            Point2D.Double point2 = trans2d(getBeginPointLine().x, getBeginPointLine().y,
117                                            rot, new Point2D.Double( dif, lengthGround ));
118            pos[i++] = GeometryFactory.createPosition( point2.x, point2.y, 0 );
119    
120            Point2D.Double point3 = trans2d(getBeginPointLine().x, getBeginPointLine().y,
121                                            rot , new Point2D.Double( -dif, lengthGround ));
122            pos[i++] = GeometryFactory.createPosition(point3.x, point3.y, 0);
123    
124            pos[i++] = pos[0];
125    
126            SurfaceInterpolation si = new SurfaceInterpolationImpl( 0 );
127            wfsReqGeom = GeometryFactory.createSurface( pos, new Position[0][0], si, getCrs() );
128            }
129    
130            /**
131             * 3-parameter transformation
132             *
133             * @param translationX the translation in x
134             * @param translationY the translation in x
135             * @param rotation rotation of the transformation
136             * @param transPoint point to transform
137             *
138             * @return the point in the new coordinatsystem
139             */
140            private Point2D.Double trans2d(double translationX, double translationY, double rotation,
141                                       Point2D.Double transPoint) {
142    
143            double xTrans = transPoint.x * Math.cos( rotation ) - transPoint.y * Math.sin( rotation ) + translationX;
144                    double yTrans = transPoint.x * Math.sin( rotation ) + transPoint.y * Math.cos( rotation ) + translationY;
145                    return new Point2D.Double( xTrans, yTrans );
146            }
147    }