PageRenderTime 44ms CodeModel.GetById 17ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/worldwind/kml/KMLViewer.java

http://wwj-kml.googlecode.com/
Java | 320 lines | 237 code | 61 blank | 22 comment | 22 complexity | 8e3acef95b3f209bf6aa2300716d7219 MD5 | raw file
  1package worldwind.kml;
  2
  3import gov.nasa.worldwind.BasicModel;
  4import gov.nasa.worldwind.Model;
  5import gov.nasa.worldwind.awt.WorldWindowGLJPanel;
  6import gov.nasa.worldwind.event.SelectEvent;
  7import gov.nasa.worldwind.event.SelectListener;
  8import gov.nasa.worldwind.geom.Angle;
  9import gov.nasa.worldwind.geom.LatLon;
 10import gov.nasa.worldwind.geom.Position;
 11import gov.nasa.worldwind.geom.Sector;
 12import gov.nasa.worldwind.layers.CompassLayer;
 13import gov.nasa.worldwind.layers.WorldMapLayer;
 14import gov.nasa.worldwind.layers.Earth.BMNGSurfaceLayer;
 15import gov.nasa.worldwind.layers.Earth.LandsatI3;
 16import gov.nasa.worldwind.render.WWIcon;
 17import gov.nasa.worldwind.util.BasicDragger;
 18import gov.nasa.worldwind.util.StatusBar;
 19import gov.nasa.worldwind.view.orbit.BasicOrbitView;
 20
 21import java.awt.BorderLayout;
 22import java.awt.Dimension;
 23import java.awt.HeadlessException;
 24import java.awt.event.ActionEvent;
 25import java.awt.event.MouseAdapter;
 26import java.awt.event.MouseEvent;
 27import java.io.File;
 28import java.net.MalformedURLException;
 29import java.net.URL;
 30
 31import javax.swing.AbstractAction;
 32import javax.swing.JFileChooser;
 33import javax.swing.JFrame;
 34import javax.swing.JLabel;
 35import javax.swing.JMenu;
 36import javax.swing.JMenuBar;
 37import javax.swing.JMenuItem;
 38import javax.swing.JOptionPane;
 39import javax.swing.JScrollPane;
 40import javax.swing.JSplitPane;
 41import javax.swing.tree.DefaultTreeModel;
 42import javax.swing.tree.TreePath;
 43
 44import worldwind.kml.model.KMLFile;
 45import worldwind.kml.model.KMLPlacemark;
 46import worldwind.kml.tree.DocListTreeNode;
 47import worldwind.kml.tree.KMLDocTreeNode;
 48import worldwind.kml.tree.KMLTreeView;
 49import worldwind.kml.tree.Sectored;
 50import worldwind.kml.ui.InfoDialog;
 51
 52
 53/**
 54 * Created by IntelliJ IDEA.
 55 * User: tgleason
 56 * Date: Oct 17, 2008
 57 * Time: 11:53:05 PM
 58 * To change this template use File | Settings | File Templates.
 59 */
 60public class KMLViewer extends JFrame {
 61    StatusBar statusBar;
 62    JLabel cursorPositionDisplay;
 63    WorldWindowGLJPanel wwd;
 64    DocListTreeNode docList = new DocListTreeNode();
 65    KMLTreeView tree;
 66    JSplitPane splitPane;
 67    DefaultTreeModel treeModel;
 68    URL iconURL;
 69
 70
 71
 72    public KMLViewer() throws HeadlessException {
 73        super("KML Viewer");
 74
 75        setLayout(new BorderLayout());
 76
 77        //--  Worldwind
 78        wwd = new WorldWindowGLJPanel();
 79        wwd.setPreferredSize(new Dimension(1000, 600));
 80
 81        //--  KLUDGE: for some reason the GLJPanel doesn't get focus when clicked
 82        wwd.addMouseListener(new MouseAdapter() {
 83            public void mouseClicked(MouseEvent e) {
 84                wwd.grabFocus();
 85            }
 86
 87            public void mouseEntered(MouseEvent e) {
 88                wwd.grabFocus();
 89            }
 90        });
 91
 92
 93        //--  Create a JTree
 94        treeModel = new DefaultTreeModel(docList);
 95        tree = new KMLTreeView(wwd, treeModel);
 96        tree.setRootVisible(false);
 97        tree.setShowsRootHandles(true);
 98
 99
100        //--  Double-click on a node in the tree and we'll try to zoom to it.
101        //--  This doesn't work too well yet (and doesn't work on folder nodes)
102        tree.addMouseListener(new MouseAdapter() {
103            public void mouseClicked(MouseEvent e) {
104                if (e.getClickCount() == 2) {
105                    TreePath path = tree.getPathForLocation(e.getX(), e.getY());
106                    if (path == null)
107                        return;
108                    Object obj = path.getLastPathComponent();
109                    if (obj instanceof Sectored) {
110                        zoomToSector (((Sectored)obj).getSector());
111                    }
112                }
113            }
114        });
115
116        //--  Set up a split view and put the tree on the left
117        JSplitPane splitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
118                new JScrollPane(tree), wwd);
119        splitter.setContinuousLayout(true);
120        splitter.setDividerSize(3);
121        splitter.setDividerLocation(300);
122        this.getContentPane().add(splitter, java.awt.BorderLayout.CENTER);
123
124        this.statusBar = new StatusBar();
125        this.getContentPane().add(statusBar, BorderLayout.PAGE_END);
126        this.statusBar.setEventSource(wwd);
127
128
129        this.pack();
130
131        //--  Set up some layers
132        Model m = new BasicModel();
133        m.getLayers().clear();
134        m.getLayers().add(new BMNGSurfaceLayer());
135
136        LandsatI3 lsi3 = new LandsatI3();
137        lsi3.setDrawBoundingVolumes(false);
138        lsi3.setOpacity(1);
139        m.getLayers().add(lsi3);
140
141        m.getLayers().add(new CompassLayer());
142        m.getLayers().add(new WorldMapLayer());
143
144        m.setShowWireframeExterior(false);
145        m.setShowWireframeInterior(false);
146        wwd.setModel(m);
147
148        wwd.grabFocus();
149
150        //--  Set up the menu bar
151        JMenuBar menuBar = new JMenuBar();
152
153        JMenu menu = new JMenu("File");
154        menu.add(new JMenuItem(new AbstractAction("Open File...") {
155            public void actionPerformed(ActionEvent ae) {
156                openFile();
157            }
158        }));
159
160        menu.add(new JMenuItem(new AbstractAction("Open URL...") {
161            public void actionPerformed(ActionEvent ae) {
162                openURL();
163            }
164        }));
165
166        menu.addSeparator();
167
168        JMenu samplesMenu = new JMenu("Samples");
169        
170        samplesMenu.add(new SampleFileAction("KML Samples", "http://code.google.com/apis/kml/documentation/KML_Samples.kml"));
171        //http://bbs.keyhole.com/ubb/placemarks/521519-Vancouver.kmz
172        samplesMenu.add(new SampleFileAction("Vancouver 3D", "http://bbs.keyhole.com/ubb/placemarks/521519-Vancouver.kmz"));
173        samplesMenu.add(new SampleFileAction("Appalachian Trail", "http://bbs.keyhole.com/ubb/download.php?Number=1114687"));
174        samplesMenu.add(new SampleFileAction("World Heritage Sites", "http://whc.unesco.org/p_dynamic/sites/whc-en.kmz"));
175        samplesMenu.add(new SampleFileAction("Inca Trail", "http://www.jqjacobs.net/archaeo/sites/machu_picchu.kmz"));
176
177        //TODO: Support: http://wikiloc.com/wikiloc/geoServer.do?format=kml&id=190160
178
179        menu.add(samplesMenu);
180
181        menuBar.add(menu);
182
183        setJMenuBar(menuBar);
184
185
186        //--  Listen for Point selections:
187        wwd.addSelectListener(new SelectListener()
188        {
189            private WWIcon lastToolTipIcon = null;
190            private BasicDragger dragger = new BasicDragger(wwd);
191
192            public void selected(SelectEvent event)
193            {
194                if (event.getEventAction().equals(SelectEvent.LEFT_CLICK))
195                {
196                    Object obj = event.getTopObject();
197                    if (obj != null && obj instanceof KMLPlacemark) {
198                        displayInfoPane((KMLPlacemark) obj);
199                    }
200                }
201            }
202        });
203
204
205    }
206
207    private void displayInfoPane(KMLPlacemark kmlPlacemark) {
208        if (kmlPlacemark.getDescription() != null) {
209            new InfoDialog(this, "<html>" + kmlPlacemark.getDescription() + "</html>");
210        }
211
212    }
213
214    class SampleFileAction extends AbstractAction {
215        String urlStr;
216        String name;
217        SampleFileAction(String name, String url) {
218            super(name);
219            this.urlStr = url;
220            this.name = name;
221        }
222
223        public void actionPerformed(ActionEvent ae) {
224            URL url = null;
225            try {
226                url = new URL(urlStr);
227            } catch (MalformedURLException e) {
228                JOptionPane.showMessageDialog(KMLViewer.this, "Not a valid URL: " + e.getMessage());
229            }
230
231            if (url != null) {
232                try {
233                    KMLFile kml = KMLParser.parseURL(url);
234                    addKMLLayer(kml, name);
235                    zoomToSector(kml.getSector());
236                } catch (Exception e) {
237                    JOptionPane.showMessageDialog(KMLViewer.this, "Error: " + e.getMessage());
238                }
239            }
240        }
241    }
242
243    private void openURL() {
244        String urlStr = JOptionPane.showInputDialog("KML/KMZ URL:");
245
246        if (urlStr == null)
247            return;
248
249        URL url = null;
250
251        try {
252            url = new URL(urlStr);
253        } catch (MalformedURLException e) {
254            JOptionPane.showMessageDialog(this, "Not a valid URL: " + e.getMessage());
255        }
256
257        if (url != null) {
258            try {
259                KMLFile kml = KMLParser.parseURL(url);
260                addKMLLayer(kml, url.toString());
261                zoomToSector(kml.getSector());
262            } catch (Exception e) {
263                JOptionPane.showMessageDialog(this, "Error: " + e.getMessage());
264            }
265        }
266    }
267
268    private void openFile () {
269        JFileChooser chooser = new JFileChooser();
270        if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
271            File f = chooser.getSelectedFile();
272            try {
273                KMLFile kml = KMLParser.parseFile(f.getAbsolutePath());
274                addKMLLayer(kml, f.getName());
275                zoomToSector(kml.getSector());
276            } catch (Exception e) {
277                JOptionPane.showMessageDialog(this, "Error: " + e.getMessage());
278            }
279        }
280    }
281
282    private void addKMLLayer (KMLFile kml, String name) {
283        KMLLayer kmlLayer = new KMLLayer(kml);
284        wwd.getModel().getLayers().add(kmlLayer);
285        docList.add(new KMLDocTreeNode(kml, name, kmlLayer));
286        treeModel.nodeStructureChanged(docList);
287    }
288
289
290    //--  TODO:  This /rotates/ to the sector, but just zooms to a fixed level.  Need to
291    //--  calculate the zoom factor from the sector size (somehow)
292    private void zoomToSector(Sector s) {
293        if (s == null){
294            //System.out.println("Null sector");
295            return;
296        }
297
298        BasicOrbitView view = (BasicOrbitView)wwd.getView();
299
300        LatLon latLon = new LatLon(Angle.average(s.getMinLatitude(), s.getMaxLatitude()), Angle.average(s.getMinLongitude(), s.getMaxLongitude()));
301        
302        // Stop all animations on the view, and start a 'pan to' animation.		
303        view.stopAnimations();
304		view.addPanToAnimator(new Position(latLon, 0), view.getHeading(), view.getPitch(), 100000);
305    }
306
307    public static void main(String[] args) {
308        if (gov.nasa.worldwind.Configuration.isMacOS())
309        {
310            System.setProperty("apple.laf.useScreenMenuBar", "true");
311            System.setProperty("com.apple.mrj.application.apple.menu.about.name", "World Wind AWT Canvas App");
312            System.setProperty("com.apple.mrj.application.growbox.intrudes", "false");
313        }
314
315        KMLViewer viewer = new KMLViewer();
316        viewer.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
317        viewer.setVisible(true);
318    }
319
320}