diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/CityRecord.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/CityRecord.java index ac4952674c..d2a1182e6a 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/CityRecord.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/CityRecord.java @@ -28,18 +28,21 @@ public class CityRecord extends KdTree.XYZPoint { private final String cityName; private final String country; + private final String state; /** * Main constructor. * * @param cityName The name of the city. + * @param state The state of the city. * @param country The country of that city. * @param latitude Latitude for the city. * @param longitude Longitude for the city. */ - CityRecord(String cityName, String country, double latitude, double longitude) { + CityRecord(String cityName, String state, String country, double latitude, double longitude) { super(latitude, longitude); this.cityName = cityName; + this.state = state; this.country = country; } @@ -50,6 +53,13 @@ public class CityRecord extends KdTree.XYZPoint { return cityName; } + /** + * @return The state of the city. + */ + public String getState() { + return state; + } + /** * @return The country of that city. */ diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/ClosestCityMapper.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/ClosestCityMapper.java index 13290e3c9a..4427d25f23 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/ClosestCityMapper.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/ClosestCityMapper.java @@ -42,6 +42,7 @@ class ClosestCityMapper { // index within a csv row of pertinent data private static final int CITY_NAME_IDX = 0; + private static final int STATE_NAME_IDX = 7; private static final int COUNTRY_NAME_IDX = 4; private static final int LAT_IDX = 2; private static final int LONG_IDX = 3; @@ -52,7 +53,7 @@ class ClosestCityMapper { // Identifies if cities are in last, first format like "Korea, South" private static final Pattern COUNTRY_WITH_COMMA = Pattern.compile("^\\s*([^,]*)\\s*,\\s*([^,]*)\\s*$"); - private static final int MAX_IDX = Stream.of(CITY_NAME_IDX, COUNTRY_NAME_IDX, LAT_IDX, LONG_IDX) + private static final int MAX_IDX = Stream.of(CITY_NAME_IDX, STATE_NAME_IDX, COUNTRY_NAME_IDX, LAT_IDX, LONG_IDX) .max(Integer::compare) .get(); @@ -169,12 +170,15 @@ class ClosestCityMapper { return null; } + // city is required String cityName = csvRow.get(CITY_NAME_IDX); if (StringUtils.isBlank(cityName)) { logger.log(Level.WARNING, String.format("No city name determined for line %d.", lineNum)); return null; } + // state and country can be optional + String stateName = csvRow.get(STATE_NAME_IDX); String countryName = parseCountryName(csvRow.get(COUNTRY_NAME_IDX), lineNum); Double lattitude = tryParse(csvRow.get(LAT_IDX)); @@ -189,7 +193,7 @@ class ClosestCityMapper { return null; } - return new CityRecord(cityName, countryName, lattitude, longitude); + return new CityRecord(cityName, stateName, countryName, lattitude, longitude); } /** diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/GeolocationSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/GeolocationSummary.java index 4f78e1ece2..046c443e4e 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/GeolocationSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/GeolocationSummary.java @@ -309,7 +309,7 @@ public class GeolocationSummary implements DefaultArtifactUpdateGovernor { Long mostRecent = null; for (MapWaypoint pt : dataSourcePoints) { - CityRecord city = closestCityMapper.findClosest(new CityRecord(null, null, pt.getX(), pt.getY())); + CityRecord city = closestCityMapper.findClosest(new CityRecord(null, null, null, pt.getX(), pt.getY())); Long curTime = pt.getTimestamp(); if (curTime != null && (mostRecent == null || curTime > mostRecent)) { mostRecent = curTime; diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/GeolocationPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/GeolocationPanel.java index 5bf4efceb4..8db1b83272 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/GeolocationPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/GeolocationPanel.java @@ -145,11 +145,19 @@ public class GeolocationPanel extends BaseDataSourceSummaryPanel { return null; } - if (StringUtils.isBlank(record.getCountry())) { - return record.getCityName(); - } + List cityIdentifiers = Stream.of(record.getCityName(), record.getState(), record.getCountry()) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toList()); - return String.format("%s, %s", record.getCityName(), record.getCountry()); + if (cityIdentifiers.size() == 1) { + return cityIdentifiers.get(0); + } else if (cityIdentifiers.size() == 2) { + return String.format("%s, %s", cityIdentifiers.get(0), cityIdentifiers.get(1)); + } else if (cityIdentifiers.size() >= 3) { + return String.format("%s, %s; %s", cityIdentifiers.get(0), cityIdentifiers.get(1), cityIdentifiers.get(2)); + } + + return null; } /**