/** * This code uses NASA WorldWind and creates some simple methods to make using * WorldWind with Java just a little easier. * * This code originally written by: * Jacob Dilles and Dan Fleck * George Mason University * All rights reserved. Please email if you want to use it dfleck(at)gmu.edu * */ package gmu.WorldWindGPS; //import java.util.*; import gov.nasa.worldwind.*; import gov.nasa.worldwind.avlist.AVKey; import gov.nasa.worldwind.awt.WorldWindowGLCanvas; import gov.nasa.worldwind.cache.MemoryCacheSet; import gov.nasa.worldwind.event.*; import gov.nasa.worldwind.examples.StatusBar; import gov.nasa.worldwind.layers.*; import gov.nasa.worldwind.layers.Earth.*; import gov.nasa.worldwind.view.*; import gov.nasa.worldwind.geom.*; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.Point; import java.awt.Toolkit; import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.*; import javax.swing.border.*; import java.awt.*; import java.awt.event.*; import javax.swing.BorderFactory; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.TitledBorder; class WorldWindAppFrame extends JFrame implements GMUWorldWindCommands, PositionListener { private final WorldWindowGLCanvas wwd = new WorldWindowGLCanvas(); private BasicOrbitView orbitalView = new BasicOrbitView(); private OrbitViewPropertyAccessor.LatLonAccessor myLatLon; private final int GPS_ZOOM_LEVEL = 250; /** An array of GMUListeners. */ private ArrayList listeners = new ArrayList(); /** An array of DistanceListeners. */ private ArrayList distanceListeners = new ArrayList(); /** Shows some text to the user on the WorldWind screen. */ private JTextArea textInfo; /** Show some text to the user. This text can also include * basic HTML markup. */ public void setInfoText(String txt) { textInfo.setText(txt); textInfo.repaint(); } public void goToGPS(double lat, double lon) { goToGPS(lat, lon, 10); } public void goToGPS(double lat, double lon, double alt) { // Create a new Position Angle newLatitude = Angle.fromDegrees(lat); Angle newLongitude = Angle.fromDegrees(lon); goToGPS(newLatitude, newLongitude, alt); } /** Are we currently iterating through a StateIterator or not? */ private boolean hasStateIterator() { return wwd.getView().hasStateIterator(); } /** Listen for position changes. */ public void addPositionListener(GMUPositionListener p) { listeners.add(p); wwd.addPositionListener(this); } /** The most recent position fired. */ private double lastLat=-10000, lastLon=-10000; public void moved(PositionEvent e) { if ((listeners == null) || hasStateIterator()) return; double distance = 10, lat1=0, lon1=0; Position newP = e.getPosition(); if (lastLon != -10000) { // Okay, because this is NOT a valid longitude lat1 = getCurrentLatitude(); lon1 = getCurrentLongitude(); distance = getDistance(lat1, lon1, lastLat, lastLon); } // Only fire the event if we've moved a little bit if (distance > 0.01) { lastLon = lon1; lastLat = lat1; // Fire the events for (GMUPositionListener l : listeners) { l.moved(e); } } } public void goToGPS(Angle newLatitude, Angle newLongitude, double alt) { // Create a new Position LatLon newLocation = new LatLon(newLatitude, newLongitude); FlyToOrbitViewStateIterator fly = FlyToOrbitViewStateIterator.createPanToIterator( orbitalView, wwd.getModel().getGlobe(), newLocation, Angle.fromDegrees(0), // Heading Angle.fromDegrees(0), // Pitch alt); // Zoom wwd.getView().applyStateIterator(fly); } /** Set the altitude of the viewer. */ public void setAltitude(double altitude) { Position eye = wwd.getView().getEyePosition(); goToGPS(eye.getLatitude(), eye.getLongitude(), altitude); } /** Zoom and center on the Johnson Center. */ private void returnHome() { goToGPS(38.8295, -77.3076); } public double getCurrentLatitude() { Position pos = wwd.getView().getEyePosition(); Angle a = pos.getLatitude(); return a.getDegrees(); } public double getCurrentLongitude() { Position pos = wwd.getView().getEyePosition(); Angle a = pos.getLongitude(); return a.getDegrees(); } /** Return the distanct between points (lat1, lon1) and (lat2, lon2) in * meters. This is from the Haversine formula shown here: * http://www.movable-type.co.uk/scripts/latlong.html * Returns the distance in kilometers. */ public double getDistance(double lat1, double lon1, double lat2, double lon2) { lat1 = lat1*Math.PI/180; lat2 = lat2*Math.PI/180; lon1 = lon1*Math.PI/180; lon2 = lon2*Math.PI/180; double d=2*Math.asin(Math.sqrt((Math.sin((lat1-lat2)/2))*(Math.sin((lat1-lat2)/2)) + Math.cos(lat1)*Math.cos(lat2)* (Math.sin((lon1-lon2)/2))*(Math.sin((lon1-lon2)/2)))); return d*6372.795; // km } public void addDistanceListener(DistanceListener dl) { distanceListeners.add(dl); } private void fireGetDistance() { for (DistanceListener dl : distanceListeners) dl.showDistance(); } public WorldWindAppFrame() { setTitle("WorldWind Demo"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Set the Log Level gov.nasa.worldwind.util.Logging.logger().setLevel(Level.SEVERE); LayerList layerList = new LayerList(); try { JPanel mainPanel = new JPanel(); mainPanel.setLayout(new BorderLayout()); //wwd.setMinimumSize(new Dimension(600, 600)); mainPanel.add(wwd, BorderLayout.CENTER); StatusBar statusBar = new StatusBar(); statusBar.setEventSource(wwd); mainPanel.add(statusBar, BorderLayout.PAGE_END); this.getContentPane().add(mainPanel, BorderLayout.CENTER); JPanel westContainer = new JPanel(new BorderLayout()); { JPanel westPanel = new JPanel(); BoxLayout bl = new BoxLayout(westPanel, BoxLayout.Y_AXIS); westPanel.setLayout(bl); westPanel.setBorder(BorderFactory.createEmptyBorder(9, 9, 9, 9)); { //------------------------ the layers checkboxes----------- JPanel layersPanel = new JPanel(new GridLayout(0, 1, 0, 15)); layersPanel.setBorder(new TitledBorder("Layers")); layersPanel.setBounds(0,0, 30,30); for(LayerAction action : layers ) { JCheckBox jcb = new JCheckBox(action); jcb.setSelected(action.getSelected()); layersPanel.add(jcb); layerList.add(action.getLayer()); } //----------------added bits for navigation -------------- //----------------gui interface into methods-------------- JPanel naviPanel = new JPanel(new GridLayout(0,1,0,15)); naviPanel.setBorder(new TitledBorder("Navigation")); JButton goBackHomeButton = new javax.swing.JButton(); goBackHomeButton.setText("ReCenter on the JC"); goBackHomeButton.setBounds(0,0,20,10); //goBackHomeButton.setAction( goToGPS(38.8295, -77.3076) ); goBackHomeButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { returnHome(); System.out.println(orbitalView.getZoom()); } }); naviPanel.add(goBackHomeButton); JButton getDistanceButton = new javax.swing.JButton("Get Distance"); getDistanceButton.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { fireGetDistance(); } }); naviPanel.add(getDistanceButton); //----------------added bits for Text Description -------------- textInfo = new JTextArea("No information yet", 20, 30); textInfo.setLineWrap(true); textInfo.setWrapStyleWord(true); textInfo.setEnabled(false); textInfo.setDisabledTextColor(Color.BLACK); JPanel textPanel = new JPanel(new BorderLayout()); textPanel.add(Box.createVerticalStrut(400), BorderLayout.WEST); textPanel.add(new JScrollPane(textInfo, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER )); textPanel.setBorder(new TitledBorder("Location Info")); // panel buisness westPanel.add(layersPanel); westPanel.add(naviPanel); westPanel.add(textPanel); westContainer.add(westPanel, BorderLayout.NORTH); } } this.getContentPane().add(westContainer, BorderLayout.WEST); this.setPreferredSize(new Dimension(1024,768)); this.pack(); /* Dimension prefSize = this.getPreferredSize(); prefSize.setSize(prefSize.getWidth(), 1.1 * prefSize.getHeight()); this.setSize(prefSize); // Center the app on the user's screen. Dimension parentSize; Point parentLocation = new Point(0, 0); parentSize = Toolkit.getDefaultToolkit().getScreenSize(); int x = parentLocation.x + (parentSize.width - prefSize.width) / 2; int y = parentLocation.y + (parentSize.height - prefSize.height) / 2; this.setLocation(x, y); **/ this.setResizable(true); Model m = (Model) WorldWind.createConfigurationComponent(AVKey.MODEL_CLASS_NAME); m.setLayers(layerList); m.setShowWireframeExterior(false); m.setShowWireframeInterior(false); m.setShowTessellationBoundingVolumes(false); wwd.setModel(m); //OrbitViewInputBroker. orbitalView = (BasicOrbitView) wwd.getView(); wwd.addRenderingListener(new RenderingListener() { public void stageChanged(RenderingEvent event) { if (event.getStage().equals(RenderingEvent.AFTER_BUFFER_SWAP)) // System.out.printf("frame time/rate = %f / %f\n", // wwd.getValue(AVKey.FRAME_TIME), wwd.getValue(AVKey.FRAME_RATE)); return; } }); //_------------------------------------- //myLatLon = OrbitViewPropertyAccessor.createLatitudeAndLongitudeAccessor(); //myAccessor = OrbitViewPropertyAccessor.createLookAtLatitudeAndLongitudeAccessor(); } catch (Exception e) { e.printStackTrace(); } // Finish All initialization here setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); } public LayerAction[] layers = new LayerAction[]{ new LayerAction(new BMNGSurfaceLayer(), true), new LayerAction(new LandsatI3(), true), new LayerAction(new USGSDigitalOrtho(), false), new LayerAction(new USGSUrbanAreaOrtho(), true), new LayerAction(new USGSTopographicMaps(), false), new LayerAction(new CountryBoundariesLayer(), false), new LayerAction(new EarthNASAPlaceNameLayer(), true), new LayerAction(new CompassLayer(), true), }; class LayerAction extends AbstractAction { private Layer layer; private boolean selected; public boolean getSelected() { return selected; } public Layer getLayer() { return layer; } public LayerAction(Layer layer, boolean selected) { super(layer.getName()); this.layer = layer; this.selected = selected; this.layer.setEnabled(this.selected); } public void actionPerformed(ActionEvent actionEvent) { if (((JCheckBox) actionEvent.getSource()).isSelected()) this.layer.setEnabled(true); else this.layer.setEnabled(false); //repaintwwd(); } /* ---------------------- I HAVE NO WAY TO TEST THIS * -----------------------AND MAC SUCKS SO I DONT CARE static { if (Configuration.isMacOS()) { System.setProperty("apple.laf.useScreenMenuBar", "true"); System.setProperty("com.apple.mrj.application.apple.menu.about.name", "World Wind Basic Demo"); System.setProperty("com.apple.mrj.application.growbox.intrudes", "false"); } } --------------------------------------------------------------*/ } }