mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 16:06:15 +00:00
Merge pull request #5469 from kellykelly3/5797-highlite-selected-waypoints
5797 highlite selected waypoints
This commit is contained in:
commit
4222a004e9
@ -4,7 +4,6 @@ CTL_GeolocationTopComponent=Geolocation
|
|||||||
RefreshPanel.refreshLabel.text=The geolocation data has been updated, the visualization may be out of date.
|
RefreshPanel.refreshLabel.text=The geolocation data has been updated, the visualization may be out of date.
|
||||||
RefreshPanel.refreshButton.text=Refresh View
|
RefreshPanel.refreshButton.text=Refresh View
|
||||||
RefreshPanel.closeButton.text=
|
RefreshPanel.closeButton.text=
|
||||||
MapPanel.cordLabel.text=
|
|
||||||
WaypointDetailPanel.closeButton.text=
|
WaypointDetailPanel.closeButton.text=
|
||||||
WaypointDetailPanel.imageLabel.text=
|
WaypointDetailPanel.imageLabel.text=
|
||||||
GeoFilterPanel.waypointSettings.border.title=
|
GeoFilterPanel.waypointSettings.border.title=
|
||||||
@ -30,3 +29,5 @@ GeolocationSettingsPanel.osmZipFileField.text=
|
|||||||
GeolocationSettingsPanel.osmZipFileBrowseButton.text=Browse
|
GeolocationSettingsPanel.osmZipFileBrowseButton.text=Browse
|
||||||
GeolocationSettingsPanel.serverTestButton.text=Test
|
GeolocationSettingsPanel.serverTestButton.text=Test
|
||||||
GeolocationSettingsPanel.osmZipButton.actionCommand=OpenStreeMap tile ZIP file
|
GeolocationSettingsPanel.osmZipButton.actionCommand=OpenStreeMap tile ZIP file
|
||||||
|
GeolocationTopComponent.reportButton.text=KML Report
|
||||||
|
GeolocationTopComponent.coordLabel.text=jLabel1
|
||||||
|
@ -11,6 +11,9 @@ GeolocationSettingsPanel_osm_server_test_success_message=The provide OSM tile se
|
|||||||
GeolocationSettingsPanel_osm_server_test_success_message_title=Success
|
GeolocationSettingsPanel_osm_server_test_success_message_title=Success
|
||||||
GeolocationTC_connection_failure_message=Failed to connect to map title source.\nPlease review map source in Options dialog.
|
GeolocationTC_connection_failure_message=Failed to connect to map title source.\nPlease review map source in Options dialog.
|
||||||
GeolocationTC_connection_failure_message_title=Connection Failure
|
GeolocationTC_connection_failure_message_title=Connection Failure
|
||||||
|
GeolocationTC_empty_waypoint_message=Unable to generate KML report due to a lack of waypoints.\nPlease make sure there are waypoints visible before generating the KML report
|
||||||
|
GeolocationTC_KML_report_title=KML Report
|
||||||
|
GeolocationTC_report_progress_title=KML Report Progress
|
||||||
GeoTopComponent_filer_data_invalid_msg=Unable to run waypoint filter.\nPlease select one or more data sources.
|
GeoTopComponent_filer_data_invalid_msg=Unable to run waypoint filter.\nPlease select one or more data sources.
|
||||||
GeoTopComponent_filer_data_invalid_Title=Filter Failure
|
GeoTopComponent_filer_data_invalid_Title=Filter Failure
|
||||||
GeoTopComponent_filter_exception_msg=Exception occured during waypoint filtering.
|
GeoTopComponent_filter_exception_msg=Exception occured during waypoint filtering.
|
||||||
@ -28,7 +31,6 @@ OpenGeolocationAction_name=Geolocation
|
|||||||
RefreshPanel.refreshLabel.text=The geolocation data has been updated, the visualization may be out of date.
|
RefreshPanel.refreshLabel.text=The geolocation data has been updated, the visualization may be out of date.
|
||||||
RefreshPanel.refreshButton.text=Refresh View
|
RefreshPanel.refreshButton.text=Refresh View
|
||||||
RefreshPanel.closeButton.text=
|
RefreshPanel.closeButton.text=
|
||||||
MapPanel.cordLabel.text=
|
|
||||||
WaypointDetailPanel.closeButton.text=
|
WaypointDetailPanel.closeButton.text=
|
||||||
WaypointDetailPanel.imageLabel.text=
|
WaypointDetailPanel.imageLabel.text=
|
||||||
GeoFilterPanel.waypointSettings.border.title=
|
GeoFilterPanel.waypointSettings.border.title=
|
||||||
@ -54,4 +56,6 @@ GeolocationSettingsPanel.osmZipFileField.text=
|
|||||||
GeolocationSettingsPanel.osmZipFileBrowseButton.text=Browse
|
GeolocationSettingsPanel.osmZipFileBrowseButton.text=Browse
|
||||||
GeolocationSettingsPanel.serverTestButton.text=Test
|
GeolocationSettingsPanel.serverTestButton.text=Test
|
||||||
GeolocationSettingsPanel.osmZipButton.actionCommand=OpenStreeMap tile ZIP file
|
GeolocationSettingsPanel.osmZipButton.actionCommand=OpenStreeMap tile ZIP file
|
||||||
|
GeolocationTopComponent.reportButton.text=KML Report
|
||||||
|
GeolocationTopComponent.coordLabel.text=jLabel1
|
||||||
WaypointExtractAction_label=Extract Files(s)
|
WaypointExtractAction_label=Extract Files(s)
|
||||||
|
@ -16,6 +16,63 @@
|
|||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
|
<Container class="org.sleuthkit.autopsy.geolocation.HidingPane" name="filterPane">
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||||
|
<BorderConstraints direction="West"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
|
||||||
|
</Container>
|
||||||
|
<Container class="javax.swing.JPanel" name="statusBar">
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||||
|
<BorderConstraints direction="South"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||||
|
<SubComponents>
|
||||||
|
<Component class="javax.swing.JButton" name="reportButton">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationTopComponent.reportButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Events>
|
||||||
|
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="reportButtonActionPerformed"/>
|
||||||
|
</Events>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="2" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="5" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JProgressBar" name="progressBar">
|
||||||
|
<Properties>
|
||||||
|
<Property name="indeterminate" type="boolean" value="true"/>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
<Component class="javax.swing.JLabel" name="coordLabel">
|
||||||
|
<Properties>
|
||||||
|
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||||
|
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationTopComponent.coordLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||||
|
</Property>
|
||||||
|
</Properties>
|
||||||
|
<Constraints>
|
||||||
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||||
|
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="5" insetsLeft="5" insetsBottom="5" insetsRight="0" anchor="17" weightX="1.0" weightY="0.0"/>
|
||||||
|
</Constraint>
|
||||||
|
</Constraints>
|
||||||
|
</Component>
|
||||||
|
</SubComponents>
|
||||||
|
</Container>
|
||||||
<Container class="org.sleuthkit.autopsy.geolocation.MapPanel" name="mapPanel">
|
<Container class="org.sleuthkit.autopsy.geolocation.MapPanel" name="mapPanel">
|
||||||
<Constraints>
|
<Constraints>
|
||||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||||
@ -24,17 +81,6 @@
|
|||||||
</Constraints>
|
</Constraints>
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||||
<SubComponents>
|
|
||||||
<Container class="org.sleuthkit.autopsy.geolocation.HidingPane" name="filterPane">
|
|
||||||
<Constraints>
|
|
||||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
|
||||||
<BorderConstraints direction="Before"/>
|
|
||||||
</Constraint>
|
|
||||||
</Constraints>
|
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JTabbedPaneSupportLayout"/>
|
|
||||||
</Container>
|
|
||||||
</SubComponents>
|
|
||||||
</Container>
|
</Container>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
@ -21,14 +21,22 @@ package org.sleuthkit.autopsy.geolocation;
|
|||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
import org.openide.filesystems.FileUtil;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.windows.RetainLocation;
|
import org.openide.windows.RetainLocation;
|
||||||
import org.openide.windows.TopComponent;
|
import org.openide.windows.TopComponent;
|
||||||
@ -46,6 +54,8 @@ import org.sleuthkit.autopsy.geolocation.datamodel.WaypointBuilder.WaypointFilte
|
|||||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||||
import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED;
|
import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED;
|
||||||
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
|
||||||
|
import org.sleuthkit.autopsy.report.ReportProgressPanel;
|
||||||
|
import org.sleuthkit.autopsy.report.modules.kml.KMLReport;
|
||||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -70,6 +80,11 @@ public final class GeolocationTopComponent extends TopComponent {
|
|||||||
|
|
||||||
final RefreshPanel refreshPanel = new RefreshPanel();
|
final RefreshPanel refreshPanel = new RefreshPanel();
|
||||||
|
|
||||||
|
private static final String REPORT_PATH_FMT_STR = "%s" + File.separator + "%s %s %s" + File.separator;
|
||||||
|
|
||||||
|
// This is the hardcoded report name from KMLReport.java
|
||||||
|
private static final String REPORT_KML = "ReportKML.kml";
|
||||||
|
|
||||||
@Messages({
|
@Messages({
|
||||||
"GLTopComponent_name=Geolocation",
|
"GLTopComponent_name=Geolocation",
|
||||||
"GLTopComponent_initilzation_error=An error occurred during waypoint initilization. Geolocation data maybe incomplete."
|
"GLTopComponent_initilzation_error=An error occurred during waypoint initilization. Geolocation data maybe incomplete."
|
||||||
@ -134,6 +149,20 @@ public final class GeolocationTopComponent extends TopComponent {
|
|||||||
updateWaypoints();
|
updateWaypoints();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
mapPanel.addPropertyChangeListener(MapPanel.CURRENT_MOUSE_GEOPOSITION, new PropertyChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
|
String label = "";
|
||||||
|
Object newValue = evt.getNewValue();
|
||||||
|
if (newValue != null) {
|
||||||
|
label = newValue.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
coordLabel.setText(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -169,15 +198,15 @@ public final class GeolocationTopComponent extends TopComponent {
|
|||||||
try {
|
try {
|
||||||
mapPanel.initMap();
|
mapPanel.initMap();
|
||||||
} catch (GeoLocationDataException ex) {
|
} catch (GeoLocationDataException ex) {
|
||||||
JOptionPane.showMessageDialog(this,
|
JOptionPane.showMessageDialog(this,
|
||||||
Bundle.GeolocationTC_connection_failure_message(),
|
Bundle.GeolocationTC_connection_failure_message(),
|
||||||
Bundle.GeolocationTC_connection_failure_message_title(),
|
Bundle.GeolocationTC_connection_failure_message_title(),
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
MessageNotifyUtil.Notify.error(
|
MessageNotifyUtil.Notify.error(
|
||||||
Bundle.GeolocationTC_connection_failure_message_title(),
|
Bundle.GeolocationTC_connection_failure_message_title(),
|
||||||
Bundle.GeolocationTC_connection_failure_message());
|
Bundle.GeolocationTC_connection_failure_message());
|
||||||
logger.log(Level.SEVERE, ex.getMessage(), ex);
|
logger.log(Level.SEVERE, ex.getMessage(), ex);
|
||||||
return; // Doen't set the waypoints.
|
return; // Doen't set the waypoints.
|
||||||
}
|
}
|
||||||
mapPanel.setWaypoints(new ArrayList<>());
|
mapPanel.setWaypoints(new ArrayList<>());
|
||||||
updateWaypoints();
|
updateWaypoints();
|
||||||
@ -217,19 +246,57 @@ public final class GeolocationTopComponent extends TopComponent {
|
|||||||
filters = geoFilterPanel.getFilterState();
|
filters = geoFilterPanel.getFilterState();
|
||||||
} catch (GeoLocationUIException ex) {
|
} catch (GeoLocationUIException ex) {
|
||||||
JOptionPane.showMessageDialog(this,
|
JOptionPane.showMessageDialog(this,
|
||||||
Bundle.GeoTopComponent_filer_data_invalid_msg(),
|
Bundle.GeoTopComponent_filer_data_invalid_msg(),
|
||||||
Bundle.GeoTopComponent_filer_data_invalid_Title(),
|
Bundle.GeoTopComponent_filer_data_invalid_Title(),
|
||||||
JOptionPane.INFORMATION_MESSAGE);
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mapPanel.setWaypointLoading(true);
|
setWaypointLoading(true);
|
||||||
geoFilterPanel.setEnabled(false);
|
geoFilterPanel.setEnabled(false);
|
||||||
|
|
||||||
Thread thread = new Thread(new WaypointRunner(filters));
|
Thread thread = new Thread(new WaypointRunner(filters));
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show or hide the waypoint loading progress bar.
|
||||||
|
*
|
||||||
|
* @param loading
|
||||||
|
*/
|
||||||
|
void setWaypointLoading(boolean loading) {
|
||||||
|
progressBar.setEnabled(true);
|
||||||
|
progressBar.setVisible(loading);
|
||||||
|
progressBar.setString("Loading Waypoints");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the directory path for the KML report.
|
||||||
|
*
|
||||||
|
* This is a modified version of the similar private function from
|
||||||
|
* KMLReport.
|
||||||
|
*
|
||||||
|
* @return Path for the report
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private static String createReportDirectory() throws IOException {
|
||||||
|
Case currentCase = Case.getCurrentCase();
|
||||||
|
|
||||||
|
// Create the root reports directory path of the form: <CASE DIRECTORY>/Reports/<Case fileName> <Timestamp>/
|
||||||
|
DateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy-HH-mm-ss", Locale.US);
|
||||||
|
Date date = new Date();
|
||||||
|
String dateNoTime = dateFormat.format(date);
|
||||||
|
String reportPath = String.format(REPORT_PATH_FMT_STR, currentCase.getReportDirectory(), currentCase.getDisplayName(), "Goggle Earth KML", dateNoTime);
|
||||||
|
// Create the root reports directory.
|
||||||
|
try {
|
||||||
|
FileUtil.createFolder(new File(reportPath));
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new IOException("Failed to make report folder, unable to generate reports.", ex);
|
||||||
|
}
|
||||||
|
return reportPath;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is called from within the constructor to initialize the form.
|
* This method is called from within the constructor to initialize the form.
|
||||||
* WARNING: Do NOT modify this code. The content of this method is always
|
* WARNING: Do NOT modify this code. The content of this method is always
|
||||||
@ -238,21 +305,86 @@ public final class GeolocationTopComponent extends TopComponent {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
|
java.awt.GridBagConstraints gridBagConstraints;
|
||||||
|
|
||||||
mapPanel = new org.sleuthkit.autopsy.geolocation.MapPanel();
|
|
||||||
filterPane = new org.sleuthkit.autopsy.geolocation.HidingPane();
|
filterPane = new org.sleuthkit.autopsy.geolocation.HidingPane();
|
||||||
|
statusBar = new javax.swing.JPanel();
|
||||||
|
reportButton = new javax.swing.JButton();
|
||||||
|
progressBar = new javax.swing.JProgressBar();
|
||||||
|
coordLabel = new javax.swing.JLabel();
|
||||||
|
mapPanel = new org.sleuthkit.autopsy.geolocation.MapPanel();
|
||||||
|
|
||||||
setLayout(new java.awt.BorderLayout());
|
setLayout(new java.awt.BorderLayout());
|
||||||
|
add(filterPane, java.awt.BorderLayout.WEST);
|
||||||
|
|
||||||
mapPanel.add(filterPane, java.awt.BorderLayout.LINE_START);
|
statusBar.setLayout(new java.awt.GridBagLayout());
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(reportButton, org.openide.util.NbBundle.getMessage(GeolocationTopComponent.class, "GeolocationTopComponent.reportButton.text")); // NOI18N
|
||||||
|
reportButton.addActionListener(new java.awt.event.ActionListener() {
|
||||||
|
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||||
|
reportButtonActionPerformed(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 2;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 5);
|
||||||
|
statusBar.add(reportButton, gridBagConstraints);
|
||||||
|
|
||||||
|
progressBar.setIndeterminate(true);
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 1;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||||
|
statusBar.add(progressBar, gridBagConstraints);
|
||||||
|
|
||||||
|
org.openide.awt.Mnemonics.setLocalizedText(coordLabel, org.openide.util.NbBundle.getMessage(GeolocationTopComponent.class, "GeolocationTopComponent.coordLabel.text")); // NOI18N
|
||||||
|
gridBagConstraints = new java.awt.GridBagConstraints();
|
||||||
|
gridBagConstraints.gridx = 0;
|
||||||
|
gridBagConstraints.gridy = 0;
|
||||||
|
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
|
||||||
|
gridBagConstraints.weightx = 1.0;
|
||||||
|
gridBagConstraints.insets = new java.awt.Insets(5, 5, 5, 0);
|
||||||
|
statusBar.add(coordLabel, gridBagConstraints);
|
||||||
|
|
||||||
|
add(statusBar, java.awt.BorderLayout.SOUTH);
|
||||||
add(mapPanel, java.awt.BorderLayout.CENTER);
|
add(mapPanel, java.awt.BorderLayout.CENTER);
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
|
@Messages({
|
||||||
|
"GeolocationTC_empty_waypoint_message=Unable to generate KML report due to a lack of waypoints.\nPlease make sure there are waypoints visible before generating the KML report",
|
||||||
|
"GeolocationTC_KML_report_title=KML Report",
|
||||||
|
"GeolocationTC_report_progress_title=KML Report Progress"
|
||||||
|
})
|
||||||
|
private void reportButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_reportButtonActionPerformed
|
||||||
|
List<MapWaypoint> visiblePoints = mapPanel.getVisibleWaypoints();
|
||||||
|
if (visiblePoints.isEmpty()) {
|
||||||
|
JOptionPane.showConfirmDialog(this, Bundle.GeolocationTC_empty_waypoint_message(), Bundle.GeolocationTC_KML_report_title(), JOptionPane.OK_OPTION, JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
ReportProgressPanel progressPanel = new ReportProgressPanel();
|
||||||
|
String reportBaseDir = createReportDirectory();
|
||||||
|
|
||||||
|
progressPanel.setLabels(REPORT_KML, reportBaseDir);
|
||||||
|
|
||||||
|
KMLReport.getDefault().generateReport(reportBaseDir, progressPanel, MapWaypoint.getDataModelWaypoints(visiblePoints));
|
||||||
|
JOptionPane.showConfirmDialog(this, progressPanel, Bundle.GeolocationTC_report_progress_title(), JOptionPane.CLOSED_OPTION, JOptionPane.PLAIN_MESSAGE);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Unable to create KML report", ex);
|
||||||
|
}
|
||||||
|
}//GEN-LAST:event_reportButtonActionPerformed
|
||||||
|
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
|
private javax.swing.JLabel coordLabel;
|
||||||
private org.sleuthkit.autopsy.geolocation.HidingPane filterPane;
|
private org.sleuthkit.autopsy.geolocation.HidingPane filterPane;
|
||||||
private org.sleuthkit.autopsy.geolocation.MapPanel mapPanel;
|
private org.sleuthkit.autopsy.geolocation.MapPanel mapPanel;
|
||||||
|
private javax.swing.JProgressBar progressBar;
|
||||||
|
private javax.swing.JButton reportButton;
|
||||||
|
private javax.swing.JPanel statusBar;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -287,10 +419,10 @@ public final class GeolocationTopComponent extends TopComponent {
|
|||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
JOptionPane.showMessageDialog(GeolocationTopComponent.this,
|
JOptionPane.showMessageDialog(GeolocationTopComponent.this,
|
||||||
Bundle.GeoTopComponent_filter_exception_Title(),
|
Bundle.GeoTopComponent_filter_exception_Title(),
|
||||||
Bundle.GeoTopComponent_filter_exception_msg(),
|
Bundle.GeoTopComponent_filter_exception_msg(),
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -321,6 +453,7 @@ public final class GeolocationTopComponent extends TopComponent {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mapPanel.setWaypoints(MapWaypoint.getWaypoints(waypoints));
|
mapPanel.setWaypoints(MapWaypoint.getWaypoints(waypoints));
|
||||||
|
setWaypointLoading(false);
|
||||||
geoFilterPanel.setEnabled(true);
|
geoFilterPanel.setEnabled(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -91,39 +91,5 @@
|
|||||||
</Container>
|
</Container>
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Container>
|
</Container>
|
||||||
<Container class="javax.swing.JPanel" name="infoPanel">
|
|
||||||
<Constraints>
|
|
||||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
|
||||||
<BorderConstraints direction="South"/>
|
|
||||||
</Constraint>
|
|
||||||
</Constraints>
|
|
||||||
|
|
||||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
|
||||||
<SubComponents>
|
|
||||||
<Component class="javax.swing.JLabel" name="cordLabel">
|
|
||||||
<Properties>
|
|
||||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
|
||||||
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="MapPanel.cordLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
|
||||||
</Property>
|
|
||||||
</Properties>
|
|
||||||
<Constraints>
|
|
||||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
|
||||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="5" insetsBottom="0" insetsRight="5" anchor="18" weightX="1.0" weightY="0.0"/>
|
|
||||||
</Constraint>
|
|
||||||
</Constraints>
|
|
||||||
</Component>
|
|
||||||
<Component class="javax.swing.JProgressBar" name="progressBar">
|
|
||||||
<Properties>
|
|
||||||
<Property name="indeterminate" type="boolean" value="true"/>
|
|
||||||
<Property name="stringPainted" type="boolean" value="true"/>
|
|
||||||
</Properties>
|
|
||||||
<Constraints>
|
|
||||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
|
||||||
<GridBagConstraints gridX="1" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="12" weightX="0.0" weightY="0.0"/>
|
|
||||||
</Constraint>
|
|
||||||
</Constraints>
|
|
||||||
</Component>
|
|
||||||
</SubComponents>
|
|
||||||
</Container>
|
|
||||||
</SubComponents>
|
</SubComponents>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
package org.sleuthkit.autopsy.geolocation;
|
package org.sleuthkit.autopsy.geolocation;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
@ -27,9 +28,12 @@ import java.awt.event.ComponentAdapter;
|
|||||||
import java.awt.event.ComponentEvent;
|
import java.awt.event.ComponentEvent;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -46,6 +50,7 @@ import javax.swing.Popup;
|
|||||||
import javax.swing.PopupFactory;
|
import javax.swing.PopupFactory;
|
||||||
import javax.swing.Timer;
|
import javax.swing.Timer;
|
||||||
import javax.swing.event.MouseInputListener;
|
import javax.swing.event.MouseInputListener;
|
||||||
|
import org.jxmapviewer.JXMapViewer;
|
||||||
import org.jxmapviewer.OSMTileFactoryInfo;
|
import org.jxmapviewer.OSMTileFactoryInfo;
|
||||||
import org.jxmapviewer.VirtualEarthTileFactoryInfo;
|
import org.jxmapviewer.VirtualEarthTileFactoryInfo;
|
||||||
import org.jxmapviewer.input.CenterMapListener;
|
import org.jxmapviewer.input.CenterMapListener;
|
||||||
@ -57,6 +62,7 @@ import org.jxmapviewer.viewer.TileFactory;
|
|||||||
import org.jxmapviewer.viewer.TileFactoryInfo;
|
import org.jxmapviewer.viewer.TileFactoryInfo;
|
||||||
import org.jxmapviewer.viewer.Waypoint;
|
import org.jxmapviewer.viewer.Waypoint;
|
||||||
import org.jxmapviewer.viewer.WaypointPainter;
|
import org.jxmapviewer.viewer.WaypointPainter;
|
||||||
|
import org.jxmapviewer.viewer.WaypointRenderer;
|
||||||
import org.jxmapviewer.viewer.util.GeoUtil;
|
import org.jxmapviewer.viewer.util.GeoUtil;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.sleuthkit.autopsy.core.UserPreferences;
|
import org.sleuthkit.autopsy.core.UserPreferences;
|
||||||
@ -64,12 +70,15 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
|||||||
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
|
||||||
import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException;
|
import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import org.jxmapviewer.viewer.DefaultWaypointRenderer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The map panel. This panel contains the jxmapviewer MapViewer
|
* The map panel. This panel contains the jxmapviewer MapViewer
|
||||||
*/
|
*/
|
||||||
final public class MapPanel extends javax.swing.JPanel {
|
final public class MapPanel extends javax.swing.JPanel {
|
||||||
|
|
||||||
|
static final String CURRENT_MOUSE_GEOPOSITION = "CURRENT_MOUSE_GEOPOSITION";
|
||||||
private static final Logger logger = Logger.getLogger(MapPanel.class.getName());
|
private static final Logger logger = Logger.getLogger(MapPanel.class.getName());
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@ -123,13 +132,34 @@ final public class MapPanel extends javax.swing.JPanel {
|
|||||||
Bundle.MapPanel_connection_failure_message_title(),
|
Bundle.MapPanel_connection_failure_message_title(),
|
||||||
JOptionPane.ERROR_MESSAGE);
|
JOptionPane.ERROR_MESSAGE);
|
||||||
MessageNotifyUtil.Notify.error(
|
MessageNotifyUtil.Notify.error(
|
||||||
Bundle.MapPanel_connection_failure_message_title(),
|
Bundle.MapPanel_connection_failure_message_title(),
|
||||||
Bundle.MapPanel_connection_failure_message());
|
Bundle.MapPanel_connection_failure_message());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of the waypoints that are currently visible in the viewport.
|
||||||
|
*
|
||||||
|
* @return A list of waypoints or empty list if none were found.
|
||||||
|
*/
|
||||||
|
List<MapWaypoint> getVisibleWaypoints() {
|
||||||
|
|
||||||
|
Rectangle viewport = mapViewer.getViewportBounds();
|
||||||
|
List<MapWaypoint> waypoints = new ArrayList<>();
|
||||||
|
|
||||||
|
Iterator<MapWaypoint> iterator = waypointTree.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
MapWaypoint waypoint = iterator.next();
|
||||||
|
if (viewport.contains(mapViewer.getTileFactory().geoToPixel(waypoint.getPosition(), mapViewer.getZoom()))) {
|
||||||
|
waypoints.add(waypoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return waypoints;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the map.
|
* Initialize the map.
|
||||||
*/
|
*/
|
||||||
@ -160,7 +190,7 @@ final public class MapPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
setZoom(tileFactory.getInfo().getMaximumZoomLevel() - 1);
|
setZoom(tileFactory.getInfo().getMaximumZoomLevel() - 1);
|
||||||
|
|
||||||
mapViewer.setCenterPosition(new GeoPosition(0,0));
|
mapViewer.setCenterPosition(new GeoPosition(0, 0));
|
||||||
|
|
||||||
// Basic painters for the way points.
|
// Basic painters for the way points.
|
||||||
WaypointPainter<Waypoint> waypointPainter = new WaypointPainter<Waypoint>() {
|
WaypointPainter<Waypoint> waypointPainter = new WaypointPainter<Waypoint>() {
|
||||||
@ -177,18 +207,14 @@ final public class MapPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
mapViewer.setOverlayPainter(waypointPainter);
|
try {
|
||||||
}
|
waypointPainter.setRenderer(new MapWaypointRenderer());
|
||||||
|
} catch (IOException ex) {
|
||||||
|
logger.log(Level.WARNING, "Failed to load waypoint image resource, using DefaultWaypointRenderer", ex);
|
||||||
|
waypointPainter.setRenderer(new DefaultWaypointRenderer());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
mapViewer.setOverlayPainter(waypointPainter);
|
||||||
* Show or hide the waypoint loading progress bar.
|
|
||||||
*
|
|
||||||
* @param loading
|
|
||||||
*/
|
|
||||||
void setWaypointLoading(boolean loading) {
|
|
||||||
progressBar.setEnabled(true);
|
|
||||||
progressBar.setVisible(loading);
|
|
||||||
progressBar.setString("Loading Waypoints");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -277,7 +303,6 @@ final public class MapPanel extends javax.swing.JPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mapViewer.repaint();
|
mapViewer.repaint();
|
||||||
setWaypointLoading(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -316,6 +341,7 @@ final public class MapPanel extends javax.swing.JPanel {
|
|||||||
if(currentPopup != null) {
|
if(currentPopup != null) {
|
||||||
showDetailsPopup();
|
showDetailsPopup();
|
||||||
}
|
}
|
||||||
|
mapViewer.repaint();
|
||||||
}
|
}
|
||||||
} catch (TskCoreException ex) {
|
} catch (TskCoreException ex) {
|
||||||
logger.log(Level.WARNING, "Failed to show popup for waypoint", ex);
|
logger.log(Level.WARNING, "Failed to show popup for waypoint", ex);
|
||||||
@ -373,6 +399,8 @@ final public class MapPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
currentPopup = popupFactory.getPopup(this, detailPane, popupLocation.x, popupLocation.y);
|
currentPopup = popupFactory.getPopup(this, detailPane, popupLocation.x, popupLocation.y);
|
||||||
currentPopup.show();
|
currentPopup.show();
|
||||||
|
|
||||||
|
mapViewer.repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,9 +527,6 @@ final public class MapPanel extends javax.swing.JPanel {
|
|||||||
mapViewer = new org.jxmapviewer.JXMapViewer();
|
mapViewer = new org.jxmapviewer.JXMapViewer();
|
||||||
zoomPanel = new javax.swing.JPanel();
|
zoomPanel = new javax.swing.JPanel();
|
||||||
zoomSlider = new javax.swing.JSlider();
|
zoomSlider = new javax.swing.JSlider();
|
||||||
infoPanel = new javax.swing.JPanel();
|
|
||||||
cordLabel = new javax.swing.JLabel();
|
|
||||||
progressBar = new javax.swing.JProgressBar();
|
|
||||||
|
|
||||||
setFocusable(false);
|
setFocusable(false);
|
||||||
setLayout(new java.awt.BorderLayout());
|
setLayout(new java.awt.BorderLayout());
|
||||||
@ -568,27 +593,6 @@ final public class MapPanel extends javax.swing.JPanel {
|
|||||||
mapViewer.add(zoomPanel, gridBagConstraints);
|
mapViewer.add(zoomPanel, gridBagConstraints);
|
||||||
|
|
||||||
add(mapViewer, java.awt.BorderLayout.CENTER);
|
add(mapViewer, java.awt.BorderLayout.CENTER);
|
||||||
|
|
||||||
infoPanel.setLayout(new java.awt.GridBagLayout());
|
|
||||||
|
|
||||||
org.openide.awt.Mnemonics.setLocalizedText(cordLabel, org.openide.util.NbBundle.getMessage(MapPanel.class, "MapPanel.cordLabel.text")); // NOI18N
|
|
||||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
|
||||||
gridBagConstraints.gridx = 0;
|
|
||||||
gridBagConstraints.gridy = 0;
|
|
||||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
|
|
||||||
gridBagConstraints.weightx = 1.0;
|
|
||||||
gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 5);
|
|
||||||
infoPanel.add(cordLabel, gridBagConstraints);
|
|
||||||
|
|
||||||
progressBar.setIndeterminate(true);
|
|
||||||
progressBar.setStringPainted(true);
|
|
||||||
gridBagConstraints = new java.awt.GridBagConstraints();
|
|
||||||
gridBagConstraints.gridx = 1;
|
|
||||||
gridBagConstraints.gridy = 0;
|
|
||||||
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHEAST;
|
|
||||||
infoPanel.add(progressBar, gridBagConstraints);
|
|
||||||
|
|
||||||
add(infoPanel, java.awt.BorderLayout.SOUTH);
|
|
||||||
}// </editor-fold>//GEN-END:initComponents
|
}// </editor-fold>//GEN-END:initComponents
|
||||||
|
|
||||||
private void zoomSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_zoomSliderStateChanged
|
private void zoomSliderStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_zoomSliderStateChanged
|
||||||
@ -611,7 +615,7 @@ final public class MapPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
private void mapViewerMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mapViewerMouseMoved
|
private void mapViewerMouseMoved(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mapViewerMouseMoved
|
||||||
GeoPosition geopos = mapViewer.getTileFactory().pixelToGeo(evt.getPoint(), mapViewer.getZoom());
|
GeoPosition geopos = mapViewer.getTileFactory().pixelToGeo(evt.getPoint(), mapViewer.getZoom());
|
||||||
cordLabel.setText(geopos.toString());
|
firePropertyChange(CURRENT_MOUSE_GEOPOSITION, null, geopos);
|
||||||
}//GEN-LAST:event_mapViewerMouseMoved
|
}//GEN-LAST:event_mapViewerMouseMoved
|
||||||
|
|
||||||
private void mapViewerMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mapViewerMouseClicked
|
private void mapViewerMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mapViewerMouseClicked
|
||||||
@ -623,11 +627,39 @@ final public class MapPanel extends javax.swing.JPanel {
|
|||||||
|
|
||||||
|
|
||||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||||
private javax.swing.JLabel cordLabel;
|
|
||||||
private javax.swing.JPanel infoPanel;
|
|
||||||
private org.jxmapviewer.JXMapViewer mapViewer;
|
private org.jxmapviewer.JXMapViewer mapViewer;
|
||||||
private javax.swing.JProgressBar progressBar;
|
|
||||||
private javax.swing.JPanel zoomPanel;
|
private javax.swing.JPanel zoomPanel;
|
||||||
private javax.swing.JSlider zoomSlider;
|
private javax.swing.JSlider zoomSlider;
|
||||||
// End of variables declaration//GEN-END:variables
|
// End of variables declaration//GEN-END:variables
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renderer for the map waypoints.
|
||||||
|
*/
|
||||||
|
private class MapWaypointRenderer implements WaypointRenderer<Waypoint> {
|
||||||
|
private final BufferedImage defaultWaypointImage;
|
||||||
|
private final BufferedImage selectedWaypointImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a WaypointRenederer
|
||||||
|
*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
MapWaypointRenderer() throws IOException {
|
||||||
|
defaultWaypointImage = ImageIO.read(getClass().getResource("/org/sleuthkit/autopsy/images/waypoint_teal.png"));
|
||||||
|
selectedWaypointImage = ImageIO.read(getClass().getResource("/org/sleuthkit/autopsy/images/waypoint_yellow.png"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintWaypoint(Graphics2D gd, JXMapViewer jxmv, Waypoint waypoint) {
|
||||||
|
Point2D point = jxmv.getTileFactory().geoToPixel(waypoint.getPosition(), jxmv.getZoom());
|
||||||
|
|
||||||
|
int x = (int)point.getX();
|
||||||
|
int y = (int)point.getY();
|
||||||
|
|
||||||
|
BufferedImage image = (waypoint == currentlySelectedWaypoint ? selectedWaypointImage: defaultWaypointImage);
|
||||||
|
|
||||||
|
(gd.create()).drawImage(image, x -image.getWidth() / 2, y -image.getHeight(), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,8 +102,8 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
|||||||
*
|
*
|
||||||
* @param dmWaypoints
|
* @param dmWaypoints
|
||||||
*
|
*
|
||||||
* @return List of MapWaypoint objects. List will be empty if dmWaypoints was
|
* @return List of MapWaypoint objects. List will be empty if dmWaypoints
|
||||||
* empty or null.
|
* was empty or null.
|
||||||
*/
|
*/
|
||||||
static List<MapWaypoint> getWaypoints(List<Waypoint> dmWaypoints) {
|
static List<MapWaypoint> getWaypoints(List<Waypoint> dmWaypoints) {
|
||||||
List<MapWaypoint> mapPoints = new ArrayList<>();
|
List<MapWaypoint> mapPoints = new ArrayList<>();
|
||||||
@ -118,6 +118,27 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
|||||||
return mapPoints;
|
return mapPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to get a list of data model waypoints from a list of
|
||||||
|
* MapWaypoints.
|
||||||
|
*
|
||||||
|
* @param mapWaypoints
|
||||||
|
*
|
||||||
|
* @return A list of Waypoint objects, or empty list if mapWaypoints was
|
||||||
|
* null or empty.
|
||||||
|
*/
|
||||||
|
static List<Waypoint> getDataModelWaypoints(List<MapWaypoint> mapWaypoints) {
|
||||||
|
List<Waypoint> waypoints = new ArrayList<>();
|
||||||
|
|
||||||
|
if (mapWaypoints != null) {
|
||||||
|
for (MapWaypoint point : mapWaypoints) {
|
||||||
|
waypoints.add(point.dataModelWaypoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return waypoints;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a MapWaypoint without a reference to the datamodel waypoint.
|
* Returns a MapWaypoint without a reference to the datamodel waypoint.
|
||||||
*
|
*
|
||||||
@ -272,10 +293,10 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
|||||||
return menuItems;
|
return menuItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the nicely formatted details for the given waypoint.
|
* Get the nicely formatted details for the given waypoint.
|
||||||
*
|
*
|
||||||
* @param point Waypoint object
|
* @param point Waypoint object
|
||||||
* @param header String details header
|
* @param header String details header
|
||||||
*
|
*
|
||||||
* @return HTML formatted String of details for given waypoint
|
* @return HTML formatted String of details for given waypoint
|
||||||
@ -298,9 +319,9 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Waypoint.Property> list = point.getOtherProperties();
|
List<Waypoint.Property> list = point.getOtherProperties();
|
||||||
for(Waypoint.Property prop: list) {
|
for (Waypoint.Property prop : list) {
|
||||||
String value = prop.getValue();
|
String value = prop.getValue();
|
||||||
if(value != null && !value.isEmpty()) {
|
if (value != null && !value.isEmpty()) {
|
||||||
result.append(formatAttribute(prop.getDisplayName(), value));
|
result.append(formatAttribute(prop.getDisplayName(), value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,7 +354,6 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
|||||||
return DATE_FORMAT.format(new java.util.Date(timeStamp * 1000));
|
return DATE_FORMAT.format(new java.util.Date(timeStamp * 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An action class for Extracting artifact files.
|
* An action class for Extracting artifact files.
|
||||||
*/
|
*/
|
||||||
|
78
Core/src/org/sleuthkit/autopsy/geolocation/datamodel/BookmarkWaypoint.java
Executable file
78
Core/src/org/sleuthkit/autopsy/geolocation/datamodel/BookmarkWaypoint.java
Executable file
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Autopsy Forensic Browser
|
||||||
|
*
|
||||||
|
* Copyright 2019 Basis Technology Corp.
|
||||||
|
* contact: carrier <at> sleuthkit <dot> org
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.sleuthkit.autopsy.geolocation.datamodel;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||||
|
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class to represent TSK_GPS_BOOKMARK waypoints
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
final class BookmarkWaypoint extends Waypoint {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new BookmarkWaypoint from the given artifact.
|
||||||
|
*
|
||||||
|
* @param artifact BlackboardArtifact for this waypoint
|
||||||
|
*
|
||||||
|
* @throws GeoLocationDataException
|
||||||
|
*/
|
||||||
|
BookmarkWaypoint(BlackboardArtifact artifact) throws GeoLocationDataException {
|
||||||
|
this(artifact, getAttributesFromArtifactAsMap(artifact));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new BookmarkWaypoint.
|
||||||
|
*
|
||||||
|
* @param artifact BlackboardArtifact for this waypoint
|
||||||
|
* @param attributeMap A Map of the BlackboardAttributes for the given
|
||||||
|
* artifact.
|
||||||
|
*
|
||||||
|
* @throws GeoLocationDataException
|
||||||
|
*/
|
||||||
|
private BookmarkWaypoint(BlackboardArtifact artifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap) throws GeoLocationDataException {
|
||||||
|
super(artifact,
|
||||||
|
getLabelFromArtifact(attributeMap),
|
||||||
|
attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME) != null ? attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME).getValueLong() : null,
|
||||||
|
attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE) != null ? attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE).getValueDouble() : null,
|
||||||
|
attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE) != null ? attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE).getValueDouble() : null,
|
||||||
|
attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE) != null ? attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE).getValueDouble() : null,
|
||||||
|
null, attributeMap, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the label for this waypoint.
|
||||||
|
*
|
||||||
|
* @param artifact BlackboardArtifact for waypoint
|
||||||
|
*
|
||||||
|
* @return Returns a label for the waypoint, or empty string if no label was
|
||||||
|
* found.
|
||||||
|
*/
|
||||||
|
private static String getLabelFromArtifact(Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap) {
|
||||||
|
BlackboardAttribute attribute = attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME);
|
||||||
|
if (attribute != null) {
|
||||||
|
return attribute.getDisplayString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -50,10 +50,10 @@ public class Waypoint {
|
|||||||
final private List<Waypoint.Property> immutablePropertiesList;
|
final private List<Waypoint.Property> immutablePropertiesList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a list of attributes that are already being handled by the
|
* This is a list of attributes that are already being handled by the by
|
||||||
* by getter functions.
|
* getter functions.
|
||||||
*/
|
*/
|
||||||
static private BlackboardAttribute.ATTRIBUTE_TYPE[] ALREADY_HANDLED_ATTRIBUTES = {
|
static final private BlackboardAttribute.ATTRIBUTE_TYPE[] ALREADY_HANDLED_ATTRIBUTES = {
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME,
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_NAME,
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE,
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE,
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE,
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE,
|
||||||
@ -65,19 +65,6 @@ public class Waypoint {
|
|||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END,
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE_END,
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END,};
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE_END,};
|
||||||
|
|
||||||
/**
|
|
||||||
* Construct a waypoint with the given artifact.
|
|
||||||
*
|
|
||||||
* @param artifact BlackboardArtifact for this waypoint
|
|
||||||
*
|
|
||||||
* @throws GeoLocationDataException Exception will be thrown if artifact did
|
|
||||||
* not have a valid longitude and latitude.
|
|
||||||
*/
|
|
||||||
Waypoint(BlackboardArtifact artifact) throws GeoLocationDataException {
|
|
||||||
this(artifact,
|
|
||||||
getAttributesFromArtifactAsMap(artifact));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor that initializes all of the member variables.
|
* Constructor that initializes all of the member variables.
|
||||||
*
|
*
|
||||||
@ -110,25 +97,6 @@ public class Waypoint {
|
|||||||
immutablePropertiesList = Collections.unmodifiableList(createGeolocationProperties(attributeMap));
|
immutablePropertiesList = Collections.unmodifiableList(createGeolocationProperties(attributeMap));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new ArtifactWaypoint.
|
|
||||||
*
|
|
||||||
* @param artifact BlackboardArtifact for this waypoint
|
|
||||||
* @param attributeMap A Map of the BlackboardAttributes for the given
|
|
||||||
* artifact.
|
|
||||||
*
|
|
||||||
* @throws GeoLocationDataException
|
|
||||||
*/
|
|
||||||
private Waypoint(BlackboardArtifact artifact, Map<BlackboardAttribute.ATTRIBUTE_TYPE, BlackboardAttribute> attributeMap) throws GeoLocationDataException {
|
|
||||||
this(artifact,
|
|
||||||
getLabelFromArtifact(attributeMap),
|
|
||||||
attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME) != null ? attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME).getValueLong() : null,
|
|
||||||
attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE) != null ? attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LATITUDE).getValueDouble() : null,
|
|
||||||
attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE) != null ? attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_LONGITUDE).getValueDouble() : null,
|
|
||||||
attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE) != null ? attributeMap.get(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_GEO_ALTITUDE).getValueDouble() : null,
|
|
||||||
null, attributeMap, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the BlackboardArtifact that this waypoint represents.
|
* Get the BlackboardArtifact that this waypoint represents.
|
||||||
*
|
*
|
||||||
@ -209,7 +177,8 @@ public class Waypoint {
|
|||||||
/**
|
/**
|
||||||
* Returns the route that this waypoint is apart of .
|
* Returns the route that this waypoint is apart of .
|
||||||
*
|
*
|
||||||
* @return The waypoint route or null if the waypoint is not apart of a route.
|
* @return The waypoint route or null if the waypoint is not apart of a
|
||||||
|
* route.
|
||||||
*/
|
*/
|
||||||
public Route getRoute() {
|
public Route getRoute() {
|
||||||
return route;
|
return route;
|
||||||
|
@ -70,8 +70,8 @@ public final class WaypointBuilder {
|
|||||||
+ " )";
|
+ " )";
|
||||||
|
|
||||||
// Returns a list of artifacts with no time stamp
|
// Returns a list of artifacts with no time stamp
|
||||||
final static String SELECT_WO_TIMESTAMP =
|
final static String SELECT_WO_TIMESTAMP
|
||||||
"SELECT DISTINCT artifact_id, artifact_type_id "
|
= "SELECT DISTINCT artifact_id, artifact_type_id "
|
||||||
+ "FROM blackboard_attributes "
|
+ "FROM blackboard_attributes "
|
||||||
+ "WHERE artifact_id NOT IN (%s) "
|
+ "WHERE artifact_id NOT IN (%s) "
|
||||||
+ "AND artifact_id IN (%s)"; //NON-NLS
|
+ "AND artifact_id IN (%s)"; //NON-NLS
|
||||||
@ -121,6 +121,25 @@ public final class WaypointBuilder {
|
|||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of routes from the given list of waypoints.
|
||||||
|
*
|
||||||
|
* @param waypoints A list of waypoints
|
||||||
|
*
|
||||||
|
* @return A list of routes or an empty list if none were found.
|
||||||
|
*/
|
||||||
|
public static List<Route> getRoutes(List<Waypoint> waypoints) {
|
||||||
|
List<Route> routeList = new ArrayList<>();
|
||||||
|
for (Waypoint point : waypoints) {
|
||||||
|
Route route = point.getRoute();
|
||||||
|
if (route != null && !routeList.contains(route)) {
|
||||||
|
routeList.add(route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return routeList;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a list of Waypoints for TSK_GPS_TRACKPOINT artifacts.
|
* Gets a list of Waypoints for TSK_GPS_TRACKPOINT artifacts.
|
||||||
*
|
*
|
||||||
@ -150,6 +169,25 @@ public final class WaypointBuilder {
|
|||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of waypoints that come from TSK_GEO_TRACKPOINT artifacts.
|
||||||
|
*
|
||||||
|
* @param waypoints A list of waypoints
|
||||||
|
*
|
||||||
|
* @return A list of trackpoint waypoints or empty list if none were found.
|
||||||
|
*/
|
||||||
|
public static List<Waypoint> getTrackpointWaypoints(List<Waypoint> waypoints) {
|
||||||
|
List<Waypoint> specificPoints = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Waypoint point : waypoints) {
|
||||||
|
if (point instanceof TrackpointWaypoint) {
|
||||||
|
specificPoints.add(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return specificPoints;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a list of Waypoints for TSK_METADATA_EXIF artifacts.
|
* Gets a list of Waypoints for TSK_METADATA_EXIF artifacts.
|
||||||
*
|
*
|
||||||
@ -183,6 +221,25 @@ public final class WaypointBuilder {
|
|||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of waypoints that come from TSK_METADATA_EXIF artifacts.
|
||||||
|
*
|
||||||
|
* @param waypoints A list of waypoints
|
||||||
|
*
|
||||||
|
* @return A list of trackpoint waypoints or empty list if none were found.
|
||||||
|
*/
|
||||||
|
public static List<Waypoint> getEXIFWaypoints(List<Waypoint> waypoints) {
|
||||||
|
List<Waypoint> specificPoints = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Waypoint point : waypoints) {
|
||||||
|
if (point instanceof EXIFWaypoint) {
|
||||||
|
specificPoints.add(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return specificPoints;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a list of Waypoints for TSK_GPS_SEARCH artifacts.
|
* Gets a list of Waypoints for TSK_GPS_SEARCH artifacts.
|
||||||
*
|
*
|
||||||
@ -214,6 +271,25 @@ public final class WaypointBuilder {
|
|||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of waypoints that come from TSK_GPS_SEARCH artifacts.
|
||||||
|
*
|
||||||
|
* @param waypoints A list of waypoints
|
||||||
|
*
|
||||||
|
* @return A list of trackpoint waypoints or empty list if none were found.
|
||||||
|
*/
|
||||||
|
public static List<Waypoint> getSearchWaypoints(List<Waypoint> waypoints) {
|
||||||
|
List<Waypoint> specificPoints = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Waypoint point : waypoints) {
|
||||||
|
if (point instanceof SearchWaypoint) {
|
||||||
|
specificPoints.add(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return specificPoints;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a list of Waypoints for TSK_GPS_LAST_KNOWN_LOCATION artifacts.
|
* Gets a list of Waypoints for TSK_GPS_LAST_KNOWN_LOCATION artifacts.
|
||||||
*
|
*
|
||||||
@ -245,6 +321,26 @@ public final class WaypointBuilder {
|
|||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of waypoints that come from TSK_GPS_LAST_KNOWN_LOCATION
|
||||||
|
* artifacts.
|
||||||
|
*
|
||||||
|
* @param waypoints A list of waypoints
|
||||||
|
*
|
||||||
|
* @return A list of trackpoint waypoints or empty list if none were found.
|
||||||
|
*/
|
||||||
|
public static List<Waypoint> getLastKnownWaypoints(List<Waypoint> waypoints) {
|
||||||
|
List<Waypoint> specificPoints = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Waypoint point : waypoints) {
|
||||||
|
if (point instanceof LastKnownWaypoint) {
|
||||||
|
specificPoints.add(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return specificPoints;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a list of Waypoints for TSK_GPS_BOOKMARK artifacts.
|
* Gets a list of Waypoints for TSK_GPS_BOOKMARK artifacts.
|
||||||
*
|
*
|
||||||
@ -266,7 +362,7 @@ public final class WaypointBuilder {
|
|||||||
if (artifacts != null) {
|
if (artifacts != null) {
|
||||||
for (BlackboardArtifact artifact : artifacts) {
|
for (BlackboardArtifact artifact : artifacts) {
|
||||||
try {
|
try {
|
||||||
Waypoint point = new Waypoint(artifact);
|
Waypoint point = new BookmarkWaypoint(artifact);
|
||||||
points.add(point);
|
points.add(point);
|
||||||
} catch (GeoLocationDataException ex) {
|
} catch (GeoLocationDataException ex) {
|
||||||
logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_BOOKMARK artifactID: %d", artifact.getArtifactID()), ex);//NON-NLS
|
logger.log(Level.WARNING, String.format("No longitude or latitude available for TSK_GPS_BOOKMARK artifactID: %d", artifact.getArtifactID()), ex);//NON-NLS
|
||||||
@ -276,6 +372,26 @@ public final class WaypointBuilder {
|
|||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of waypoints that come from TSK_GPS_LAST_KNOWN_LOCATION
|
||||||
|
* artifacts.
|
||||||
|
*
|
||||||
|
* @param waypoints A list of waypoints
|
||||||
|
*
|
||||||
|
* @return A list of trackpoint waypoints or empty list if none were found.
|
||||||
|
*/
|
||||||
|
public static List<Waypoint> getBookmarkWaypoints(List<Waypoint> waypoints) {
|
||||||
|
List<Waypoint> specificPoints = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Waypoint point : waypoints) {
|
||||||
|
if (point instanceof BookmarkWaypoint) {
|
||||||
|
specificPoints.add(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return specificPoints;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a filtered list of waypoints.
|
* Get a filtered list of waypoints.
|
||||||
*
|
*
|
||||||
@ -386,7 +502,7 @@ public final class WaypointBuilder {
|
|||||||
String mostRecentQuery = "";
|
String mostRecentQuery = "";
|
||||||
|
|
||||||
if (!showAll && cntDaysFromRecent > 0) {
|
if (!showAll && cntDaysFromRecent > 0) {
|
||||||
mostRecentQuery = String.format("AND value_int64 > (%s)", //NON-NLS
|
mostRecentQuery = String.format("AND value_int64 > (%s)", //NON-NLS
|
||||||
String.format(MOST_RECENT_TIME,
|
String.format(MOST_RECENT_TIME,
|
||||||
cntDaysFromRecent,
|
cntDaysFromRecent,
|
||||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),
|
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),
|
||||||
@ -464,7 +580,7 @@ public final class WaypointBuilder {
|
|||||||
waypoints.add(new EXIFWaypoint(artifact));
|
waypoints.add(new EXIFWaypoint(artifact));
|
||||||
break;
|
break;
|
||||||
case TSK_GPS_BOOKMARK:
|
case TSK_GPS_BOOKMARK:
|
||||||
waypoints.add(new Waypoint(artifact));
|
waypoints.add(new BookmarkWaypoint(artifact));
|
||||||
break;
|
break;
|
||||||
case TSK_GPS_TRACKPOINT:
|
case TSK_GPS_TRACKPOINT:
|
||||||
waypoints.add(new TrackpointWaypoint(artifact));
|
waypoints.add(new TrackpointWaypoint(artifact));
|
||||||
@ -477,8 +593,7 @@ public final class WaypointBuilder {
|
|||||||
waypoints.addAll(route.getRoute());
|
waypoints.addAll(route.getRoute());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
waypoints.add(new Waypoint(artifact));
|
throw new GeoLocationDataException(String.format("Unable to create waypoint for artifact of type %s", type.toString()));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return waypoints;
|
return waypoints;
|
||||||
|
BIN
Core/src/org/sleuthkit/autopsy/images/waypoint_teal.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/images/waypoint_teal.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 912 B |
BIN
Core/src/org/sleuthkit/autopsy/images/waypoint_yellow.png
Executable file
BIN
Core/src/org/sleuthkit/autopsy/images/waypoint_yellow.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 891 B |
@ -33,6 +33,7 @@ import java.io.OutputStream;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import org.jdom2.Document;
|
import org.jdom2.Document;
|
||||||
@ -59,7 +60,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
|||||||
/**
|
/**
|
||||||
* Generates a KML file based on geospatial information from the BlackBoard.
|
* Generates a KML file based on geospatial information from the BlackBoard.
|
||||||
*/
|
*/
|
||||||
class KMLReport implements GeneralReportModule {
|
public class KMLReport implements GeneralReportModule {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(KMLReport.class.getName());
|
private static final Logger logger = Logger.getLogger(KMLReport.class.getName());
|
||||||
private static final String KML_STYLE_FILE = "style.kml";
|
private static final String KML_STYLE_FILE = "style.kml";
|
||||||
@ -79,6 +80,8 @@ class KMLReport implements GeneralReportModule {
|
|||||||
private Element gpsSearchesFolder;
|
private Element gpsSearchesFolder;
|
||||||
private Element gpsTrackpointsFolder;
|
private Element gpsTrackpointsFolder;
|
||||||
|
|
||||||
|
private List<Waypoint> waypointList = null;
|
||||||
|
|
||||||
private enum FeatureColor {
|
private enum FeatureColor {
|
||||||
RED("style.kml#redFeature"),
|
RED("style.kml#redFeature"),
|
||||||
GREEN("style.kml#greenFeature"),
|
GREEN("style.kml#greenFeature"),
|
||||||
@ -141,6 +144,11 @@ class KMLReport implements GeneralReportModule {
|
|||||||
"Route_Details_Header=GPS Route"
|
"Route_Details_Header=GPS Route"
|
||||||
})
|
})
|
||||||
|
|
||||||
|
public void generateReport(String baseReportDir, ReportProgressPanel progressPanel, List<Waypoint> waypointList) {
|
||||||
|
this.waypointList = waypointList;
|
||||||
|
generateReport(baseReportDir, progressPanel);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generateReport(String baseReportDir, ReportProgressPanel progressPanel) {
|
public void generateReport(String baseReportDir, ReportProgressPanel progressPanel) {
|
||||||
try {
|
try {
|
||||||
@ -298,7 +306,7 @@ class KMLReport implements GeneralReportModule {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
void addExifMetadataContent(List<Waypoint> points, String baseReportDirectory) throws IOException {
|
void addExifMetadataContent(List<Waypoint> points, String baseReportDirectory) throws IOException {
|
||||||
for(Waypoint point: points) {
|
for (Waypoint point : points) {
|
||||||
Element mapPoint = makePoint(point);
|
Element mapPoint = makePoint(point);
|
||||||
if (mapPoint == null) {
|
if (mapPoint == null) {
|
||||||
return;
|
return;
|
||||||
@ -332,23 +340,31 @@ class KMLReport implements GeneralReportModule {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
void addLocationsToReport(SleuthkitCase skCase, String baseReportDir) throws GeoLocationDataException, IOException {
|
void addLocationsToReport(SleuthkitCase skCase, String baseReportDir) throws GeoLocationDataException, IOException {
|
||||||
addExifMetadataContent(WaypointBuilder.getEXIFWaypoints(skCase), baseReportDir);
|
if (waypointList == null) {
|
||||||
addWaypoints(WaypointBuilder.getBookmarkWaypoints(skCase), gpsBookmarksFolder, FeatureColor.BLUE, Bundle.Waypoint_Bookmark_Display_String());
|
addExifMetadataContent(WaypointBuilder.getEXIFWaypoints(skCase), baseReportDir);
|
||||||
addWaypoints(WaypointBuilder.getLastKnownWaypoints(skCase), gpsLastKnownLocationFolder, FeatureColor.PURPLE, Bundle.Waypoint_Last_Known_Display_String());
|
addWaypoints(WaypointBuilder.getBookmarkWaypoints(skCase), gpsBookmarksFolder, FeatureColor.BLUE, Bundle.Waypoint_Bookmark_Display_String());
|
||||||
addWaypoints(WaypointBuilder.getSearchWaypoints(skCase), gpsSearchesFolder, FeatureColor.WHITE, Bundle.Waypoint_Search_Display_String());
|
addWaypoints(WaypointBuilder.getLastKnownWaypoints(skCase), gpsLastKnownLocationFolder, FeatureColor.PURPLE, Bundle.Waypoint_Last_Known_Display_String());
|
||||||
addWaypoints(WaypointBuilder.getTrackpointWaypoints(skCase), gpsTrackpointsFolder, FeatureColor.WHITE, Bundle.Waypoint_Trackpoint_Display_String());
|
addWaypoints(WaypointBuilder.getSearchWaypoints(skCase), gpsSearchesFolder, FeatureColor.WHITE, Bundle.Waypoint_Search_Display_String());
|
||||||
|
addWaypoints(WaypointBuilder.getTrackpointWaypoints(skCase), gpsTrackpointsFolder, FeatureColor.WHITE, Bundle.Waypoint_Trackpoint_Display_String());
|
||||||
|
} else {
|
||||||
|
addExifMetadataContent(WaypointBuilder.getEXIFWaypoints(waypointList), baseReportDir);
|
||||||
|
addWaypoints(WaypointBuilder.getBookmarkWaypoints(waypointList), gpsBookmarksFolder, FeatureColor.BLUE, Bundle.Waypoint_Bookmark_Display_String());
|
||||||
|
addWaypoints(WaypointBuilder.getLastKnownWaypoints(waypointList), gpsLastKnownLocationFolder, FeatureColor.PURPLE, Bundle.Waypoint_Last_Known_Display_String());
|
||||||
|
addWaypoints(WaypointBuilder.getSearchWaypoints(waypointList), gpsSearchesFolder, FeatureColor.WHITE, Bundle.Waypoint_Search_Display_String());
|
||||||
|
addWaypoints(WaypointBuilder.getTrackpointWaypoints(waypointList), gpsTrackpointsFolder, FeatureColor.WHITE, Bundle.Waypoint_Trackpoint_Display_String());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For each point in the waypoint list an Element to represent the given waypoint
|
* For each point in the waypoint list an Element to represent the given
|
||||||
* is created and added it to the given Element folder.
|
* waypoint is created and added it to the given Element folder.
|
||||||
*
|
*
|
||||||
* @param points List of waypoints to add to the report
|
* @param points List of waypoints to add to the report
|
||||||
* @param folder The Element folder to add the points to
|
* @param folder The Element folder to add the points to
|
||||||
* @param waypointColor The color the waypoint should appear in the report
|
* @param waypointColor The color the waypoint should appear in the report
|
||||||
*/
|
*/
|
||||||
void addWaypoints(List<Waypoint> points, Element folder, FeatureColor waypointColor, String headerLabel) {
|
void addWaypoints(List<Waypoint> points, Element folder, FeatureColor waypointColor, String headerLabel) {
|
||||||
for(Waypoint point: points) {
|
for (Waypoint point : points) {
|
||||||
addContent(folder, point.getLabel(), waypointColor, getFormattedDetails(point, headerLabel), point.getTimestamp(), makePoint(point), point.getLatitude(), point.getLongitude());
|
addContent(folder, point.getLabel(), waypointColor, getFormattedDetails(point, headerLabel), point.getTimestamp(), makePoint(point), point.getLatitude(), point.getLongitude());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -356,17 +372,17 @@ class KMLReport implements GeneralReportModule {
|
|||||||
/**
|
/**
|
||||||
* Adds the waypoint Element with details to the report in the given folder.
|
* Adds the waypoint Element with details to the report in the given folder.
|
||||||
*
|
*
|
||||||
* @param folder Element folder to add the waypoint to
|
* @param folder Element folder to add the waypoint to
|
||||||
* @param waypointLabel String waypoint Label
|
* @param waypointLabel String waypoint Label
|
||||||
* @param waypointColor FeatureColor for the waypoint
|
* @param waypointColor FeatureColor for the waypoint
|
||||||
* @param formattedDetails String HTML formatted waypoint details
|
* @param formattedDetails String HTML formatted waypoint details
|
||||||
* @param timestamp Long timestamp (unix\jave epoch seconds)
|
* @param timestamp Long timestamp (unix\jave epoch seconds)
|
||||||
* @param point Element point object
|
* @param point Element point object
|
||||||
* @param latitude Double latitude value
|
* @param latitude Double latitude value
|
||||||
* @param longitude Double longitude value
|
* @param longitude Double longitude value
|
||||||
*/
|
*/
|
||||||
void addContent(Element folder, String waypointLabel, FeatureColor waypointColor, String formattedDetails, Long timestamp, Element point, Double latitude, Double longitude) {
|
void addContent(Element folder, String waypointLabel, FeatureColor waypointColor, String formattedDetails, Long timestamp, Element point, Double latitude, Double longitude) {
|
||||||
if(folder != null && point != null) {
|
if (folder != null && point != null) {
|
||||||
String formattedCords = formattedCoordinates(latitude, longitude);
|
String formattedCords = formattedCoordinates(latitude, longitude);
|
||||||
folder.addContent(makePlacemark(waypointLabel, waypointColor, formattedDetails, timestamp, point, formattedCords));
|
folder.addContent(makePlacemark(waypointLabel, waypointColor, formattedDetails, timestamp, point, formattedCords));
|
||||||
}
|
}
|
||||||
@ -380,10 +396,12 @@ class KMLReport implements GeneralReportModule {
|
|||||||
* @throws TskCoreException
|
* @throws TskCoreException
|
||||||
*/
|
*/
|
||||||
void makeRoutes(SleuthkitCase skCase) throws GeoLocationDataException {
|
void makeRoutes(SleuthkitCase skCase) throws GeoLocationDataException {
|
||||||
List<Route> routes = Route.getRoutes(skCase);
|
List<Route> routes = null;
|
||||||
|
|
||||||
if(routes == null) {
|
if (waypointList == null) {
|
||||||
return;
|
routes = Route.getRoutes(skCase);
|
||||||
|
} else {
|
||||||
|
routes = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Route route : routes) {
|
for (Route route : routes) {
|
||||||
@ -431,7 +449,7 @@ class KMLReport implements GeneralReportModule {
|
|||||||
if (endingPoint != null) {
|
if (endingPoint != null) {
|
||||||
gpsRouteFolder.addContent(makePlacemark(end.getLabel(),
|
gpsRouteFolder.addContent(makePlacemark(end.getLabel(),
|
||||||
FeatureColor.GREEN,
|
FeatureColor.GREEN,
|
||||||
getFormattedDetails(end, Bundle.Waypoint_Route_Point_Display_String()),
|
getFormattedDetails(end, Bundle.Waypoint_Route_Point_Display_String()),
|
||||||
end.getTimestamp(), endingPoint, formattedEnd)); //NON-NLS
|
end.getTimestamp(), endingPoint, formattedEnd)); //NON-NLS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -689,7 +707,7 @@ class KMLReport implements GeneralReportModule {
|
|||||||
/**
|
/**
|
||||||
* Get the nicely formatted details for the given waypoint.
|
* Get the nicely formatted details for the given waypoint.
|
||||||
*
|
*
|
||||||
* @param point Waypoint object
|
* @param point Waypoint object
|
||||||
* @param header String details header
|
* @param header String details header
|
||||||
*
|
*
|
||||||
* @return HTML formatted String of details for given waypoint
|
* @return HTML formatted String of details for given waypoint
|
||||||
@ -712,9 +730,9 @@ class KMLReport implements GeneralReportModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Waypoint.Property> list = point.getOtherProperties();
|
List<Waypoint.Property> list = point.getOtherProperties();
|
||||||
for(Waypoint.Property prop: list) {
|
for (Waypoint.Property prop : list) {
|
||||||
String value = prop.getValue();
|
String value = prop.getValue();
|
||||||
if(value != null && !value.isEmpty()) {
|
if (value != null && !value.isEmpty()) {
|
||||||
result.append(formatAttribute(prop.getDisplayName(), value));
|
result.append(formatAttribute(prop.getDisplayName(), value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -733,8 +751,7 @@ class KMLReport implements GeneralReportModule {
|
|||||||
*
|
*
|
||||||
* @return A HTML formatted list of the Route attributes
|
* @return A HTML formatted list of the Route attributes
|
||||||
*/
|
*/
|
||||||
|
private String getFormattedDetails(Route route) {
|
||||||
private String getFormattedDetails(Route route) {
|
|
||||||
List<Waypoint> points = route.getRoute();
|
List<Waypoint> points = route.getRoute();
|
||||||
StringBuilder result = new StringBuilder(); //NON-NLS
|
StringBuilder result = new StringBuilder(); //NON-NLS
|
||||||
|
|
||||||
@ -754,7 +771,7 @@ class KMLReport implements GeneralReportModule {
|
|||||||
.append(formatAttribute("Start Longitude", start.getLongitude().toString()));
|
.append(formatAttribute("Start Longitude", start.getLongitude().toString()));
|
||||||
|
|
||||||
Double altitude = start.getAltitude();
|
Double altitude = start.getAltitude();
|
||||||
if(altitude != null) {
|
if (altitude != null) {
|
||||||
result.append(formatAttribute("Start Altitude", altitude.toString()));
|
result.append(formatAttribute("Start Altitude", altitude.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -762,15 +779,15 @@ class KMLReport implements GeneralReportModule {
|
|||||||
.append(formatAttribute("End Longitude", end.getLongitude().toString()));
|
.append(formatAttribute("End Longitude", end.getLongitude().toString()));
|
||||||
|
|
||||||
altitude = end.getAltitude();
|
altitude = end.getAltitude();
|
||||||
if(altitude != null) {
|
if (altitude != null) {
|
||||||
result.append(formatAttribute("End Altitude", altitude.toString()));
|
result.append(formatAttribute("End Altitude", altitude.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Waypoint.Property> list = route.getOtherProperties();
|
List<Waypoint.Property> list = route.getOtherProperties();
|
||||||
for(Waypoint.Property prop: list) {
|
for (Waypoint.Property prop : list) {
|
||||||
String value = prop.getValue();
|
String value = prop.getValue();
|
||||||
if(value != null && !value.isEmpty()) {
|
if (value != null && !value.isEmpty()) {
|
||||||
result.append(formatAttribute(prop.getDisplayName(), value));
|
result.append(formatAttribute(prop.getDisplayName(), value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -781,7 +798,7 @@ class KMLReport implements GeneralReportModule {
|
|||||||
/**
|
/**
|
||||||
* Helper functions for consistently formatting longitude and latitude.
|
* Helper functions for consistently formatting longitude and latitude.
|
||||||
*
|
*
|
||||||
* @param latitude Double latitude value
|
* @param latitude Double latitude value
|
||||||
* @param longitude Double longitude value
|
* @param longitude Double longitude value
|
||||||
*
|
*
|
||||||
* @return String Nicely formatted double values separated by a comma
|
* @return String Nicely formatted double values separated by a comma
|
||||||
|
Loading…
x
Reference in New Issue
Block a user