//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/ogcwebservices/wpvs/util/Attic/StripeFactory.java,v 1.8 2006/11/28 16:53:45 bezema Exp $
/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstraße 19
53177 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.ogcwebservices.wpvs.util;
import java.awt.Color;
import java.awt.Graphics2D;
import java.util.ArrayList;
import javax.media.j3d.Transform3D;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import org.deegree.framework.util.MapUtils;
import org.deegree.model.spatialschema.Envelope;
import org.deegree.model.spatialschema.GeometryException;
import org.deegree.model.spatialschema.GeometryFactory;
import org.deegree.model.spatialschema.Position;
import org.deegree.model.spatialschema.Surface;
import org.deegree.ogcwebservices.wpvs.j3d.ViewPoint;
/**
* This class divides a visible area into stripes by calculating a resolution for the near clipping
* plane and the far clipping plane. The near resolution (the one closest to the viewer) is doubled
* until it is <= far clippingplane resolution. If the Viewer has a pitch which is greater than the
* angle of view (in other words: looking steeply down) the resolutionstripes are concentric quads,
* which are adapted to the form of the footprint (aka. the perspective ViewFrustrum projected
* onto the ground).
*
* @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a>
* @author last edited by: $Author: bezema $
*
* $Revision: 1.8 $, $Date: 2006/11/28 16:53:45 $
*
*/
public class StripeFactory {
private final ViewPoint viewPoint;
private double minScaleResolution;
/**
* @param vp
* the capsulation of the location and viewing direction of the viewer.
* @param minScaleDenominator
* the best possible resolution the datasets can show.
*/
public StripeFactory( ViewPoint vp, double minScaleDenominator ) {
this.viewPoint = vp;
if ( minScaleDenominator < 0.0001 )
minScaleDenominator = 0.0001;
this.minScaleResolution = minScaleDenominator * MapUtils.DEFAULT_PIXEL_SIZE;
}
/**
* Calculates the number of resolutionstripes, their size and their position in
* worldcoordinates.
*
* @param imageWidth
* of the request
* @param minimalHeight
* the minimalHeight of the terrain
* @param g2d
* if !null the stripes are drawn on the graphics object (handy for debugging
* purposes
* @return the resolutionsstripes for the footprint
*/
public ArrayList<ResolutionStripe> createResolutionStripes( int imageWidth,
double minimalHeight, Graphics2D g2d ) {
// Transformations used to calculate the footprint
Transform3D invertTransform = viewPoint.getSimpleTransform();
invertTransform.invert();
Transform3D transform = viewPoint.getSimpleTransform();
Point3d[] footprint = this.viewPoint.getFootprint();
Vector3d farRight = new Vector3d( footprint[0] );
Vector3d farLeft = new Vector3d( footprint[1] );
Vector3d nearestRight = new Vector3d( footprint[2] );
Vector3d nearestLeft = new Vector3d( footprint[3] );
double halfAngleOfView = viewPoint.getAngleOfView() * 0.5;
// We use a tangens therefore checking if we are close to 0 - 180
if ( Math.abs( ( halfAngleOfView + Math.toRadians( 90 ) ) % Math.toRadians( 180 ) ) <= 0.00001 )
return null;
// !!!!For now the footprint dimensions are in meters
double footprintNearResolution = StripeFactory.calcScaleOfVector( nearestRight,
nearestLeft, imageWidth );
double footprintFarResolution = StripeFactory.calcScaleOfVector( farRight, farLeft,
imageWidth );
// if the near clipping plane is behind the viewer, which means pitch > angleOfView the
// resolutionStripes should be centered around the viewpoint
if ( viewPoint.isNearClippingplaneBehindViewPoint() ) {
return createStripesForHighPitch( invertTransform, transform, farRight, farLeft,
nearestRight, nearestLeft, imageWidth, minimalHeight,
halfAngleOfView, footprintNearResolution,
footprintFarResolution, g2d );
}
return createStripesForFrontalPerspective( invertTransform, transform, farRight, farLeft,
nearestRight, nearestLeft, imageWidth,
minimalHeight, halfAngleOfView,
footprintNearResolution, footprintFarResolution,
g2d );
}
private ArrayList<ResolutionStripe> createStripesForFrontalPerspective(
Transform3D invertTransform,
Transform3D transform,
Vector3d farRight,
Vector3d farLeft,
Vector3d nearestRight,
Vector3d nearestLeft,
double imageWidth,
double minimalHeight,
double halfAngleOfView,
double footprintNearResolution,
double footprintFarResolution,
Graphics2D g2d ) {
ArrayList<ResolutionStripe> resultStripes = new ArrayList<ResolutionStripe>( 10 );
if ( minScaleResolution > footprintNearResolution )
footprintNearResolution = minScaleResolution;
double resolutionQuotient = Math.floor( footprintFarResolution / footprintNearResolution );
int numberOfStripes = nearestPowerOfTwo( resolutionQuotient );
// Find the distances to switch levelofdetail
for ( int stripesCounter = 0; stripesCounter < numberOfStripes; ++stripesCounter ) {
// go back to null point
invertTransform.transform( nearestRight );
invertTransform.transform( nearestLeft );
double xLength = ( nearestRight.x - nearestLeft.x ) * 0.5;
double yLength = xLength / Math.tan( halfAngleOfView );
// create the new slice by adding the lengt in x and y direction
Vector3d tmpFarRight = new Vector3d( nearestRight.x + xLength,
nearestRight.y + yLength, nearestRight.z );
Vector3d tmpFarLeft = new Vector3d( nearestLeft.x - xLength, nearestLeft.y + yLength,
nearestLeft.z );
// transform the resulting shape back to the original position.
transform.transform( tmpFarRight );
transform.transform( tmpFarLeft );
transform.transform( nearestRight );
transform.transform( nearestLeft );
ResolutionStripe rs = createResolutionStripe( nearestLeft, nearestRight, tmpFarRight,
tmpFarLeft, imageWidth, minimalHeight );
if ( rs != null )
resultStripes.add( rs );
/**
* For debugging purposes
*/
if ( g2d != null ) {
g2d.setColor( Color.BLACK );
g2d.drawLine( (int) nearestRight.x, (int) nearestRight.y, (int) nearestLeft.x,
(int) nearestLeft.y );
}
nearestRight = new Vector3d( tmpFarRight );
nearestLeft = new Vector3d( tmpFarLeft );
}
ResolutionStripe rs = createResolutionStripe( nearestLeft, nearestRight, farRight, farLeft,
imageWidth, minimalHeight );
if ( rs != null )
resultStripes.add( rs );
if ( g2d != null ) {
g2d.setColor( Color.BLACK );
g2d.drawLine( (int) nearestRight.x, (int) nearestRight.y, (int) nearestLeft.x,
(int) nearestLeft.y );
g2d.drawLine( (int) farRight.x, (int) farRight.y, (int) farLeft.x, (int) farLeft.y );
}
return resultStripes;
}
/**
* This method finds the resolutionstripes around the Viewpoint if the nearClippingplane is
* behind the viewer (which happens if the pitch is higher as the angleOfView).
*
* @param invertTransform
* @param transform
* @param farRight
* @param farLeft
* @param nearestRight
* @param nearestLeft
* @param imageWidth
* @param minimalHeight
* @param halfAngleOfView
* @param footprintNearResolution
* @param footprintFarResolution
* @param g2d
* @return the ResolutionStripes centered around the viewpoint.
*/
private ArrayList<ResolutionStripe> createStripesForHighPitch( Transform3D invertTransform,
Transform3D transform,
Vector3d farRight,
Vector3d farLeft,
Vector3d nearestRight,
Vector3d nearestLeft,
double imageWidth,
double minimalHeight,
double halfAngleOfView,
double footprintNearResolution,
double footprintFarResolution,
Graphics2D g2d ) {
ArrayList<ResolutionStripe> resultStripes = new ArrayList<ResolutionStripe>( 40 );
Vector3d origin = new Vector3d( viewPoint.getObserverPosition() );
invertTransform.transform( origin );
if ( minScaleResolution > footprintNearResolution )
footprintNearResolution = minScaleResolution;
double resolutionStripeLength = imageWidth * ( minScaleResolution / MapUtils.SQRT2 );
int numberOfStripesNear = nearestPowerOfTwo( Math.floor( footprintNearResolution
/ minScaleResolution ) );
double tangensOfHalfAngleOfView = Math.tan( halfAngleOfView );
double yDistance = ( resolutionStripeLength * 0.5 ) / tangensOfHalfAngleOfView;
Vector3d backNearestLeft = new Vector3d( origin.x + resolutionStripeLength * 0.5,
origin.y - yDistance, nearestLeft.z );
Vector3d backNearestRight = new Vector3d( origin.x - resolutionStripeLength * 0.5,
origin.y - yDistance, nearestLeft.z );
Vector3d frontalNearestLeft = new Vector3d( origin.x - resolutionStripeLength * 0.5,
origin.y + yDistance, nearestLeft.z );
Vector3d frontalNearestRight = new Vector3d( origin.x + resolutionStripeLength * 0.5,
origin.y + yDistance, nearestLeft.z );
transform.transform( backNearestLeft );
transform.transform( backNearestRight );
transform.transform( frontalNearestLeft );
transform.transform( frontalNearestRight );
ResolutionStripe middleStripe = createResolutionStripe( backNearestLeft, backNearestRight,
frontalNearestRight,
frontalNearestLeft, minimalHeight,
minScaleResolution,
minScaleResolution );
if ( middleStripe != null )
resultStripes.add( middleStripe );
/**
* For debugging purpaces
*/
if ( g2d != null ) {
g2d.setColor( Color.GREEN );
g2d.drawLine( (int) backNearestRight.x, (int) backNearestRight.y,
(int) backNearestLeft.x, (int) backNearestLeft.y );
g2d.setColor( Color.RED );
g2d.drawLine( (int) frontalNearestRight.x, (int) frontalNearestRight.y,
(int) frontalNearestLeft.x, (int) frontalNearestLeft.y );
}
// Find the distances to switch levelofdetail
/**
* If the near clipping plane is behind the viewer the resolutionstripes are centered around
* the viewpoint. <code>
* FL = farLeft = UpperLeft
* FR = FarRight = UpperRight
* NL = nearLeft = LowerLeft
* NR = nearRight = LowerRight
* VP = viewPoint
* R = Right
* L = Left
* F = front
* B = Back
* FL__________________FR .
* \ / /|\
* \ _F_ / |
* \ L |VP| R / viewDir
* \ -B- / |
* \ / |
* NL------NR
* </code>
*/
for ( int stripesCounter = 0; stripesCounter < numberOfStripesNear; ++stripesCounter ) {
// go back to null point
invertTransform.transform( backNearestRight );
invertTransform.transform( backNearestLeft );
// find the distance from the center of the far from the center of the near
// clipping plane
double xLength = Math.abs( ( backNearestRight.x - backNearestLeft.x ) * 0.5 );
double yLength = xLength / tangensOfHalfAngleOfView;
// For the frontal perspective ResolutionStripes we need to know the distance from the
// origin
double nearFrontalYDistance = origin.y + Math.abs( origin.y - backNearestLeft.y );
double farFrontalYDistance = nearFrontalYDistance + yLength;
// create the new Back-ResolutionStripe by adding the length in x and y direction
// according to the angleOfView. From this resolutionStripe the left, front and right
// stripes are calculated
Vector3d tmpBackLowerLeft = new Vector3d( backNearestLeft.x + xLength,
backNearestLeft.y - yLength,
backNearestLeft.z );
Vector3d tmpBackLowerRight = new Vector3d( backNearestRight.x - xLength,
backNearestRight.y - yLength,
backNearestRight.z );
Vector3d tmpBackUpperRight = new Vector3d( backNearestRight.x - xLength,
backNearestRight.y, backNearestRight.z );
Vector3d tmpBackUpperLeft = new Vector3d( backNearestLeft.x + xLength,
backNearestLeft.y, backNearestLeft.z );
// left
Vector3d tmpLeftLowerLeft = new Vector3d( tmpBackUpperLeft );
Vector3d tmpLeftLowerRight = new Vector3d( backNearestLeft );
Vector3d tmpLeftUpperRight = new Vector3d( backNearestLeft.x, nearFrontalYDistance,
backNearestLeft.z );
Vector3d tmpLeftUpperLeft = new Vector3d( tmpBackUpperLeft.x, nearFrontalYDistance,
backNearestLeft.z );
// front
Vector3d tmpFrontLowerLeft = new Vector3d( tmpLeftUpperLeft );
Vector3d tmpFrontLowerRight = new Vector3d( tmpBackLowerRight.x, nearFrontalYDistance,
backNearestLeft.z );
Vector3d tmpFrontUpperRight = new Vector3d( tmpBackLowerRight.x, farFrontalYDistance,
backNearestLeft.z );
Vector3d tmpFrontUpperLeft = new Vector3d( tmpLeftUpperLeft.x, farFrontalYDistance,
backNearestLeft.z );
// right
Vector3d tmpRightLowerLeft = new Vector3d( backNearestRight );
Vector3d tmpRightLowerRight = new Vector3d( tmpBackUpperRight );
Vector3d tmpRightUpperRight = new Vector3d( tmpFrontLowerRight );
Vector3d tmpRightUpperLeft = new Vector3d( backNearestRight.x, nearFrontalYDistance,
backNearestLeft.z );
// transform the resulting shape back to scene space
transform.transform( tmpBackLowerLeft );
transform.transform( tmpBackLowerRight );
transform.transform( tmpBackUpperRight );
transform.transform( tmpBackUpperLeft );
transform.transform( tmpLeftLowerLeft );
transform.transform( tmpLeftLowerRight );
transform.transform( tmpLeftUpperRight );
transform.transform( tmpLeftUpperLeft );
transform.transform( tmpFrontLowerLeft );
transform.transform( tmpFrontLowerRight );
transform.transform( tmpFrontUpperRight );
transform.transform( tmpFrontUpperLeft );
transform.transform( tmpRightLowerLeft );
transform.transform( tmpRightLowerRight );
transform.transform( tmpRightUpperRight );
transform.transform( tmpRightUpperLeft );
double resolution = StripeFactory.calcScaleOfVector( tmpBackLowerLeft,
tmpBackLowerRight, imageWidth );
ResolutionStripe rs = createResolutionStripe( tmpBackLowerLeft, tmpBackLowerRight,
tmpBackUpperRight, tmpBackUpperLeft,
minimalHeight, resolution, resolution );
if ( rs != null ) {
resultStripes.add( rs );
}
rs = createResolutionStripe( tmpLeftLowerLeft, tmpLeftLowerRight, tmpLeftUpperRight,
tmpLeftUpperLeft, minimalHeight, resolution, resolution );
if ( rs != null ) {
resultStripes.add( rs );
}
rs = createResolutionStripe( tmpFrontLowerLeft, tmpFrontLowerRight, tmpFrontUpperRight,
tmpFrontUpperLeft, minimalHeight, resolution, resolution );
if ( rs != null ) {
resultStripes.add( rs );
}
rs = createResolutionStripe( tmpRightLowerLeft, tmpRightLowerRight, tmpRightUpperRight,
tmpRightUpperLeft, minimalHeight, resolution, resolution );
if ( rs != null ) {
resultStripes.add( rs );
}
/**
* For debugging purpaces
*/
if ( g2d != null ) {
g2d.setColor( Color.GREEN );
g2d.drawLine( (int) tmpBackLowerLeft.x, (int) tmpBackLowerLeft.y,
(int) tmpBackLowerRight.x, (int) tmpBackLowerRight.y );
g2d.drawLine( (int) tmpBackLowerRight.x, (int) tmpBackLowerRight.y,
(int) tmpBackUpperRight.x, (int) tmpBackUpperRight.y );
g2d.drawLine( (int) tmpBackUpperRight.x, (int) tmpBackUpperRight.y,
(int) tmpBackUpperLeft.x, (int) tmpBackUpperLeft.y );
g2d.drawLine( (int) tmpBackUpperLeft.x, (int) tmpBackUpperLeft.y,
(int) tmpBackLowerLeft.x, (int) tmpBackLowerLeft.y );
g2d.setColor( Color.RED );
g2d.drawLine( (int) tmpLeftLowerLeft.x, (int) tmpLeftLowerLeft.y,
(int) tmpLeftLowerRight.x, (int) tmpLeftLowerRight.y );
g2d.drawLine( (int) tmpLeftLowerRight.x, (int) tmpLeftLowerRight.y,
(int) tmpLeftUpperRight.x, (int) tmpLeftUpperRight.y );
g2d.drawLine( (int) tmpLeftUpperRight.x, (int) tmpLeftUpperRight.y,
(int) tmpLeftUpperLeft.x, (int) tmpLeftUpperLeft.y );
g2d.drawLine( (int) tmpLeftUpperLeft.x, (int) tmpLeftUpperLeft.y,
(int) tmpLeftLowerLeft.x, (int) tmpLeftLowerLeft.y );
g2d.setColor( Color.BLUE );
g2d.drawLine( (int) tmpFrontLowerLeft.x, (int) tmpFrontLowerLeft.y,
(int) tmpFrontLowerRight.x, (int) tmpFrontLowerRight.y );
g2d.drawLine( (int) tmpFrontLowerRight.x, (int) tmpFrontLowerRight.y,
(int) tmpFrontUpperRight.x, (int) tmpFrontUpperRight.y );
g2d.drawLine( (int) tmpFrontUpperRight.x, (int) tmpFrontUpperRight.y,
(int) tmpFrontUpperLeft.x, (int) tmpFrontUpperLeft.y );
g2d.drawLine( (int) tmpFrontUpperLeft.x, (int) tmpFrontUpperLeft.y,
(int) tmpFrontLowerLeft.x, (int) tmpFrontLowerLeft.y );
g2d.setColor( Color.MAGENTA );
g2d.drawLine( (int) tmpRightLowerLeft.x, (int) tmpRightLowerLeft.y,
(int) tmpRightLowerRight.x, (int) tmpRightLowerRight.y );
g2d.drawLine( (int) tmpRightLowerRight.x, (int) tmpRightLowerRight.y,
(int) tmpRightUpperRight.x, (int) tmpRightUpperRight.y );
g2d.drawLine( (int) tmpRightUpperRight.x, (int) tmpRightUpperRight.y,
(int) tmpRightUpperLeft.x, (int) tmpRightUpperLeft.y );
g2d.drawLine( (int) tmpRightUpperLeft.x, (int) tmpRightUpperLeft.y,
(int) tmpRightLowerLeft.x, (int) tmpRightLowerLeft.y );
}
backNearestRight = new Vector3d( tmpBackLowerRight );
backNearestLeft = new Vector3d( tmpBackLowerLeft );
}
// Find intersection of the line connecting lowerLeft and upperleft of the footprint
invertTransform.transform( nearestLeft );
invertTransform.transform( farLeft );
invertTransform.transform( nearestRight );
invertTransform.transform( farRight );
invertTransform.transform( backNearestLeft );
invertTransform.transform( backNearestRight );
double nearFrontalYDistance = origin.y + Math.abs( origin.y - backNearestLeft.y );
/*
* We have the circular resolutionstripes, now the last back, left and right stripes (which
* are bounded by the footprint) have to be calculated, which can be done by Finding
* intersection between a horizontalLine (constant gradient) and the footprint.
*
* A line is defined as yValue = gradient*xValue + offset therefor intersection between
* those two lines as follows: offsetTwo = gradientOne*xValueOne + offsetOne => xValueOne =
* (offsetOne - offsetTwo) / gradientOne;
*/
double gradientLeft = ( nearestLeft.y - farRight.y ) / ( nearestLeft.x - farRight.x );
double offsetLeft = nearestLeft.y - gradientLeft * nearestLeft.x;
double gradientRight = ( nearestRight.y - farLeft.y ) / ( nearestRight.x - farLeft.x );
double offsetRight = nearestRight.y - gradientRight * nearestRight.x;
double xIntersectionLeft = ( backNearestRight.y - offsetLeft ) / gradientLeft;
double xIntersectionRight = ( backNearestRight.y - offsetRight ) / gradientRight;
// Back
Vector3d tmpBackLowerLeft = new Vector3d( nearestLeft );
Vector3d tmpBackLowerRight = new Vector3d( nearestRight );
Vector3d tmpBackUpperRight = new Vector3d( xIntersectionRight, backNearestRight.y,
backNearestRight.z );
Vector3d tmpBackUpperLeft = new Vector3d( xIntersectionLeft, backNearestLeft.y,
backNearestLeft.z );
// left
xIntersectionLeft = ( nearFrontalYDistance - offsetLeft ) / gradientLeft;
Vector3d tmpLeftLowerLeft = new Vector3d( tmpBackUpperLeft );
Vector3d tmpLeftLowerRight = new Vector3d( backNearestLeft );
Vector3d tmpLeftUpperRight = new Vector3d( backNearestLeft.x, nearFrontalYDistance,
backNearestLeft.z );
Vector3d tmpLeftUpperLeft = new Vector3d( xIntersectionLeft, nearFrontalYDistance,
backNearestLeft.z );
// right
xIntersectionRight = ( nearFrontalYDistance - offsetRight ) / gradientRight;
Vector3d tmpRightLowerLeft = new Vector3d( backNearestRight );
Vector3d tmpRightLowerRight = new Vector3d( tmpBackUpperRight );
Vector3d tmpRightUpperRight = new Vector3d( xIntersectionRight, nearFrontalYDistance,
backNearestLeft.z );
Vector3d tmpRightUpperLeft = new Vector3d( backNearestRight.x, nearFrontalYDistance,
backNearestLeft.z );
// back
transform.transform( tmpBackLowerLeft );
transform.transform( tmpBackLowerRight );
transform.transform( tmpBackUpperRight );
transform.transform( tmpBackUpperLeft );
// left
transform.transform( tmpLeftLowerLeft );
transform.transform( tmpLeftLowerRight );
transform.transform( tmpLeftUpperRight );
transform.transform( tmpLeftUpperLeft );
// right
transform.transform( tmpRightLowerLeft );
transform.transform( tmpRightLowerRight );
transform.transform( tmpRightUpperRight );
transform.transform( tmpRightUpperLeft );
double minResolution = StripeFactory.calcScaleOfVector( tmpBackUpperLeft,
tmpBackUpperRight, imageWidth );
double maxResolution = StripeFactory.calcScaleOfVector( tmpBackLowerLeft,
tmpBackLowerRight, imageWidth );
resultStripes.add( createResolutionStripe( tmpBackLowerLeft, tmpBackLowerRight,
tmpBackUpperRight, tmpBackUpperLeft,
minimalHeight, maxResolution, minResolution ) );
resultStripes.add( createResolutionStripe( tmpLeftLowerLeft, tmpLeftLowerRight,
tmpLeftUpperRight, tmpLeftUpperLeft,
minimalHeight, maxResolution, minResolution ) );
resultStripes.add( createResolutionStripe( tmpRightLowerLeft, tmpRightLowerRight,
tmpRightUpperRight, tmpRightUpperLeft,
minimalHeight, maxResolution, minResolution ) );
/**
* For debugging purpaces
*/
if ( g2d != null ) {
g2d.setColor( Color.GREEN );
g2d.drawLine( (int) tmpBackLowerLeft.x, (int) tmpBackLowerLeft.y,
(int) tmpBackLowerRight.x, (int) tmpBackLowerRight.y );
g2d.drawLine( (int) tmpBackLowerRight.x, (int) tmpBackLowerRight.y,
(int) tmpBackUpperRight.x, (int) tmpBackUpperRight.y );
g2d.drawLine( (int) tmpBackUpperRight.x, (int) tmpBackUpperRight.y,
(int) tmpBackUpperLeft.x, (int) tmpBackUpperLeft.y );
g2d.drawLine( (int) tmpBackUpperLeft.x, (int) tmpBackUpperLeft.y,
(int) tmpBackLowerLeft.x, (int) tmpBackLowerLeft.y );
g2d.setColor( Color.RED );
g2d.drawLine( (int) tmpLeftLowerLeft.x, (int) tmpLeftLowerLeft.y,
(int) tmpLeftLowerRight.x, (int) tmpLeftLowerRight.y );
g2d.drawLine( (int) tmpLeftLowerRight.x, (int) tmpLeftLowerRight.y,
(int) tmpLeftUpperRight.x, (int) tmpLeftUpperRight.y );
g2d.drawLine( (int) tmpLeftUpperRight.x, (int) tmpLeftUpperRight.y,
(int) tmpLeftUpperLeft.x, (int) tmpLeftUpperLeft.y );
g2d.drawLine( (int) tmpLeftUpperLeft.x, (int) tmpLeftUpperLeft.y,
(int) tmpLeftLowerLeft.x, (int) tmpLeftLowerLeft.y );
g2d.setColor( Color.MAGENTA );
g2d.drawLine( (int) tmpRightLowerLeft.x, (int) tmpRightLowerLeft.y,
(int) tmpRightLowerRight.x, (int) tmpRightLowerRight.y );
g2d.drawLine( (int) tmpRightLowerRight.x, (int) tmpRightLowerRight.y,
(int) tmpRightUpperRight.x, (int) tmpRightUpperRight.y );
g2d.drawLine( (int) tmpRightUpperRight.x, (int) tmpRightUpperRight.y,
(int) tmpRightUpperLeft.x, (int) tmpRightUpperLeft.y );
g2d.drawLine( (int) tmpRightUpperLeft.x, (int) tmpRightUpperLeft.y,
(int) tmpRightLowerLeft.x, (int) tmpRightLowerLeft.y );
}
// What is left, are the frontal Stripes which can be more than one (whith steep pitch).
Vector3d tmpFrontLowerLeft = new Vector3d( tmpLeftUpperLeft );
Vector3d tmpFrontLowerRight = new Vector3d( tmpRightUpperRight );
transform.transform( nearestLeft );
transform.transform( farLeft );
transform.transform( nearestRight );
transform.transform( farRight );
double frontalScale = StripeFactory.calcScaleOfVector( tmpFrontLowerLeft,
tmpFrontLowerRight, imageWidth );
if ( Math.abs( ( ( Math.abs( 1.0 / gradientLeft ) ) + Math.toRadians( 90 ) )
% Math.toRadians( 180 ) ) > 0.0001 ) {
double footPrintAngle = Math.atan( 1.0 / gradientLeft );
resultStripes.addAll( createStripesForFrontalPerspective( invertTransform, transform,
farRight, farLeft,
tmpFrontLowerLeft,
tmpFrontLowerRight,
imageWidth, minimalHeight,
footPrintAngle, frontalScale,
footprintFarResolution, g2d ) );
} else {
// Just one remaining ResolutionStripe, because only a square is left over (could be
// rounding error).
resultStripes.add( createResolutionStripe( tmpFrontLowerLeft, tmpFrontLowerRight,
farRight, farLeft, imageWidth, minimalHeight ) );
}
return resultStripes;
}
/**
* Creates a ResolutionStripe fromt the given Vectors. The variable names are just indicators
* for the order in which the Position are added to the polygon which is min, (min+width), max,
* (min+height).
*
* @param lowerLeft
* the min-value of the surface
* @param lowerRight
* the (min + width)-value of the surface
* @param upperRight
* the max-value of the surface
* @param upperLeft
* the (min + height)-value of the surface
* @param imageWidth
* needed to calculate the resolution
* @param minimalHeight
* to put the z-value to if it does not exist
* @return a brand new ResolutionStripe or <tt>null</tt> if an exception occurred.
*/
private ResolutionStripe createResolutionStripe( Vector3d lowerLeft, Vector3d lowerRight,
Vector3d upperRight, Vector3d upperLeft,
double imageWidth, double minimalHeight ) {
double maxResolution = StripeFactory.calcScaleOfVector( upperRight, upperLeft, imageWidth );
double minResolution = StripeFactory.calcScaleOfVector( lowerRight, lowerLeft, imageWidth );
return createResolutionStripe( lowerLeft, lowerRight, upperRight, upperLeft, minimalHeight,
maxResolution, minResolution );
}
private ResolutionStripe createResolutionStripe( Vector3d lowerLeft, Vector3d lowerRight,
Vector3d upperRight, Vector3d upperLeft,
double minimalHeight, double maxResolution,
double minResolution ) {
Position[] pos = new Position[5];
pos[0] = GeometryFactory.createPosition( lowerLeft.x, lowerLeft.y, lowerLeft.z );
pos[1] = GeometryFactory.createPosition( lowerRight.x, lowerRight.y, lowerLeft.z );
pos[2] = GeometryFactory.createPosition( upperRight.x, upperRight.y, lowerLeft.z );
pos[3] = GeometryFactory.createPosition( upperLeft.x, upperLeft.y, lowerLeft.z );
pos[4] = GeometryFactory.createPosition( lowerLeft.x, lowerLeft.y, lowerLeft.z );
try {
Surface surf = GeometryFactory.createSurface( pos, null, null, viewPoint.getCrs() );
return new ResolutionStripe( surf, maxResolution, minResolution, minimalHeight );
} catch ( GeometryException e ) {
e.printStackTrace();
}
return null;
}
/**
* @param bbox
* @param imageWidth
* @param minimalHeight
* @return a BoundingBox request ResolutionStripe
*/
public ArrayList<ResolutionStripe> createBBoxResolutionStripe( Envelope bbox, int imageWidth,
double minimalHeight ) {
Surface resultSurface = null;
try {
resultSurface = GeometryFactory.createSurface( bbox, viewPoint.getCrs() );
} catch ( GeometryException e ) {
e.printStackTrace();
}
Position min = bbox.getMin();
Position max = bbox.getMax();
System.out.println( "min: " + min );
System.out.println( "max: " + max );
double zValue = min.getZ();
if ( min.getCoordinateDimension() == 2 )
zValue = minimalHeight;
Vector3d lowerLeftPoint = new Vector3d( min.getX(), min.getY(), zValue );
Vector3d lowerRightPoint = new Vector3d( min.getX() + ( bbox.getWidth() ), min.getY(),
zValue );
double resolution = StripeFactory.calcScaleOfVector( lowerLeftPoint, lowerRightPoint,
imageWidth );
ArrayList<ResolutionStripe> resultStripe = new ArrayList<ResolutionStripe>();
resultStripe.add( new ResolutionStripe( resultSurface, resolution, resolution,
minimalHeight ) );
return resultStripe;
}
/**
* Calculates the Scale ( = Resolution* sqrt( 2 ) (== diagonal of pixel)) of a Vector between
* two points on the Screen given an imagewidth. That is, how much meter is the Scale of one
* Pixel in an Image given a certain vector.
*
* @param a
* "from" point
* @param b
* "to" point
* @param imageWidth
* the target imagewidth
* @return the scale on the screen.
*/
public static double calcScaleOfVector( Vector3d a, Vector3d b, double imageWidth ) {
Vector3d line = new Vector3d( a.x - b.x, a.y - b.y, a.z - b.z );
// how much meter is one pixel
// scale = the diagonal of one pixel
return ( line.length() / imageWidth ) * MapUtils.SQRT2;
}
/**
* @param value
* @return the nearestPowerOfTwo of the given value
*/
private int nearestPowerOfTwo( double value ) {
int result = 0;
int power = 2;
while ( power <= value ) {
power = power << 1;
result++;
}
return result;
}
}
/***************************************************************************************************
* Changes to this class. What the people have been up to: $Log: StripeFactory.java,v $
* Changes to this class. What the people have been up to: Revision 1.8 2006/11/28 16:53:45 bezema
* Changes to this class. What the people have been up to: bbox resolution works plus clean up and javadoc
* Changes to this class. What the people have been up to: Changes to
* this class. What the people have been up to: Revision 1.7 2006/11/27 11:46:51 bezema Changes to
* this class. What the people have been up to: boundingbox creation uses the viewpoints crs Changes
* to this class. What the people have been up to: Changes to this class. What the people have been
* up to: Revision 1.6 2006/11/23 11:46:40 bezema Changes to this class. What the people have been
* up to: The initial version of the new wpvs Changes to this class. What the people have been up
* to: Revision 1.5 2006/06/20 10:16:01 taddei clean up and javadoc
*
* Revision 1.4 2006/04/06 20:25:25 poth ** empty log message ***
*
* Revision 1.3 2006/03/30 21:20:26 poth ** empty log message ***
*
* Revision 1.2 2006/02/24 11:41:10 taddei commit sz (�)
*
* Revision 1.1 2006/02/09 15:47:24 taddei bug fixes, refactoring and javadoc
*
*
**************************************************************************************************/