//$Header: /home/deegree/jail/deegreerepository/deegree/src/org/deegree/ogcwebservices/wpvs/util/Attic/VisADWrapper.java,v 1.10 2006/11/23 11:46:40 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.rmi.RemoteException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import org.deegree.framework.log.ILogger; import org.deegree.framework.log.LoggerFactory; import org.deegree.model.spatialschema.Point; import visad.Delaunay; import visad.DelaunayClarkson; import visad.FlatField; import visad.FunctionType; import visad.Irregular2DSet; import visad.RealTupleType; import visad.RealType; import visad.VisADException; /** * A wrapper for VisAD objects. This class takes care of collecting points to build a TIN, of TIN * creation itself and its output as a geometry collection. * * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a> * */ public class VisADWrapper { private static final ILogger LOG = LoggerFactory.getLogger( VisADWrapper.class ); /** * A list for hold points representing te DEM/TIN. */ private List<Point> pointsList; /** * The minimum altitude value used for boundary points of the main envelope. This is calculated * for each request and it is a better approach then extrapolating the altitude values. */ private float minimumAltitude = Float.POSITIVE_INFINITY; /** * Initializes the object by creating a common domain field from the geometrical information * (the envelope, the width and the height) supplied. The envelope cannot the null, nor can the * dimensions by < 1. * * @param ptsList * a list of Points */ public VisADWrapper( List<Point> ptsList ) { this.pointsList = ptsList; } /** * Add <code>Point</code>s to the internal list. Lists without any elements (or null lists) * are ignored. * * @param points * to be added to the list */ public final void addPoints( List<Point> points ) { LOG.entering(); if ( points == null || points.size() == 0 ) { return; } this.pointsList.addAll( points ); LOG.exiting(); } /** * Generates a list of tringles containing the triangles representing the TIN. Triangles are * represented float[3][3] * * @return a collection of <code>float[3][3]</code>, each of which representing a TIN * triangle * */ public final List<float[][]> getTriangleCollectionAsList() { LOG.entering(); List<float[][]> list = null; long time = System.currentTimeMillis(); FlatField tinField = triangulatePoints( ); if( tinField == null ) return null; LOG.logDebug( "Triangulation time: " + ( System.currentTimeMillis() - time ) / 1000d ); try { list = toGeoCollectionList( tinField ); } catch ( Exception e ) { throw new RuntimeException( e ); } LOG.exiting(); return list; } /** * Triangulate <code>GM_Point</code>s contained in <code>gmPointsList</code> using the * Clarkson algorithm. This method returns a <code>FlatField</code> containing all points * triangulated and with their elevation values.<br/> * * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a> * * @param gmPointsList * the list of <code>GM_Point</code>s. Cannot be null and must contain at least 3 * <code>GM_Point</code>s. * @return a <code>FlatField</code> containg a TIN (with an <code>Irregular2DSet</code> as * its domain set and the elevation values) * */ private FlatField triangulatePoints( ) { LOG.entering(); if ( this.pointsList == null || this.pointsList.size() < 3 ) { throw new IllegalArgumentException( "Points list cannot be null and must contain at least 3 GM_Points." ); } float[][] triPoints = new float[3][this.pointsList.size()]; int cnt = 0; for ( Point p : this.pointsList) { triPoints[0][cnt] = (float) p.getX(); triPoints[1][cnt] = (float) p.getY(); triPoints[2][cnt++] = (float) p.getZ(); } try { FunctionType functionType = new FunctionType( new RealTupleType( RealType.XAxis, RealType.YAxis ), RealType.ZAxis ); float[][] ptsXY = new float[][] { triPoints[0], triPoints[1] }; // ptsXY = Delaunay.perturb(ptsXY,0.21f, false); LOG.logDebug( "Number of Points = " + triPoints[0].length ); Delaunay delan = new DelaunayClarkson( ptsXY ); Irregular2DSet pointsSet = new Irregular2DSet( functionType.getDomain(), ptsXY, null, null, null, delan ); FlatField ff = new FlatField( functionType, pointsSet ); ff.setSamples( new float[][] { triPoints[2] }, true ); return ff; } catch ( VisADException e ) { e.printStackTrace(); return null; } catch ( RemoteException re ) { re.printStackTrace(); return null; } catch ( IndexOutOfBoundsException ioobe ){ ioobe.printStackTrace(); return null; } } /** * Generated a list of triangles from the FlatField passed in as tinField * * @param tinField * the FlatField containing triangles * @return a collection of <code>float[3][3]</code>, each of which representing a TIN * triangle * @throws Exception * in the unlikely event that a VisAD expcetion is thrown */ private final List<float[][]> toGeoCollectionList( FlatField tinField ) throws Exception { LOG.entering(); if ( tinField == null ) { throw new RuntimeException( "FlatField cannot be null." ); } List<float[][]> geoCollec = new ArrayList<float[][]>( 5000 ); Irregular2DSet domainSet = (Irregular2DSet) tinField.getDomainSet(); float[][] xyPositions = domainSet.getSamples(); float[][] zValues = tinField.getFloats(); int[][] indices = domainSet.Delan.Tri; // loop over triangles... for ( int i = 0; i < indices.length; i++ ) { // indices[i].length == coords.length == 3 // this is float[3][3] -> 3 points per triabngle, each point with 3 coords float[][] myCoords = new float[3][3]; // ...then over points for ( int j = 0; j < indices[i].length; j++ ) { int index = indices[i][j]; myCoords[j] = new float[3]; myCoords[j][0] = xyPositions[0][index]; myCoords[j][1] = xyPositions[1][index]; myCoords[j][2] = zValues[0][index]; } geoCollec.add( myCoords ); } tinField = null; LOG.exiting(); return geoCollec; } /** * Clear all points and invalidate list. * */ public void clear() { this.pointsList.clear(); this.pointsList = null; } /** * Get the minimum altitude value. This is used for points on the edge of the WTS view. * * @return the minimum altitude value of the points' list of this object */ public final float getMinimumAltitude() { // Debug.debugMethodBegin(); for ( Iterator iter = pointsList.iterator(); iter.hasNext(); ) { Point point = (Point) iter.next(); minimumAltitude = Math.min( minimumAltitude, (float) point.getZ() ); } // Debug.debugMethodEnd(); return this.minimumAltitude; } // public void setPointList( List<Point> ptsList ) { // this.pointsList = ptsList; // } } /*************************************************************************************************** * Changes to this class. What the people have been up to: $Log: VisADWrapper.java,v $ * Changes to this class. What the people have been up to: Revision 1.10 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.9 * 2006/07/12 14:46:19 poth comment footer added * **************************************************************************************************/