/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2013, Geomatys * * 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; * version 2.1 of the License. * * 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. */ package org.geotoolkit.display3d.scene; import com.jogamp.opengl.GL; import com.jogamp.opengl.GLAutoDrawable; import com.jogamp.opengl.GLException; import com.jogamp.opengl.GLProfile; import com.jogamp.opengl.util.texture.TextureData; import com.jogamp.opengl.util.texture.TextureIO; import java.awt.Dimension; import java.awt.Point; import java.io.InputStream; import javax.measure.IncommensurableException; import org.geotoolkit.display.PortrayalException; import org.geotoolkit.display3d.Map3D; import org.geotoolkit.display3d.scene.camera.TrackBallCamera; import org.geotoolkit.display3d.scene.component.Tile3D; import org.geotoolkit.display3d.scene.loader.ElevationLoader; import org.geotoolkit.display3d.scene.loader.ImageLoader; import org.geotoolkit.display3d.scene.quadtree.QuadTree; import org.geotoolkit.display3d.scene.quadtree.QuadTreeNode; import org.geotoolkit.display3d.scene.quadtree.QuadTreeUtils; import org.opengis.geometry.DirectPosition; import org.opengis.geometry.Envelope; import org.opengis.referencing.operation.TransformException; import org.opengis.util.FactoryException; /** * * @author Thomas Rouby (Geomatys) * @author Johann Sorel (Geomatys) */ public class Terrain extends SceneNode3D { private final QuadTree quadTree; private ImageLoader loaderImg; private ElevationLoader loaderMNT; private TextureData textureDataDefault, textureDataError, textureDataBlank; public Terrain(Map3D map, Envelope envelope, int numMosaic) throws TransformException, FactoryException { super(map); this.quadTree = new QuadTree(map, envelope, 1, numMosaic); setUpdater(new TerrainUpdater(this)); } public QuadTree getQuadTree() { return this.quadTree; } @Override protected void initInternal(GLAutoDrawable glDrawable) throws GLException { final GL gl = glDrawable.getGL(); final GLProfile glProfile = glDrawable.getGLProfile(); if (gl.isGL2()) { try{ InputStream defaultImgStream = this.getClass().getClassLoader().getResourceAsStream("img/default.png"); textureDataDefault = TextureIO.newTextureData(glProfile, defaultImgStream, 3, GL.GL_RGB, false, null); InputStream errorImgStream = this.getClass().getClassLoader().getResourceAsStream("img/error.png"); textureDataError = TextureIO.newTextureData(glProfile, errorImgStream, 3, GL.GL_RGB, false, null); InputStream blankImgStream = this.getClass().getClassLoader().getResourceAsStream("img/blank.png"); textureDataBlank = TextureIO.newTextureData(glProfile, blankImgStream, 3, GL.GL_RGB, false, null); final QuadTreeNode root = quadTree.getRootNode(); final SceneNode3D tile = root.getOrCreateData(); TerrainUpdater updater = (TerrainUpdater) getUpdater(); if (updater == null) { updater = new TerrainUpdater(this); setUpdater(updater); } updater.initialize(glDrawable); updater.updateImageOn(root); updater.updateMntOn(root); if ( tile instanceof Tile3D){ ((Tile3D)tile).checkTexture(glDrawable, Tile3D.INDEX_IMAGE); } } catch (Exception ex) { throw new GLException(ex.getMessage(),ex); } } } /* *********************************************************** ***************** GETTER & SETTER CLASSIC ******************* *************************************************************/ public TextureData getTextureDataDefault() { return textureDataDefault; } public TextureData getTextureDataError() { return textureDataError; } public TextureData getTextureDataBlank() { return textureDataBlank; } public ElevationLoader getElevationLoader(){ return this.loaderMNT; } public void setElevationLoader(ElevationLoader loaderMNT) throws PortrayalException { this.loaderMNT = loaderMNT; this.loaderMNT.setOutputCRS(this.quadTree.getCoordinateReferenceSystem()); } public ImageLoader getImageLoader() { return loaderImg; } public void setImageLoader(ImageLoader loaderImg) throws PortrayalException { this.loaderImg = loaderImg; this.loaderImg.setOutputCRS(this.quadTree.getCoordinateReferenceSystem()); } public double getProjectionDist(double length) { final TrackBallCamera camera = getCanvas().getCamera(); return camera.getProjectionLength(length); } /* *********************************************************** ***************** GETTER & SETTER OTHERS ******************* *************************************************************/ public double getAltitudeOf(DirectPosition position, double scale) throws PortrayalException { return this.loaderMNT.getValueOf(position, scale); } public double getAltitudeSmoothOf(DirectPosition position, double scale) throws PortrayalException { return this.loaderMNT.getSmoothValueOf(position, scale); } public Point getPositionOf(double longitude, double latitude, Envelope gridEnvelope, Dimension gridSize){ final double stepLon = gridEnvelope.getSpan(0) / gridSize.width; final double stepLat = gridEnvelope.getSpan(1) / gridSize.height; final double minLon = gridEnvelope.getMinimum(0); final double minLat = gridEnvelope.getMinimum(1); final int posLon = (int)(Math.floor((longitude-minLon)/stepLon)); final int posLat = (gridSize.height-1) - (int)(Math.floor((latitude-minLat)/stepLat)); return new Point(posLon, posLat); } public Point getPositionOf(double longitude, double latitude){ final TrackBallCamera camera = getCanvas().getCamera(); final double scale = camera.getViewScale(camera.getLength()); final int scaleIndex = this.getNearestScaleIndex(scale); return getPositionOf(longitude, latitude, this.quadTree.getGeneralEnvelope(), QuadTreeUtils.getGridSize(scaleIndex)); } public Envelope getEnvelope(){ return this.quadTree.getGeneralEnvelope(); } public double getMinScale() { final int treeDepth = this.quadTree.getMinTreeDepth(); final int tileWidth = this.quadTree.getTileSize().width; final double tileSpan = this.quadTree.getGeneralEnvelope().getSpan(0); return QuadTreeUtils.getScale(treeDepth, tileWidth, tileSpan); } public double getMaxScale() { final int treeDepth = this.quadTree.getMaxTreeDepth(); final int tileWidth = this.quadTree.getTileSize().width; final double tileSpan = this.quadTree.getGeneralEnvelope().getSpan(0); return QuadTreeUtils.getScale(treeDepth, tileWidth, tileSpan); } public int getNearestScaleIndex(double scale) { return Math.min(this.quadTree.getMaxTreeDepth(), QuadTreeUtils.getTreeDepth(scale, this.quadTree.getTileSize().width, this.getEnvelope().getSpan(0))); } @Override public void dispose(GLAutoDrawable glDrawable){ super.dispose(glDrawable); } }