19 package org.sleuthkit.autopsy.geolocation;
21 import java.awt.AlphaComposite;
22 import java.awt.BasicStroke;
23 import java.awt.Color;
24 import java.awt.Dimension;
25 import java.awt.Graphics2D;
26 import java.awt.Paint;
27 import java.awt.Point;
28 import java.awt.Rectangle;
29 import java.awt.RenderingHints;
30 import java.awt.event.ActionEvent;
31 import java.awt.event.ActionListener;
32 import java.awt.event.ComponentAdapter;
33 import java.awt.event.ComponentEvent;
34 import java.awt.geom.GeneralPath;
35 import java.awt.geom.Point2D;
36 import java.awt.image.BufferedImage;
37 import java.beans.PropertyChangeEvent;
38 import java.beans.PropertyChangeListener;
40 import java.io.IOException;
41 import java.util.ArrayList;
42 import java.util.Collection;
43 import java.util.HashMap;
44 import java.util.HashSet;
45 import java.util.Iterator;
46 import java.util.List;
49 import java.util.logging.Level;
50 import java.util.prefs.PreferenceChangeEvent;
51 import java.util.prefs.PreferenceChangeListener;
52 import javax.swing.JMenuItem;
53 import javax.swing.JOptionPane;
54 import javax.swing.JPopupMenu;
55 import javax.swing.JSeparator;
56 import javax.swing.Popup;
57 import javax.swing.PopupFactory;
58 import javax.swing.Timer;
59 import javax.swing.event.MouseInputListener;
60 import org.jxmapviewer.JXMapViewer;
61 import org.jxmapviewer.OSMTileFactoryInfo;
62 import org.jxmapviewer.VirtualEarthTileFactoryInfo;
63 import org.jxmapviewer.input.CenterMapListener;
64 import org.jxmapviewer.input.ZoomMouseWheelListenerCursor;
65 import org.jxmapviewer.viewer.DefaultTileFactory;
66 import org.jxmapviewer.viewer.GeoPosition;
67 import org.jxmapviewer.viewer.TileFactory;
68 import org.jxmapviewer.viewer.TileFactoryInfo;
69 import org.jxmapviewer.viewer.WaypointPainter;
70 import org.jxmapviewer.viewer.WaypointRenderer;
71 import org.openide.util.NbBundle.Messages;
77 import javax.imageio.ImageIO;
78 import javax.swing.SwingUtilities;
79 import org.jxmapviewer.painter.CompoundPainter;
80 import org.jxmapviewer.painter.Painter;
81 import org.
sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
86 @SuppressWarnings(
"deprecation")
87 final public class
MapPanel extends javax.swing.JPanel {
89 static final String CURRENT_MOUSE_GEOPOSITION =
"CURRENT_MOUSE_GEOPOSITION";
93 private static final long serialVersionUID = 1L;
94 private static final Set<Integer> DOT_WAYPOINT_TYPES =
new HashSet<>();
95 private static final int DOT_SIZE = 12;
96 private static final Set<Integer> VERY_SMALL_DOT_WAYPOINT_TYPES =
new HashSet<>();
97 private static final int VERY_SMALL_DOT_SIZE = 6;
102 private List<Set<MapWaypoint>> tracks =
new ArrayList<>();
103 private List<Set<MapWaypoint>> areas =
new ArrayList<>();
108 private static final int POPUP_WIDTH = 300;
109 private static final int POPUP_HEIGHT = 200;
110 private static final int POPUP_MARGIN = 10;
119 DOT_WAYPOINT_TYPES.add(ARTIFACT_TYPE.TSK_GPS_TRACKPOINT.getTypeID());
120 DOT_WAYPOINT_TYPES.add(ARTIFACT_TYPE.TSK_GPS_TRACK.getTypeID());
121 DOT_WAYPOINT_TYPES.add(ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID());
122 VERY_SMALL_DOT_WAYPOINT_TYPES.add(ARTIFACT_TYPE.TSK_GPS_AREA.getTypeID());
129 "MapPanel_connection_failure_message=Failed to connect to new geolocation map tile source.",
130 "MapPanel_connection_failure_message_title=Connection Failure"
135 zoomChanging =
false;
137 popupFactory =
new PopupFactory();
140 whiteWaypointImage = ImageIO.read(getClass().getResource(
"/org/sleuthkit/autopsy/images/waypoint_white.png"));
141 transparentWaypointImage = ImageIO.read(getClass().getResource(
"/org/sleuthkit/autopsy/images/waypoint_transparent.png"));
142 }
catch (IOException ex) {
143 logger.log(Level.WARNING,
"Unable to load geolocation waypoint images", ex);
152 public void resizeTimedOut() {
153 if(currentPopup != null) {
161 public void preferenceChange(PreferenceChangeEvent evt) {
164 mapViewer.getTileFactory().dispose();
166 mapViewer.setTileFactory(getTileFactory());
167 initializeZoomSlider();
169 logger.log(Level.SEVERE,
"Failed to connect to new geolocation tile server.", ex);
170 JOptionPane.showMessageDialog(
MapPanel.this,
171 Bundle.MapPanel_connection_failure_message(),
172 Bundle.MapPanel_connection_failure_message_title(),
173 JOptionPane.ERROR_MESSAGE);
175 Bundle.MapPanel_connection_failure_message_title(),
176 Bundle.MapPanel_connection_failure_message());
187 List<MapWaypoint> getVisibleWaypoints() {
189 Rectangle viewport = mapViewer.getViewportBounds();
190 List<MapWaypoint> waypoints =
new ArrayList<>();
192 Iterator<MapWaypoint> iterator = waypointTree.
iterator();
193 while (iterator.hasNext()) {
195 if (viewport.contains(mapViewer.getTileFactory().geoToPixel(waypoint.
getPosition(), mapViewer.getZoom()))) {
196 waypoints.add(waypoint);
206 void initMap() throws GeoLocationDataException {
208 TileFactory tileFactory = getTileFactory();
209 mapViewer.setTileFactory(tileFactory);
212 MouseInputListener mia =
new MapPanMouseInputListener(mapViewer);
213 mapViewer.addMouseListener(mia);
214 mapViewer.addMouseMotionListener(mia);
216 mapViewer.addMouseListener(
new CenterMapListener(mapViewer));
217 mapViewer.addMouseWheelListener(
new ZoomMouseWheelListenerCursor(mapViewer));
220 mapViewer.addPropertyChangeListener(
"zoom",
new PropertyChangeListener() {
222 public void propertyChange(PropertyChangeEvent evt) {
223 zoomSlider.setValue(mapViewer.getZoom());
227 zoomSlider.setMinimum(tileFactory.getInfo().getMinimumZoomLevel());
228 zoomSlider.setMaximum(tileFactory.getInfo().getMaximumZoomLevel());
230 setZoom(tileFactory.getInfo().getMaximumZoomLevel() - 1);
232 mapViewer.setCenterPosition(
new GeoPosition(0, 0));
237 void initializePainter() {
239 WaypointPainter<MapWaypoint> waypointPainter =
new WaypointPainter<MapWaypoint>() {
241 public Set<MapWaypoint> getWaypoints() {
242 if (currentlySelectedWaypoint != null) {
243 waypointSet.remove(currentlySelectedWaypoint);
244 waypointSet.add(currentlySelectedWaypoint);
249 waypointPainter.setRenderer(
new MapWaypointRenderer());
251 ArrayList<Painter<JXMapViewer>> painters =
new ArrayList<>();
252 painters.add(
new MapAreaRenderer(areas));
253 painters.add(
new MapTrackRenderer(tracks));
254 painters.add(waypointPainter);
256 CompoundPainter<JXMapViewer> compoundPainter =
new CompoundPainter<>(painters);
257 mapViewer.setOverlayPainter(compoundPainter);
263 void initializeZoomSlider() {
264 TileFactory tileFactory = mapViewer.getTileFactory();
265 zoomSlider.setMinimum(tileFactory.getInfo().getMinimumZoomLevel());
266 zoomSlider.setMaximum(tileFactory.getInfo().getMaximumZoomLevel());
268 zoomSlider.repaint();
269 zoomSlider.revalidate();
279 case ONLINE_USER_DEFINED_OSM_SERVER:
281 case OFFLINE_OSM_ZIP:
283 case OFFILE_MBTILES_FILE:
286 return new DefaultTileFactory(
new VirtualEarthTileFactoryInfo(VirtualEarthTileFactoryInfo.MAP));
300 if (address.isEmpty()) {
301 throw new GeoLocationDataException(
"Invalid user preference for OSM user define tile server. Address is an empty string.");
303 TileFactoryInfo info =
new OSMTileFactoryInfo(
"User Defined Server", address);
318 if (path.isEmpty()) {
319 throw new GeoLocationDataException(
"Invalid OSM tile Zip file. User preference value is empty string.");
321 File file =
new File(path);
322 if (!file.exists() || !file.canRead()) {
323 throw new GeoLocationDataException(
"Invalid OSM tile zip file. Unable to read file: " + path);
326 String zipPath = path.replaceAll(
"\\\\",
"/");
328 return new OSMTileFactoryInfo(
"ZIP archive",
"jar:file:/" + zipPath +
"!");
337 void setWaypoints(Set<MapWaypoint> waypoints) {
339 this.waypointSet = waypoints;
341 waypointTree.
add(waypoint);
351 void setTracks(List<Set<MapWaypoint>> tracks) {
352 this.tracks = tracks;
360 void setAreas(List<Set<MapWaypoint>> areas) {
369 void setZoom(
int zoom) {
371 mapViewer.setZoom(zoom);
372 zoomSlider.setValue(zoom);
373 zoomChanging =
false;
379 void clearWaypoints() {
381 currentlySelectedWaypoint = null;
382 currentlySelectedSet = null;
383 if (currentPopup != null) {
397 List<MapWaypoint> waypoints = findClosestWaypoint(point);
399 if (waypoints.size() > 0) {
400 waypoint = waypoints.get(0);
402 showPopupMenu(waypoint, point);
405 if (waypoint != null && !waypoint.
equals(currentlySelectedWaypoint)) {
406 currentlySelectedWaypoint = waypoint;
407 if (currentPopup != null) {
412 }
catch (TskCoreException ex) {
413 logger.log(Level.WARNING,
"Failed to show popup for waypoint", ex);
424 if (waypoint == null) {
428 JMenuItem[] items = waypoint.getMenuItems();
429 JPopupMenu popupMenu =
new JPopupMenu();
430 for (JMenuItem menu : items) {
435 popupMenu.add(
new JSeparator());
438 popupMenu.show(mapViewer, point.x, point.y);
445 if (currentlySelectedWaypoint != null) {
446 if (currentPopup != null) {
450 WaypointDetailPanel detailPane =
new WaypointDetailPanel();
451 detailPane.setWaypoint(currentlySelectedWaypoint);
452 detailPane.setPreferredSize(
new Dimension(POPUP_WIDTH, POPUP_HEIGHT));
453 detailPane.addActionListener(
new ActionListener() {
455 public void actionPerformed(ActionEvent e) {
456 if (currentPopup != null) {
464 Point popupLocation = getLocationForDetailsPopup();
466 currentPopup = popupFactory.getPopup(
this, detailPane, popupLocation.x, popupLocation.y);
470 if (currentPopup != null) {
475 mapViewer.revalidate();
485 Point panelCorner = this.getLocationOnScreen();
486 int width = this.getWidth();
488 int popupX = panelCorner.x + width - POPUP_WIDTH - POPUP_MARGIN;
489 int popupY = panelCorner.y + POPUP_MARGIN;
491 return new Point(popupX, popupY);
503 if (waypointTree == null) {
504 return new ArrayList<>();
508 GeoPosition geopos = mapViewer.convertPointToGeoPosition(clickPoint);
513 if (waypoints == null || waypoints.isEmpty()) {
517 Iterator<MapWaypoint> iterator = waypoints.iterator();
521 List<MapWaypoint> closestPoints =
new ArrayList<>();
522 while (iterator.hasNext()) {
524 Point2D point = mapViewer.convertGeoPositionToPoint(nextWaypoint.
getPosition());
525 int pointX = (int) point.
getX();
526 int pointY = (int) point.getY();
528 if (DOT_WAYPOINT_TYPES.contains(nextWaypoint.getArtifactTypeID())) {
529 rect =
new Rectangle(
530 pointX - (DOT_SIZE / 2),
531 pointY - (DOT_SIZE / 2),
535 }
else if (VERY_SMALL_DOT_WAYPOINT_TYPES.contains(nextWaypoint.getArtifactTypeID())) {
536 rect =
new Rectangle(
537 pointX - (VERY_SMALL_DOT_SIZE / 2),
538 pointY - (VERY_SMALL_DOT_SIZE / 2),
543 rect =
new Rectangle(
544 pointX - (whiteWaypointImage.getWidth() / 2),
545 pointY - whiteWaypointImage.getHeight(),
546 whiteWaypointImage.getWidth(),
547 whiteWaypointImage.getHeight()
551 if (rect.contains(clickPoint)) {
552 closestPoints.add(nextWaypoint);
556 return closestPoints;
569 extends ComponentAdapter
570 implements ActionListener {
573 private static final int DEFAULT_TIMEOUT = 200;
580 this(DEFAULT_TIMEOUT);
589 timer =
new Timer(delayMS,
this);
590 timer.setRepeats(
false);
591 timer.setCoalesce(
false);
607 public abstract void resizeTimedOut();
615 @SuppressWarnings(
"unchecked")
617 private
void initComponents() {
618 java.awt.GridBagConstraints gridBagConstraints;
620 mapViewer =
new org.jxmapviewer.JXMapViewer();
621 zoomPanel =
new javax.swing.JPanel();
622 zoomSlider =
new javax.swing.JSlider();
623 javax.swing.JButton zoomInBtn =
new javax.swing.JButton();
624 javax.swing.JButton zoomOutBtn =
new javax.swing.JButton();
627 setLayout(
new java.awt.BorderLayout());
629 mapViewer.addMouseMotionListener(
new java.awt.event.MouseMotionAdapter() {
630 public void mouseMoved(java.awt.event.MouseEvent evt) {
631 mapViewerMouseMoved(evt);
634 mapViewer.addMouseListener(
new java.awt.event.MouseAdapter() {
635 public void mouseClicked(java.awt.event.MouseEvent evt) {
636 mapViewerMouseClicked(evt);
638 public void mousePressed(java.awt.event.MouseEvent evt) {
639 mapViewerMousePressed(evt);
641 public void mouseReleased(java.awt.event.MouseEvent evt) {
642 mapViewerMouseReleased(evt);
645 mapViewer.setLayout(
new java.awt.GridBagLayout());
647 zoomPanel.setFocusable(
false);
648 zoomPanel.setOpaque(
false);
649 zoomPanel.setRequestFocusEnabled(
false);
650 zoomPanel.setLayout(
new java.awt.GridBagLayout());
652 zoomSlider.setMaximum(15);
653 zoomSlider.setMinimum(10);
654 zoomSlider.setMinorTickSpacing(1);
655 zoomSlider.setOrientation(javax.swing.JSlider.VERTICAL);
656 zoomSlider.setPaintTicks(
true);
657 zoomSlider.setSnapToTicks(
true);
658 zoomSlider.setInverted(
true);
659 zoomSlider.setMinimumSize(
new java.awt.Dimension(35, 100));
660 zoomSlider.setOpaque(
false);
661 zoomSlider.setPreferredSize(
new java.awt.Dimension(35, 190));
662 zoomSlider.addChangeListener(
new javax.swing.event.ChangeListener() {
663 public void stateChanged(javax.swing.event.ChangeEvent evt) {
664 zoomSliderStateChanged(evt);
667 gridBagConstraints =
new java.awt.GridBagConstraints();
668 gridBagConstraints.gridx = 0;
669 gridBagConstraints.gridy = 1;
670 zoomPanel.add(zoomSlider, gridBagConstraints);
672 zoomInBtn.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/plus-grey.png")));
673 org.openide.awt.Mnemonics.setLocalizedText(zoomInBtn,
org.openide.util.NbBundle.getMessage(
MapPanel.class,
"MapPanel.zoomInBtn.text"));
674 zoomInBtn.setBorder(null);
675 zoomInBtn.setBorderPainted(
false);
676 zoomInBtn.setFocusPainted(
false);
677 zoomInBtn.setRequestFocusEnabled(
false);
678 zoomInBtn.setRolloverEnabled(
false);
679 zoomInBtn.addActionListener(
new java.awt.event.ActionListener() {
680 public void actionPerformed(java.awt.event.ActionEvent evt) {
681 zoomInBtnActionPerformed(evt);
684 gridBagConstraints =
new java.awt.GridBagConstraints();
685 gridBagConstraints.gridx = 0;
686 gridBagConstraints.gridy = 0;
687 zoomPanel.add(zoomInBtn, gridBagConstraints);
689 zoomOutBtn.setIcon(
new javax.swing.ImageIcon(getClass().getResource(
"/org/sleuthkit/autopsy/images/minus-grey.png")));
690 org.openide.awt.Mnemonics.setLocalizedText(zoomOutBtn,
org.openide.util.NbBundle.getMessage(
MapPanel.class,
"MapPanel.zoomOutBtn.text"));
691 zoomOutBtn.setBorder(null);
692 zoomOutBtn.setBorderPainted(
false);
693 zoomOutBtn.setFocusPainted(
false);
694 zoomOutBtn.setRequestFocusEnabled(
false);
695 zoomOutBtn.setRolloverEnabled(
false);
696 zoomOutBtn.addActionListener(
new java.awt.event.ActionListener() {
697 public void actionPerformed(java.awt.event.ActionEvent evt) {
698 zoomOutBtnActionPerformed(evt);
701 gridBagConstraints =
new java.awt.GridBagConstraints();
702 gridBagConstraints.gridx = 0;
703 gridBagConstraints.gridy = 2;
704 zoomPanel.add(zoomOutBtn, gridBagConstraints);
706 gridBagConstraints =
new java.awt.GridBagConstraints();
707 gridBagConstraints.anchor = java.awt.GridBagConstraints.SOUTHWEST;
708 gridBagConstraints.weightx = 1.0;
709 gridBagConstraints.weighty = 1.0;
710 gridBagConstraints.insets =
new java.awt.Insets(4, 4, 4, 4);
711 mapViewer.add(zoomPanel, gridBagConstraints);
713 add(mapViewer, java.awt.BorderLayout.CENTER);
718 setZoom(zoomSlider.getValue());
723 if (evt.isPopupTrigger()) {
724 showPopupMenu(evt.getPoint());
729 if (evt.isPopupTrigger()) {
730 showPopupMenu(evt.getPoint());
735 GeoPosition geopos = mapViewer.convertPointToGeoPosition(evt.getPoint());
736 firePropertyChange(CURRENT_MOUSE_GEOPOSITION, null, geopos);
740 if (!evt.isPopupTrigger() && SwingUtilities.isLeftMouseButton(evt)) {
741 List<MapWaypoint> waypoints = findClosestWaypoint(evt.getPoint());
742 if (waypoints.size() > 0) {
744 currentlySelectedWaypoint = selection;
745 currentlySelectedSet = null;
746 for (Set<MapWaypoint> track : tracks) {
747 if (track.contains(selection)) {
748 currentlySelectedSet = track;
752 if (currentlySelectedSet == null) {
753 for (Set<MapWaypoint> area : areas) {
754 if (area.contains(selection)) {
755 currentlySelectedSet = area;
761 currentlySelectedWaypoint = null;
762 currentlySelectedSet = null;
769 int currentValue = mapViewer.getZoom();
770 setZoom(currentValue - 1);
774 int currentValue = mapViewer.getZoom();
775 setZoom(currentValue + 1);
790 private final Map<Color, BufferedImage> dotImageCache =
new HashMap<>();
791 private final Map<Color, BufferedImage> verySmallDotImageCache =
new HashMap<>();
792 private final Map<Color, BufferedImage> waypointImageCache =
new HashMap<>();
801 Color baseColor = waypoint.getColor();
802 if (waypoint.
equals(currentlySelectedWaypoint)
803 || (currentlySelectedSet != null && currentlySelectedSet.contains(waypoint))) {
821 BufferedImage ret =
new BufferedImage(s, s, BufferedImage.TYPE_INT_ARGB);
822 Graphics2D g = ret.createGraphics();
823 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
825 g.fillOval(1, 1, s - 2, s - 2);
826 g.setColor(Color.BLACK);
827 g.setStroke(
new BasicStroke(1));
828 g.drawOval(1, 1, s - 2, s - 2);
841 int w = whiteWaypointImage.getWidth();
842 int h = whiteWaypointImage.getHeight();
844 BufferedImage ret =
new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
846 Graphics2D g = ret.createGraphics();
847 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
848 g.drawImage(whiteWaypointImage, 0, 0, null);
849 g.setComposite(AlphaComposite.SrcIn);
851 g.fillRect(0, 0, w, h);
852 g.setComposite(AlphaComposite.SrcAtop);
853 g.drawImage(transparentWaypointImage, 0, 0, null);
860 Color color = getColor(waypoint);
862 Point2D point = map.getTileFactory().geoToPixel(waypoint.
getPosition(), map.getZoom());
863 int x = (int) point.getX();
864 int y = (int) point.getY();
866 if (DOT_WAYPOINT_TYPES.contains(waypoint.getArtifactTypeID())) {
867 image = dotImageCache.computeIfAbsent(color, k -> {
868 return createTrackDotImage(color, DOT_SIZE);
871 y -= image.getHeight() / 2;
872 }
else if (VERY_SMALL_DOT_WAYPOINT_TYPES.contains(waypoint.getArtifactTypeID())) {
873 image = verySmallDotImageCache.computeIfAbsent(color, k -> {
874 return createTrackDotImage(color, VERY_SMALL_DOT_SIZE);
877 y -= image.getHeight() / 2;
879 image = waypointImageCache.computeIfAbsent(color, k -> {
880 return createWaypointImage(color);
883 y -= image.getHeight();
886 x -= image.getWidth() / 2;
888 Graphics2D g2d = (Graphics2D) g.create();
889 g2d.drawImage(image, x, y, null);
899 private final List<Set<MapWaypoint>>
tracks;
902 this.tracks = tracks;
905 private void drawRoute(Set<MapWaypoint> track, Graphics2D g, JXMapViewer map) {
909 boolean first =
true;
912 Point2D p = map.getTileFactory().geoToPixel(wp.getPosition(), map.getZoom());
913 int thisX = (int) p.getX();
914 int thisY = (int) p.getY();
919 g.drawLine(lastX, lastY, thisX, thisY);
928 public void paint(Graphics2D g, JXMapViewer map,
int w,
int h) {
929 Graphics2D g2d = (Graphics2D) g.create();
931 Rectangle bounds = map.getViewportBounds();
932 g2d.translate(-bounds.x, -bounds.y);
934 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
936 g2d.setColor(Color.BLACK);
937 g2d.setStroke(
new BasicStroke(2));
939 for (Set<MapWaypoint> track : tracks) {
940 drawRoute(track, g2d, map);
952 private final List<Set<MapWaypoint>>
areas;
965 private void drawArea(Set<MapWaypoint> area, Graphics2D g, JXMapViewer map) {
966 if (area.isEmpty()) {
969 boolean first =
true;
971 GeneralPath polygon =
new GeneralPath(GeneralPath.WIND_EVEN_ODD, area.size());
974 Point2D p = map.getTileFactory().geoToPixel(wp.getPosition(), map.getZoom());
975 int thisX = (int) p.getX();
976 int thisY = (int) p.getY();
979 polygon.moveTo(thisX, thisY);
982 polygon.lineTo(thisX, thisY);
987 Color areaColor = area.iterator().next().getColor();
988 final double maxColorValue = 255.0;
989 g.setPaint(
new Color((
float)(areaColor.getRed() / maxColorValue),
990 (
float)(areaColor.getGreen() / maxColorValue),
991 (
float)(areaColor.getBlue() / maxColorValue),
998 public void paint(Graphics2D g, JXMapViewer map,
int w,
int h) {
999 Graphics2D g2d = (Graphics2D) g.create();
1001 Rectangle bounds = map.getViewportBounds();
1002 g2d.translate(-bounds.x, -bounds.y);
1004 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
1006 g2d.setColor(Color.BLACK);
1007 g2d.setStroke(
new BasicStroke(2));
1009 for (Set<MapWaypoint> area : areas) {
1010 drawArea(area, g2d, map);
void paint(Graphics2D g, JXMapViewer map, int w, int h)
final List< Set< MapWaypoint > > tracks
void zoomInBtnActionPerformed(java.awt.event.ActionEvent evt)
static String getGeolocationOsmZipPath()
final PopupFactory popupFactory
void showPopupMenu(MapWaypoint waypoint, Point point)
boolean equals(Object obj)
BufferedImage createWaypointImage(Color color)
void zoomSliderStateChanged(javax.swing.event.ChangeEvent evt)
void componentResized(ComponentEvent e)
void mapViewerMouseReleased(java.awt.event.MouseEvent evt)
Collection< T > nearestNeighbourSearch(int numNeighbors, T value)
ComponentResizeEndListener()
javax.swing.JPanel zoomPanel
KdTree< MapWaypoint > waypointTree
static String getGeolocationMBTilesFilePath()
TileFactoryInfo createOnlineOSMFactory(String address)
BufferedImage whiteWaypointImage
javax.swing.JSlider zoomSlider
void mapViewerMouseClicked(java.awt.event.MouseEvent evt)
void mapViewerMousePressed(java.awt.event.MouseEvent evt)
void mapViewerMouseMoved(java.awt.event.MouseEvent evt)
void drawRoute(Set< MapWaypoint > track, Graphics2D g, JXMapViewer map)
Set< MapWaypoint > currentlySelectedSet
Color getColor(MapWaypoint waypoint)
List< MapWaypoint > findClosestWaypoint(Point clickPoint)
void drawArea(Set< MapWaypoint > area, Graphics2D g, JXMapViewer map)
static int getGeolocationtTileOption()
Point getLocationForDetailsPopup()
void actionPerformed(ActionEvent e)
final List< Set< MapWaypoint > > areas
TileFactoryInfo createOSMZipFactory(String path)
BufferedImage createTrackDotImage(Color color, int s)
static String getGeolocationOsmServerAddress()
void paintWaypoint(Graphics2D g, JXMapViewer map, MapWaypoint waypoint)
static void error(String title, String message)
TileFactory getTileFactory()
synchronized static Logger getLogger(String name)
void zoomOutBtnActionPerformed(java.awt.event.ActionEvent evt)
static void addChangeListener(PreferenceChangeListener listener)
ComponentResizeEndListener(int delayMS)
void paint(Graphics2D g, JXMapViewer map, int w, int h)
BufferedImage transparentWaypointImage
GeoPosition getPosition()
Set< MapWaypoint > waypointSet
org.jxmapviewer.JXMapViewer mapViewer
void showPopupMenu(Point point)
MapWaypoint currentlySelectedWaypoint