/*
* Copyright (C) 2011-2014 GeoForge Project
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.geoforge.worldwind.awt;
import gov.nasa.worldwind.Configuration;
import gov.nasa.worldwind.Model;
import gov.nasa.worldwind.WorldWind;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.awt.WorldWindowGLCanvas;
import gov.nasa.worldwind.geom.Angle;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.globes.*;
import gov.nasa.worldwind.layers.*;
import gov.nasa.worldwind.view.orbit.BasicOrbitView;
import gov.nasa.worldwind.view.orbit.FlatOrbitView;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.geoforge.java.enumeration.GfrEnuSystemPropertiesKeys;
import org.geoforge.lang.handler.IGfrHandlerLifeCycleObject;
import org.geoforge.java.util.logging.filehandler.FileHandlerLogger;
import org.geoforge.worldwind.util.listener.OurClickAndGoSelectListener;
/**
*
* @author bantchao
*
* email: bantchao_AT_gmail.com
* ... please remove "_AT_" from the above string to get the right email address
*
*/
public class GfrWorldWindowGLCanvas extends WorldWindowGLCanvas implements
IGfrHandlerLifeCycleObject
{
static private boolean _BLN_DEBUG_ = false;
static
{
String str = System.getProperty(GfrEnuSystemPropertiesKeys.DEBUG_APPLI.getLabel());
if (str != null && str.compareTo("true") == 0)
_BLN_DEBUG_ = true;
}
static
{
// Get the World Wind logger by name.
Logger logger = Logger.getLogger("gov.nasa.worldwind");
// Turn off logging to parent handlers of the World Wind handler.
logger.setUseParentHandlers(false);
// code below does not work!!!!!!!!!!!!!!!!!
// Create a console handler (defined below) that we use to write log messages.
//final ConsoleHandler handler = new MyHandler();
// Enable all logging levels on both the logger and the handler.
logger.setLevel(Level.ALL);
FileHandlerLogger.s_getInstance().setLevel(Level.ALL);
//handler.setLevel(Level.ALL);
// Add our handler to the logger
logger.addHandler(FileHandlerLogger.s_getInstance());
//logger.addHandler(handler);
//WorldWind.s_getNetworkStatus().setOfflineMode(false);
}
// below: not working!
/*static
{
// memo bantchao: redirecting WW's output logs from default console to geotriple's log file
Logger lgg = Logger.getLogger(Configuration.DEFAULT_LOGGER_NAME);
lgg.addHandler(FileHandlerLogger.s_getInstance());
}*/
transient private OurClickAndGoSelectListener _lstClickAndGo_ = null;
//final static private double _DBL_ZOOM_TO_POINT_ = 60000.d;
transient protected Globe _glbGlobeRound = null;
transient protected FlatGlobe _glbGlobeFlat = null;
transient private String _strKindProjection_ = FlatGlobe.PROJECTION_MERCATOR; // default
public void zoomTo(
Position posCenter,
double dblZoom,
boolean blnIsPoint)
{
BasicOrbitView view = (BasicOrbitView) super.getView();
Angle heading = Angle.fromDegrees(0.0);
Angle pitch = Angle.fromDegrees(30.0);
//if (! blnIsPoint)
// dblZoom *= 10.d;
view.addPanToAnimator(posCenter, heading, pitch, dblZoom, true);
}
public void resetWwdViewDefault()
{
BasicOrbitView view = (BasicOrbitView) super.getView();
/*
* This code works, but there is a trouble-shooting when reseting default veis
* in Flat world.
* This code has been taken from demo : RoundWorldEarthquakes
*
* In this demo, the following is performed :
Configuration.setValue(AVKey.INITIAL_LATITUDE, 0);
Configuration.setValue(AVKey.INITIAL_LONGITUDE, 0);
Configuration.setValue(AVKey.INITIAL_ALTITUDE, 50e6);
*
* It ensures could behaviour when reseting default view with flat map.
* In the applis, the AvKeys are kept to worldwin defaults, i.e :
* definel in : ressources/config/worldwind.xml
* <Property name="gov.nasa.worldwind.avkey.InitialLatitude" value="38"/>
* <Property name="gov.nasa.worldwind.avkey.InitialAltitude" value="19.07e6"/>
* The initial longitude is set in :
* gov.nasa.worldwind.Configuration.initializeDefaults()
* and depends on user time zone.
*
*/
Double lat = -9999.9d; //Configuration.getDoubleValue(AVKey.INITIAL_LATITUDE);
Double lon = -9999.9d; // Configuration.getDoubleValue(AVKey.INITIAL_LONGITUDE);
Double elevation = -9999.9d; // Configuration.getDoubleValue(AVKey.INITIAL_ALTITUDE);
// beg bantchao
Globe glbDefault = getModel().getGlobe();
if (glbDefault instanceof FlatGlobe)
{
lat = 0d;
lon = 0d;
elevation = 50e6d;
}
else if (glbDefault instanceof Earth)
{
lat = Configuration.getDoubleValue(AVKey.INITIAL_LATITUDE);
lon = Configuration.getDoubleValue(AVKey.INITIAL_LONGITUDE);
elevation = 19.07e6d; // memo: default value, not really needed
}
else
{
System.err.println("Uncaught instanceof glbDefault: " + glbDefault.getClass().toString());
System.exit(1);
}
// end bantchao
Position targetPos = Position.fromDegrees(lat, lon, 0);
view.addPanToAnimator(
// The elevation component of 'targetPos' here is not the surface elevation,
// so we ignore it when specifying the view center position.
new Position(targetPos, 0),
Angle.ZERO,
Angle.ZERO,//pitch
elevation);//zoom
/*
* Memo : the following commented code works, same location than previous code,
* but without any anmination.
*
* There is a tbrl on amadeus computer : after reseting default view, the
* globe return to initial position.
* It could be fixed with : view.stopMovement();
*/
/*view.setPitch(Angle.ZERO);
view.setHeading(Angle.ZERO);
view.setZoom(elevation);
view.setCenterPosition(new Position(targetPos, 0));
view.stopMovement();*/
}
private void _shutdownGlobe_(Model mod)
{
Globe glb = mod.getGlobe();
if (glb == null)
return;
ElevationModel eml = glb.getElevationModel();
if (eml == null)
return;
//if (_BLN_DEBUG_)
// System.out.println(">> ElevationModel: " + eml.getName());
eml.dispose();
eml = null;
glb.setElevationModel(null);
}
private void _shutdownLayers_(Model mod)
{
gov.nasa.worldwind.layers.LayerList llt = mod.getLayers();
if (llt == null)
return;
for (Layer lyrCur : llt)
{
if (lyrCur instanceof AbstractLayer)
{
//if (_BLN_DEBUG_)
// System.out.println(">> AbstractLayer: " + lyrCur.getName());
lyrCur.dispose();
lyrCur = null;
}
else
{
//if (_BLN_DEBUG_)
// System.out.println("UNKNOWN: lyrCur.getClass().getName()=" +lyrCur.getClass().getName());
lyrCur.dispose();
lyrCur = null;
}
}
}
@Override
public void shutdown()
{
super.shutdown();
gov.nasa.worldwind.Model mod = super.getModel();
if (mod == null)
return;
_shutdownLayers_(mod);
_shutdownGlobe_(mod);
//if (_BLN_DEBUG_)
// System.out.println("TODO: kill remaining threads in wwd's canvas");
}
public GfrWorldWindowGLCanvas()
{
super();
/*this._lstClickAndGo_ = new OurClickAndGoSelectListener(this,
gov.nasa.worldwind.layers.WorldMapLayer.class);
*/
//_createGlobeFlat();
this._glbGlobeRound = new Earth();
// Create the default model as described in the current worldwind properties.
gov.nasa.worldwind.Model mod =
(gov.nasa.worldwind.Model) WorldWind.createConfigurationComponent(
gov.nasa.worldwind.avlist.AVKey.MODEL_CLASS_NAME);
mod.setGlobe(this._glbGlobeRound);
//mod.setGlobe(this._glbGlobeFlat);
super.setModel(mod);
}
// end tempo
// Update flat globe projection
public void setProjection(String strKindProjection)
{
if (!_isGlobeFlat_())
return; // rather throw an exception!
if (this._strKindProjection_ != null && this._strKindProjection_.compareTo(strKindProjection) == 0)
return;
this._strKindProjection_ = strKindProjection;
// Update flat globe projection
if (this._glbGlobeFlat == null)
{
_createGlobeFlat();
}
this._glbGlobeFlat.setProjection(this._strKindProjection_);
super.wwd.redraw();
}
@Override
public boolean init()
{
// Setup a select listener for the worldmap click-and-go feature
//super.addSelectListener(this._lstClickAndGo_);
/*if (_isGlobeFlat_())
{
this._glbGlobeFlat = (FlatGlobe) super.wwd.getModel().getGlobe();
this._glbGlobeRound = new Earth();
}
else*/
/*{
this._glbGlobeFlat = new EarthFlat();
this._glbGlobeRound = super.wwd.getModel().getGlobe();
}*/
return true;
}
@Override
public void destroy()
{
super.setVisible(false);
super.removeNotify();
shutdown();
super.getGpuResourceCache().clear();
if (this._lstClickAndGo_ != null)
{
super.removeSelectListener(this._lstClickAndGo_);
this._lstClickAndGo_ = null;
}
//this.transferFocusUpCycle();
/*try
{
finalize();
}
catch(Throwable exc)
{
exc.printStackTrace();
}*/
}
private boolean _isGlobeFlat_()
{
return super.wwd.getModel().getGlobe() instanceof FlatGlobe;
}
private void _createGlobeFlat()
{
this._glbGlobeFlat = new EarthFlat();
this._glbGlobeFlat.setProjection(FlatGlobe.PROJECTION_MERCATOR);
this._glbGlobeFlat.setProjection(this._strKindProjection_);
}
public void setEnabledFlatGlobe(boolean blnFlat) throws Exception
{
boolean blnCurGlobeKindFlat = _isGlobeFlat_();
if (blnFlat && blnCurGlobeKindFlat)
return;
if (!blnFlat && !blnCurGlobeKindFlat)
return;
if (!blnFlat)
{
// Switch to round globe
super.wwd.getModel().setGlobe(_glbGlobeRound);
// Switch to orbit view and update with current position
FlatOrbitView flatOrbitView = (FlatOrbitView) super.wwd.getView();
BasicOrbitView orbitView = new BasicOrbitView();
orbitView.setCenterPosition(flatOrbitView.getCenterPosition());
orbitView.setZoom(flatOrbitView.getZoom());
orbitView.setHeading(flatOrbitView.getHeading());
orbitView.setPitch(flatOrbitView.getPitch());
super.wwd.setView(orbitView);
}
else
{
if (this._glbGlobeFlat == null)
{
_createGlobeFlat();
}
// Switch to flat globe
super.wwd.getModel().setGlobe(this._glbGlobeFlat);
// Switch to flat view and update with current position
BasicOrbitView orbitView = (BasicOrbitView) super.wwd.getView();
FlatOrbitView flatOrbitView = new FlatOrbitView();
flatOrbitView.setCenterPosition(orbitView.getCenterPosition());
flatOrbitView.setZoom(orbitView.getZoom());
flatOrbitView.setHeading(orbitView.getHeading());
flatOrbitView.setPitch(orbitView.getPitch());
super.wwd.setView(flatOrbitView);
}
// Change sky layer
LayerList layers = super.wwd.getModel().getLayers();
for (int i = 0; i < layers.size(); i++)
{
if (layers.get(i) instanceof SkyColorLayer)
layers.set(i, new SkyGradientLayer());
}
super.wwd.redraw();
}
// beg inner-class
/*private static class MyHandler extends ConsoleHandler
{
@Override
public void publish(LogRecord logRecord)
{
// Just redirect the record to ConsoleHandler for printing.
super.publish(logRecord);
}
}*/
// end inner-class
}