20 package org.sleuthkit.autopsy.report.modules.kml;
23 import javax.swing.JPanel;
24 import org.openide.util.NbBundle;
29 import java.io.FileOutputStream;
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import java.nio.file.Path;
34 import java.nio.file.Paths;
35 import java.text.SimpleDateFormat;
36 import java.util.List;
37 import java.util.logging.Level;
38 import java.util.stream.Collectors;
39 import org.jdom2.Document;
40 import org.jdom2.Element;
41 import org.jdom2.Namespace;
42 import org.jdom2.output.Format;
43 import org.jdom2.output.XMLOutputter;
44 import org.jdom2.CDATA;
45 import org.openide.filesystems.FileUtil;
46 import org.openide.util.NbBundle.Messages;
61 import org.
sleuthkit.datamodel.ReadContentInputStream.ReadContentInputStreamException;
72 private static final String
REPORT_KML =
"ReportKML.kml";
73 private static final String
STYLESHEETS_PATH =
"/org/sleuthkit/autopsy/report/stylesheets/";
77 private final SimpleDateFormat
kmlDateFormat =
new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ssX");
95 RED(
"style.kml#redFeature"),
96 GREEN(
"style.kml#greenFeature"),
97 BLUE(
"style.kml#blueFeature"),
99 WHITE(
"style.kml#whiteFeature"),
118 if (instance == null) {
132 "KMLReport.failedToCompleteReport=Failed to complete report.",
133 "KMLReport.partialFailure=There was an error creating the report. Some items were not exported.",
134 "KMLReport.unableToExtractPhotos=Could not extract photo information.",
135 "KMLReport.exifPhotoError=Could not extract photos with EXIF metadata.",
136 "KMLReport.bookmarkError=Could not extract Bookmark information.",
137 "KMLReport.gpsBookmarkError=Could not get GPS Bookmarks from database.",
138 "KMLReport.locationError=Could not extract Last Known Location information.",
139 "KMLReport.locationDatabaseError=Could not get GPS Last Known Location from database.",
140 "KMLReport.gpsRouteError=Could not extract GPS Route information.",
141 "KMLReport.gpsRouteDatabaseError=Could not get GPS Routes from database.",
142 "KMLReport.gpsSearchDatabaseError=Could not get GPS Searches from database.",
143 "KMLReport.trackpointError=Could not extract Trackpoint information.",
144 "KMLReport.trackpointDatabaseError=Could not get GPS Trackpoints from database.",
145 "KMLReport.stylesheetError=Error placing KML stylesheet. The .KML file will not function properly.",
146 "KMLReport.kmlFileWriteError=Could not write the KML file.",
148 "KMLReport.errorGeneratingReport=Error adding {0} to case as a report.",
149 "KMLReport.unableToOpenCase=Exception while getting open case.",
150 "Waypoint_Bookmark_Display_String=GPS Bookmark",
151 "Waypoint_Last_Known_Display_String=GPS Last Known Location",
152 "Waypoint_EXIF_Display_String=EXIF Metadata With Location",
153 "Waypoint_Route_Point_Display_String=GPS Individual Route Point",
154 "Waypoint_Search_Display_String=GPS Search",
155 "Waypoint_Trackpoint_Display_String=GPS Trackpoint",
156 "Waypoint_Track_Display_String=GPS Track",
157 "Route_Details_Header=GPS Route",
158 "ReportBodyFile.ingestWarning.text=Ingest Warning message",
159 "Waypoint_Track_Point_Display_String=GPS Individual Track Point",
160 "Waypoint_Area_Point_Display_String=GPS Area Outline Point",
180 logger.log(Level.SEVERE,
"Exception while getting open case.", ex);
190 .collect(Collectors.toList());
192 }
catch (TskCoreException ex) {
193 logger.log(Level.SEVERE,
"Could not get the datasources from the case", ex);
202 progressPanel.
start();
203 progressPanel.
updateStatusLabel(NbBundle.getMessage(
this.getClass(),
"ReportKML.progress.querying"));
204 String kmlFileFullPath = baseReportDir +
REPORT_KML;
205 String errorMessage =
"";
209 progressPanel.
updateStatusLabel(NbBundle.getMessage(
this.getClass(),
"ReportKML.progress.loading"));
217 boolean entirelySuccessful = makeTracks(skCase);
218 if (!entirelySuccessful) {
220 errorMessage = Bundle.KMLReport_partialFailure();
222 entirelySuccessful = makeAreas(skCase);
223 if (!entirelySuccessful) {
225 errorMessage = Bundle.KMLReport_partialFailure();
228 addLocationsToReport(skCase, baseReportDir);
230 errorMessage = Bundle.KMLReport_failedToCompleteReport();
231 logger.log(Level.SEVERE, errorMessage, ex);
237 InputStream input = getClass().getResourceAsStream(STYLESHEETS_PATH + KML_STYLE_FILE);
238 OutputStream output =
new FileOutputStream(baseReportDir + KML_STYLE_FILE);
239 FileUtil.copy(input, output);
240 }
catch (IOException ex) {
241 errorMessage = Bundle.KMLReport_stylesheetError();
242 logger.log(Level.SEVERE, errorMessage, ex);
246 try (FileOutputStream writer =
new FileOutputStream(kmlFileFullPath)) {
247 XMLOutputter outputter =
new XMLOutputter(Format.getPrettyFormat());
248 outputter.output(kmlDocument, writer);
249 String prependedStatus =
"";
251 prependedStatus =
"Incomplete ";
254 NbBundle.getMessage(
this.getClass(),
"ReportKML.genReport.srcModuleName.text"),
255 prependedStatus + NbBundle.getMessage(
this.getClass(),
"ReportKML.genReport.reportName"));
256 }
catch (IOException ex) {
257 errorMessage = Bundle.KMLReport_kmlFileWriteError();
258 logger.log(Level.SEVERE, errorMessage, ex);
260 }
catch (TskCoreException ex) {
261 errorMessage = Bundle.KMLReport_errorGeneratingReport(kmlFileFullPath);
262 logger.log(Level.SEVERE, errorMessage, ex);
265 errorMessage = Bundle.KMLReport_unableToOpenCase();
266 logger.log(Level.SEVERE, errorMessage, ex);
270 progressPanel.
complete(result, errorMessage);
279 ns = Namespace.getNamespace(
"",
"http://www.opengis.net/kml/2.2");
281 Element kml =
new Element(
"kml", ns);
282 kml.addNamespaceDeclaration(Namespace.getNamespace(
"gx",
"http://www.google.com/kml/ext/2.2"));
283 kml.addNamespaceDeclaration(Namespace.getNamespace(
"kml",
"http://www.opengis.net/kml/2.2"));
284 kml.addNamespaceDeclaration(Namespace.getNamespace(
"atom",
"http://www.w3.org/2005/Atom"));
285 Document kmlDocument =
new Document(kml);
287 Element document =
new Element(
"Document", ns);
288 kml.addContent(document);
290 Element name =
new Element(
"name", ns);
293 document.addContent(name);
297 Element ingestwarning =
new Element(
"snippet", ns);
298 ingestwarning.addContent(NbBundle.getMessage(
this.getClass(),
"ReportBodyFile.ingestWarning.text"));
299 document.addContent(ingestwarning);
303 gpsExifMetadataFolder =
new Element(
"Folder", ns);
304 CDATA cdataExifMetadataFolder =
new CDATA(
"https://raw.githubusercontent.com/sleuthkit/autopsy/develop/Core/src/org/sleuthkit/autopsy/images/camera-icon-16.png");
305 Element hrefExifMetadata =
new Element(
"href", ns).addContent(cdataExifMetadataFolder);
306 gpsExifMetadataFolder.addContent(
new Element(
"Icon", ns).addContent(hrefExifMetadata));
308 gpsBookmarksFolder =
new Element(
"Folder", ns);
309 CDATA cdataBookmarks =
new CDATA(
"https://raw.githubusercontent.com/sleuthkit/autopsy/develop/Core/src/org/sleuthkit/autopsy/images/gpsfav.png");
310 Element hrefBookmarks =
new Element(
"href", ns).addContent(cdataBookmarks);
311 gpsBookmarksFolder.addContent(
new Element(
"Icon", ns).addContent(hrefBookmarks));
313 gpsLastKnownLocationFolder =
new Element(
"Folder", ns);
314 CDATA cdataLastKnownLocation =
new CDATA(
"https://raw.githubusercontent.com/sleuthkit/autopsy/develop/Core/src/org/sleuthkit/autopsy/images/gps-lastlocation.png");
315 Element hrefLastKnownLocation =
new Element(
"href", ns).addContent(cdataLastKnownLocation);
316 gpsLastKnownLocationFolder.addContent(
new Element(
"Icon", ns).addContent(hrefLastKnownLocation));
318 gpsRouteFolder =
new Element(
"Folder", ns);
319 CDATA cdataRoute =
new CDATA(
"https://raw.githubusercontent.com/sleuthkit/autopsy/develop/Core/src/org/sleuthkit/autopsy/images/gps-trackpoint.png");
320 Element hrefRoute =
new Element(
"href", ns).addContent(cdataRoute);
321 gpsRouteFolder.addContent(
new Element(
"Icon", ns).addContent(hrefRoute));
323 gpsSearchesFolder =
new Element(
"Folder", ns);
324 CDATA cdataSearches =
new CDATA(
"https://raw.githubusercontent.com/sleuthkit/autopsy/develop/Core/src/org/sleuthkit/autopsy/images/gps-search.png");
325 Element hrefSearches =
new Element(
"href", ns).addContent(cdataSearches);
326 gpsSearchesFolder.addContent(
new Element(
"Icon", ns).addContent(hrefSearches));
328 gpsTrackpointsFolder =
new Element(
"Folder", ns);
329 CDATA cdataTrackpoints =
new CDATA(
"https://raw.githubusercontent.com/sleuthkit/autopsy/develop/Core/src/org/sleuthkit/autopsy/images/gps-trackpoint.png");
330 Element hrefTrackpoints =
new Element(
"href", ns).addContent(cdataTrackpoints);
331 gpsTrackpointsFolder.addContent(
new Element(
"Icon", ns).addContent(hrefTrackpoints));
333 gpsTracksFolder =
new Element(
"Folder", ns);
334 CDATA cdataTrack =
new CDATA(
"https://raw.githubusercontent.com/sleuthkit/autopsy/develop/Core/src/org/sleuthkit/autopsy/images/gps-trackpoint.png");
335 Element hrefTrack =
new Element(
"href", ns).addContent(cdataTrack);
336 gpsTracksFolder.addContent(
new Element(
"Icon", ns).addContent(hrefTrack));
338 gpsAreasFolder =
new Element(
"Folder", ns);
339 CDATA cdataArea =
new CDATA(
"https://raw.githubusercontent.com/sleuthkit/autopsy/develop/Core/src/org/sleuthkit/autopsy/images/gps-area.png");
340 Element hrefArea =
new Element(
"href", ns).addContent(cdataArea);
341 gpsAreasFolder.addContent(
new Element(
"Icon", ns).addContent(hrefArea));
343 gpsExifMetadataFolder.addContent(
new Element(
"name", ns).addContent(
"EXIF Metadata"));
344 gpsBookmarksFolder.addContent(
new Element(
"name", ns).addContent(
"GPS Bookmarks"));
345 gpsLastKnownLocationFolder.addContent(
new Element(
"name", ns).addContent(
"GPS Last Known Location"));
346 gpsRouteFolder.addContent(
new Element(
"name", ns).addContent(
"GPS Routes"));
347 gpsSearchesFolder.addContent(
new Element(
"name", ns).addContent(
"GPS Searches"));
348 gpsTrackpointsFolder.addContent(
new Element(
"name", ns).addContent(
"GPS Trackpoints"));
349 gpsTracksFolder.addContent(
new Element(
"name", ns).addContent(
"GPS Tracks"));
350 gpsAreasFolder.addContent(
new Element(
"name", ns).addContent(
"GPS Areas"));
352 document.addContent(gpsExifMetadataFolder);
353 document.addContent(gpsBookmarksFolder);
354 document.addContent(gpsLastKnownLocationFolder);
355 document.addContent(gpsRouteFolder);
356 document.addContent(gpsSearchesFolder);
357 document.addContent(gpsTrackpointsFolder);
358 document.addContent(gpsTracksFolder);
359 document.addContent(gpsAreasFolder);
373 void addExifMetadataContent(List<Waypoint> points, String baseReportDirectory)
throws IOException, TskCoreException {
380 if (mapPoint == null) {
384 AbstractFile abstractFile = point.getImage();
388 copyFileUsingStream(abstractFile, Paths.get(baseReportDirectory, abstractFile.getName()).toFile());
391 }
catch (TskCoreException ex) {
392 path = Paths.get(abstractFile.getParentPath(), abstractFile.getName());
395 path = Paths.get(abstractFile.getName());
411 void addLocationsToReport(SleuthkitCase skCase, String baseReportDir)
throws GeoLocationDataException, IOException, TskCoreException {
412 if (waypointList == null) {
413 addExifMetadataContent(WaypointBuilder.getEXIFWaypoints(skCase), baseReportDir);
414 addWaypoints(WaypointBuilder.getBookmarkWaypoints(skCase),
gpsBookmarksFolder, FeatureColor.BLUE, Bundle.Waypoint_Bookmark_Display_String());
415 addWaypoints(WaypointBuilder.getLastKnownWaypoints(skCase),
gpsLastKnownLocationFolder, FeatureColor.PURPLE, Bundle.Waypoint_Last_Known_Display_String());
416 addWaypoints(WaypointBuilder.getSearchWaypoints(skCase),
gpsSearchesFolder, FeatureColor.WHITE, Bundle.Waypoint_Search_Display_String());
417 addWaypoints(WaypointBuilder.getTrackpointWaypoints(skCase),
gpsTrackpointsFolder, FeatureColor.WHITE, Bundle.Waypoint_Trackpoint_Display_String());
419 addExifMetadataContent(WaypointBuilder.getEXIFWaypoints(waypointList), baseReportDir);
420 addWaypoints(WaypointBuilder.getBookmarkWaypoints(waypointList),
gpsBookmarksFolder, FeatureColor.BLUE, Bundle.Waypoint_Bookmark_Display_String());
421 addWaypoints(WaypointBuilder.getLastKnownWaypoints(waypointList),
gpsLastKnownLocationFolder, FeatureColor.PURPLE, Bundle.Waypoint_Last_Known_Display_String());
422 addWaypoints(WaypointBuilder.getSearchWaypoints(waypointList),
gpsSearchesFolder, FeatureColor.WHITE, Bundle.Waypoint_Search_Display_String());
423 addWaypoints(WaypointBuilder.getTrackpointWaypoints(waypointList),
gpsTrackpointsFolder, FeatureColor.WHITE, Bundle.Waypoint_Trackpoint_Display_String());
435 void addWaypoints(List<Waypoint> points, Element folder, FeatureColor waypointColor, String headerLabel)
throws TskCoreException {
436 for (Waypoint point : points) {
440 addContent(folder, point.getLabel(), waypointColor,
getFormattedDetails(point, headerLabel), point.getTimestamp(),
makePoint(point), point.getLatitude(), point.getLongitude());
456 void addContent(Element folder, String waypointLabel, FeatureColor waypointColor, String formattedDetails, Long timestamp, Element point, Double latitude, Double longitude) {
457 if (folder != null && point != null) {
459 folder.addContent(
makePlacemark(waypointLabel, waypointColor, formattedDetails, timestamp, point, formattedCords));
470 void makeRoutes(SleuthkitCase skCase)
throws GeoLocationDataException, TskCoreException {
471 List<Route> routes = null;
473 if (waypointList == null) {
474 routes = Route.getRoutes(skCase);
476 routes = WaypointBuilder.getRoutes(waypointList);
479 for (Route route : routes) {
493 List<Waypoint> routePoints = route.
getRoute();
501 if (routePoints != null && routePoints.size() > 1) {
502 start = routePoints.get(0);
503 end = routePoints.get(1);
506 if (start == null || end == null) {
519 if (reportRoute != null) {
523 if (startingPoint != null) {
529 if (endingPoint != null) {
545 boolean makeTracks(SleuthkitCase skCase)
throws GeoLocationDataException, TskCoreException {
546 List<Track> tracks = null;
547 boolean successful =
true;
549 if (waypointList == null) {
554 tracks = WaypointBuilder.getTracks(waypointList);
557 for (Track track : tracks) {
573 List<Waypoint> trackPoints = track.
getPath();
577 Element trackFolder =
new Element(
"Folder", ns);
578 trackFolder.addContent(
new Element(
"name", ns).addContent(track.
getLabel()));
579 gpsTracksFolder.addContent(trackFolder);
581 for (
Waypoint point : trackPoints) {
582 Element element =
makePoint(point.getLatitude(), point.getLongitude(), point.getAltitude());
585 point.getTimestamp(), element,
formattedCoordinates(point.getLatitude(), point.getLongitude())));
597 boolean makeAreas(SleuthkitCase skCase)
throws GeoLocationDataException, TskCoreException {
599 boolean successful =
true;
601 if (waypointList == null) {
606 areas = WaypointBuilder.getAreas(waypointList);
609 for (Area area : areas) {
625 List<Waypoint> areaPoints = area.
getPath();
627 if (areaPoints.isEmpty()) {
633 Element areaFolder =
new Element(
"Folder", ns);
634 areaFolder.addContent(
new Element(
"name", ns).addContent(area.
getLabel()));
635 gpsAreasFolder.addContent(areaFolder);
639 Waypoint firstWp = areaPoints.get(0);
653 return kmlDateFormat.format(
new java.util.Date(timeStamp * 1000));
678 private Element
makePoint(Double latitude, Double longitude, Double altitude) {
679 if (latitude == null || longitude == null) {
683 Element point =
new Element(
"Point", ns);
686 Element coordinates =
new Element(
"coordinates", ns).addContent(longitude +
"," + latitude +
"," + (altitude != null ? altitude : 0.0));
688 if (altitude != null && altitude != 0) {
696 Element altitudeMode =
new Element(
"altitudeMode", ns).addContent(
"clampToGround");
697 point.addContent(altitudeMode);
699 point.addContent(coordinates);
720 private Element
makeLineString(Double startLatitude, Double startLongitude, Double stopLatitude, Double stopLongitude) {
721 if (startLatitude == null || startLongitude == null || stopLatitude == null || stopLongitude == null) {
725 Element lineString =
new Element(
"LineString", ns);
726 lineString.addContent(
new Element(
"extrude", ns).addContent(
"1"));
727 lineString.addContent(
new Element(
"tessellate", ns).addContent(
"1"));
728 lineString.addContent(
new Element(
"altitudeMode", ns).addContent(
"clampToGround"));
730 lineString.addContent(
new Element(
"coordinates", ns).addContent(
731 startLongitude +
"," + startLatitude +
",0.0,"
732 + stopLongitude +
"," + stopLatitude +
",0.0"));
745 Element polygon =
new Element(
"Polygon", ns);
747 Element altitudeMode =
new Element(
"altitudeMode", ns).addContent(
"clampToGround");
748 polygon.addContent(altitudeMode);
751 Element coordinates =
new Element(
"coordinates", ns);
753 coordinates.addContent(wp.getLongitude() +
"," + wp.getLatitude() +
",0 ");
756 coordinates.addContent(waypoints.get(0).getLongitude() +
"," + waypoints.get(0).getLatitude() +
",0 ");
758 Element linearRing =
new Element(
"LinearRing", ns).addContent(coordinates);
759 Element outerBoundary =
new Element(
"outerBoundaryIs", ns).addContent(linearRing);
760 polygon.addContent(outerBoundary);
779 private Element
makePlacemark(String name,
FeatureColor color, String description, Long timestamp, Element feature, String coordinates) {
780 Element placemark =
new Element(
"Placemark", ns);
781 if (name != null && !name.isEmpty()) {
782 placemark.addContent(
new Element(
"name", ns).addContent(name));
783 }
else if (timestamp != null) {
784 placemark.addContent(
new Element(
"name", ns).addContent(
getTimeStamp(timestamp)));
786 placemark.addContent(
new Element(
"name", ns).addContent(
""));
788 placemark.addContent(
new Element(
"styleUrl", ns).addContent(color.
getColor()));
789 placemark.addContent(
new Element(
"description", ns).addContent(description));
790 if (timestamp != null) {
791 Element time =
new Element(
"TimeStamp", ns);
792 time.addContent(
new Element(
"when", ns).addContent(
getTimeStamp(timestamp)));
793 placemark.addContent(time);
795 placemark.addContent(feature);
796 if (coordinates != null && !coordinates.isEmpty()) {
797 placemark.addContent(
new Element(
"snippet", ns).addContent(coordinates));
818 Element placemark =
new Element(
"Placemark", ns);
819 Element desc =
new Element(
"description", ns);
820 if (name != null && !name.isEmpty()) {
821 placemark.addContent(
new Element(
"name", ns).addContent(name));
822 String image =
"<img src='" + name +
"' width='400'/>";
823 desc.addContent(image);
825 placemark.addContent(
new Element(
"styleUrl", ns).addContent(color.
getColor()));
827 String pathAsString = path.toString();
828 if (pathAsString != null && !pathAsString.isEmpty()) {
829 desc.addContent(description +
"<b>Source Path:</b> " + pathAsString);
832 placemark.addContent(desc);
834 if (timestamp != null) {
835 Element time =
new Element(
"TimeStamp", ns);
836 time.addContent(
new Element(
"when", ns).addContent(
getTimeStamp(timestamp)));
837 placemark.addContent(time);
839 placemark.addContent(feature);
840 if (coordinates != null && !coordinates.isEmpty()) {
841 placemark.addContent(
new Element(
"snippet", ns).addContent(coordinates));
856 private void copyFileUsingStream(AbstractFile inputFile, File outputFile)
throws ReadContentInputStreamException, IOException {
857 byte[] buffer =
new byte[65536];
859 outputFile.createNewFile();
860 try (InputStream is =
new ReadContentInputStream(inputFile);
861 OutputStream os =
new FileOutputStream(outputFile)) {
862 while ((length = is.read(buffer)) != -1) {
863 os.write(buffer, 0, length);
870 String name = NbBundle.getMessage(this.getClass(),
"ReportKML.getName.text");
876 return "ReportKML.kml";
881 String desc = NbBundle.getMessage(this.getClass(),
"ReportKML.getDesc.text");
902 String[] pathSegments = uniquePath.replaceFirst(
"^/*",
"").split(
"/");
905 if (pathSegments.length > 0) {
906 pathSegments[0] = pathSegments[0].replaceFirst(
"^img_",
"");
908 if (pathSegments.length > 1) {
909 pathSegments[1] = pathSegments[1].replaceFirst(
"^vol_",
"");
913 StringBuilder strbuf =
new StringBuilder();
914 for (String segment : pathSegments) {
915 if (!segment.isEmpty()) {
916 strbuf.append(
"/").append(segment);
919 return strbuf.toString();
931 StringBuilder result =
new StringBuilder();
932 result.append(String.format(
"<h3>%s</h3>", header))
936 if (timestamp != null) {
949 String value = prop.getValue();
950 if (value != null && !value.isEmpty()) {
955 return result.toString();
967 return String.format(HTML_PROP_FORMAT, title, value);
978 List<Waypoint> points = route.
getRoute();
979 StringBuilder result =
new StringBuilder();
981 result.append(String.format(
"<h3>%s</h3>", Bundle.Route_Details_Header()))
985 if (timestamp != null) {
989 if (points.size() > 1) {
997 if (altitude != null) {
1005 if (altitude != null) {
1012 String value = prop.getValue();
1013 if (value != null && !value.isEmpty()) {
1018 return result.toString();
1030 if (latitude == null || longitude == null) {
1034 return String.format(
"%.2f, %.2f", latitude, longitude);
1044 long dataSourceId = content.getDataSource().getId();
static final String HTML_PROP_FORMAT
List< Content > getDataSources()
boolean shouldFilterFromReport(Content content)
void copyFileUsingStream(AbstractFile inputFile, File outputFile)
Element makeLineString(Double startLatitude, Double startLongitude, Double stopLatitude, Double stopLongitude)
String getRelativeFilePath()
static synchronized IngestManager getInstance()
List< Waypoint > waypointList
List< Waypoint.Property > getOtherProperties()
void generateReport(GeneralReportSettings settings, ReportProgressPanel progressPanel)
String getFormattedDetails(Route route)
void complete(ReportStatus reportStatus)
static GeoLocationParseResult< Track > getTracks(SleuthkitCase skCase, List<?extends Content > sourceList)
Element makePlacemarkWithPicture(String name, FeatureColor color, String description, Long timestamp, Element feature, Path path, String coordinates)
Element makePoint(Double latitude, Double longitude, Double altitude)
boolean isIngestRunning()
Element gpsTrackpointsFolder
Element gpsBookmarksFolder
List< Waypoint > getRoute()
void addReport(String localPath, String srcModuleName, String reportName)
void addAreaToReport(Area area)
void setIndeterminate(boolean indeterminate)
Element makePolygon(List< Waypoint > waypoints)
void addRouteToReport(Route route)
static String removeLeadingImgAndVol(String uniquePath)
void addTrackToReport(Track track)
Element gpsExifMetadataFolder
Document setupReportDocument()
static final String KML_STYLE_FILE
static final Logger logger
static synchronized KMLReport getDefault()
void setReportDirectoryPath(String reportDirectoryPath)
final List< Waypoint > getPath()
List< Waypoint.Property > getOtherProperties()
void generateReport(String baseReportDir, ReportProgressPanel progressPanel, List< Waypoint > waypointList)
SleuthkitCase getSleuthkitCase()
static final String REPORT_KML
FeatureColor(String color)
String formatAttribute(String title, String value)
static KMLReport instance
Element makePlacemark(String name, FeatureColor color, String description, Long timestamp, Element feature, String coordinates)
List< Long > getSelectedDataSources()
Element gpsLastKnownLocationFolder
synchronized static Logger getLogger(String name)
static Case getCurrentCaseThrows()
static GeoLocationParseResult< Area > getAreas(SleuthkitCase skCase, List<?extends Content > sourceList)
void updateStatusLabel(String statusMessage)
Element gpsSearchesFolder
void setSelectedDataSources(List< Long > selectedDataSources)
boolean isSuccessfullyParsed()
String getTimeStamp(long timeStamp)
final SimpleDateFormat kmlDateFormat
boolean supportsDataSourceSelection()
Element makePoint(Waypoint point)
String getFormattedDetails(Waypoint point, String header)
String getReportDirectoryPath()
JPanel getConfigurationPanel()
GeneralReportSettings settings
static final String STYLESHEETS_PATH
String formattedCoordinates(Double latitude, Double longitude)