mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-12 07:56:16 +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.refreshButton.text=Refresh View
|
||||
RefreshPanel.closeButton.text=
|
||||
MapPanel.cordLabel.text=
|
||||
WaypointDetailPanel.closeButton.text=
|
||||
WaypointDetailPanel.imageLabel.text=
|
||||
GeoFilterPanel.waypointSettings.border.title=
|
||||
@ -30,3 +29,5 @@ GeolocationSettingsPanel.osmZipFileField.text=
|
||||
GeolocationSettingsPanel.osmZipFileBrowseButton.text=Browse
|
||||
GeolocationSettingsPanel.serverTestButton.text=Test
|
||||
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
|
||||
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_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_Title=Filter Failure
|
||||
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.refreshButton.text=Refresh View
|
||||
RefreshPanel.closeButton.text=
|
||||
MapPanel.cordLabel.text=
|
||||
WaypointDetailPanel.closeButton.text=
|
||||
WaypointDetailPanel.imageLabel.text=
|
||||
GeoFilterPanel.waypointSettings.border.title=
|
||||
@ -54,4 +56,6 @@ GeolocationSettingsPanel.osmZipFileField.text=
|
||||
GeolocationSettingsPanel.osmZipFileBrowseButton.text=Browse
|
||||
GeolocationSettingsPanel.serverTestButton.text=Test
|
||||
GeolocationSettingsPanel.osmZipButton.actionCommand=OpenStreeMap tile ZIP file
|
||||
GeolocationTopComponent.reportButton.text=KML Report
|
||||
GeolocationTopComponent.coordLabel.text=jLabel1
|
||||
WaypointExtractAction_label=Extract Files(s)
|
||||
|
@ -16,6 +16,63 @@
|
||||
|
||||
<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="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">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
@ -24,17 +81,6 @@
|
||||
</Constraints>
|
||||
|
||||
<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>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
</Form>
|
||||
|
@ -21,14 +21,22 @@ package org.sleuthkit.autopsy.geolocation;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
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.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.filesystems.FileUtil;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.RetainLocation;
|
||||
import org.openide.windows.TopComponent;
|
||||
@ -46,6 +54,8 @@ import org.sleuthkit.autopsy.geolocation.datamodel.WaypointBuilder.WaypointFilte
|
||||
import org.sleuthkit.autopsy.ingest.IngestManager;
|
||||
import static org.sleuthkit.autopsy.ingest.IngestManager.IngestModuleEvent.DATA_ADDED;
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -70,6 +80,11 @@ public final class GeolocationTopComponent extends TopComponent {
|
||||
|
||||
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({
|
||||
"GLTopComponent_name=Geolocation",
|
||||
"GLTopComponent_initilzation_error=An error occurred during waypoint initilization. Geolocation data maybe incomplete."
|
||||
@ -81,7 +96,7 @@ public final class GeolocationTopComponent extends TopComponent {
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
public GeolocationTopComponent() {
|
||||
initComponents();
|
||||
|
||||
|
||||
setName(Bundle.GLTopComponent_name());
|
||||
|
||||
this.ingestListener = pce -> {
|
||||
@ -134,6 +149,20 @@ public final class GeolocationTopComponent extends TopComponent {
|
||||
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
|
||||
@ -156,7 +185,7 @@ public final class GeolocationTopComponent extends TopComponent {
|
||||
WindowManager.getDefault().setTopComponentFloating(this, true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Messages({
|
||||
"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"
|
||||
@ -169,15 +198,15 @@ public final class GeolocationTopComponent extends TopComponent {
|
||||
try {
|
||||
mapPanel.initMap();
|
||||
} catch (GeoLocationDataException ex) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.GeolocationTC_connection_failure_message(),
|
||||
Bundle.GeolocationTC_connection_failure_message_title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
MessageNotifyUtil.Notify.error(
|
||||
Bundle.GeolocationTC_connection_failure_message_title(),
|
||||
Bundle.GeolocationTC_connection_failure_message());
|
||||
logger.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
return; // Doen't set the waypoints.
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.GeolocationTC_connection_failure_message(),
|
||||
Bundle.GeolocationTC_connection_failure_message_title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
MessageNotifyUtil.Notify.error(
|
||||
Bundle.GeolocationTC_connection_failure_message_title(),
|
||||
Bundle.GeolocationTC_connection_failure_message());
|
||||
logger.log(Level.SEVERE, ex.getMessage(), ex);
|
||||
return; // Doen't set the waypoints.
|
||||
}
|
||||
mapPanel.setWaypoints(new ArrayList<>());
|
||||
updateWaypoints();
|
||||
@ -216,20 +245,58 @@ public final class GeolocationTopComponent extends TopComponent {
|
||||
try {
|
||||
filters = geoFilterPanel.getFilterState();
|
||||
} catch (GeoLocationUIException ex) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.GeoTopComponent_filer_data_invalid_msg(),
|
||||
Bundle.GeoTopComponent_filer_data_invalid_Title(),
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.GeoTopComponent_filer_data_invalid_msg(),
|
||||
Bundle.GeoTopComponent_filer_data_invalid_Title(),
|
||||
JOptionPane.INFORMATION_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
mapPanel.setWaypointLoading(true);
|
||||
|
||||
setWaypointLoading(true);
|
||||
geoFilterPanel.setEnabled(false);
|
||||
|
||||
|
||||
Thread thread = new Thread(new WaypointRunner(filters));
|
||||
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.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
@ -238,23 +305,88 @@ public final class GeolocationTopComponent extends TopComponent {
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
java.awt.GridBagConstraints gridBagConstraints;
|
||||
|
||||
mapPanel = new org.sleuthkit.autopsy.geolocation.MapPanel();
|
||||
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());
|
||||
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);
|
||||
}// </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
|
||||
private javax.swing.JLabel coordLabel;
|
||||
private org.sleuthkit.autopsy.geolocation.HidingPane filterPane;
|
||||
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
|
||||
|
||||
|
||||
/**
|
||||
* A runnable class for getting waypoints based on the current filters.
|
||||
*/
|
||||
@ -264,8 +396,8 @@ public final class GeolocationTopComponent extends TopComponent {
|
||||
|
||||
/**
|
||||
* Constructs the Waypoint Runner
|
||||
*
|
||||
* @param filters
|
||||
*
|
||||
* @param filters
|
||||
*/
|
||||
WaypointRunner(GeoFilter filters) {
|
||||
this.filters = filters;
|
||||
@ -281,16 +413,16 @@ public final class GeolocationTopComponent extends TopComponent {
|
||||
filters.getMostRecentNumDays(),
|
||||
filters.showWaypointsWithoutTimeStamp(),
|
||||
new WaypointCallBack());
|
||||
|
||||
|
||||
} catch (GeoLocationDataException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to filter waypoints.", ex);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
JOptionPane.showMessageDialog(GeolocationTopComponent.this,
|
||||
Bundle.GeoTopComponent_filter_exception_Title(),
|
||||
Bundle.GeoTopComponent_filter_exception_msg(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
JOptionPane.showMessageDialog(GeolocationTopComponent.this,
|
||||
Bundle.GeoTopComponent_filter_exception_Title(),
|
||||
Bundle.GeoTopComponent_filter_exception_msg(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -321,6 +453,7 @@ public final class GeolocationTopComponent extends TopComponent {
|
||||
return;
|
||||
}
|
||||
mapPanel.setWaypoints(MapWaypoint.getWaypoints(waypoints));
|
||||
setWaypointLoading(false);
|
||||
geoFilterPanel.setEnabled(true);
|
||||
}
|
||||
});
|
||||
|
@ -91,39 +91,5 @@
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</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>
|
||||
</Form>
|
||||
|
@ -19,6 +19,7 @@
|
||||
package org.sleuthkit.autopsy.geolocation;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
@ -27,9 +28,12 @@ import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@ -46,6 +50,7 @@ import javax.swing.Popup;
|
||||
import javax.swing.PopupFactory;
|
||||
import javax.swing.Timer;
|
||||
import javax.swing.event.MouseInputListener;
|
||||
import org.jxmapviewer.JXMapViewer;
|
||||
import org.jxmapviewer.OSMTileFactoryInfo;
|
||||
import org.jxmapviewer.VirtualEarthTileFactoryInfo;
|
||||
import org.jxmapviewer.input.CenterMapListener;
|
||||
@ -57,6 +62,7 @@ import org.jxmapviewer.viewer.TileFactory;
|
||||
import org.jxmapviewer.viewer.TileFactoryInfo;
|
||||
import org.jxmapviewer.viewer.Waypoint;
|
||||
import org.jxmapviewer.viewer.WaypointPainter;
|
||||
import org.jxmapviewer.viewer.WaypointRenderer;
|
||||
import org.jxmapviewer.viewer.util.GeoUtil;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
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.geolocation.datamodel.GeoLocationDataException;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import javax.imageio.ImageIO;
|
||||
import org.jxmapviewer.viewer.DefaultWaypointRenderer;
|
||||
|
||||
/**
|
||||
* The map panel. This panel contains the jxmapviewer MapViewer
|
||||
*/
|
||||
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 long serialVersionUID = 1L;
|
||||
@ -123,13 +132,34 @@ final public class MapPanel extends javax.swing.JPanel {
|
||||
Bundle.MapPanel_connection_failure_message_title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
MessageNotifyUtil.Notify.error(
|
||||
Bundle.MapPanel_connection_failure_message_title(),
|
||||
Bundle.MapPanel_connection_failure_message());
|
||||
Bundle.MapPanel_connection_failure_message_title(),
|
||||
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.
|
||||
*/
|
||||
@ -159,8 +189,8 @@ final public class MapPanel extends javax.swing.JPanel {
|
||||
zoomSlider.setMaximum(tileFactory.getInfo().getMaximumZoomLevel());
|
||||
|
||||
setZoom(tileFactory.getInfo().getMaximumZoomLevel() - 1);
|
||||
|
||||
mapViewer.setCenterPosition(new GeoPosition(0,0));
|
||||
|
||||
mapViewer.setCenterPosition(new GeoPosition(0, 0));
|
||||
|
||||
// Basic painters for the way points.
|
||||
WaypointPainter<Waypoint> waypointPainter = new WaypointPainter<Waypoint>() {
|
||||
@ -176,20 +206,16 @@ final public class MapPanel extends javax.swing.JPanel {
|
||||
return set;
|
||||
}
|
||||
};
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the zoom slider based on the current tileFactory.
|
||||
@ -218,15 +244,15 @@ final public class MapPanel extends javax.swing.JPanel {
|
||||
return new VirtualEarthTileFactoryInfo(VirtualEarthTileFactoryInfo.MAP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the TileFactoryInfo for an online OSM tile server.
|
||||
*
|
||||
* @param address Tile server address
|
||||
*
|
||||
*
|
||||
* @param address Tile server address
|
||||
*
|
||||
* @return TileFactoryInfo object for server address.
|
||||
*
|
||||
* @throws GeoLocationDataException
|
||||
*
|
||||
* @throws GeoLocationDataException
|
||||
*/
|
||||
private TileFactoryInfo createOnlineOSMFactory(String address) throws GeoLocationDataException {
|
||||
if (address.isEmpty()) {
|
||||
@ -239,15 +265,15 @@ final public class MapPanel extends javax.swing.JPanel {
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create the TileFactoryInfo for OSM zip File
|
||||
*
|
||||
*
|
||||
* @param zipPath Path to zip file.
|
||||
*
|
||||
*
|
||||
* @return TileFactoryInfo for zip file.
|
||||
*
|
||||
* @throws GeoLocationDataException
|
||||
*
|
||||
* @throws GeoLocationDataException
|
||||
*/
|
||||
private TileFactoryInfo createOSMZipFactory(String path) throws GeoLocationDataException {
|
||||
if (path.isEmpty()) {
|
||||
@ -277,7 +303,6 @@ final public class MapPanel extends javax.swing.JPanel {
|
||||
}
|
||||
|
||||
mapViewer.repaint();
|
||||
setWaypointLoading(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -316,6 +341,7 @@ final public class MapPanel extends javax.swing.JPanel {
|
||||
if(currentPopup != null) {
|
||||
showDetailsPopup();
|
||||
}
|
||||
mapViewer.repaint();
|
||||
}
|
||||
} catch (TskCoreException 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.show();
|
||||
|
||||
mapViewer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
@ -499,9 +527,6 @@ final public class MapPanel extends javax.swing.JPanel {
|
||||
mapViewer = new org.jxmapviewer.JXMapViewer();
|
||||
zoomPanel = new javax.swing.JPanel();
|
||||
zoomSlider = new javax.swing.JSlider();
|
||||
infoPanel = new javax.swing.JPanel();
|
||||
cordLabel = new javax.swing.JLabel();
|
||||
progressBar = new javax.swing.JProgressBar();
|
||||
|
||||
setFocusable(false);
|
||||
setLayout(new java.awt.BorderLayout());
|
||||
@ -568,27 +593,6 @@ final public class MapPanel extends javax.swing.JPanel {
|
||||
mapViewer.add(zoomPanel, gridBagConstraints);
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
GeoPosition geopos = mapViewer.getTileFactory().pixelToGeo(evt.getPoint(), mapViewer.getZoom());
|
||||
cordLabel.setText(geopos.toString());
|
||||
firePropertyChange(CURRENT_MOUSE_GEOPOSITION, null, geopos);
|
||||
}//GEN-LAST:event_mapViewerMouseMoved
|
||||
|
||||
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
|
||||
private javax.swing.JLabel cordLabel;
|
||||
private javax.swing.JPanel infoPanel;
|
||||
private org.jxmapviewer.JXMapViewer mapViewer;
|
||||
private javax.swing.JProgressBar progressBar;
|
||||
private javax.swing.JPanel zoomPanel;
|
||||
private javax.swing.JSlider zoomSlider;
|
||||
// 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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -95,21 +95,21 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
||||
|
||||
return mapPoints;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a list of of MapWaypoint objects for the given list of
|
||||
* Returns a list of of MapWaypoint objects for the given list of
|
||||
* datamodel.Waypoint objects.
|
||||
*
|
||||
*
|
||||
* @param dmWaypoints
|
||||
*
|
||||
* @return List of MapWaypoint objects. List will be empty if dmWaypoints was
|
||||
* empty or null.
|
||||
*
|
||||
* @return List of MapWaypoint objects. List will be empty if dmWaypoints
|
||||
* was empty or null.
|
||||
*/
|
||||
static List<MapWaypoint> getWaypoints(List<Waypoint> dmWaypoints) {
|
||||
List<MapWaypoint> mapPoints = new ArrayList<>();
|
||||
|
||||
if (dmWaypoints != null) {
|
||||
|
||||
|
||||
for (Waypoint point : dmWaypoints) {
|
||||
mapPoints.add(new MapWaypoint(point));
|
||||
}
|
||||
@ -118,6 +118,27 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
||||
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.
|
||||
*
|
||||
@ -271,20 +292,20 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
||||
}
|
||||
return menuItems;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Get the nicely formatted details for the given waypoint.
|
||||
*
|
||||
* @param point Waypoint object
|
||||
*
|
||||
* @param point Waypoint object
|
||||
* @param header String details header
|
||||
*
|
||||
* @return HTML formatted String of details for given waypoint
|
||||
*
|
||||
* @return HTML formatted String of details for given waypoint
|
||||
*/
|
||||
private String getFormattedDetails(Waypoint point) {
|
||||
StringBuilder result = new StringBuilder(); //NON-NLS
|
||||
|
||||
|
||||
result.append("<html>").append(formatAttribute("Name", point.getLabel()));
|
||||
|
||||
|
||||
Long timestamp = point.getTimestamp();
|
||||
if (timestamp != null) {
|
||||
result.append(formatAttribute("Timestamp", getTimeStamp(timestamp)));
|
||||
@ -292,19 +313,19 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
||||
|
||||
result.append(formatAttribute("Latitude", point.getLatitude().toString()))
|
||||
.append(formatAttribute("Longitude", point.getLongitude().toString()));
|
||||
|
||||
|
||||
if (point.getAltitude() != null) {
|
||||
result.append(formatAttribute("Altitude", point.getAltitude().toString()));
|
||||
}
|
||||
|
||||
List<Waypoint.Property> list = point.getOtherProperties();
|
||||
for(Waypoint.Property prop: list) {
|
||||
for (Waypoint.Property prop : list) {
|
||||
String value = prop.getValue();
|
||||
if(value != null && !value.isEmpty()) {
|
||||
if (value != null && !value.isEmpty()) {
|
||||
result.append(formatAttribute(prop.getDisplayName(), value));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
result.append("</html>");
|
||||
|
||||
return result.toString();
|
||||
@ -312,16 +333,16 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
||||
|
||||
/**
|
||||
* Format a title value pair.
|
||||
*
|
||||
*
|
||||
* @param title Title of the property
|
||||
* @param value Value of the property
|
||||
*
|
||||
* @return Formatted string with the title and value
|
||||
*
|
||||
* @return Formatted string with the title and value
|
||||
*/
|
||||
private String formatAttribute(String title, String value) {
|
||||
return String.format(HTML_PROP_FORMAT, title, value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Format a point time stamp (in seconds) to the report format.
|
||||
*
|
||||
@ -333,7 +354,6 @@ final class MapWaypoint extends KdTree.XYZPoint implements org.jxmapviewer.viewe
|
||||
return DATE_FORMAT.format(new java.util.Date(timeStamp * 1000));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* This is a list of attributes that are already being handled by the
|
||||
* by getter functions.
|
||||
* This is a list of attributes that are already being handled by the by
|
||||
* 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_GEO_LONGITUDE,
|
||||
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_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.
|
||||
*
|
||||
@ -110,25 +97,6 @@ public class Waypoint {
|
||||
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.
|
||||
*
|
||||
@ -205,11 +173,12 @@ public class Waypoint {
|
||||
public List<Waypoint.Property> getOtherProperties() {
|
||||
return immutablePropertiesList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
return route;
|
||||
|
@ -45,7 +45,7 @@ public final class WaypointBuilder {
|
||||
= "SELECT artifact_id, artifact_type_id "
|
||||
+ "FROM blackboard_attributes "
|
||||
+ "WHERE attribute_type_id IN (%d, %d) "; //NON-NLS
|
||||
|
||||
|
||||
// SELECT statement to get only artifact_ids
|
||||
final static String GEO_ARTIFACT_QUERY_ID_ONLY
|
||||
= "SELECT artifact_id "
|
||||
@ -70,8 +70,8 @@ public final class WaypointBuilder {
|
||||
+ " )";
|
||||
|
||||
// Returns a list of artifacts with no time stamp
|
||||
final static String SELECT_WO_TIMESTAMP =
|
||||
"SELECT DISTINCT artifact_id, artifact_type_id "
|
||||
final static String SELECT_WO_TIMESTAMP
|
||||
= "SELECT DISTINCT artifact_id, artifact_type_id "
|
||||
+ "FROM blackboard_attributes "
|
||||
+ "WHERE artifact_id NOT IN (%s) "
|
||||
+ "AND artifact_id IN (%s)"; //NON-NLS
|
||||
@ -121,6 +121,25 @@ public final class WaypointBuilder {
|
||||
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.
|
||||
*
|
||||
@ -150,6 +169,25 @@ public final class WaypointBuilder {
|
||||
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.
|
||||
*
|
||||
@ -183,6 +221,25 @@ public final class WaypointBuilder {
|
||||
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.
|
||||
*
|
||||
@ -214,6 +271,25 @@ public final class WaypointBuilder {
|
||||
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.
|
||||
*
|
||||
@ -245,6 +321,26 @@ public final class WaypointBuilder {
|
||||
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.
|
||||
*
|
||||
@ -266,7 +362,7 @@ public final class WaypointBuilder {
|
||||
if (artifacts != null) {
|
||||
for (BlackboardArtifact artifact : artifacts) {
|
||||
try {
|
||||
Waypoint point = new Waypoint(artifact);
|
||||
Waypoint point = new BookmarkWaypoint(artifact);
|
||||
points.add(point);
|
||||
} 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
|
||||
@ -276,6 +372,26 @@ public final class WaypointBuilder {
|
||||
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.
|
||||
*
|
||||
@ -386,7 +502,7 @@ public final class WaypointBuilder {
|
||||
String mostRecentQuery = "";
|
||||
|
||||
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,
|
||||
cntDaysFromRecent,
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME.getTypeID(),
|
||||
@ -464,7 +580,7 @@ public final class WaypointBuilder {
|
||||
waypoints.add(new EXIFWaypoint(artifact));
|
||||
break;
|
||||
case TSK_GPS_BOOKMARK:
|
||||
waypoints.add(new Waypoint(artifact));
|
||||
waypoints.add(new BookmarkWaypoint(artifact));
|
||||
break;
|
||||
case TSK_GPS_TRACKPOINT:
|
||||
waypoints.add(new TrackpointWaypoint(artifact));
|
||||
@ -477,8 +593,7 @@ public final class WaypointBuilder {
|
||||
waypoints.addAll(route.getRoute());
|
||||
break;
|
||||
default:
|
||||
waypoints.add(new Waypoint(artifact));
|
||||
break;
|
||||
throw new GeoLocationDataException(String.format("Unable to create waypoint for artifact of type %s", type.toString()));
|
||||
}
|
||||
|
||||
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.Paths;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.jdom2.Document;
|
||||
@ -59,7 +60,7 @@ import org.sleuthkit.datamodel.TskCoreException;
|
||||
/**
|
||||
* 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 String KML_STYLE_FILE = "style.kml";
|
||||
@ -79,6 +80,8 @@ class KMLReport implements GeneralReportModule {
|
||||
private Element gpsSearchesFolder;
|
||||
private Element gpsTrackpointsFolder;
|
||||
|
||||
private List<Waypoint> waypointList = null;
|
||||
|
||||
private enum FeatureColor {
|
||||
RED("style.kml#redFeature"),
|
||||
GREEN("style.kml#greenFeature"),
|
||||
@ -141,6 +144,11 @@ class KMLReport implements GeneralReportModule {
|
||||
"Route_Details_Header=GPS Route"
|
||||
})
|
||||
|
||||
public void generateReport(String baseReportDir, ReportProgressPanel progressPanel, List<Waypoint> waypointList) {
|
||||
this.waypointList = waypointList;
|
||||
generateReport(baseReportDir, progressPanel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateReport(String baseReportDir, ReportProgressPanel progressPanel) {
|
||||
try {
|
||||
@ -298,7 +306,7 @@ class KMLReport implements GeneralReportModule {
|
||||
* @throws IOException
|
||||
*/
|
||||
void addExifMetadataContent(List<Waypoint> points, String baseReportDirectory) throws IOException {
|
||||
for(Waypoint point: points) {
|
||||
for (Waypoint point : points) {
|
||||
Element mapPoint = makePoint(point);
|
||||
if (mapPoint == null) {
|
||||
return;
|
||||
@ -332,41 +340,49 @@ class KMLReport implements GeneralReportModule {
|
||||
* @throws IOException
|
||||
*/
|
||||
void addLocationsToReport(SleuthkitCase skCase, String baseReportDir) throws GeoLocationDataException, IOException {
|
||||
addExifMetadataContent(WaypointBuilder.getEXIFWaypoints(skCase), baseReportDir);
|
||||
addWaypoints(WaypointBuilder.getBookmarkWaypoints(skCase), gpsBookmarksFolder, FeatureColor.BLUE, Bundle.Waypoint_Bookmark_Display_String());
|
||||
addWaypoints(WaypointBuilder.getLastKnownWaypoints(skCase), gpsLastKnownLocationFolder, FeatureColor.PURPLE, Bundle.Waypoint_Last_Known_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());
|
||||
if (waypointList == null) {
|
||||
addExifMetadataContent(WaypointBuilder.getEXIFWaypoints(skCase), baseReportDir);
|
||||
addWaypoints(WaypointBuilder.getBookmarkWaypoints(skCase), gpsBookmarksFolder, FeatureColor.BLUE, Bundle.Waypoint_Bookmark_Display_String());
|
||||
addWaypoints(WaypointBuilder.getLastKnownWaypoints(skCase), gpsLastKnownLocationFolder, FeatureColor.PURPLE, Bundle.Waypoint_Last_Known_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
|
||||
* is created and added it to the given Element folder.
|
||||
*
|
||||
* @param points List of waypoints to add to the report
|
||||
* @param folder The Element folder to add the points to
|
||||
* For each point in the waypoint list an Element to represent the given
|
||||
* waypoint is created and added it to the given Element folder.
|
||||
*
|
||||
* @param points List of waypoints to add to the report
|
||||
* @param folder The Element folder to add the points to
|
||||
* @param waypointColor The color the waypoint should appear in the report
|
||||
*/
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds the waypoint Element with details to the report in the given folder.
|
||||
*
|
||||
* @param folder Element folder to add the waypoint to
|
||||
* @param waypointLabel String waypoint Label
|
||||
* @param waypointColor FeatureColor for the waypoint
|
||||
*
|
||||
* @param folder Element folder to add the waypoint to
|
||||
* @param waypointLabel String waypoint Label
|
||||
* @param waypointColor FeatureColor for the waypoint
|
||||
* @param formattedDetails String HTML formatted waypoint details
|
||||
* @param timestamp Long timestamp (unix\jave epoch seconds)
|
||||
* @param point Element point object
|
||||
* @param latitude Double latitude value
|
||||
* @param longitude Double longitude value
|
||||
* @param timestamp Long timestamp (unix\jave epoch seconds)
|
||||
* @param point Element point object
|
||||
* @param latitude Double latitude value
|
||||
* @param longitude Double longitude value
|
||||
*/
|
||||
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);
|
||||
folder.addContent(makePlacemark(waypointLabel, waypointColor, formattedDetails, timestamp, point, formattedCords));
|
||||
}
|
||||
@ -380,17 +396,19 @@ class KMLReport implements GeneralReportModule {
|
||||
* @throws TskCoreException
|
||||
*/
|
||||
void makeRoutes(SleuthkitCase skCase) throws GeoLocationDataException {
|
||||
List<Route> routes = Route.getRoutes(skCase);
|
||||
|
||||
if(routes == null) {
|
||||
return;
|
||||
List<Route> routes = null;
|
||||
|
||||
if (waypointList == null) {
|
||||
routes = Route.getRoutes(skCase);
|
||||
} else {
|
||||
routes = new ArrayList<>();
|
||||
}
|
||||
|
||||
for (Route route : routes) {
|
||||
addRouteToReport(route);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void addRouteToReport(Route route) {
|
||||
List<Waypoint> routePoints = route.getRoute();
|
||||
Waypoint start = null;
|
||||
@ -423,15 +441,15 @@ class KMLReport implements GeneralReportModule {
|
||||
}
|
||||
|
||||
if (startingPoint != null) {
|
||||
gpsRouteFolder.addContent(makePlacemark(start.getLabel(),
|
||||
FeatureColor.GREEN, getFormattedDetails(start, Bundle.Waypoint_Route_Point_Display_String()),
|
||||
gpsRouteFolder.addContent(makePlacemark(start.getLabel(),
|
||||
FeatureColor.GREEN, getFormattedDetails(start, Bundle.Waypoint_Route_Point_Display_String()),
|
||||
start.getTimestamp(), startingPoint, formattedStart)); //NON-NLS
|
||||
}
|
||||
|
||||
if (endingPoint != null) {
|
||||
gpsRouteFolder.addContent(makePlacemark(end.getLabel(),
|
||||
FeatureColor.GREEN,
|
||||
getFormattedDetails(end, Bundle.Waypoint_Route_Point_Display_String()),
|
||||
gpsRouteFolder.addContent(makePlacemark(end.getLabel(),
|
||||
FeatureColor.GREEN,
|
||||
getFormattedDetails(end, Bundle.Waypoint_Route_Point_Display_String()),
|
||||
end.getTimestamp(), endingPoint, formattedEnd)); //NON-NLS
|
||||
}
|
||||
}
|
||||
@ -688,11 +706,11 @@ class KMLReport implements GeneralReportModule {
|
||||
|
||||
/**
|
||||
* Get the nicely formatted details for the given waypoint.
|
||||
*
|
||||
* @param point Waypoint object
|
||||
*
|
||||
* @param point Waypoint object
|
||||
* @param header String details header
|
||||
*
|
||||
* @return HTML formatted String of details for given waypoint
|
||||
*
|
||||
* @return HTML formatted String of details for given waypoint
|
||||
*/
|
||||
private String getFormattedDetails(Waypoint point, String header) {
|
||||
StringBuilder result = new StringBuilder(); //NON-NLS
|
||||
@ -706,15 +724,15 @@ class KMLReport implements GeneralReportModule {
|
||||
|
||||
result.append(formatAttribute("Latitude", point.getLatitude().toString()))
|
||||
.append(formatAttribute("Longitude", point.getLongitude().toString()));
|
||||
|
||||
|
||||
if (point.getAltitude() != null) {
|
||||
result.append(formatAttribute("Altitude", point.getAltitude().toString()));
|
||||
}
|
||||
|
||||
List<Waypoint.Property> list = point.getOtherProperties();
|
||||
for(Waypoint.Property prop: list) {
|
||||
for (Waypoint.Property prop : list) {
|
||||
String value = prop.getValue();
|
||||
if(value != null && !value.isEmpty()) {
|
||||
if (value != null && !value.isEmpty()) {
|
||||
result.append(formatAttribute(prop.getDisplayName(), value));
|
||||
}
|
||||
}
|
||||
@ -733,8 +751,7 @@ class KMLReport implements GeneralReportModule {
|
||||
*
|
||||
* @return A HTML formatted list of the Route attributes
|
||||
*/
|
||||
|
||||
private String getFormattedDetails(Route route) {
|
||||
private String getFormattedDetails(Route route) {
|
||||
List<Waypoint> points = route.getRoute();
|
||||
StringBuilder result = new StringBuilder(); //NON-NLS
|
||||
|
||||
@ -752,38 +769,38 @@ class KMLReport implements GeneralReportModule {
|
||||
|
||||
result.append(formatAttribute("Start Latitude", start.getLatitude().toString()))
|
||||
.append(formatAttribute("Start Longitude", start.getLongitude().toString()));
|
||||
|
||||
|
||||
Double altitude = start.getAltitude();
|
||||
if(altitude != null) {
|
||||
if (altitude != null) {
|
||||
result.append(formatAttribute("Start Altitude", altitude.toString()));
|
||||
}
|
||||
|
||||
|
||||
result.append(formatAttribute("End Latitude", end.getLatitude().toString()))
|
||||
.append(formatAttribute("End Longitude", end.getLongitude().toString()));
|
||||
|
||||
|
||||
altitude = end.getAltitude();
|
||||
if(altitude != null) {
|
||||
if (altitude != null) {
|
||||
result.append(formatAttribute("End Altitude", altitude.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
List<Waypoint.Property> list = route.getOtherProperties();
|
||||
for(Waypoint.Property prop: list) {
|
||||
for (Waypoint.Property prop : list) {
|
||||
String value = prop.getValue();
|
||||
if(value != null && !value.isEmpty()) {
|
||||
if (value != null && !value.isEmpty()) {
|
||||
result.append(formatAttribute(prop.getDisplayName(), value));
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper functions for consistently formatting longitude and latitude.
|
||||
*
|
||||
* @param latitude Double latitude value
|
||||
*
|
||||
* @param latitude Double latitude value
|
||||
* @param longitude Double longitude value
|
||||
*
|
||||
*
|
||||
* @return String Nicely formatted double values separated by a comma
|
||||
*/
|
||||
private String formattedCoordinates(Double latitude, Double longitude) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user