diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/AbstractWaypointFetcher.java b/Core/src/org/sleuthkit/autopsy/geolocation/AbstractWaypointFetcher.java
index bc56968f9926f1f742f53fb36dd0dc8618bb8674..e923d6dbd67b71036c1e76455c699440d76000cc 100755
--- a/Core/src/org/sleuthkit/autopsy/geolocation/AbstractWaypointFetcher.java
+++ b/Core/src/org/sleuthkit/autopsy/geolocation/AbstractWaypointFetcher.java
@@ -22,6 +22,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.logging.Level;
+import javafx.util.Pair;
 import org.sleuthkit.autopsy.casemodule.Case;
 import org.sleuthkit.autopsy.coreutils.Logger;
 import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException;
@@ -75,11 +76,11 @@ void getWaypoints() throws GeoLocationDataException {
      *
      * @param mapWaypoints List of filtered MapWaypoints.
      */
-    abstract void handleFilteredWaypointSet(Set<MapWaypoint> mapWaypoints);
+    abstract void handleFilteredWaypointSet(Set<MapWaypoint> mapWaypoints, List<Set<MapWaypoint>> tracks);
 
     @Override
     public void process(List<Waypoint> waypoints) {
-        List<Track> tracks = null;
+        List<Track> tracks = new ArrayList<>();
         if (filters.getArtifactTypes().contains(ARTIFACT_TYPE.TSK_GPS_TRACK)) {
             try {
                 tracks = Track.getTracks(Case.getCurrentCase().getSleuthkitCase(), filters.getDataSources());
@@ -87,11 +88,15 @@ public void process(List<Waypoint> waypoints) {
                 logger.log(Level.WARNING, "Exception thrown while retrieving list of Tracks", ex);
             }
         }
+        Pair<List<Waypoint>, List<List<Waypoint>>> waypointsAndTracks = createWaypointList(waypoints, tracks);
+        
+        final Set<MapWaypoint> pointSet = MapWaypoint.getWaypoints(waypointsAndTracks.getKey());
+        final List<Set<MapWaypoint>> trackSets = new ArrayList<>();
+        for (List<Waypoint> t : waypointsAndTracks.getValue()) {
+            trackSets.add(MapWaypoint.getWaypoints(t));
+        }
 
-        List<Waypoint> completeList = createWaypointList(waypoints, tracks);
-        final Set<MapWaypoint> pointSet = MapWaypoint.getWaypoints(completeList);
-
-        handleFilteredWaypointSet(pointSet);
+        handleFilteredWaypointSet(pointSet, trackSets);
     }
 
     /**
@@ -104,8 +109,9 @@ public void process(List<Waypoint> waypoints) {
      * @return A list of waypoints including the tracks based on the current
      *         filters.
      */
-    private List<Waypoint> createWaypointList(List<Waypoint> waypoints, List<Track> tracks) {
+    private Pair<List<Waypoint>, List<List<Waypoint>>> createWaypointList(List<Waypoint> waypoints, List<Track> tracks) {
         final List<Waypoint> completeList = new ArrayList<>();
+        List<List<Waypoint>> filteredTracks = new ArrayList<>();
 
         if (tracks != null) {
             Long timeRangeEnd;
@@ -117,19 +123,22 @@ private List<Waypoint> createWaypointList(List<Waypoint> waypoints, List<Track>
                 timeRangeStart = timeRangeEnd - (86400 * filters.getMostRecentNumDays());
 
                 completeList.addAll(getWaypointsInRange(timeRangeStart, timeRangeEnd, waypoints));
-                completeList.addAll(getTracksInRange(timeRangeStart, timeRangeEnd, tracks));
-
+                
+                filteredTracks = getTracksInRange(timeRangeStart, timeRangeEnd, tracks);
+                for (List<Waypoint> filteredTrack : filteredTracks) {
+                    completeList.addAll(filteredTrack);
+                }
             } else {
                 completeList.addAll(waypoints);
                 for (Track track : tracks) {
                     completeList.addAll(track.getPath());
+                    filteredTracks.add(track.getPath());
                 }
             }
         } else {
             completeList.addAll(waypoints);
         }
-
-        return completeList;
+        return new Pair<>(completeList, filteredTracks);
     }
 
     /**
@@ -158,31 +167,30 @@ private List<Waypoint> getWaypointsInRange(Long timeRangeStart, Long timeRangeEn
     }
 
     /**
-     * Return a list of waypoints from the given tracks that fall into for
-     * tracks that fall into the given time range. The track start time will
-     * used for determining if the whole track falls into the range.
+     * Return a list of lists of waypoints from the given tracks that fall into 
+     * the given time range. The track start time will used for determining if
+     * the whole track falls into the range.
      *
      * @param timeRangeStart start timestamp of range (seconds from java epoch)
      * @param timeRangeEnd   start timestamp of range (seconds from java epoch)
      * @param tracks         Track list.
      *
-     * @return A list of waypoints that that belong to tracks that fall into the
-     *         time range.
+     * @return A list of lists of waypoints corresponding to belong to tracks
+     *         that exist within the time range.
      */
-    private List<Waypoint> getTracksInRange(Long timeRangeStart, Long timeRangeEnd, List<Track> tracks) {
-        List<Waypoint> completeList = new ArrayList<>();
+    private List<List<Waypoint>> getTracksInRange(Long timeRangeStart, Long timeRangeEnd, List<Track> tracks) {
+        List<List<Waypoint>> ret = new ArrayList<>();
         if (tracks != null) {
             for (Track track : tracks) {
                 Long trackTime = track.getStartTime();
 
                 if ((trackTime == null && filters.showWaypointsWithoutTimeStamp())
                         || (trackTime != null && (trackTime >= timeRangeStart && trackTime <= timeRangeEnd))) {
-
-                    completeList.addAll(track.getPath());
+                    ret.add(track.getPath());
                 }
             }
         }
-        return completeList;
+        return ret;
     }
 
     /**
diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/GeolocationTopComponent.java b/Core/src/org/sleuthkit/autopsy/geolocation/GeolocationTopComponent.java
index da8e14a65baa81da975a3b44bcac2e1b8c7fcd51..ae387c7847b03d9d6be6369281cb5b0b58da68fc 100755
--- a/Core/src/org/sleuthkit/autopsy/geolocation/GeolocationTopComponent.java
+++ b/Core/src/org/sleuthkit/autopsy/geolocation/GeolocationTopComponent.java
@@ -330,7 +330,7 @@ public void run() {
      *
      * @param waypointList
      */
-    void addWaypointsToMap(Set<MapWaypoint> waypointList) {
+    void addWaypointsToMap(Set<MapWaypoint> waypointList, List<Set<MapWaypoint>> tracks) {
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
@@ -347,6 +347,8 @@ public void run() {
                 }
                 mapPanel.clearWaypoints();
                 mapPanel.setWaypoints(waypointList);
+                mapPanel.setTracks(tracks);
+                mapPanel.initializePainter();
                 setWaypointLoading(false);
                 geoFilterPanel.setEnabled(true);
             }
@@ -499,8 +501,8 @@ final private class WaypointFetcher extends AbstractWaypointFetcher {
         }
 
         @Override
-        void handleFilteredWaypointSet(Set<MapWaypoint> mapWaypoints) {
-            addWaypointsToMap(mapWaypoints);
+        void handleFilteredWaypointSet(Set<MapWaypoint> mapWaypoints, List<Set<MapWaypoint>> tracks) {
+            addWaypointsToMap(mapWaypoints, tracks);
         }
     }
 }
diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java
index 46600f2c86ccef1be0b6e7b442b0e58d761b2cfe..44de21ff81725a2fef97e0adda9f9a445cd03505 100755
--- a/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java
+++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapPanel.java
@@ -19,11 +19,13 @@
 package org.sleuthkit.autopsy.geolocation;
 
 import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.Rectangle;
+import java.awt.RenderingHints;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.ComponentAdapter;
@@ -71,6 +73,9 @@
 import org.sleuthkit.datamodel.TskCoreException;
 import javax.imageio.ImageIO;
 import javax.swing.SwingUtilities;
+import org.jxmapviewer.painter.CompoundPainter;
+import org.jxmapviewer.painter.Painter;
+import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
 
 /**
  * The map panel. This panel contains the jxmapviewer MapViewer
@@ -84,6 +89,7 @@ final public class MapPanel extends javax.swing.JPanel {
     private boolean zoomChanging;
     private KdTree<MapWaypoint> waypointTree;
     private Set<MapWaypoint> waypointSet;
+    private List<Set<MapWaypoint>> tracks = new ArrayList<>();
 
     private Popup currentPopup;
     private final PopupFactory popupFactory;
@@ -96,6 +102,7 @@ final public class MapPanel extends javax.swing.JPanel {
     private BufferedImage transparentWaypointImage;
 
     private MapWaypoint currentlySelectedWaypoint;
+    private Set<MapWaypoint> currentlySelectedTrack;
 
     /**
      * Creates new form MapPanel
@@ -204,6 +211,10 @@ public void propertyChange(PropertyChangeEvent evt) {
 
         mapViewer.setCenterPosition(new GeoPosition(0, 0));
 
+        initializePainter();
+    }
+
+    void initializePainter() {
         // Basic painters for the way points. 
         WaypointPainter<MapWaypoint> waypointPainter = new WaypointPainter<MapWaypoint>() {
             @Override
@@ -217,7 +228,12 @@ public Set<MapWaypoint> getWaypoints() {
         };
         waypointPainter.setRenderer(new MapWaypointRenderer());
 
-        mapViewer.setOverlayPainter(waypointPainter);
+        ArrayList<Painter<JXMapViewer>> painters = new ArrayList<>();
+        painters.add(new MapTrackRenderer(tracks));
+        painters.add(waypointPainter);
+
+        CompoundPainter<JXMapViewer> compoundPainter = new CompoundPainter<>(painters);
+        mapViewer.setOverlayPainter(compoundPainter);
     }
 
     /**
@@ -306,6 +322,15 @@ void setWaypoints(Set<MapWaypoint> waypoints) {
         mapViewer.repaint();
     }
 
+    /**
+     * Stores the given List of tracks from which to draw paths later
+     *
+     * @param tracks
+     */
+    void setTracks(List<Set<MapWaypoint>> tracks) {
+        this.tracks = tracks;
+    }
+
     /**
      * Set the current zoom level.
      *
@@ -324,6 +349,7 @@ void setZoom(int zoom) {
     void clearWaypoints() {
         waypointTree = null;
         currentlySelectedWaypoint = null;
+        currentlySelectedTrack = null;
         if (currentPopup != null) {
             currentPopup.hide();
         }
@@ -661,9 +687,17 @@ private void mapViewerMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:e
         if (!evt.isPopupTrigger() && SwingUtilities.isLeftMouseButton(evt)) {
             List<MapWaypoint> waypoints = findClosestWaypoint(evt.getPoint());
             if (waypoints.size() > 0) {
-                currentlySelectedWaypoint = waypoints.get(0);
+                MapWaypoint selection = waypoints.get(0);
+                currentlySelectedWaypoint = selection;
+                for (Set<MapWaypoint> track : tracks) {
+                    if (track.contains(selection)) {
+                        currentlySelectedTrack = track;
+                        break;
+                    }
+                }
             } else {
                 currentlySelectedWaypoint = null;
+                currentlySelectedTrack = null;
             }
             showDetailsPopup();
         }
@@ -691,18 +725,18 @@ private void zoomOutBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FI
      */
     private class MapWaypointRenderer implements WaypointRenderer<MapWaypoint> {
 
-        private final Map<Color, BufferedImage> imageCache = new HashMap<>();
+        private final Map<Color, BufferedImage> dotImageCache = new HashMap<>();
+        private final Map<Color, BufferedImage> waypointImageCache = new HashMap<>();
 
         /**
          *
-         * @param waypoint the waypoint for which to get the color
-         * @param currentlySelectedWaypoint the waypoint that is currently
-         * selected
+         * @param waypoint the waypoint for which to get the color selected
          * @return the color that this waypoint should be rendered
          */
-        private Color getColor(MapWaypoint waypoint, MapWaypoint currentlySelectedWaypoint) {
+        private Color getColor(MapWaypoint waypoint) {
             Color baseColor = waypoint.getColor();
-            if (waypoint.equals(currentlySelectedWaypoint)) {
+            if (waypoint.equals(currentlySelectedWaypoint)
+                    || (currentlySelectedTrack != null && currentlySelectedTrack.contains(waypoint))) {
                 // Highlight this waypoint since it is selected
                 return Color.YELLOW;
             } else {
@@ -710,10 +744,32 @@ private Color getColor(MapWaypoint waypoint, MapWaypoint currentlySelectedWaypoi
             }
         }
 
+        /**
+         * Creates a dot image with the specified color
+         *
+         * @param color the color of the new image
+         * @return the new dot image
+         */
+        private BufferedImage createTrackDotImage(Color color) {
+            int w = 10;
+            int h = 10;
+
+            BufferedImage ret = new BufferedImage(w + 2, h + 2, BufferedImage.TYPE_INT_ARGB);
+            Graphics2D g = ret.createGraphics();
+            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+            g.setColor(color);
+            g.fillOval(1, 1, w, h);
+            g.setColor(Color.BLACK);
+            g.setStroke(new BasicStroke(1));
+            g.drawOval(1, 1, w, h);
+            g.dispose();
+            return ret;
+        }
+
         /**
          * Creates a waypoint image with the specified color
          *
-         * @param color the color of the new waypoint image
+         * @param color the color of the new image
          * @return the new waypoint image
          */
         private BufferedImage createWaypointImage(Color color) {
@@ -723,6 +779,7 @@ private BufferedImage createWaypointImage(Color color) {
             BufferedImage ret = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
 
             Graphics2D g = ret.createGraphics();
+            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
             g.drawImage(whiteWaypointImage, 0, 0, null);
             g.setComposite(AlphaComposite.SrcIn);
             g.setColor(color);
@@ -734,22 +791,88 @@ private BufferedImage createWaypointImage(Color color) {
         }
 
         @Override
-        public void paintWaypoint(Graphics2D gd, JXMapViewer jxmv, MapWaypoint waypoint) {
-            Color color = getColor(waypoint, currentlySelectedWaypoint);
+        public void paintWaypoint(Graphics2D g, JXMapViewer map, MapWaypoint waypoint) {
+            Color color = getColor(waypoint);
+            BufferedImage image;
+            int artifactType = waypoint.getArtifactTypeID();
+            Point2D point = map.getTileFactory().geoToPixel(waypoint.getPosition(), map.getZoom());
+            int x = (int) point.getX();
+            int y = (int) point.getY();
 
-            // Store computed images in cache for later use
-            BufferedImage image = imageCache.computeIfAbsent(color, k -> {
-                return createWaypointImage(color);
-            });
+            if (artifactType == ARTIFACT_TYPE.TSK_GPS_TRACKPOINT.getTypeID()
+                    || artifactType == ARTIFACT_TYPE.TSK_GPS_TRACK.getTypeID()
+                    || artifactType == ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID()) {
+                image = dotImageCache.computeIfAbsent(color, k -> {
+                    return createTrackDotImage(color);
+                });
+                // Center the dot on the GPS coordinate
+                y -= image.getHeight() / 2;
+            } else {
+                image = waypointImageCache.computeIfAbsent(color, k -> {
+                    return createWaypointImage(color);
+                });
+                // Align the bottom of the pin with the GPS coordinate
+                y -= image.getHeight();
+            }
+            // Center image horizontally on image
+            x -= image.getWidth() / 2;
 
-            Point2D point = jxmv.getTileFactory().geoToPixel(waypoint.getPosition(), jxmv.getZoom());
+            Graphics2D g2d = (Graphics2D) g.create();
+            g2d.drawImage(image, x, y, null);
+            g2d.dispose();
+        }
+    }
 
-            int x = (int) point.getX();
-            int y = (int) point.getY();
+    /**
+     * Renderer for map track routes
+     */
+    private class MapTrackRenderer implements Painter<JXMapViewer> {
+
+        private final List<Set<MapWaypoint>> tracks;
+
+        MapTrackRenderer(List<Set<MapWaypoint>> tracks) {
+            this.tracks = tracks;
+        }
+
+        private void drawRoute(Set<MapWaypoint> track, Graphics2D g, JXMapViewer map) {
+            int lastX = 0;
+            int lastY = 0;
+
+            boolean first = true;
+
+            for (MapWaypoint wp : track) {
+                Point2D p = map.getTileFactory().geoToPixel(wp.getPosition(), map.getZoom());
+                int thisX = (int) p.getX();
+                int thisY = (int) p.getY();
+
+                if (first) {
+                    first = false;
+                } else {
+                    g.drawLine(lastX, lastY, thisX, thisY);
+                }
+
+                lastX = thisX;
+                lastY = thisY;
+            }
+        }
+
+        @Override
+        public void paint(Graphics2D g, JXMapViewer map, int w, int h) {
+            Graphics2D g2d = (Graphics2D) g.create();
+
+            Rectangle bounds = map.getViewportBounds();
+            g2d.translate(-bounds.x, -bounds.y);
+
+            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+
+            g2d.setColor(Color.BLACK);
+            g2d.setStroke(new BasicStroke(2));
+
+            for (Set<MapWaypoint> track : tracks) {
+                drawRoute(track, g2d, map);
+            }
 
-            gd = (Graphics2D) gd.create();
-            gd.drawImage(image, x - image.getWidth() / 2, y - image.getHeight(), null);
-            gd.dispose();
+            g2d.dispose();
         }
     }
 }
diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java
index f9e4ed86ee5f10775da71524f1ef30e8c34f3632..f7673338b1e4ef8988669c9efc34b12d07eb35bc 100755
--- a/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java
+++ b/Core/src/org/sleuthkit/autopsy/geolocation/MapWaypoint.java
@@ -84,7 +84,7 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
     private final GeoPosition position;
 
     /**
-     * Returns a list of of MapWaypoint objects for the given list of
+     * Returns a list of MapWaypoint objects for the given list of
      * datamodel.Waypoint objects.
      *
      * @param dmWaypoints
@@ -199,6 +199,13 @@ String getHTMLFormattedWaypointDetails() {
         return getFormattedDetails(dataModelWaypoint);
     }
 
+    /**
+     * Returns the artifact type for this waypoint's data source
+     */
+    int getArtifactTypeID() {
+        return dataModelWaypoint.getArtifact().getArtifactTypeID();
+    }
+
     /**
      * Returns a list of JMenuItems for the waypoint. The list list may contain
      * nulls which should be removed or replaced with JSeparators.
diff --git a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java
index 1f8f25452e25ac690666724b4871cb6fbd816f60..11ff0107dd9fe5dd6e8925e90fd3fae310ac694d 100755
--- a/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java
+++ b/Core/src/org/sleuthkit/autopsy/geolocation/datamodel/WaypointBuilder.java
@@ -98,7 +98,7 @@ public interface WaypointFilterQueryCallBack {
          *
          * @param wwaypoints This of waypoints.
          */
-        void process(List<Waypoint> wwaypoints);
+        void process(List<Waypoint> waypoints);
     }
 
     /**