001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/ogcwebservices/wpvs/utils/VisADWrapper.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 package org.deegree.ogcwebservices.wpvs.utils;
044
045 import java.rmi.RemoteException;
046 import java.util.ArrayList;
047 import java.util.List;
048
049 import org.deegree.framework.log.ILogger;
050 import org.deegree.framework.log.LoggerFactory;
051 import org.deegree.model.spatialschema.Point;
052
053 import visad.Delaunay;
054 import visad.FlatField;
055 import visad.FunctionType;
056 import visad.Irregular2DSet;
057 import visad.RealTupleType;
058 import visad.RealType;
059 import visad.VisADException;
060
061 /**
062 * A wrapper for VisAD objects. This class takes care of collecting points to build a TIN, of TIN
063 * creation itself and its output as a geometry collection.
064 *
065 * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a>
066 * @author last edited by: $Author: rbezema $
067 *
068 * $Revision: 7963 $, $Date: 2007-08-09 12:03:15 +0200 (Do, 09 Aug 2007) $
069 *
070 *
071 */
072 public class VisADWrapper {
073
074 private static final ILogger LOG = LoggerFactory.getLogger( VisADWrapper.class );
075
076 /**
077 * A list for hold points representing te DEM/TIN.
078 */
079 private List<Point> pointsList;
080
081 private double scale;
082
083 /**
084 * Initializes the object by creating a common domain field from the geometrical information
085 * (the envelope, the width and the height) supplied. The envelope cannot the null, nor can the
086 * dimensions by < 1.
087 *
088 * @param ptsList
089 * a list of Points
090 * @param scale to multiply to the z-value
091 */
092 public VisADWrapper( List<Point> ptsList, double scale ) {
093 this.pointsList = ptsList;
094 this.scale = scale;
095 }
096
097 /**
098 * Add <code>Point</code>s to the internal list. Lists without any elements (or null lists)
099 * are ignored.
100 *
101 * @param points
102 * to be added to the list
103 */
104 public final void addPoints( List<Point> points ) {
105
106 if ( points == null || points.size() == 0 ) {
107 return;
108 }
109
110 this.pointsList.addAll( points );
111 }
112
113 /**
114 * Generates a list of tringles containing the triangles representing the TIN. Triangles are
115 * represented float[3][3]
116 *
117 * @return a collection of <code>float[3][3]</code>, each of which representing a TIN
118 * triangle
119 *
120 */
121 public final List<float[][]> getTriangleCollectionAsList() {
122
123 List<float[][]> list = null;
124 try {
125 FlatField tinField = triangulatePoints();
126 if ( tinField == null )
127 return null;
128 list = toGeoCollectionList( tinField );
129 } catch ( NoClassDefFoundError ncdfe ) {
130 LOG.logError( "WPVS: It seems that the visad library could not be found: "
131 + ncdfe.getLocalizedMessage(), ncdfe );
132 } catch ( VisADException ve ) {
133 LOG.logError( ve.getLocalizedMessage(), ve );
134 }
135 return list;
136 }
137
138 /**
139 * Triangulate <code>GM_Point</code>s contained in <code>gmPointsList</code> using the
140 * Clarkson algorithm. This method returns a <code>FlatField</code> containing all points
141 * triangulated and with their elevation values.<br/>
142 *
143 * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a>
144 *
145 * @param gmPointsList
146 * the list of <code>GM_Point</code>s. Cannot be null and must contain at least 3
147 * <code>GM_Point</code>s.
148 * @return a <code>FlatField</code> containg a TIN (with an <code>Irregular2DSet</code> as
149 * its domain set and the elevation values)
150 *
151 */
152 private FlatField triangulatePoints()
153 throws NoClassDefFoundError {
154
155 if ( this.pointsList == null || this.pointsList.size() < 3 ) {
156 throw new IllegalArgumentException(
157 "Points list cannot be null and must contain at least 3 GM_Points." );
158 }
159
160 //removing double points
161 ArrayList<Point> remove = new ArrayList<Point>();
162 for ( int i = 0; i < pointsList.size(); ++i ) {
163 Point p = pointsList.get( i );
164
165 if ( !remove.contains( p ) ) {
166 for ( int j = i+1; j < pointsList.size(); ++j ) {
167 Point tmpP = pointsList.get( j );
168 if ( ( Math.abs( tmpP.getX() - p.getX() ) < 0.001 )
169 && ( Math.abs( tmpP.getY() - p.getY() ) < 0.001 ) ) {
170 remove.add( tmpP );
171 }
172 }
173 }
174 }
175 for( Point p : remove ){
176 pointsList.remove( p );
177 }
178 float[][] triPoints = new float[3][this.pointsList.size()];
179 int cnt = 0;
180
181 for ( Point p : this.pointsList ) {
182 triPoints[0][cnt] = (float) p.getX();
183 triPoints[1][cnt] = (float) p.getY();
184 triPoints[2][cnt++] = (float) (p.getZ()*scale);
185 }
186
187 try {
188 FunctionType functionType = new FunctionType( new RealTupleType( RealType.XAxis,
189 RealType.YAxis ),
190 RealType.ZAxis );
191 float[][] ptsXY = new float[][] { triPoints[0], triPoints[1] };
192
193 // ptsXY = Delaunay.perturb(ptsXY,0.21f, false);
194 ptsXY = Delaunay.perturb( ptsXY, 5.5f, false );
195 Delaunay delan = Delaunay.factory( ptsXY, true );
196 //Delaunay delan = new DelaunayClarkson( ptsXY );
197 //Delaunay delan = new DelaunayWatson( ptsXY );
198 //delan.setNonConvex();
199 try {
200 delan.improve( ptsXY, 3 );
201 } catch ( Exception e ) {
202 // just do noting
203 }
204
205
206 // Delaunay delan = new DelaunayClarkson( ptsXY );
207 // Delaunay delan = new DelaunayFast( ptsXY );
208 Irregular2DSet pointsSet = new Irregular2DSet( functionType.getDomain(), ptsXY, null,
209 null, null, delan );
210
211 FlatField ff = new FlatField( functionType, pointsSet );
212
213 ff.setSamples( new float[][] { triPoints[2] }, true );
214
215 return ff;
216
217 } catch ( VisADException e ) {
218 System.out.println( e.getMessage() );
219 e.printStackTrace();
220 return null;
221 } catch ( RemoteException re ) {
222 re.printStackTrace();
223 return null;
224 } catch ( IndexOutOfBoundsException ioobe ) {
225 ioobe.printStackTrace();
226 return null;
227 }
228 }
229
230 /**
231 * Generated a list of triangles from the FlatField passed in as tinField
232 *
233 * @param tinField
234 * the FlatField containing triangles
235 * @return a collection of <code>float[3][3]</code>, each of which representing a TIN
236 * triangle
237 * @throws VisADException
238 * @throws Exception
239 * in the unlikely event that a VisAD expcetion is thrown
240 */
241 private final List<float[][]> toGeoCollectionList( FlatField tinField )
242 throws NoClassDefFoundError, VisADException {
243 if ( tinField == null ) {
244 throw new RuntimeException( "FlatField cannot be null." );
245 }
246
247 List<float[][]> geoCollec = new ArrayList<float[][]>( 5000 );
248
249 Irregular2DSet domainSet = (Irregular2DSet) tinField.getDomainSet();
250
251 float[][] xyPositions = domainSet.getSamples();
252 float[][] zValues = tinField.getFloats();
253 int[][] indices = domainSet.Delan.Tri;
254
255 // loop over triangles...
256 for ( int i = 0; i < indices.length; i++ ) {
257
258 // indices[i].length == coords.length == 3
259 // this is float[3][3] -> 3 points per triabngle, each point with 3 coords
260 float[][] myCoords = new float[3][3];
261
262 // ...then over points
263 for ( int j = 0; j < indices[i].length; j++ ) {
264
265 int index = indices[i][j];
266 myCoords[j] = new float[3];
267 myCoords[j][0] = xyPositions[0][index];
268 myCoords[j][1] = xyPositions[1][index];
269 myCoords[j][2] = zValues[0][index];
270 }
271
272 geoCollec.add( myCoords );
273 }
274
275 tinField = null;
276
277 return geoCollec;
278 }
279
280 /**
281 * Clear all points and invalidate list.
282 *
283 */
284 public void clear() {
285 this.pointsList.clear();
286 this.pointsList = null;
287
288 }
289
290 }
291 /***************************************************************************************************
292 * Changes to this class. What the people have been up to: $Log$
293 * Changes to this class. What the people have been up to: Revision 1.4 2007/01/23 15:19:11 bezema
294 * Changes to this class. What the people have been up to: added the scale "parameter" to the measurepoints
295 * Changes to this class. What the people have been up to:
296 * Changes to this class. What the people have been up to: Revision 1.3 2007/01/23 15:09:41 bezema
297 * Changes to this class. What the people have been up to: added some methods for wfs dgm to sow together the triangle terrains
298 * Changes to this class. What the people have been up to: Changes to
299 * this class. What the people have been up to: Revision 1.2 2007/01/15 17:03:25 bezema Changes to
300 * this class. What the people have been up to: if no library is found, this will be catched now
301 * Changes to this class. What the people have been up to: Changes to this class. What the people
302 * have been up to: Revision 1.1 2006/12/06 15:11:24 bezema Changes to this class. What the people
303 * have been up to: renamed the wpvs.util package into wpvs.utils, removed not used classes and
304 * moved SunPosition SUnLight in the util package Changes to this class. What the people have been
305 * up to: Changes to this class. What the people have been up to: Revision 1.10 2006/11/23 11:46:40
306 * bezema Changes to this class. What the people have been up to: The initial version of the new
307 * wpvs Changes to this class. What the people have been up to: Revision 1.9 2006/07/12 14:46:19
308 * poth comment footer added
309 *
310 **************************************************************************************************/