Autopsy  4.14.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
MapPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.geolocation;
20 
21 import java.awt.Dimension;
22 import java.awt.Graphics2D;
23 import java.awt.Point;
24 import java.awt.Rectangle;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.ActionListener;
27 import java.awt.event.ComponentAdapter;
28 import java.awt.event.ComponentEvent;
29 import java.awt.geom.Point2D;
30 import java.awt.image.BufferedImage;
31 import java.beans.PropertyChangeEvent;
32 import java.beans.PropertyChangeListener;
33 import java.io.File;
34 import java.io.IOException;
35 import java.util.ArrayList;
36 import java.util.Collection;
37 import java.util.Iterator;
38 import java.util.List;
39 import java.util.Set;
40 import java.util.logging.Level;
41 import java.util.prefs.PreferenceChangeEvent;
42 import java.util.prefs.PreferenceChangeListener;
43 import javax.swing.JMenuItem;
44 import javax.swing.JOptionPane;
45 import javax.swing.JPopupMenu;
46 import javax.swing.JSeparator;
47 import javax.swing.Popup;
48 import javax.swing.PopupFactory;
49 import javax.swing.Timer;
50 import javax.swing.event.MouseInputListener;
51 import org.jxmapviewer.JXMapViewer;
52 import org.jxmapviewer.OSMTileFactoryInfo;
53 import org.jxmapviewer.VirtualEarthTileFactoryInfo;
54 import org.jxmapviewer.input.CenterMapListener;
55 import org.jxmapviewer.input.ZoomMouseWheelListenerCursor;
56 import org.jxmapviewer.viewer.DefaultTileFactory;
57 import org.jxmapviewer.viewer.GeoPosition;
58 import org.jxmapviewer.viewer.TileFactory;
59 import org.jxmapviewer.viewer.TileFactoryInfo;
60 import org.jxmapviewer.viewer.WaypointPainter;
61 import org.jxmapviewer.viewer.WaypointRenderer;
62 import org.openide.util.NbBundle.Messages;
67 import org.sleuthkit.datamodel.TskCoreException;
68 import javax.imageio.ImageIO;
69 import javax.swing.SwingUtilities;
70 
74 final public class MapPanel extends javax.swing.JPanel {
75 
76  static final String CURRENT_MOUSE_GEOPOSITION = "CURRENT_MOUSE_GEOPOSITION";
77  private static final Logger logger = Logger.getLogger(MapPanel.class.getName());
78 
79  private static final long serialVersionUID = 1L;
80  private boolean zoomChanging;
82  private Set<MapWaypoint> waypointSet;
83 
84  private Popup currentPopup;
85  private final PopupFactory popupFactory;
86 
87  private static final int POPUP_WIDTH = 300;
88  private static final int POPUP_HEIGHT = 200;
89  private static final int POPUP_MARGIN = 10;
90 
91  private BufferedImage defaultWaypointImage;
92  private BufferedImage selectedWaypointImage;
93 
94  private MapWaypoint currentlySelectedWaypoint;
95 
99  @Messages({
100  "MapPanel_connection_failure_message=Failed to connect to new geolocation map tile source.",
101  "MapPanel_connection_failure_message_title=Connection Failure"
102  })
103  public MapPanel() {
104  initComponents();
105 
106  zoomChanging = false;
107  currentPopup = null;
108  popupFactory = new PopupFactory();
109 
110  try {
111  defaultWaypointImage = ImageIO.read(getClass().getResource("/org/sleuthkit/autopsy/images/waypoint_teal.png"));
112  selectedWaypointImage = ImageIO.read(getClass().getResource("/org/sleuthkit/autopsy/images/waypoint_yellow.png"));
113  } catch (IOException ex) {
114  logger.log(Level.WARNING, "Unable to load geolocation waypoint images", ex);
115  }
116 
117  // ComponentListeners do not have a concept of resize event "complete"
118  // therefore if we move the popup as the window resizes there will be
119  // a weird blinking behavior. Using the CompnentResizeEndListener the
120  // popup will move to its corner one the resize is completed.
121  this.addComponentListener(new ComponentResizeEndListener() {
122  @Override
123  public void resizeTimedOut() {
125  }
126  });
127 
128  UserPreferences.addChangeListener(new PreferenceChangeListener() {
129  @Override
130  public void preferenceChange(PreferenceChangeEvent evt) {
131  try {
132  // Tell the old factory to cleanup
133  mapViewer.getTileFactory().dispose();
134 
135  mapViewer.setTileFactory(getTileFactory());
136  initializeZoomSlider();
137  } catch (GeoLocationDataException ex) {
138  logger.log(Level.SEVERE, "Failed to connect to new geolocation tile server.", ex); //NON-NLS
139  JOptionPane.showMessageDialog(MapPanel.this,
140  Bundle.MapPanel_connection_failure_message(),
141  Bundle.MapPanel_connection_failure_message_title(),
142  JOptionPane.ERROR_MESSAGE);
144  Bundle.MapPanel_connection_failure_message_title(),
145  Bundle.MapPanel_connection_failure_message());
146  }
147  }
148  });
149  }
150 
156  List<MapWaypoint> getVisibleWaypoints() {
157 
158  Rectangle viewport = mapViewer.getViewportBounds();
159  List<MapWaypoint> waypoints = new ArrayList<>();
160 
161  Iterator<MapWaypoint> iterator = waypointTree.iterator();
162  while (iterator.hasNext()) {
163  MapWaypoint waypoint = iterator.next();
164  if (viewport.contains(mapViewer.getTileFactory().geoToPixel(waypoint.getPosition(), mapViewer.getZoom()))) {
165  waypoints.add(waypoint);
166  }
167  }
168 
169  return waypoints;
170  }
171 
175  void initMap() throws GeoLocationDataException {
176 
177  TileFactory tileFactory = getTileFactory();
178  mapViewer.setTileFactory(tileFactory);
179 
180  // Add Mouse interactions
181  MouseInputListener mia = new MapPanMouseInputListener(mapViewer);
182  mapViewer.addMouseListener(mia);
183  mapViewer.addMouseMotionListener(mia);
184 
185  mapViewer.addMouseListener(new CenterMapListener(mapViewer));
186  mapViewer.addMouseWheelListener(new ZoomMouseWheelListenerCursor(mapViewer));
187 
188  // Listen to the map for a change in zoom so that we can update the slider.
189  mapViewer.addPropertyChangeListener("zoom", new PropertyChangeListener() {
190  @Override
191  public void propertyChange(PropertyChangeEvent evt) {
192  zoomSlider.setValue(mapViewer.getZoom());
193  }
194  });
195 
196  zoomSlider.setMinimum(tileFactory.getInfo().getMinimumZoomLevel());
197  zoomSlider.setMaximum(tileFactory.getInfo().getMaximumZoomLevel());
198 
199  setZoom(tileFactory.getInfo().getMaximumZoomLevel() - 1);
200 
201  mapViewer.setCenterPosition(new GeoPosition(0, 0));
202 
203  // Basic painters for the way points.
204  WaypointPainter<MapWaypoint> waypointPainter = new WaypointPainter<MapWaypoint>() {
205  @Override
206  public Set<MapWaypoint> getWaypoints() {
207  if (currentlySelectedWaypoint != null) {
208  waypointSet.remove(currentlySelectedWaypoint);
209  waypointSet.add(currentlySelectedWaypoint);
210  }
211  return waypointSet;
212  }
213  };
214  waypointPainter.setRenderer(new MapWaypointRenderer());
215 
216  mapViewer.setOverlayPainter(waypointPainter);
217  }
218 
222  void initializeZoomSlider() {
223  TileFactory tileFactory = mapViewer.getTileFactory();
224  zoomSlider.setMinimum(tileFactory.getInfo().getMinimumZoomLevel());
225  zoomSlider.setMaximum(tileFactory.getInfo().getMaximumZoomLevel());
226 
227  zoomSlider.repaint();
228  zoomSlider.revalidate();
229  }
230 
236  private TileFactory getTileFactory() throws GeoLocationDataException {
237  switch (GeolocationSettingsPanel.GeolocationDataSourceType.getOptionForValue(UserPreferences.getGeolocationtTileOption())) {
238  case ONLINE_USER_DEFINED_OSM_SERVER:
240  case OFFLINE_OSM_ZIP:
241  return new DefaultTileFactory(createOSMZipFactory(UserPreferences.getGeolocationOsmZipPath()));
242  case OFFILE_MBTILES_FILE:
243  return new MBTilesTileFactory(UserPreferences.getGeolocationMBTilesFilePath());
244  default:
245  return new DefaultTileFactory(new VirtualEarthTileFactoryInfo(VirtualEarthTileFactoryInfo.MAP));
246  }
247  }
248 
258  private TileFactoryInfo createOnlineOSMFactory(String address) throws GeoLocationDataException {
259  if (address.isEmpty()) {
260  throw new GeoLocationDataException("Invalid user preference for OSM user define tile server. Address is an empty string.");
261  } else {
262  TileFactoryInfo info = new OSMTileFactoryInfo("User Defined Server", address);
263  return info;
264  }
265  }
266 
276  private TileFactoryInfo createOSMZipFactory(String path) throws GeoLocationDataException {
277  if (path.isEmpty()) {
278  throw new GeoLocationDataException("Invalid OSM tile Zip file. User preference value is empty string.");
279  } else {
280  File file = new File(path);
281  if (!file.exists() || !file.canRead()) {
282  throw new GeoLocationDataException("Invalid OSM tile zip file. Unable to read file: " + path);
283  }
284 
285  String zipPath = path.replaceAll("\\\\", "/");
286 
287  return new OSMTileFactoryInfo("ZIP archive", "jar:file:/" + zipPath + "!"); //NON-NLS
288  }
289  }
290 
296  void setWaypoints(Set<MapWaypoint> waypoints) {
297  waypointTree = new KdTree<>();
298  this.waypointSet = waypoints;
299  for (MapWaypoint waypoint : waypoints) {
300  waypointTree.add(waypoint);
301  }
302  mapViewer.repaint();
303  }
304 
310  void setZoom(int zoom) {
311  zoomChanging = true;
312  mapViewer.setZoom(zoom);
313  zoomSlider.setValue((zoomSlider.getMaximum() + zoomSlider.getMinimum()) - zoom);
314  zoomChanging = false;
315  }
316 
320  void clearWaypoints() {
321  waypointTree = null;
322  currentlySelectedWaypoint = null;
323  if (currentPopup != null) {
324  currentPopup.hide();
325  }
326  mapViewer.repaint();
327  }
328 
335  private void showPopupMenu(Point point) {
336  try {
337  List<MapWaypoint> waypoints = findClosestWaypoint(point);
338  MapWaypoint waypoint = null;
339  if (waypoints.size() > 0) {
340  waypoint = waypoints.get(0);
341  }
342  showPopupMenu(waypoint, point);
343  // Change the details popup to the currently selected point only if
344  // it the popup is currently visible
345  if (waypoint != null && !waypoint.equals(currentlySelectedWaypoint)) {
346  currentlySelectedWaypoint = waypoint;
347  if (currentPopup != null) {
349  }
350  mapViewer.repaint();
351  }
352  } catch (TskCoreException ex) {
353  logger.log(Level.WARNING, "Failed to show popup for waypoint", ex);
354  }
355  }
356 
363  private void showPopupMenu(MapWaypoint waypoint, Point point) throws TskCoreException {
364  if (waypoint == null) {
365  return;
366  }
367 
368  JMenuItem[] items = waypoint.getMenuItems();
369  JPopupMenu popupMenu = new JPopupMenu();
370  for (JMenuItem menu : items) {
371 
372  if (menu != null) {
373  popupMenu.add(menu);
374  } else {
375  popupMenu.add(new JSeparator());
376  }
377  }
378  popupMenu.show(mapViewer, point.x, point.y);
379  }
380 
384  private void showDetailsPopup() {
385  if (currentlySelectedWaypoint != null) {
386  if (currentPopup != null) {
387  currentPopup.hide();
388  }
389 
390  WaypointDetailPanel detailPane = new WaypointDetailPanel();
391  detailPane.setWaypoint(currentlySelectedWaypoint);
392  detailPane.setPreferredSize(new Dimension(POPUP_WIDTH, POPUP_HEIGHT));
393  detailPane.addActionListener(new ActionListener() {
394  @Override
395  public void actionPerformed(ActionEvent e) {
396  if (currentPopup != null) {
397  currentPopup.hide();
398  currentPopup = null;
399  }
400  }
401 
402  });
403 
404  Point popupLocation = getLocationForDetailsPopup();
405 
406  currentPopup = popupFactory.getPopup(this, detailPane, popupLocation.x, popupLocation.y);
407  currentPopup.show();
408 
409  } else {
410  if (currentPopup != null) {
411  currentPopup.hide();
412  }
413  }
414 
415  mapViewer.revalidate();
416  mapViewer.repaint();
417  }
418 
424  private Point getLocationForDetailsPopup() {
425  Point panelCorner = this.getLocationOnScreen();
426  int width = this.getWidth();
427 
428  int popupX = panelCorner.x + width - POPUP_WIDTH - POPUP_MARGIN;
429  int popupY = panelCorner.y + POPUP_MARGIN;
430 
431  return new Point(popupX, popupY);
432  }
433 
442  private List<MapWaypoint> findClosestWaypoint(Point clickPoint) {
443  if (waypointTree == null) {
444  return new ArrayList<>();
445  }
446 
447  // Convert the mouse click location to latitude & longitude
448  GeoPosition geopos = mapViewer.convertPointToGeoPosition(clickPoint);
449 
450  // Get the nearest neightbors to the point
451  Collection<MapWaypoint> waypoints = waypointTree.nearestNeighbourSearch(1, MapWaypoint.getDummyWaypoint(geopos));
452 
453  if (waypoints == null || waypoints.isEmpty()) {
454  return null;
455  }
456 
457  Iterator<MapWaypoint> iterator = waypoints.iterator();
458 
459  // These maybe the points closest to lat/log was clicked but
460  // that doesn't mean they are close in terms of pixles.
461  List<MapWaypoint> closestPoints = new ArrayList<>();
462  while (iterator.hasNext()) {
463  MapWaypoint nextWaypoint = iterator.next();
464 
465  Point2D point = mapViewer.convertGeoPositionToPoint(nextWaypoint.getPosition());
466  Rectangle rect = new Rectangle((int) point.getX() - (defaultWaypointImage.getWidth() / 2), (int) point.getY() - defaultWaypointImage.getHeight(), defaultWaypointImage.getWidth(), defaultWaypointImage.getHeight());
467 
468  if (rect.contains(clickPoint)) {
469  closestPoints.add(nextWaypoint);
470  }
471  }
472 
473  return closestPoints;
474  }
475 
485  public abstract class ComponentResizeEndListener
486  extends ComponentAdapter
487  implements ActionListener {
488 
489  private final Timer timer;
490  private static final int DEFAULT_TIMEOUT = 200;
491 
497  this(DEFAULT_TIMEOUT);
498  }
499 
505  public ComponentResizeEndListener(int delayMS) {
506  timer = new Timer(delayMS, this);
507  timer.setRepeats(false);
508  timer.setCoalesce(false);
509  }
510 
511  @Override
512  public void componentResized(ComponentEvent e) {
513  timer.restart();
514  }
515 
516  @Override
517  public void actionPerformed(ActionEvent e) {
518  resizeTimedOut();
519  }
520 
524  public abstract void resizeTimedOut();
525  }
526 
532  @SuppressWarnings("unchecked")
533  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
534  private void initComponents() {
535  java.awt.GridBagConstraints gridBagConstraints;
536 
537  mapViewer = new org.jxmapviewer.JXMapViewer();
538  zoomPanel = new javax.swing.JPanel();
539  zoomSlider = new javax.swing.JSlider();
540  javax.swing.JButton zoomInBtn = new javax.swing.JButton();
541  javax.swing.JButton zoomOutBtn = new javax.swing.JButton();
542 
543  setFocusable(false);
544  setLayout(new java.awt.BorderLayout());
545 
546  mapViewer.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
547  public void mouseMoved(java.awt.event.MouseEvent evt) {
548  mapViewerMouseMoved(evt);
549  }
550  });
551  mapViewer.addMouseListener(new java.awt.event.MouseAdapter() {
552  public void mouseClicked(java.awt.event.MouseEvent evt) {
554  }
555  public void mousePressed(java.awt.event.MouseEvent evt) {
557  }
558  public void mouseReleased(java.awt.event.MouseEvent evt) {
560  }
561  });
562  mapViewer.setLayout(new java.awt.GridBagLayout());
563 
564  zoomPanel.setFocusable(false);
565  zoomPanel.setOpaque(false);
566  zoomPanel.setRequestFocusEnabled(false);
567  zoomPanel.setLayout(new java.awt.GridBagLayout());
568 
569  zoomSlider.setMaximum(15);
570  zoomSlider.setMinimum(10);
571  zoomSlider.setMinorTickSpacing(1);
572  zoomSlider.setOrientation(javax.swing.JSlider.VERTICAL);
573  zoomSlider.setPaintTicks(true);
574  zoomSlider.setSnapToTicks(true);
575  zoomSlider.setMinimumSize(new java.awt.Dimension(35, 100));
576  zoomSlider.setOpaque(false);
577  zoomSlider.setPreferredSize(new java.awt.Dimension(35, 190));
578  zoomSlider.addChangeListener(new javax.swing.event.ChangeListener() {
579  public void stateChanged(javax.swing.event.ChangeEvent evt) {
581  }
582  });
583  gridBagConstraints = new java.awt.GridBagConstraints();
584  gridBagConstraints.gridx = 0;
585  gridBagConstraints.gridy = 1;
586  zoomPanel.add(zoomSlider, gridBagConstraints);
587 
588  zoomInBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/plus-grey.png"))); // NOI18N
589  org.openide.awt.Mnemonics.setLocalizedText(zoomInBtn, org.openide.util.NbBundle.getMessage(MapPanel.class, "MapPanel.zoomInBtn.text")); // NOI18N
590  zoomInBtn.setBorder(null);
591  zoomInBtn.setBorderPainted(false);
592  zoomInBtn.setFocusPainted(false);
593  zoomInBtn.setRequestFocusEnabled(false);
594  zoomInBtn.setRolloverEnabled(false);
595  zoomInBtn.addActionListener(new java.awt.event.ActionListener() {
596  public void actionPerformed(java.awt.event.ActionEvent evt) {
598  }
599  });
600  gridBagConstraints = new java.awt.GridBagConstraints();
601  gridBagConstraints.gridx = 0;
602  gridBagConstraints.gridy = 0;
603  zoomPanel.add(zoomInBtn, gridBagConstraints);
604 
605  zoomOutBtn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/minus-grey.png"))); // NOI18N
606  org.openide.awt.Mnemonics.setLocalizedText(zoomOutBtn, org.openide.util.NbBundle.getMessage(MapPanel.class, "MapPanel.zoomOutBtn.text")); // NOI18N
607  zoomOutBtn.setBorder(null);
608  zoomOutBtn.setBorderPainted(false);
609  zoomOutBtn.setFocusPainted(false);
610  zoomOutBtn.setRequestFocusEnabled(false);
611  zoomOutBtn.setRolloverEnabled(false);
612  zoomOutBtn.addActionListener(new java.awt.event.ActionListener() {
613  public void actionPerformed(java.awt.event.ActionEvent evt) {
615  }
616  });
617  gridBagConstraints = new java.awt.GridBagConstraints();
618  gridBagConstraints.gridx = 0;
619  gridBagConstraints.gridy = 2;
620  zoomPanel.add(zoomOutBtn, gridBagConstraints);
621 
622  gridBagConstraints = new java.awt.GridBagConstraints();
623  gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
624  gridBagConstraints.weightx = 1.0;
625  gridBagConstraints.weighty = 1.0;
626  gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
627  mapViewer.add(zoomPanel, gridBagConstraints);
628 
629  add(mapViewer, java.awt.BorderLayout.CENTER);
630  }// </editor-fold>//GEN-END:initComponents
631 
632  private void zoomSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_zoomSliderStateChanged
633  if (!zoomChanging) {
634  setZoom(zoomSlider.getValue());
635  }
636  }//GEN-LAST:event_zoomSliderStateChanged
637 
638  private void mapViewerMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mapViewerMousePressed
639  if (evt.isPopupTrigger()) {
640  showPopupMenu(evt.getPoint());
641  }
642  }//GEN-LAST:event_mapViewerMousePressed
643 
644  private void mapViewerMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mapViewerMouseReleased
645  if (evt.isPopupTrigger()) {
646  showPopupMenu(evt.getPoint());
647  }
648  }//GEN-LAST:event_mapViewerMouseReleased
649 
650  private void mapViewerMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mapViewerMouseMoved
651  GeoPosition geopos = mapViewer.convertPointToGeoPosition(evt.getPoint());
652  firePropertyChange(CURRENT_MOUSE_GEOPOSITION, null, geopos);
653  }//GEN-LAST:event_mapViewerMouseMoved
654 
655  private void mapViewerMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mapViewerMouseClicked
656  if (!evt.isPopupTrigger() && SwingUtilities.isLeftMouseButton(evt)) {
657  List<MapWaypoint> waypoints = findClosestWaypoint(evt.getPoint());
658  if (waypoints.size() > 0) {
659  currentlySelectedWaypoint = waypoints.get(0);
660  } else {
661  currentlySelectedWaypoint = null;
662  }
664  }
665  }//GEN-LAST:event_mapViewerMouseClicked
666 
667  private void zoomInBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomInBtnActionPerformed
668  int currentValue = mapViewer.getZoom();
669  setZoom(currentValue - 1);
670  }//GEN-LAST:event_zoomInBtnActionPerformed
671 
672  private void zoomOutBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zoomOutBtnActionPerformed
673  int currentValue = mapViewer.getZoom();
674  setZoom(currentValue + 1);
675  }//GEN-LAST:event_zoomOutBtnActionPerformed
676 
677 
678  // Variables declaration - do not modify//GEN-BEGIN:variables
679  private org.jxmapviewer.JXMapViewer mapViewer;
680  private javax.swing.JPanel zoomPanel;
681  private javax.swing.JSlider zoomSlider;
682  // End of variables declaration//GEN-END:variables
683 
687  private class MapWaypointRenderer implements WaypointRenderer<MapWaypoint> {
688 
689  @Override
690  public void paintWaypoint(Graphics2D gd, JXMapViewer jxmv, MapWaypoint waypoint) {
691  Point2D point = jxmv.getTileFactory().geoToPixel(waypoint.getPosition(), jxmv.getZoom());
692 
693  int x = (int) point.getX();
694  int y = (int) point.getY();
695 
696  BufferedImage image = (waypoint == currentlySelectedWaypoint ? selectedWaypointImage : defaultWaypointImage);
697 
698  (gd.create()).drawImage(image, x - image.getWidth() / 2, y - image.getHeight(), null);
699  }
700  }
701 }
void zoomInBtnActionPerformed(java.awt.event.ActionEvent evt)
Definition: MapPanel.java:667
void showPopupMenu(MapWaypoint waypoint, Point point)
Definition: MapPanel.java:363
void zoomSliderStateChanged(javax.swing.event.ChangeEvent evt)
Definition: MapPanel.java:632
void mapViewerMouseReleased(java.awt.event.MouseEvent evt)
Definition: MapPanel.java:644
Collection< T > nearestNeighbourSearch(int numNeighbors, T value)
Definition: KdTree.java:206
TileFactoryInfo createOnlineOSMFactory(String address)
Definition: MapPanel.java:258
void mapViewerMouseClicked(java.awt.event.MouseEvent evt)
Definition: MapPanel.java:655
void mapViewerMousePressed(java.awt.event.MouseEvent evt)
Definition: MapPanel.java:638
void mapViewerMouseMoved(java.awt.event.MouseEvent evt)
Definition: MapPanel.java:650
void paintWaypoint(Graphics2D gd, JXMapViewer jxmv, MapWaypoint waypoint)
Definition: MapPanel.java:690
List< MapWaypoint > findClosestWaypoint(Point clickPoint)
Definition: MapPanel.java:442
TileFactoryInfo createOSMZipFactory(String path)
Definition: MapPanel.java:276
static void error(String title, String message)
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
void zoomOutBtnActionPerformed(java.awt.event.ActionEvent evt)
Definition: MapPanel.java:672
static void addChangeListener(PreferenceChangeListener listener)
org.jxmapviewer.JXMapViewer mapViewer
Definition: MapPanel.java:679

Copyright © 2012-2020 Basis Technology. Generated on: Wed Apr 8 2020
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.