/*
* Licensed Materials - Property of Rogue Wave Software, Inc.
* © Copyright Rogue Wave Software, Inc. 2014, 2017
* © Copyright IBM Corp. 2009, 2014
* © Copyright ILOG 1996, 2009
* All Rights Reserved.
*
* Note to U.S. Government Users Restricted Rights:
* The Software and Documentation were developed at private expense and
* are "Commercial Items" as that term is defined at 48 CFR 2.101,
* consisting of "Commercial Computer Software" and
* "Commercial Computer Software Documentation", as such terms are
* used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
* as applicable.
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.StringTokenizer;
import javax.swing.JFrame;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import ilog.views.IlvGrapher;
import ilog.views.IlvManagerView;
import ilog.views.IlvPoint;
import ilog.views.maps.IlvCoordinate;
import ilog.views.maps.IlvCoordinateSystemProperty;
import ilog.views.maps.IlvDisplayPreferencesProperty;
import ilog.views.maps.IlvMapLayerTreeProperty;
import ilog.views.maps.IlvMapScaleLimiter;
import ilog.views.maps.beans.IlvJMapsManagerViewControlBar;
import ilog.views.maps.beans.IlvLayerTreePanel;
import ilog.views.maps.beans.IlvMapLayer;
import ilog.views.maps.beans.IlvMapLayerTreeModel;
import ilog.views.maps.beans.editor.IlvCoordinatePanelFactory;
import ilog.views.maps.datasource.IlvGraphicLayerDataSource;
import ilog.views.maps.datasource.IlvMapDataSourceModel;
import ilog.views.maps.datasource.IlvMapDataSourceProperty;
import ilog.views.maps.defense.symbology.app6a.IlvApp6aSymbol;
import ilog.views.maps.defense.symbology.app6a.IlvApp6aSymbologyTreeViewActions;
import ilog.views.maps.defense.terrain.IlvMapControllingPolyline;
import ilog.views.maps.defense.terrain3d.component.Ilv3DCorridor;
import ilog.views.maps.defense.terrain3d.component.Ilv3DExtrudedPolygon;
import ilog.views.maps.defense.terrain3d.component.Ilv3DHemisphere;
import ilog.views.maps.defense.terrain3d.component.Ilv3DLabel;
import ilog.views.maps.defense.terrain3d.model.Ilv3DModel;
import ilog.views.maps.defense.terrain3d.symbol.Ilv3DSymbolManager;
import ilog.views.maps.defense.terrain3d.view.Ilv3DTrajectory;
import ilog.views.maps.defense.terrain3d.view.Ilv3DView;
import ilog.views.maps.defense.terrain3d.view.IlvFlyThroughAction;
import ilog.views.maps.defense.terrain3d.view.IlvFlyThroughStyle;
import ilog.views.maps.defense.terrain3d.view.IlvMapTerrainFlyThrough;
import ilog.views.maps.format.dted.IlvRasterDTEDReader;
import ilog.views.maps.graphic.style.StyleEvent;
import ilog.views.maps.graphic.style.StyleListener;
import ilog.views.maps.raster.datasource.IlvRasterDataSourceFactory;
import ilog.views.maps.raster.datasource.IlvTiledRasterDataSource;
import ilog.views.maps.srs.coordsys.IlvGeographicCoordinateSystem;
import ilog.views.maps.symbology.swing.IlvSymbologyTreeView;
import ilog.views.sdm.IlvSDMEngine;
import ilog.views.sdm.IlvSDMException;
import ilog.views.sdm.renderer.IlvRendererUtil;
import ilog.views.sdm.renderer.IlvStyleSheetRenderer;
import ilog.views.swing.IlvJScrollManagerView;
import ilog.views.util.IlvProductUtil;
import ilog.views.util.waitcursor.IlvWaitCursorManager;
/**
* This class is a basic sample application that displays a 2D view and a 3D
* view of the same DTED elevation data. A few symbols are also added to the
* map, and automatically represented in the 3D view as well.
*
*/
SuppressWarnings("serial")
public class Simple3DScene extends JFrame {
static {
// This sample uses JViews Maps for Defense features. When deploying an
// application that includes this code, you need to be in possession
// of a Rogue Wave JViews Maps for Defense Deployment license.
IlvProductUtil.DeploymentLicenseRequired(IlvProductUtil.JViews_Maps_for_Defense_Deployment);
// replace the stylesheet renderer with map class.
IlvRendererUtil.addRendererAlias(IlvRendererUtil.getRendererAlias(IlvStyleSheetRenderer.class.getName()),
ilog.views.sdm.renderer.maps.IlvMapStyleSheetRenderer.class.getName());
}
// members
private IlvManagerView view;
private Ilv3DView view3D;
private IlvSDMEngine symbology;
private JSplitPane p;
private IlvApp6aSymbol moving, ground1, ground2;
private Font font = new Font("Times New Roman", Font.ITALIC, 16); //$NON-NLS-1$
/**
* Convenience method to resolve URLs
*
* @param resource
* @return URL
*/
private static URL findURL(String resource) {
URL rtnURL = null;
if (new File(resource).exists()) {
try {
rtnURL = new File(resource).toURI().toURL();
} catch (Exception e) {
e.printStackTrace();
}
} else {
rtnURL = Simple3DScene.class.getResource(resource);
}
return rtnURL;
}
/**
* Constructor
*/
private Simple3DScene() {
setTitle("Sample 3D application"); //$NON-NLS-1$
getContentPane().setLayout(new BorderLayout());
// create and configure manager view
view = new IlvManagerView();
view.setManager(new IlvGrapher());
view.setBackground(new Color(168, 207, 247));
view.setSize(480, 480);
view.setKeepingAspectRatio(true);
view.getManager().setNamedProperty(new IlvCoordinateSystemProperty(IlvGeographicCoordinateSystem.WGS84));
IlvMapDataSourceModel dsm = IlvMapDataSourceProperty.GetMapDataSourceModel(view.getManager());
IlvMapLayerTreeModel ltm = IlvMapLayerTreeProperty.GetMapLayerTreeModel(view.getManager());
// limit zoom in/out
IlvMapScaleLimiter limiter = new IlvMapScaleLimiter(1, 1 / 1E9);
limiter.setView(view);
// create DTED reader
IlvRasterDTEDReader r = new IlvRasterDTEDReader();
try {
// add DTED file
r.addMap(findURL("data/N45.DT1"));//$NON-NLS-1$
} catch (IOException e) {
// ignore
}
// Create a data source from the DTED reader, and insert it in the data
// source model of the map
IlvTiledRasterDataSource ds = IlvRasterDataSourceFactory.buildTiledImageDataSource(view.getManager(), r, true,
false, null);
dsm.insert(ds);
ltm.addChild(null, ds.getInsertionLayer());
ds.getInsertionLayer().setName("DTED N45.DT1"); //$NON-NLS-1$
ds.getInsertionLayer().getStyle().setVisibleIn3DView(true);
ds.start();
// create symbols.
moving = new IlvApp6aSymbol("SFAPMHR----CUS-", Math.toRadians(10.5), Math.toRadians(45.5)); //$NON-NLS-1$
ground1 = new IlvApp6aSymbol("SFAPMHR----CUS-", Math.toRadians(10.86), Math.toRadians(45.9));//$NON-NLS-1$
ground2 = new IlvApp6aSymbol("SHGPEWMAS-FA--A", Math.toRadians(10.875), Math.toRadians(45.885));//$NON-NLS-1$
// add symbols on the map and start the map loading process
buildSymbology(view);
// build the 3D view.
build3DScene();
buildFlyThrough(view);
// configure GUI
IlvJScrollManagerView scroll = new IlvJScrollManagerView(view);
scroll.setPreferredSize(view.getSize());
p = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scroll, view3D);
IlvJMapsManagerViewControlBar toolbar = new IlvJMapsManagerViewControlBar();
toolbar.setView(view);
getContentPane().add(toolbar, BorderLayout.NORTH);
getContentPane().add(p, BorderLayout.CENTER);
IlvLayerTreePanel pp = new IlvLayerTreePanel();
pp.setView(view);
getContentPane().add(pp, BorderLayout.EAST);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
}
private void buildFlyThrough(IlvManagerView view1) {
// Retrieve some global properties of the manager.
IlvMapDataSourceModel dsm = IlvMapDataSourceProperty.GetMapDataSourceModel(view1.getManager());
IlvMapLayerTreeModel ltm = IlvMapLayerTreeProperty.GetMapLayerTreeModel(view1.getManager());
// Create a data source to store the fly through polygon.
IlvGraphicLayerDataSource ds = new IlvGraphicLayerDataSource();
ds.setManager(view1.getManager());
// insert the data source into the manager's data source tree.
dsm.insert(ds);
// set its layer up.
final IlvMapLayer layer = ds.getInsertionLayer();
layer.setAllowingMoveObjects(true);
layer.setName("Fly Through"); //$NON-NLS-1$
IlvFlyThroughStyle flyThroughStyle = new IlvFlyThroughStyle();
flyThroughStyle.setAltitude(100);
flyThroughStyle.setSpeed(100);
layer.setStyle(flyThroughStyle);
// insert the layer on the manager's layer tree
ltm.addChild(null, layer);
// Create a fly through graphical object.
IlvPoint points[];
points = new IlvPoint[] { new IlvPoint( Math.toRadians(10.2), -Math.toRadians(45.2)),
new IlvPoint(Math.toRadians(10.2), -Math.toRadians(45.3)),
new IlvPoint(Math.toRadians(10.5), -Math.toRadians(45.4)),
new IlvPoint(Math.toRadians(10.8), -Math.toRadians(45.8)), };
final IlvMapTerrainFlyThrough flyThroughGraphics = new IlvMapTerrainFlyThrough(points);
flyThroughGraphics.setStyle(layer.getStyle());
// add a listener to register a new fly through action on the 3D view when
// the polygon changes.
flyThroughGraphics.addChangeListener(new IlvMapControllingPolyline.ComputeListener() {
Override
public void computationDone(IlvMapControllingPolyline tc) {
registerFlyThroughAction(tc, layer);
}
});
// add some control that updates the fly through when layer style changes.
flyThroughStyle.addStyleListener(new StyleListener() {
Override
public void styleChanged(StyleEvent event) {
if (event.getAttribute().equals(IlvFlyThroughStyle.SPEED)
|| event.getAttribute().equals(IlvFlyThroughStyle.HEIGHT)) {
registerFlyThroughAction(flyThroughGraphics, layer);
}
}
});
// Add the fly through graphical object to the data source.
ds.add(flyThroughGraphics, IlvGeographicCoordinateSystem.KERNEL);
// Start the data source to transform the polygon and display it on the
// view.
try {
ds.start();
} catch (Exception e) {
e.printStackTrace();
}
// register initial action:
registerFlyThroughAction(flyThroughGraphics, layer);
}
void registerFlyThroughAction(IlvMapControllingPolyline flyThroughGraphics, IlvMapLayer layer) {
// retrieve the fly through coordinates:
IlvCoordinate[] coords = flyThroughGraphics.getLatLongs();
// retrieve other parameters in the object style
IlvFlyThroughStyle ftstyle = (IlvFlyThroughStyle) flyThroughGraphics.getStyle();
// create a fly through trajectory
Ilv3DTrajectory.Point[] trajPoints = new Ilv3DTrajectory.Point[coords.length];
for (int i = 0; i < coords.length; i++) {
Ilv3DTrajectory.Point lookat = null;
if (i < (coords.length - 1)) {
lookat = new Ilv3DTrajectory.Point(ftstyle.getSpeed(), coords[i + 1].x, coords[i + 1].y,
ftstyle.getAltitude() * 0.9);
}
trajPoints[i] = new Ilv3DTrajectory.Point(ftstyle.getSpeed(), coords[i].x, coords[i].y, ftstyle.getAltitude(),
lookat);
}
Ilv3DTrajectory traj = new Ilv3DTrajectory(trajPoints);
// Create the fly through action and register it
IlvFlyThroughAction action = new IlvFlyThroughAction(layer.getName(), traj, view3D);
view3D.registerFlyThrough(layer, action);
}
/**
* This method adds a few symbols on the map
*
* @param v
*/
private void buildSymbology(IlvManagerView v) {
try {
URL symbolCss = findURL("data/app6.css");//$NON-NLS-1$
symbology = new IlvSDMEngine();
symbology.setReferenceView(v);
symbology.setHighlightingSelection(false);
symbology.setGrapher((IlvGrapher) v.getManager());
symbology.setStyleSheets(new String[] { symbolCss.toString() });
symbology.getModel().setAdjusting(true);
symbology.getModel().addObject(moving, null, null);
symbology.getModel().setObjectProperty(moving, IlvApp6aSymbol.MODIFIER_ALTITUDE_OR_DEPTH, "1000");//$NON-NLS-1$
symbology.getModel().setObjectProperty(moving, IlvApp6aSymbol.MODIFIER_DIRECTION_OF_MOVEMENT_INDICATOR, "100");//$NON-NLS-1$
symbology.getModel().addObject(ground1, null, null);
symbology.getModel().addObject(ground2, null, null);
symbology.getModel().setAdjusting(false);
} catch (IlvSDMException e) {
e.printStackTrace();
}
// show symbology panel
IlvSymbologyTreeView symbPanel = new IlvSymbologyTreeView(symbology);
IlvApp6aSymbologyTreeViewActions app6Actions = new IlvApp6aSymbologyTreeViewActions();
app6Actions.setLatLonPicker(new IlvCoordinatePanelFactory.CoordPointInputPanel(v,
IlvDisplayPreferencesProperty.GetDisplayPreferences(v.getManager()).getCoordinateFormatter()));
symbPanel.setSymbologyTreeViewActions(app6Actions);
getContentPane().add(symbPanel, BorderLayout.WEST);
Timer timer = new Timer(20, new ActionListener() {
Override
public void actionPerformed(ActionEvent e) {
long t = System.currentTimeMillis();
double lon = Math.toRadians(10.5 + 0.2 * Math.cos(t / 5000.0));
double lat = Math.toRadians(45.5 + 0.2 * Math.sin(t / 5000.0));
symbology.getModel().setAdjusting(true);
symbology.getModel().setObjectProperty(moving, "longitude", new Double(lon)); //$NON-NLS-1$
symbology.getModel().setObjectProperty(moving, "latitude", new Double(lat)); //$NON-NLS-1$
symbology.getModel().setAdjusting(false);
}
});
timer.start();
}
/**
* this method monitors performs 3D view creation when the data source.
*
*/
void build3DScene() {
view.fitTransformerToContent();
view.repaint();
Ilv3DModel model3D = new Ilv3DModel(view.getManager());
// model3D.setKeepElevationDataCache(false);
// build 3D terrain for specified region
model3D.buildTerrain(Math.toRadians(10), Math.toRadians(45), Math.toRadians(11), Math.toRadians(46));
URL url = findURL("data/zones.txt"); //$NON-NLS-1$
createExtrudedPolygons(model3D, url);
// create 3D hemisphere (radius in meters)
Ilv3DHemisphere hemiSphere1 = new Ilv3DHemisphere(ground1.getLongitude(), ground1.getLatitude(), 0, 1000);
hemiSphere1.setColor(new Color(0f, 0.5f, 0, 0.3f));
hemiSphere1.setLonLatSteps(40);
hemiSphere1.setElevationSteps(40);
model3D.add3DComponent(hemiSphere1);
// create 3D hemisphere (radius in meters)
Ilv3DHemisphere hemiSphere2 = new Ilv3DHemisphere(ground2.getLongitude(), ground2.getLatitude(), 0, 1000);
hemiSphere2.setColor(new Color(1.0f, 0.3f, 0.3f, 0.5f));
hemiSphere2.setLonLatSteps(20);
hemiSphere2.setElevationSteps(20);
model3D.add3DComponent(hemiSphere2);
// corridor coordinates
final double[] longs;
final double[] lats;
final double[] elevs;
final double[] radiuses;
longs = new double[] { Math.toRadians(10.57), Math.toRadians(10.62), Math.toRadians(10.68), Math.toRadians(10.79),
ground2.getLongitude() };
lats = new double[] { Math.toRadians(45.53), Math.toRadians(45.6), Math.toRadians(45.65), Math.toRadians(45.75),
ground2.getLatitude() };
elevs = new double[] { 3000, 2000, 1200, 500, 250 };
radiuses = new double[] { 2000, 1500, 1000, 500, 200 }; // in meters
// create 3D corridor
Ilv3DCorridor corridor = new Ilv3DCorridor(longs, lats, elevs, radiuses);
corridor.setStepsAlongAxis(1);
corridor.setStepsAboutAxis(20);
corridor.setColor(new Color(0.3f, 0.3f, 0.6f, 0.5f));
model3D.add3DComponent(corridor);
// create 3D labels
addLabelForSymbol(ground1, font, model3D);
addLabelForSymbol(ground2, font, model3D);
// create 3D view
view3D = new Ilv3DView(model3D);
view3D.setUseLighting(true);
view3D.setPreferredSize(new Dimension(640, 400));
// create a 3D symbol manager, and set it on the 3D model
Ilv3DSymbolManager symbolManager = new Ilv3DSymbolManager(symbology, view3D);
model3D.setSymbolManager(symbolManager);
}
private void createExtrudedPolygons(Ilv3DModel model3D, URL url) {
try {
InputStreamReader isr = new InputStreamReader(url.openStream());
BufferedReader buf = new BufferedReader(isr);
while (true) {
String label = buf.readLine();
if (label == null) {
// no more lines to read
break;
}
if (label.length() == 0) {
continue;
}
String color = buf.readLine();
String line = buf.readLine();
StringTokenizer st = new StringTokenizer(line, " ,"); //$NON-NLS-1$
int count = st.countTokens() / 2;
double[] xi = new double[count];
double[] yi = new double[count];
double centerX = 0;
double centerY = 0;
for (int i = count - 1; i >= 0; i--) {
String lon = st.nextToken();
String lat = st.nextToken();
xi[i] = Double.parseDouble(lon);
yi[i] = Double.parseDouble(lat);
centerX += xi[i];
centerY += yi[i];
}
// create extruded polygon
double altitude = 500;
Ilv3DExtrudedPolygon polygon = new Ilv3DExtrudedPolygon(xi, yi, 0, 400);
st = new StringTokenizer(color, ","); //$NON-NLS-1$
int[] colorElements = new int[] { 128, 128, 128, 255 };
int i = 0;
while (st.hasMoreElements()) {
colorElements[i] = Integer.parseInt(st.nextToken());
i++;
}
polygon.setColor(new Color(colorElements[0], colorElements[1], colorElements[2], colorElements[3]));
model3D.add3DComponent(polygon);
Ilv3DLabel label1 = new Ilv3DLabel(centerX / count, centerY / count, altitude + 20, label, font);
label1.setHorizontalOffset(10);
label1.setVerticalOffset(10);
label1.setOutlineWidth(3.0);
model3D.add3DComponent(label1);
}
} catch (IOException e) {
// ignore
}
}
private void addLabelForSymbol(IlvApp6aSymbol symbol, Font symbolfont, Ilv3DModel model3D) {
double groundHeight = model3D.getGroundHeightAt(symbol.getLongitude(), -symbol.getLatitude());
String alt = (String) symbol.getProperty(IlvApp6aSymbol.MODIFIER_ALTITUDE_OR_DEPTH);
double altitude = 0;
if (alt != null) {
altitude = Double.parseDouble(alt);
} else {
alt = "0"; //$NON-NLS-1$
}
Ilv3DLabel label1 = new Ilv3DLabel(symbol.getLongitude(), symbol.getLatitude(), altitude + 1000 + groundHeight,
"Alt = " + alt, symbolfont); //$NON-NLS-1$
label1.setHorizontalOffset(20);
label1.setVerticalOffset(10);
label1.setOutlineWidth(3.0);
model3D.add3DComponent(label1);
}
/**
* Main method
*
* @param args
* unused parameter.
*/
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
Override
public void run() {
IlvWaitCursorManager.init(); // magically fixes the 'unable to set pixel
// format ...' jogl exception by pushing a
// new EventQueue
Simple3DScene frame = new Simple3DScene();
frame.setVisible(true);
}
});
}
}