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;
 
   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());
 
  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); 
 
  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) {
 
  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()))); 
 
  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)); 
 
  857         byte[] buffer = 
new byte[65536];
 
  859         outputFile.createNewFile();
 
  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)