001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/tools/app3d/Open3DFile.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 037 package org.deegree.tools.app3d; 038 039 import java.awt.Color; 040 import java.io.File; 041 import java.io.FileWriter; 042 import java.io.IOException; 043 import java.util.ArrayList; 044 import java.util.HashMap; 045 import java.util.List; 046 import java.util.Map; 047 import java.util.Set; 048 049 import javax.media.j3d.Appearance; 050 import javax.media.j3d.BranchGroup; 051 import javax.media.j3d.ColoringAttributes; 052 import javax.media.j3d.GeometryArray; 053 import javax.media.j3d.LineArray; 054 import javax.media.j3d.Material; 055 import javax.media.j3d.PointArray; 056 import javax.media.j3d.PolygonAttributes; 057 import javax.media.j3d.RenderingAttributes; 058 import javax.media.j3d.Shape3D; 059 import javax.swing.JOptionPane; 060 import javax.swing.JProgressBar; 061 import javax.vecmath.Color3f; 062 import javax.vecmath.Point3d; 063 064 import org.deegree.datatypes.Types; 065 import org.deegree.framework.log.ILogger; 066 import org.deegree.framework.log.LoggerFactory; 067 import org.deegree.framework.xml.XMLFragment; 068 import org.deegree.framework.xml.XSLTDocument; 069 import org.deegree.io.shpapi.shape_new.ShapeFile; 070 import org.deegree.io.shpapi.shape_new.ShapeFileReader; 071 import org.deegree.model.feature.Feature; 072 import org.deegree.model.feature.FeatureCollection; 073 import org.deegree.model.feature.FeatureProperty; 074 import org.deegree.model.feature.GMLFeatureAdapter; 075 import org.deegree.model.feature.GMLFeatureCollectionDocument; 076 import org.deegree.model.feature.schema.FeatureType; 077 import org.deegree.model.feature.schema.PropertyType; 078 import org.deegree.model.spatialschema.Curve; 079 import org.deegree.model.spatialschema.CurveSegment; 080 import org.deegree.model.spatialschema.Envelope; 081 import org.deegree.model.spatialschema.Geometry; 082 import org.deegree.model.spatialschema.GeometryException; 083 import org.deegree.model.spatialschema.MultiSurface; 084 import org.deegree.model.spatialschema.Point; 085 import org.deegree.model.spatialschema.Position; 086 import org.deegree.model.spatialschema.Ring; 087 import org.deegree.model.spatialschema.Surface; 088 import org.deegree.model.spatialschema.WKTAdapter; 089 import org.deegree.ogcbase.CommonNamespaces; 090 import org.deegree.ogcwebservices.wpvs.j3d.DefaultSurface; 091 import org.deegree.ogcwebservices.wpvs.j3d.Object3DFactory; 092 import org.deegree.ogcwebservices.wpvs.j3d.TexturedSurface; 093 import org.jdesktop.j3d.loaders.vrml97.VrmlLoader; 094 import org.w3c.dom.Node; 095 import org.w3c.dom.NodeList; 096 097 import com.sun.j3d.loaders.Scene; 098 import com.sun.j3d.utils.geometry.GeometryInfo; 099 import com.sun.j3d.utils.geometry.NormalGenerator; 100 101 /** 102 * <code>Open3DFile</code> reads a vrml, gml and shape files and creates a j3d scene from them. 103 * 104 * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a> 105 * @author last edited by: $Author: mschneider $ 106 * 107 * @version $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18 Jun 2009) $ 108 */ 109 public class Open3DFile { 110 private static ILogger LOG = LoggerFactory.getLogger( Open3DFile.class ); 111 112 private String fileName; 113 114 private BranchGroup openedFile; 115 116 private View3DFile parent; 117 118 /** 119 * @param fileName 120 * @param parent 121 * the frame to which message can be sent 122 */ 123 public Open3DFile( String fileName, View3DFile parent ) { 124 this.fileName = fileName; 125 this.parent = parent; 126 openedFile = null; 127 } 128 129 /** 130 * @param progressBar 131 * 132 * 133 */ 134 public void openFile( final JProgressBar progressBar ) { 135 136 try { 137 if ( fileName.toUpperCase().endsWith( ".SHP" ) ) { 138 openedFile = readShape( fileName, progressBar ); 139 } else if ( fileName.toUpperCase().endsWith( ".XML" ) || fileName.toUpperCase().endsWith( ".GML" ) ) { 140 openedFile = readGML( fileName, progressBar ); 141 } else if ( fileName.toUpperCase().endsWith( ".WRL" ) || fileName.toUpperCase().endsWith( ".VRML" ) ) { 142 openedFile = readVRML( fileName, progressBar ); 143 } 144 } catch ( IOException e ) { 145 parent.showExceptionDialog( e.getMessage() + "\nPlease, see the error log for detailed information." ); 146 } 147 if ( progressBar != null ) { 148 progressBar.setValue( 100 ); 149 } 150 151 } 152 153 /** 154 * @return the instantiated branchgroup or <code>null</code> if no branchgroup was instantiated 155 */ 156 public BranchGroup getOpenedFile() { 157 return openedFile; 158 } 159 160 private BranchGroup readShape( String fileName, JProgressBar progressBar ) 161 throws IOException { 162 try { 163 ShapeFile file = new ShapeFileReader( fileName ).read(); 164 if ( progressBar != null ) { 165 progressBar.setValue( 10 ); 166 } 167 return createUniformShape3D( file.getFeatureCollection(), progressBar ); 168 } catch ( Exception e ) { 169 LOG.logError( "Could not open shape file: " + fileName + " because: " + e.getMessage(), e ); 170 throw new IOException( "Could not open shape file: " + fileName ); 171 } 172 } 173 174 private BranchGroup readGML( String fileName, JProgressBar progressBar ) 175 throws IOException { 176 try { 177 XMLFragment doc = new XMLFragment( new File( fileName ) ); 178 boolean isCityGML = ( doc.getRootElement().getOwnerDocument().lookupPrefix( 179 CommonNamespaces.CITYGMLNS.toASCIIString() ) != null ) 180 || CommonNamespaces.CITYGMLNS.toASCIIString().equals( 181 doc.getRootElement().getOwnerDocument().lookupNamespaceURI( 182 "" ) ); 183 184 if ( !isCityGML ) { 185 isCityGML = isCityGMLDefined( doc.getRootElement() ); 186 } 187 boolean useDeegree = false; 188 if ( progressBar != null ) { 189 progressBar.setValue( 5 ); 190 } 191 if ( isCityGML ) { 192 useDeegree = ( JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog( 193 parent, 194 "The given file contains cityGML, please choose the import method.\n 1) Load the file with all it's textures and colors.\n 2) Load the file with a uniform color.\nDue to a bug in Java3d the first option may lead to unwanted results.\n\nLoad the file with all colors and textures?", 195 "Choose import method", 196 JOptionPane.YES_NO_OPTION ) ); 197 XSLTDocument transformer = null; 198 if ( useDeegree ) { 199 transformer = new XSLTDocument( View3DFile.class.getResource( "citygmlTOgml3.xsl" ) ); 200 } else { 201 transformer = new XSLTDocument( View3DFile.class.getResource( "toShape.xsl" ) ); 202 } 203 doc = transformer.transform( doc ); 204 } 205 if ( progressBar != null ) { 206 progressBar.setValue( 10 ); 207 } 208 GMLFeatureCollectionDocument gmlDoc = new GMLFeatureCollectionDocument(); 209 gmlDoc.setRootElement( doc.getRootElement() ); 210 211 FeatureCollection fc = gmlDoc.parse(); 212 if ( LOG.isDebug() ) { 213 File f = File.createTempFile( "in_file", ".gml" ); 214 LOG.logDebug( "temp file created at: ", f ); 215 f.deleteOnExit(); 216 FileWriter fw = new FileWriter( f ); 217 fw.write( gmlDoc.getAsPrettyString() ); 218 fw.close(); 219 GMLFeatureAdapter fa = new GMLFeatureAdapter( true ); 220 GMLFeatureCollectionDocument faDoc = fa.export( fc ); 221 f = File.createTempFile( "out_file", ".gml" ); 222 f.deleteOnExit(); 223 fw = new FileWriter( f ); 224 LOG.logDebug( "temp file created at: ", f ); 225 fw.write( faDoc.getAsPrettyString() ); 226 fw.close(); 227 } 228 if ( useDeegree ) { 229 return createShape3DWithMaterial( fc, progressBar ); 230 } 231 return createUniformShape3D( fc, progressBar ); 232 } catch ( Exception e ) { 233 LOG.logError( "Could not open gml file: " + fileName + " because: " + e.getMessage(), e ); 234 throw new IOException( "Could not open gml file: " + fileName ); 235 } 236 } 237 238 private BranchGroup readVRML( String fileName, JProgressBar progressBar ) 239 throws IOException { 240 VrmlLoader loader = new VrmlLoader(); 241 try { 242 if ( progressBar != null ) { 243 progressBar.setValue( 10 ); 244 } 245 Scene scene = loader.load( fileName ); 246 if ( scene != null ) { 247 if ( progressBar != null ) { 248 progressBar.setValue( 60 ); 249 Thread.sleep( 50 ); 250 } 251 BranchGroup bg = scene.getSceneGroup(); 252 bg.setCapability( BranchGroup.ALLOW_DETACH ); 253 if ( progressBar != null ) { 254 progressBar.setValue( 90 ); 255 Thread.sleep( 50 ); 256 } 257 return bg; 258 } 259 throw new Exception( "Could not create scene from file: " + fileName ); 260 } catch ( Exception e ) { 261 LOG.logError( "Error while loading vrml from file: " + fileName, e ); 262 throw new IOException( "Could not create vrml scene from file: " + fileName + " because: " + e.getMessage() ); 263 } 264 } 265 266 /** 267 * @param contextNode 268 * @return true if the namespace "http://www.citygml.org/citygml/1/0/0" was found in one of the nodes of the 269 * dom-tree. 270 */ 271 private boolean isCityGMLDefined( Node contextNode ) { 272 273 boolean isCityGML = ( contextNode.lookupPrefix( CommonNamespaces.CITYGMLNS.toASCIIString() ) != null ) 274 || CommonNamespaces.CITYGMLNS.toASCIIString().equals( contextNode.lookupNamespaceURI( null ) ); 275 if ( !isCityGML ) { 276 NodeList nl = contextNode.getChildNodes(); 277 for ( int i = 0; i < nl.getLength(); ++i ) { 278 isCityGML = isCityGMLDefined( nl.item( i ) ); 279 if ( isCityGML ) { 280 return true; 281 } 282 } 283 } 284 return isCityGML; 285 } 286 287 private Shape3D mapGeometryToShape3D( Geometry geom, Point3d translation ) { 288 if ( geom instanceof Point ) { 289 return createShape3D( (Point) geom, translation ); 290 } else if ( geom instanceof Curve ) { 291 return createShape3D( (Curve) geom, translation ); 292 } else if ( geom instanceof Surface ) { 293 return createShape3D( (Surface) geom, translation ); 294 } else if ( geom instanceof MultiSurface ) { 295 return createShape3D( (MultiSurface) geom, translation ); 296 } else { 297 if ( geom == null ) { 298 LOG.logError( "Could not map the geometry which was not instantiated" ); 299 } else { 300 LOG.logError( "Could not map the geometry: " + geom.getClass().getName() ); 301 } 302 return null; 303 } 304 } 305 306 private Shape3D createShape3D( Point p, Point3d translation ) { 307 GeometryArray geomArray = new PointArray( 1, GeometryArray.COORDINATES ); 308 double z = p.getZ(); 309 if ( Double.isInfinite( z ) || Double.isNaN( z ) ) { 310 z = 0; 311 } 312 geomArray.setCoordinate( 0, new Point3d( p.getX() + translation.x, p.getY() + translation.y, z + translation.z ) ); 313 Shape3D result = new Shape3D( geomArray ); 314 result.setAppearanceOverrideEnable( true ); 315 return result; 316 } 317 318 private Shape3D createShape3D( Curve c, Point3d translation ) { 319 int totalPoints = 0; 320 List<Integer> failSegments = new ArrayList<Integer>(); 321 for ( int i = 0; i < c.getNumberOfCurveSegments(); ++i ) { 322 try { 323 totalPoints += c.getCurveSegmentAt( i ).getNumberOfPoints(); 324 } catch ( GeometryException e ) { 325 LOG.logError( "Could not get CurveSegment at position: " + i ); 326 failSegments.add( new Integer( i ) ); 327 } 328 } 329 330 LineArray geomArray = new LineArray( totalPoints, GeometryArray.COORDINATES ); 331 for ( int i = 0, pointCounter = 0; i < c.getNumberOfCurveSegments(); ++i ) { 332 if ( !failSegments.contains( new Integer( i ) ) ) { 333 CurveSegment segment = null; 334 try { 335 segment = c.getCurveSegmentAt( i ); 336 } catch ( GeometryException e ) { 337 // cannot happen. 338 } 339 for ( int k = 0; k < segment.getNumberOfPoints(); ++k ) { 340 Position p = segment.getPositionAt( k ); 341 double z = p.getZ(); 342 if ( Double.isInfinite( z ) || Double.isNaN( z ) ) { 343 z = 0; 344 } 345 geomArray.setCoordinate( pointCounter++, new Point3d( p.getX() + translation.x, p.getY() 346 + translation.y, 347 z + translation.z ) ); 348 } 349 } 350 } 351 Shape3D result = new Shape3D( geomArray ); 352 result.setAppearanceOverrideEnable( true ); 353 return result; 354 } 355 356 /** 357 * 358 * @param surface 359 * to be created 360 * @param translation 361 * to origin of the scene 362 * @return a Shape3D created from the surface. 363 */ 364 private Shape3D createShape3D( Surface surface, Point3d translation ) { 365 GeometryInfo geometryInfo = new GeometryInfo( GeometryInfo.POLYGON_ARRAY ); 366 Position[] pos = surface.getSurfaceBoundary().getExteriorRing().getPositions(); 367 Ring[] innerRings = surface.getSurfaceBoundary().getInteriorRings(); 368 int numberOfRings = 1; 369 int numberOfCoordinates = 3 * ( pos.length ); 370 if ( innerRings != null ) { 371 for ( int i = 0; i < innerRings.length; i++ ) { 372 numberOfRings++; 373 numberOfCoordinates += ( 3 * innerRings[i].getPositions().length ); 374 } 375 } 376 377 float[] coords = new float[numberOfCoordinates]; 378 int contourCounts[] = { numberOfRings }; 379 int[] stripCounts = new int[numberOfRings]; 380 numberOfRings = 0; 381 stripCounts[numberOfRings++] = pos.length; 382 383 int z = 0; 384 for ( int i = 0; i < pos.length; i++ ) { 385 double zValue = pos[i].getZ(); 386 if ( Double.isInfinite( zValue ) || Double.isNaN( zValue ) ) { 387 zValue = 0; 388 } 389 // LOG.logDebug( "Found a point in a surface: " + pos[i] ); 390 coords[z++] = (float) ( pos[i].getX() + translation.x ); 391 coords[z++] = (float) ( pos[i].getY() + translation.y ); 392 coords[z++] = (float) ( zValue + translation.z ); 393 } 394 395 if ( innerRings != null ) { 396 for ( int j = 0; j < innerRings.length; j++ ) { 397 pos = innerRings[j].getPositions(); 398 stripCounts[numberOfRings++] = pos.length; 399 for ( int i = 0; i < pos.length; i++ ) { 400 double zValue = pos[i].getZ(); 401 if ( Double.isInfinite( zValue ) || Double.isNaN( zValue ) ) { 402 zValue = 0; 403 } 404 coords[z++] = (float) ( pos[i].getX() + translation.x ); 405 coords[z++] = (float) ( pos[i].getY() + translation.y ); 406 coords[z++] = (float) ( zValue + translation.z ); 407 } 408 } 409 } 410 geometryInfo.setCoordinates( coords ); 411 geometryInfo.setStripCounts( stripCounts ); 412 geometryInfo.setContourCounts( contourCounts ); 413 geometryInfo.recomputeIndices(); 414 415 NormalGenerator ng = new NormalGenerator(); 416 ng.generateNormals( geometryInfo ); 417 Shape3D result = new Shape3D( geometryInfo.getGeometryArray() ); 418 result.setCapability( Shape3D.ALLOW_GEOMETRY_READ ); 419 result.setCapability( Shape3D.ALLOW_GEOMETRY_WRITE ); 420 result.setAppearanceOverrideEnable( true ); 421 return result; 422 } 423 424 /** 425 * @param multiSurface 426 * @param translation 427 * @return a Shape3D created from the multisurfaces. 428 */ 429 private Shape3D createShape3D( MultiSurface multiSurface, Point3d translation ) { 430 LOG.logDebug( "Found a Multi surface" ); 431 Shape3D result = new Shape3D(); 432 result.setCapability( Shape3D.ALLOW_GEOMETRY_READ ); 433 result.setCapability( Shape3D.ALLOW_GEOMETRY_WRITE ); 434 Surface[] allSurfaces = multiSurface.getAllSurfaces(); 435 for ( int surfaceCount = 0; surfaceCount < allSurfaces.length; ++surfaceCount ) { 436 Surface surface = multiSurface.getSurfaceAt( surfaceCount ); 437 Shape3D s3D = createShape3D( surface, translation ); 438 result.addGeometry( s3D.getGeometry() ); 439 } 440 result.setAppearanceOverrideEnable( true ); 441 return result; 442 } 443 444 /** 445 * This method recursively constructs all the surfaces contained in the given feature. If the Feature contains a 446 * PropertyType of {@link Types#FEATURE} this Feature will also be traversed, if it contains a 447 * {@link Types#GEOMETRY} a {@link DefaultSurface} will be created. 448 * 449 * @param o3DFactory 450 * the Factory to create the defaultservice 451 * @param feature 452 * the feature to traverse. 453 */ 454 private void createSurfaces( Object3DFactory o3DFactory, Feature feature, Map<String, TexturedSurface> textureMap, 455 BranchGroup result ) { 456 457 FeatureType ft = feature.getFeatureType(); 458 PropertyType[] propertyTypes = ft.getProperties(); 459 for ( PropertyType pt : propertyTypes ) { 460 if ( pt.getType() == Types.FEATURE ) { 461 FeatureProperty[] fp = feature.getProperties( pt.getName() ); 462 if ( fp != null ) { 463 for ( int i = 0; i < fp.length; i++ ) { 464 createSurfaces( o3DFactory, (Feature) fp[i].getValue(), textureMap, result ); 465 } 466 } 467 } else if ( pt.getType() == Types.GEOMETRY ) { 468 DefaultSurface ds = o3DFactory.createSurface( feature, textureMap ); 469 if ( ds != null ) { 470 ds.compile(); 471 result.addChild( ds ); 472 // resolutionStripe.addFeature( id + "_" + ds.getDefaultSurfaceID(), ds ); 473 } 474 } 475 } 476 } 477 478 private BranchGroup createUniformShape3D( FeatureCollection fc, JProgressBar progressBar ) { 479 BranchGroup bg = new BranchGroup(); 480 bg.setCapability( BranchGroup.ALLOW_DETACH ); 481 Appearance app = new Appearance(); 482 RenderingAttributes ra = new RenderingAttributes(); 483 ra.setDepthBufferEnable( true ); 484 app.setRenderingAttributes( ra ); 485 Material material = new Material(); 486 material.setAmbientColor( new Color3f( Color.WHITE ) ); 487 material.setDiffuseColor( new Color3f( Color.RED ) ); 488 material.setSpecularColor( new Color3f( Color.BLUE ) ); 489 ColoringAttributes ca = new ColoringAttributes(); 490 ca.setShadeModel( ColoringAttributes.SHADE_GOURAUD ); 491 ca.setCapability( ColoringAttributes.NICEST ); 492 app.setColoringAttributes( ca ); 493 PolygonAttributes pa = new PolygonAttributes(); 494 pa.setCullFace( PolygonAttributes.CULL_NONE ); 495 pa.setBackFaceNormalFlip( true ); 496 pa.setPolygonMode( PolygonAttributes.POLYGON_FILL ); 497 app.setPolygonAttributes( pa ); 498 app.setMaterial( material ); 499 Envelope bbox = null; 500 for ( int i = 0; i < fc.size(); ++i ) { 501 Feature f = fc.getFeature( i ); 502 Geometry geom = f.getDefaultGeometryPropertyValue(); 503 if ( LOG.isDebug() ) { 504 try { 505 LOG.logDebug( "Found geometry: " + WKTAdapter.export( geom ) ); 506 } catch ( GeometryException e ) { 507 LOG.logError( e.getMessage(), e ); 508 } 509 510 } 511 if ( bbox == null ) { 512 bbox = geom.getEnvelope(); 513 } else { 514 try { 515 bbox = bbox.merge( geom.getEnvelope() ); 516 LOG.logDebug( "merging the bboxes resulted in: " + bbox ); 517 } catch ( GeometryException e ) { 518 LOG.logError( "Couldn't merge the bboxes of the found featureCollection", e ); 519 } 520 } 521 } 522 if ( progressBar != null ) { 523 progressBar.setValue( 20 ); 524 } 525 Point3d centroid = new Point3d( 0, 0, 0 ); 526 if ( bbox != null ) { 527 Point p = bbox.getCentroid(); 528 double zValue = p.getZ(); 529 if ( Double.isInfinite( zValue ) || Double.isNaN( zValue ) ) { 530 zValue = 0; 531 } 532 centroid.set( -p.getX(), -p.getY(), -zValue ); 533 } 534 final double progress = ( (double) ( ( progressBar.getMaximum() - 10 ) - progressBar.getValue() ) ) / fc.size(); 535 double currentProg = progressBar.getValue(); 536 for ( int i = 0; i < fc.size(); ++i ) { 537 Feature f = fc.getFeature( i ); 538 if ( progressBar != null ) { 539 currentProg += progress; 540 if ( ( (int) Math.floor( currentProg ) - progressBar.getValue() ) > 5 ) { 541 progressBar.setValue( (int) Math.floor( currentProg ) ); 542 } 543 } 544 Geometry geom = f.getDefaultGeometryPropertyValue(); 545 Shape3D shape = mapGeometryToShape3D( geom, centroid ); 546 if ( shape != null ) { 547 shape.setAppearance( app ); 548 bg.addChild( shape ); 549 } else { 550 // System.out.println( "ERRORORORORORORO" ); 551 } 552 } 553 if ( !bg.getAllChildren().hasMoreElements() ) { 554 throw new IllegalArgumentException( "Could not read any 3D-Info from given featurecollection." ); 555 } 556 return bg; 557 } 558 559 /** 560 * Use the Object3DFactory of the wpvs to create colored surfaces and textures. 561 * 562 * @param fc 563 * @return the branch group 564 */ 565 private BranchGroup createShape3DWithMaterial( FeatureCollection fc, JProgressBar progressBar ) { 566 BranchGroup bg = new BranchGroup(); 567 bg.setCapability( BranchGroup.ALLOW_DETACH ); 568 569 Object3DFactory o3DFactory = new Object3DFactory(); 570 Map<String, TexturedSurface> textureMap = new HashMap<String, TexturedSurface>( fc.size() * 10 ); 571 final double progress = ( (double) ( ( progressBar.getMaximum() - 10 ) - progressBar.getValue() ) ) / fc.size(); 572 double currentProg = progressBar.getValue(); 573 for ( int i = 0; i < fc.size(); ++i ) { 574 if ( progressBar != null ) { 575 currentProg += progress; 576 if ( ( (int) Math.floor( currentProg ) - progressBar.getValue() ) > 5 ) { 577 progressBar.setValue( (int) Math.floor( currentProg ) ); 578 } 579 } 580 Feature feature = fc.getFeature( i ); 581 createSurfaces( o3DFactory, feature, textureMap, bg ); 582 } 583 if ( textureMap.size() > 0 ) { 584 Set<String> keys = textureMap.keySet(); 585 for ( String key : keys ) { 586 if ( key != null ) { 587 TexturedSurface surf = textureMap.get( key ); 588 if ( surf != null ) { 589 surf.compile(); 590 bg.addChild( surf ); 591 } 592 } 593 594 } 595 } 596 if ( !bg.getAllChildren().hasMoreElements() ) { 597 throw new IllegalArgumentException( "Could not read any 3D-Info from given featurecollection." ); 598 } 599 return bg; 600 } 601 }