Added support for mbtile files

This commit is contained in:
Kelly Kelly 2019-11-22 15:39:45 -05:00
parent 6689565e6e
commit fe61a37d29
9 changed files with 945 additions and 182 deletions

View File

@ -81,6 +81,7 @@ public final class UserPreferences {
private static final String GEO_TILE_OPTION = "GeolocationTileOption";
private static final String GEO_OSM_TILE_ZIP_PATH = "GeolocationOsmZipPath";
private static final String GEO_OSM_SERVER_ADDRESS = "GeolocationOsmServerAddress";
private static final String GEO_MBTILES_FILE_PATH = "GeolcoationMBTilesFilePath";
// Prevent instantiation.
private UserPreferences() {
@ -576,7 +577,7 @@ public final class UserPreferences {
}
/**
* Sets the address of the OSM tile server.
* Sets the address of geolocation window user defined OSM server data source.
*
* @param address
*/
@ -592,4 +593,22 @@ public final class UserPreferences {
public static String getGeolocationOsmServerAddress() {
return preferences.get(GEO_OSM_SERVER_ADDRESS, "");
}
/**
* Sets the path for Geolocation MBTiles data source file.
*
* @param absolutePath
*/
public static void setGeolocationMBTilesFilePath(String absolutePath) {
preferences.put(GEO_MBTILES_FILE_PATH, absolutePath);
}
/**
* Retrieves the path for the Geolocation MBTiles data source file.
*
* @return Absolute path to MBTiles file or empty string if none was found.
*/
public static String getGeolocationMBTilesFilePath() {
return preferences.get(GEO_MBTILES_FILE_PATH, "");
}
}

View File

@ -19,14 +19,18 @@ CheckBoxListPanel.uncheckButton.text=Uncheck All
GeoFilterPanel.optionsLabel.text=Waypoints
OptionsCategory_Name_Geolocation=Geolocation
OptionsCategory_Keywords_Geolocation=Geolocation Settings
GeolocationSettingsPanel.tilePane.border.title=Map Tile Source
GeolocationSettingsPanel.tilePane.border.title=Map Tile Data Source
OptionsCategory_Keywords_Geolocation=Geolocation
OptionsCategory_Name_Geolocation=Geolocation
GeolocationSettingsPanel.defaultButton.text=Default online tile server (bing.com/maps)
GeolocationSettingsPanel.tileServerButton.text=OpenStreetMap tile server
GeolocationSettingsPanel.tileServerFiled.text=
GeolocationSettingsPanel.osmZipButton.text=OpenStreeMap Tile Zip File
GeolocationSettingsPanel.osmZipFileField.text=
GeolocationSettingsPanel.osmZipFileBrowseButton.text=Browse
GeolocationSettingsPanel.serverTestButton.text=Test
GeolocationSettingsPanel.osmZipButton.actionCommand=OpenStreeMap tile ZIP file
GeolocationSettingsPanel.mbtileFileField.toolTipText=
GeolocationSettingsPanel.mbtileFileField.text=
GeolocationSettingsPanel.defaultDataSource.text=Default online tile server (bing.com/maps)
GeolocationSettingsPanel.osmServerRBnt.text=OpenStreetMap server
GeolocationSettingsPanel.zipFileRBnt.text=OpenStreeMap zip file
GeolocationSettingsPanel.zipFileRBnt.actionCommand=OpenStreeMap tile ZIP file
GeolocationSettingsPanel.mbtilesRBtn.text=MBTiles file
GeolocationSettingsPanel.osmServerAddressField.text=
GeolocationSettingsPanel.zipFilePathField.text=
GeolocationSettingsPanel.serverTestBtn.text=Test
GeolocationSettingsPanel.mbtilesBrowseBtn.text=Browse
GeolocationSettingsPanel.zipFileBrowseBnt.text=Browse

View File

@ -43,15 +43,19 @@ CheckBoxListPanel.uncheckButton.text=Uncheck All
GeoFilterPanel.optionsLabel.text=Waypoints
OptionsCategory_Name_Geolocation=Geolocation
OptionsCategory_Keywords_Geolocation=Geolocation Settings
GeolocationSettingsPanel.tilePane.border.title=Map Tile Source
GeolocationSettingsPanel.tilePane.border.title=Map Tile Data Source
OptionsCategory_Keywords_Geolocation=Geolocation
OptionsCategory_Name_Geolocation=Geolocation
GeolocationSettingsPanel.defaultButton.text=Default online tile server (bing.com/maps)
GeolocationSettingsPanel.tileServerButton.text=OpenStreetMap tile server
GeolocationSettingsPanel.tileServerFiled.text=
GeolocationSettingsPanel.osmZipButton.text=OpenStreeMap Tile Zip File
GeolocationSettingsPanel.osmZipFileField.text=
GeolocationSettingsPanel.osmZipFileBrowseButton.text=Browse
GeolocationSettingsPanel.serverTestButton.text=Test
GeolocationSettingsPanel.osmZipButton.actionCommand=OpenStreeMap tile ZIP file
GeolocationSettingsPanel.mbtileFileField.toolTipText=
GeolocationSettingsPanel.mbtileFileField.text=
GeolocationSettingsPanel.defaultDataSource.text=Default online tile server (bing.com/maps)
GeolocationSettingsPanel.osmServerRBnt.text=OpenStreetMap server
GeolocationSettingsPanel.zipFileRBnt.text=OpenStreeMap zip file
GeolocationSettingsPanel.zipFileRBnt.actionCommand=OpenStreeMap tile ZIP file
GeolocationSettingsPanel.mbtilesRBtn.text=MBTiles file
GeolocationSettingsPanel.osmServerAddressField.text=
GeolocationSettingsPanel.zipFilePathField.text=
GeolocationSettingsPanel.serverTestBtn.text=Test
GeolocationSettingsPanel.mbtilesBrowseBtn.text=Browse
GeolocationSettingsPanel.zipFileBrowseBnt.text=Browse
WaypointExtractAction_label=Extract Files(s)

View File

@ -28,7 +28,7 @@
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="Map Tile Source">
<TitledBorder title="Map Tile Data Source">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.tilePane.border.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</TitledBorder>
</Border>
@ -46,72 +46,36 @@
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JRadioButton" name="defaultButton">
<Component class="javax.swing.JRadioButton" name="defaultDataSource">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup"/>
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.defaultButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.defaultDataSource.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="defaultButtonActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="defaultDataSourceActionPerformed"/>
</Events>
<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="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="5" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
<GridBagConstraints gridX="0" gridY="0" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="9" insetsLeft="0" insetsBottom="9" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JRadioButton" name="tileServerButton">
<Component class="javax.swing.JRadioButton" name="osmServerRBnt">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.tileServerButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.osmServerRBnt.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="tileServerButtonActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="5" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JTextField" name="tileServerFiled">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.tileServerFiled.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[300, 26]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="5" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JRadioButton" name="osmZipButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.osmZipButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.osmZipButton.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="osmZipButtonActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="osmServerRBntActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
@ -119,10 +83,46 @@
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JTextField" name="osmZipFileField">
<Component class="javax.swing.JTextField" name="osmServerAddressField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.osmZipFileField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.osmServerAddressField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[300, 26]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="9" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JRadioButton" name="zipFileRBnt">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.zipFileRBnt.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.zipFileRBnt.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="zipFileRBntActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="-1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="9" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JTextField" name="zipFilePathField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.zipFilePathField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[300, 26]"/>
@ -134,14 +134,14 @@
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JButton" name="osmZipFileBrowseButton">
<Component class="javax.swing.JButton" name="zipFileBrowseBnt">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.osmZipFileBrowseButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.zipFileBrowseBnt.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="osmZipFileBrowseButtonActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="zipFileBrowseBntActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
@ -149,18 +149,69 @@
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JButton" name="serverTestButton">
<Component class="javax.swing.JButton" name="serverTestBtn">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.serverTestButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.serverTestBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="serverTestButtonActionPerformed"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="serverTestBtnActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="9" insetsBottom="9" insetsRight="9" anchor="18" weightX="0.0" weightY="0.0"/>
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="20" ipadY="0" insetsTop="0" insetsLeft="9" insetsBottom="9" insetsRight="9" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JRadioButton" name="mbtilesRBtn">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.mbtilesRBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="mbtilesRBtnActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="0" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="9" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JTextField" name="mbtileFileField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.mbtileFileField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.mbtileFileField.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[300, 26]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="9" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JButton" name="mbtilesBrowseBtn">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/geolocation/Bundle.properties" key="GeolocationSettingsPanel.mbtilesBrowseBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="mbtilesBrowseBtnActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="2" gridY="3" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="9" insetsBottom="9" insetsRight="9" anchor="18" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>

View File

@ -52,24 +52,29 @@ final class GeolocationSettingsPanel extends javax.swing.JPanel implements Optio
@Override
public void store() {
UserPreferences.setGeolocationTileOption(getServerOption().getValue());
UserPreferences.setGeolocationOsmZipPath(osmZipFileField.getText());
UserPreferences.setGeolocationOsmServerAddress(tileServerFiled.getText());
UserPreferences.setGeolocationTileOption(getDataSourceOption().getValue());
UserPreferences.setGeolocationOsmZipPath(zipFilePathField.getText());
UserPreferences.setGeolocationOsmServerAddress(osmServerAddressField.getText());
UserPreferences.setGeolocationMBTilesFilePath(mbtileFileField.getText());
}
@Override
public void load() {
tileServerFiled.setText(UserPreferences.getGeolocationOsmServerAddress());
osmZipFileField.setText(UserPreferences.getGeolocationOsmZipPath());
switch (GeolocationTileOption.getOptionForValue(UserPreferences.getGeolocationtTileOption())) {
osmServerAddressField.setText(UserPreferences.getGeolocationOsmServerAddress());
zipFilePathField.setText(UserPreferences.getGeolocationOsmZipPath());
mbtileFileField.setText(UserPreferences.getGeolocationMBTilesFilePath());
switch (GeolocationDataSourceType.getOptionForValue(UserPreferences.getGeolocationtTileOption())) {
case ONLINE_USER_DEFINED_OSM_SERVER:
tileServerButton.setSelected(true);
osmServerRBnt.setSelected(true);
break;
case OFFLINE_OSM_ZIP:
osmZipButton.setSelected(true);
zipFileRBnt.setSelected(true);
break;
case OFFILE_MBTILES_FILE:
mbtilesRBtn.setSelected(true);
break;
default:
defaultButton.setSelected(true);
defaultDataSource.setSelected(true);
break;
}
@ -81,10 +86,12 @@ final class GeolocationSettingsPanel extends javax.swing.JPanel implements Optio
* selection state.
*/
private void updateControlState() {
tileServerFiled.setEnabled(tileServerButton.isSelected());
serverTestButton.setEnabled(tileServerButton.isSelected());
osmZipFileField.setEnabled(osmZipButton.isSelected());
osmZipFileBrowseButton.setEnabled(osmZipButton.isSelected());
osmServerAddressField.setEnabled(osmServerRBnt.isSelected());
serverTestBtn.setEnabled(osmServerRBnt.isSelected());
zipFilePathField.setEnabled(zipFileRBnt.isSelected());
zipFileBrowseBnt.setEnabled(zipFileRBnt.isSelected());
mbtileFileField.setEnabled(mbtilesRBtn.isSelected());
mbtilesBrowseBtn.setEnabled(mbtilesRBtn.isSelected());
}
/**
@ -93,13 +100,15 @@ final class GeolocationSettingsPanel extends javax.swing.JPanel implements Optio
*
* @return Current GEOLOCATION_TILE_OPTION
*/
private GeolocationTileOption getServerOption() {
if (tileServerButton.isSelected()) {
return GeolocationTileOption.ONLINE_USER_DEFINED_OSM_SERVER;
} else if (osmZipButton.isSelected()) {
return GeolocationTileOption.OFFLINE_OSM_ZIP;
private GeolocationDataSourceType getDataSourceOption() {
if (osmServerRBnt.isSelected()) {
return GeolocationDataSourceType.ONLINE_USER_DEFINED_OSM_SERVER;
} else if (zipFileRBnt.isSelected()) {
return GeolocationDataSourceType.OFFLINE_OSM_ZIP;
} else if (mbtilesRBtn.isSelected()) {
return GeolocationDataSourceType.OFFILE_MBTILES_FILE;
}
return GeolocationTileOption.ONLINE_DEFAULT_SERVER;
return GeolocationDataSourceType.ONLINE_DEFAULT_SERVER;
}
/**
@ -135,25 +144,28 @@ final class GeolocationSettingsPanel extends javax.swing.JPanel implements Optio
javax.swing.ButtonGroup buttonGroup = new javax.swing.ButtonGroup();
javax.swing.JPanel tilePane = new javax.swing.JPanel();
defaultButton = new javax.swing.JRadioButton();
tileServerButton = new javax.swing.JRadioButton();
tileServerFiled = new javax.swing.JTextField();
osmZipButton = new javax.swing.JRadioButton();
osmZipFileField = new javax.swing.JTextField();
osmZipFileBrowseButton = new javax.swing.JButton();
serverTestButton = new javax.swing.JButton();
defaultDataSource = new javax.swing.JRadioButton();
osmServerRBnt = new javax.swing.JRadioButton();
osmServerAddressField = new javax.swing.JTextField();
zipFileRBnt = new javax.swing.JRadioButton();
zipFilePathField = new javax.swing.JTextField();
zipFileBrowseBnt = new javax.swing.JButton();
serverTestBtn = new javax.swing.JButton();
mbtilesRBtn = new javax.swing.JRadioButton();
mbtileFileField = new javax.swing.JTextField();
mbtilesBrowseBtn = new javax.swing.JButton();
setLayout(new java.awt.GridBagLayout());
tilePane.setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.tilePane.border.title"))); // NOI18N
tilePane.setLayout(new java.awt.GridBagLayout());
buttonGroup.add(defaultButton);
defaultButton.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(defaultButton, org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.defaultButton.text")); // NOI18N
defaultButton.addActionListener(new java.awt.event.ActionListener() {
buttonGroup.add(defaultDataSource);
defaultDataSource.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(defaultDataSource, org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.defaultDataSource.text")); // NOI18N
defaultDataSource.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
defaultButtonActionPerformed(evt);
defaultDataSourceActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
@ -162,56 +174,56 @@ final class GeolocationSettingsPanel extends javax.swing.JPanel implements Optio
gridBagConstraints.gridwidth = 3;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
tilePane.add(defaultButton, gridBagConstraints);
gridBagConstraints.insets = new java.awt.Insets(9, 0, 9, 0);
tilePane.add(defaultDataSource, gridBagConstraints);
buttonGroup.add(tileServerButton);
org.openide.awt.Mnemonics.setLocalizedText(tileServerButton, org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.tileServerButton.text")); // NOI18N
tileServerButton.addActionListener(new java.awt.event.ActionListener() {
buttonGroup.add(osmServerRBnt);
org.openide.awt.Mnemonics.setLocalizedText(osmServerRBnt, org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.osmServerRBnt.text")); // NOI18N
osmServerRBnt.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
tileServerButtonActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
tilePane.add(tileServerButton, gridBagConstraints);
tileServerFiled.setText(org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.tileServerFiled.text")); // NOI18N
tileServerFiled.setPreferredSize(new java.awt.Dimension(300, 26));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 1;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
tilePane.add(tileServerFiled, gridBagConstraints);
buttonGroup.add(osmZipButton);
org.openide.awt.Mnemonics.setLocalizedText(osmZipButton, org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.osmZipButton.text")); // NOI18N
osmZipButton.setActionCommand(org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.osmZipButton.actionCommand")); // NOI18N
osmZipButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
osmZipButtonActionPerformed(evt);
osmServerRBntActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 9, 0);
tilePane.add(osmZipButton, gridBagConstraints);
tilePane.add(osmServerRBnt, gridBagConstraints);
osmZipFileField.setText(org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.osmZipFileField.text")); // NOI18N
osmZipFileField.setPreferredSize(new java.awt.Dimension(300, 26));
osmServerAddressField.setText(org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.osmServerAddressField.text")); // NOI18N
osmServerAddressField.setPreferredSize(new java.awt.Dimension(300, 26));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 1;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 9, 0);
tilePane.add(osmServerAddressField, gridBagConstraints);
buttonGroup.add(zipFileRBnt);
org.openide.awt.Mnemonics.setLocalizedText(zipFileRBnt, org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.zipFileRBnt.text")); // NOI18N
zipFileRBnt.setActionCommand(org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.zipFileRBnt.actionCommand")); // NOI18N
zipFileRBnt.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
zipFileRBntActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 9, 0);
tilePane.add(zipFileRBnt, gridBagConstraints);
zipFilePathField.setText(org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.zipFilePathField.text")); // NOI18N
zipFilePathField.setPreferredSize(new java.awt.Dimension(300, 26));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 2;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 9, 0);
tilePane.add(osmZipFileField, gridBagConstraints);
tilePane.add(zipFilePathField, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(osmZipFileBrowseButton, org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.osmZipFileBrowseButton.text")); // NOI18N
osmZipFileBrowseButton.addActionListener(new java.awt.event.ActionListener() {
org.openide.awt.Mnemonics.setLocalizedText(zipFileBrowseBnt, org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.zipFileBrowseBnt.text")); // NOI18N
zipFileBrowseBnt.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
osmZipFileBrowseButtonActionPerformed(evt);
zipFileBrowseBntActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
@ -220,20 +232,57 @@ final class GeolocationSettingsPanel extends javax.swing.JPanel implements Optio
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.insets = new java.awt.Insets(0, 9, 9, 9);
tilePane.add(osmZipFileBrowseButton, gridBagConstraints);
tilePane.add(zipFileBrowseBnt, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(serverTestButton, org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.serverTestButton.text")); // NOI18N
serverTestButton.addActionListener(new java.awt.event.ActionListener() {
org.openide.awt.Mnemonics.setLocalizedText(serverTestBtn, org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.serverTestBtn.text")); // NOI18N
serverTestBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
serverTestButtonActionPerformed(evt);
serverTestBtnActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 2;
gridBagConstraints.gridy = 1;
gridBagConstraints.ipadx = 20;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(0, 9, 9, 9);
tilePane.add(serverTestButton, gridBagConstraints);
tilePane.add(serverTestBtn, gridBagConstraints);
buttonGroup.add(mbtilesRBtn);
org.openide.awt.Mnemonics.setLocalizedText(mbtilesRBtn, org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.mbtilesRBtn.text")); // NOI18N
mbtilesRBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
mbtilesRBtnActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 3;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 9, 0);
tilePane.add(mbtilesRBtn, gridBagConstraints);
mbtileFileField.setText(org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.mbtileFileField.text")); // NOI18N
mbtileFileField.setToolTipText(org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.mbtileFileField.toolTipText")); // NOI18N
mbtileFileField.setPreferredSize(new java.awt.Dimension(300, 26));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 3;
gridBagConstraints.insets = new java.awt.Insets(0, 0, 9, 0);
tilePane.add(mbtileFileField, gridBagConstraints);
org.openide.awt.Mnemonics.setLocalizedText(mbtilesBrowseBtn, org.openide.util.NbBundle.getMessage(GeolocationSettingsPanel.class, "GeolocationSettingsPanel.mbtilesBrowseBtn.text")); // NOI18N
mbtilesBrowseBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
mbtilesBrowseBtnActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 2;
gridBagConstraints.gridy = 3;
gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
gridBagConstraints.insets = new java.awt.Insets(0, 9, 9, 9);
tilePane.add(mbtilesBrowseBtn, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
@ -243,7 +292,7 @@ final class GeolocationSettingsPanel extends javax.swing.JPanel implements Optio
add(tilePane, gridBagConstraints);
}// </editor-fold>//GEN-END:initComponents
private void osmZipFileBrowseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_osmZipFileBrowseButtonActionPerformed
private void zipFileBrowseBntActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zipFileBrowseBntActionPerformed
JFileChooser fileWindow = new JFileChooser();
fileWindow.setFileSelectionMode(JFileChooser.FILES_ONLY);
GeneralFilter fileFilter = new GeneralFilter(Arrays.asList(".zip"), "Zips (*.zip)"); //NON-NLS
@ -253,26 +302,26 @@ final class GeolocationSettingsPanel extends javax.swing.JPanel implements Optio
int returnVal = fileWindow.showSaveDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File zipFile = fileWindow.getSelectedFile();
osmZipFileField.setForeground(Color.BLACK);
osmZipFileField.setText(zipFile.getAbsolutePath());
zipFilePathField.setForeground(Color.BLACK);
zipFilePathField.setText(zipFile.getAbsolutePath());
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}
}//GEN-LAST:event_osmZipFileBrowseButtonActionPerformed
}//GEN-LAST:event_zipFileBrowseBntActionPerformed
private void defaultButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_defaultButtonActionPerformed
private void defaultDataSourceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_defaultDataSourceActionPerformed
updateControlState();
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_defaultButtonActionPerformed
}//GEN-LAST:event_defaultDataSourceActionPerformed
private void tileServerButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tileServerButtonActionPerformed
private void osmServerRBntActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_osmServerRBntActionPerformed
updateControlState();
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_tileServerButtonActionPerformed
}//GEN-LAST:event_osmServerRBntActionPerformed
private void osmZipButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_osmZipButtonActionPerformed
private void zipFileRBntActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_zipFileRBntActionPerformed
updateControlState();
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_osmZipButtonActionPerformed
}//GEN-LAST:event_zipFileRBntActionPerformed
@Messages({
"GeolocationSettingsPanel_malformed_url_message=The supplies OSM tile server address is invalid.\nPlease supply a well formed url prefixed with http://",
@ -281,8 +330,8 @@ final class GeolocationSettingsPanel extends javax.swing.JPanel implements Optio
"GeolocationSettingsPanel_osm_server_test_fail_message_title=Error",
"GeolocationSettingsPanel_osm_server_test_success_message=The provide OSM tile server address is valid.",
"GeolocationSettingsPanel_osm_server_test_success_message_title=Success",})
private void serverTestButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_serverTestButtonActionPerformed
String address = tileServerFiled.getText();
private void serverTestBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_serverTestBtnActionPerformed
String address = osmServerAddressField.getText();
String message = Bundle.GeolocationSettingsPanel_osm_server_test_fail_message();
String title = Bundle.GeolocationSettingsPanel_osm_server_test_fail_message_title();
@ -297,31 +346,56 @@ final class GeolocationSettingsPanel extends javax.swing.JPanel implements Optio
}
JOptionPane.showMessageDialog(this, message, title, JOptionPane.INFORMATION_MESSAGE);
}//GEN-LAST:event_serverTestButtonActionPerformed
}//GEN-LAST:event_serverTestBtnActionPerformed
private void mbtilesRBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mbtilesRBtnActionPerformed
updateControlState();
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}//GEN-LAST:event_mbtilesRBtnActionPerformed
private void mbtilesBrowseBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mbtilesBrowseBtnActionPerformed
JFileChooser fileWindow = new JFileChooser();
fileWindow.setFileSelectionMode(JFileChooser.FILES_ONLY);
GeneralFilter fileFilter = new GeneralFilter(Arrays.asList(".mbtiles"), "MBTiles (*.mbtiles)"); //NON-NLS
fileWindow.setDragEnabled(false);
fileWindow.setFileFilter(fileFilter);
fileWindow.setMultiSelectionEnabled(false);
int returnVal = fileWindow.showSaveDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File zipFile = fileWindow.getSelectedFile();
mbtileFileField.setForeground(Color.BLACK);
mbtileFileField.setText(zipFile.getAbsolutePath());
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}
}//GEN-LAST:event_mbtilesBrowseBtnActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JRadioButton defaultButton;
private javax.swing.JRadioButton osmZipButton;
private javax.swing.JButton osmZipFileBrowseButton;
private javax.swing.JTextField osmZipFileField;
private javax.swing.JButton serverTestButton;
private javax.swing.JRadioButton tileServerButton;
private javax.swing.JTextField tileServerFiled;
private javax.swing.JRadioButton defaultDataSource;
private javax.swing.JTextField mbtileFileField;
private javax.swing.JButton mbtilesBrowseBtn;
private javax.swing.JRadioButton mbtilesRBtn;
private javax.swing.JTextField osmServerAddressField;
private javax.swing.JRadioButton osmServerRBnt;
private javax.swing.JButton serverTestBtn;
private javax.swing.JButton zipFileBrowseBnt;
private javax.swing.JTextField zipFilePathField;
private javax.swing.JRadioButton zipFileRBnt;
// End of variables declaration//GEN-END:variables
/**
* Tile server option enum. The enum was given values to simplify the
* storing of the user preference for a particular option.
*/
enum GeolocationTileOption{
enum GeolocationDataSourceType{
ONLINE_DEFAULT_SERVER(0),
ONLINE_USER_DEFINED_OSM_SERVER(1),
OFFLINE_OSM_ZIP(2);
OFFLINE_OSM_ZIP(2),
OFFILE_MBTILES_FILE(3);
private final int value;
GeolocationTileOption(int value) {
GeolocationDataSourceType(int value) {
this.value = value;
}
@ -329,8 +403,8 @@ final class GeolocationSettingsPanel extends javax.swing.JPanel implements Optio
return value;
}
static GeolocationTileOption getOptionForValue(int value) {
for (GeolocationTileOption option : GeolocationTileOption.values()) {
static GeolocationDataSourceType getOptionForValue(int value) {
for (GeolocationDataSourceType option : GeolocationDataSourceType.values()) {
if (option.getValue() == value) {
return option;
}

View File

@ -0,0 +1,159 @@
/*
* 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;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.jxmapviewer.OSMTileFactoryInfo;
import org.jxmapviewer.viewer.TileFactoryInfo;
import org.openide.util.Exceptions;
import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException;
/**
* Wraps the connection to the MBTiles file\sqlite db.
*/
final class MBTilesFileConnector {
private final static String DB_URL = "jdbc:sqlite:%s";
private final static String TILE_QUERY = "SELECT tile_data FROM images WHERE tile_id = '%s'";
private final static String FORMAT_QUERY = "SELECT value FROM metadata WHERE name='format'";
private TileFactoryInfo factoryInfo;
private Connection dbConnection = null;
/**
* Returns whether or not the file at the given path is a mbtiles file.
*
* @param filePath Absolute path the the file.
*
* @return True if the file is an mbtiles file
*
* @throws SQLException
*/
static boolean isValidMBTileRasterFile(String filePath) throws SQLException{
String path = filePath.replaceAll("\\\\", "/");
String url = String.format(DB_URL, path);
Path p = Paths.get(filePath);
if( !p.toFile().exists()) {
return false;
}
try(Connection connection = DriverManager.getConnection(url)) {
try(Statement statement = connection.createStatement()){
ResultSet resultSet = statement.executeQuery(FORMAT_QUERY);
if(resultSet.next()) {
String format = resultSet.getString(1);
return format.equals("jpg");
}
}
}
return false;
}
/**
* Construct a new connection to the MBTile file.
*
* @param tileFilePath MBTiles file absolute path
*
* @throws GeoLocationDataException
*/
MBTilesFileConnector(String tileFilePath) throws GeoLocationDataException{
try{
String path = tileFilePath.replaceAll("\\\\", "/");
String url = String.format(DB_URL, path);
dbConnection = DriverManager.getConnection(url);
factoryInfo = new MBTilesInfo();
} catch(SQLException ex) {
throw new GeoLocationDataException(String.format("Unable to create sql connection to %s", tileFilePath), ex);
}
}
/**
* Returns the TileFacortyInfo object for the MBTile file.
*
* @return TileFactoryInfo object or null if the connection has been closed.
*/
TileFactoryInfo getInfo() {
return factoryInfo;
}
/**
* Get the tile for the given tileID.
*
* @param tileID String tile ID in the format of
* zoom/x/y
*
* @return The tile image byte array or null if the tile was not found
*
* @throws GeoLocationDataException
*/
byte[] getTileBytes(String tileID) throws GeoLocationDataException{
String query = String.format(TILE_QUERY, tileID);
try (Statement statement = dbConnection.createStatement()) {
ResultSet resultSet = statement.executeQuery(query);
if (resultSet.next()) {
return resultSet.getBytes(1);
}
} catch (SQLException ex) {
throw new GeoLocationDataException(String.format("Failed to get tile %s", tileID), ex);
}
return null;
}
/**
* Close the connection to the MBTile file.
*/
void closeConnection() {
if(dbConnection != null) {
try {
dbConnection.close();
} catch (SQLException ex) {
Exceptions.printStackTrace(ex);
}
dbConnection = null;
factoryInfo = null;
}
}
/**
* Overload the existing OSMTileFacotyInfo to return a "url" specific to
* MBTiles.
*/
private final class MBTilesInfo extends OSMTileFactoryInfo {
MBTilesInfo() {
super("MBTilesFile", "");
}
@Override
public String getTileUrl(int x, int y, int zoom) {
// OSM zoom levels are reversed from how the TileFactory deals with
// them.
int osmZoom = getTotalMapZoom() - zoom;
return String.format("%d/%d/%d", osmZoom, x, y);
}
}
}

View File

@ -0,0 +1,122 @@
/*
* 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;
import java.awt.image.BufferedImage;
import java.lang.ref.SoftReference;
import org.jxmapviewer.viewer.Tile;
/**
* Provides a MBTile specific implementation of Tile.
*
* This class borrows functionality from Tile.
*/
final class MBTilesTile extends Tile {
private SoftReference<BufferedImage> image = new SoftReference<>(null);
private Priority priority = Priority.High;
private boolean loaded = false;
private final String tileID;
/**
* Construct an empty tile.
*
* @param x
* @param y
* @param zoom
*/
MBTilesTile(int x, int y, int zoom) {
super(x, y, zoom);
tileID = null;
}
/**
* Construct a new tile.
*
* @param x Tile row
* @param y Tile column
* @param zoom Tile Zoom level
* @param tileID Tile identifier
* @param priority Priority for loading the tile
*/
MBTilesTile(int x, int y, int zoom, String tileID, Priority priority) {
super(x, y, zoom);
this.priority = priority;
this.tileID = tileID;
}
/**
* Sets the image for this Tile.
*
* @param image
*/
void setImage(BufferedImage image) {
this.image = new SoftReference<>(image);
setLoaded(true);
}
/**
* Indicates if this tile's underlying image has been successfully loaded
* yet.
*
* @return true if the Tile has been loaded
*/
@Override
public synchronized boolean isLoaded() {
return loaded;
}
synchronized void setLoaded(boolean loaded) {
boolean old = isLoaded();
this.loaded = loaded;
firePropertyChange("loaded", old, isLoaded());
}
@Override
public BufferedImage getImage() {
BufferedImage img = image.get();
if (img == null) {
setLoaded(false);
}
return img;
}
@Override
public Priority getPriority() {
return priority;
}
@Override
public void setPriority(Priority priority) {
this.priority = priority;
}
/**
* Overloading the original version of this function to return
* the tileID for this tile.
*
* @return tileID or null if none was set
*/
@Override
public String getURL() {
return tileID;
}
}

View File

@ -0,0 +1,330 @@
/*
* 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;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.logging.Level;
import javax.imageio.ImageIO;
import javax.swing.SwingUtilities;
import org.jxmapviewer.viewer.Tile;
import org.jxmapviewer.viewer.TileCache;
import org.jxmapviewer.viewer.TileFactory;
import org.jxmapviewer.viewer.util.GeoUtil;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.geolocation.datamodel.GeoLocationDataException;
/**
* This TileFactory class borrows from AbstractTileFactory, changing to
* support the getting the tiles from a database instead the web.
*
*/
final class MBTilesTileFactory extends TileFactory {
private static final Logger logger = Logger.getLogger(MBTilesTileFactory.class.getName());
private volatile int pendingTiles = 0;
private int threadPoolSize = 4;
private ExecutorService service;
private Map<String, Tile> tileMap = new HashMap<>();
private TileCache cache = new TileCache();
private MBTilesFileConnector connector;
/**
* Construct a new TileFactory for the MBTiles file at the given location.
*
* @param filePath
* @throws GeoLocationDataException
*/
MBTilesTileFactory(String filePath) throws GeoLocationDataException{
this(new MBTilesFileConnector(filePath));
}
/**
* Construct a new TileFacotry.
*
* @param connector
*/
private MBTilesTileFactory(MBTilesFileConnector connector) {
super(connector.getInfo());
this.connector = connector;
}
/**
* Returns the tile that is located at the given tile point for this zoom.
*
* @param x Tile column
* @param y Tile row
* @param zoom Current zoom level
*
* @return A new Tile object
*
*/
@Override
public Tile getTile(int x, int y, int zoom) {
return getTile(x, y, zoom, true);
}
/**
* Returns the tile object for the given location.
*
* @param tpx
* @param tpy
* @param zoom
* @param eagerLoad
*
* @return
*/
private Tile getTile(int tpx, int tpy, int zoom, boolean eagerLoad) {
// wrap the tiles horizontally --> mod the X with the max width
// and use that
int tileX = tpx;// tilePoint.getX();
int numTilesWide = (int) getMapSize(zoom).getWidth();
if (tileX < 0) {
tileX = numTilesWide - (Math.abs(tileX) % numTilesWide);
}
tileX %= numTilesWide;
int tileY = tpy;
String url = getInfo().getTileUrl(tileX, tileY, zoom);
Tile.Priority pri = Tile.Priority.High;
if (!eagerLoad) {
pri = Tile.Priority.Low;
}
Tile tile;
if (!tileMap.containsKey(url)) {
// If its not a valid tile location return an empty tile.
if (!GeoUtil.isValidTile(tileX, tileY, zoom, getInfo())) {
tile = new MBTilesTile(tileX, tileY, zoom);
} else {
tile = new MBTilesTile(tileX, tileY, zoom, url, pri);
startLoading(tile);
}
tileMap.put(url, tile);
} else {
tile = tileMap.get(url);
// If the tile is in the tileMap, but the image is not loaded yet,
// bump the priority.
if (tile.getPriority() == Tile.Priority.Low && eagerLoad && !tile.isLoaded()) {
promote(tile);
}
}
return tile;
}
/**
* Returns the TileCache.
*
* @return the tile cache
*/
TileCache getTileCache() {
return cache;
}
/**
* ==== Threaded Tile loading code ===
*/
/**
* Thread pool for loading the tiles
*/
private final BlockingQueue<Tile> tileQueue = new PriorityBlockingQueue<>(5, new Comparator<Tile>() {
@Override
public int compare(Tile o1, Tile o2) {
if (o1.getPriority() == Tile.Priority.Low && o2.getPriority() == Tile.Priority.High) {
return 1;
}
if (o1.getPriority() == Tile.Priority.High && o2.getPriority() == Tile.Priority.Low) {
return -1;
}
return 0;
}
});
/**
* Subclasses may override this method to provide their own executor
* services. This method will be called each time a tile needs to be loaded.
* Implementations should cache the ExecutorService when possible.
*
* @return ExecutorService to load tiles with
*/
synchronized ExecutorService getService() {
if (service == null) {
// System.out.println("creating an executor service with a threadpool of size " + threadPoolSize);
service = Executors.newFixedThreadPool(threadPoolSize, new ThreadFactory() {
private int count = 0;
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r, "tile-pool-" + count++);
t.setPriority(Thread.MIN_PRIORITY);
t.setDaemon(true);
return t;
}
});
}
return service;
}
@Override
public void dispose() {
if (service != null) {
service.shutdown();
service = null;
}
if(connector != null) {
connector.closeConnection();
connector = null;
}
}
@Override
protected synchronized void startLoading(Tile tile) {
if (tile.isLoading()) {
return;
}
pendingTiles++;
tile.setLoading(true);
try {
tileQueue.put(tile);
getService().submit(new TileRunner());
} catch(InterruptedException ex) {
}
}
/**
* Increase the priority of this tile so it will be loaded sooner.
*
* @param tile the tile
*/
synchronized void promote(Tile tile) {
if (tileQueue.contains(tile)) {
try {
tileQueue.remove(tile);
tile.setPriority(Tile.Priority.High);
tileQueue.put(tile);
} catch (InterruptedException ex) {
}
}
}
/**
* @return the number of pending (loading or queues) tiles
*/
int getPendingTiles() {
return pendingTiles;
}
/**
* An inner class which actually loads the tiles. Used by the thread queue.
* Subclasses can override this via {@link #createTileRunner(Tile)} if
* necessary.
*/
private class TileRunner implements Runnable {
/**
* Gets the full URI of a tile.
*
* @param tile the tile
*
* @throws URISyntaxException if the URI is invalid
* @return a URI for the tile
*/
protected URI getURI(Tile tile) throws URISyntaxException {
if (tile.getURL() == null) {
return null;
}
return new URI(tile.getURL());
}
@Override
public void run() {
/*
* Attempt to load the tile from . If loading fails, retry
* two more times. If all attempts fail, nothing else is done. This
* way, if there is some kind of failure, the pooled
* thread can try to load other tiles.
*/
final Tile tile = tileQueue.remove();
int remainingAttempts = 3;
while (!tile.isLoaded() && remainingAttempts > 0) {
remainingAttempts--;
try {
URI uri = getURI(tile);
BufferedImage img = cache.get(uri);
if (img == null) {
byte[] bimg = connector.getTileBytes(uri.toString());
if (bimg != null) {
img = ImageIO.read(new ByteArrayInputStream(bimg));
cache.put(uri, bimg, img);
img = cache.get(uri);
}
}
if (img == null) {
logger.log(Level.INFO, String.format("Failed to load: %s", uri));
} else {
final BufferedImage image = img;
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
if (tile instanceof MBTilesTile) {
((MBTilesTile) tile).setImage(image);
}
pendingTiles--;
fireTileLoadedEvent(tile);
}
});
}
} catch (OutOfMemoryError memErr) {
cache.needMoreMemory();
} catch (Throwable ex) {
if (remainingAttempts == 0) {
logger.log(Level.SEVERE, String.format("Failed to load a tile at URL: %s, stopping", tile.getURL()), ex);
} else {
logger.log(Level.WARNING, "Failed to load a tile at URL: " + tile.getURL() + ", retrying", ex);
}
}
}
tile.setLoading(false);
}
}
}

View File

@ -56,7 +56,6 @@ import org.jxmapviewer.viewer.TileFactory;
import org.jxmapviewer.viewer.TileFactoryInfo;
import org.jxmapviewer.viewer.Waypoint;
import org.jxmapviewer.viewer.WaypointPainter;
import org.jxmapviewer.viewer.util.GeoUtil;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.core.UserPreferences;
import org.sleuthkit.autopsy.coreutils.Logger;
@ -113,7 +112,10 @@ final public class MapPanel extends javax.swing.JPanel {
@Override
public void preferenceChange(PreferenceChangeEvent evt) {
try {
mapViewer.setTileFactory(new DefaultTileFactory(getTileFactoryInfo()));
// Tell the old factory to cleanup
mapViewer.getTileFactory().dispose();
mapViewer.setTileFactory(getTileFactory());
initializeZoomSlider();
} catch (GeoLocationDataException ex) {
logger.log(Level.SEVERE, "Failed to connect to new geolocation tile server.", ex); //NON-NLS
@ -134,8 +136,7 @@ final public class MapPanel extends javax.swing.JPanel {
*/
void initMap() throws GeoLocationDataException {
TileFactoryInfo info = getTileFactoryInfo();
DefaultTileFactory tileFactory = new DefaultTileFactory(info);
TileFactory tileFactory = getTileFactory();
mapViewer.setTileFactory(tileFactory);
// Add Mouse interactions
@ -192,18 +193,20 @@ final public class MapPanel extends javax.swing.JPanel {
}
/**
* Create the TileFactoryInfo object based on the user preference.
* Create the TileFactory object based on the user preference.
*
* @return
*/
TileFactoryInfo getTileFactoryInfo() throws GeoLocationDataException {
switch (GeolocationSettingsPanel.GeolocationTileOption.getOptionForValue(UserPreferences.getGeolocationtTileOption())) {
private TileFactory getTileFactory() throws GeoLocationDataException {
switch (GeolocationSettingsPanel.GeolocationDataSourceType.getOptionForValue(UserPreferences.getGeolocationtTileOption())) {
case ONLINE_USER_DEFINED_OSM_SERVER:
return createOnlineOSMFactory(UserPreferences.getGeolocationOsmServerAddress());
return new DefaultTileFactory(createOnlineOSMFactory(UserPreferences.getGeolocationOsmServerAddress()));
case OFFLINE_OSM_ZIP:
return createOSMZipFactory(UserPreferences.getGeolocationOsmZipPath());
return new DefaultTileFactory(createOSMZipFactory(UserPreferences.getGeolocationOsmZipPath()));
case OFFILE_MBTILES_FILE:
return new MBTilesTileFactory(UserPreferences.getGeolocationMBTilesFilePath());
default:
return new VirtualEarthTileFactoryInfo(VirtualEarthTileFactoryInfo.MAP);
return new DefaultTileFactory(new VirtualEarthTileFactoryInfo(VirtualEarthTileFactoryInfo.MAP));
}
}
@ -221,9 +224,6 @@ final public class MapPanel extends javax.swing.JPanel {
throw new GeoLocationDataException("Invalid user preference for OSM user define tile server. Address is an empty string.");
} else {
TileFactoryInfo info = new OSMTileFactoryInfo("User Defined Server", address);
if (!GeoUtil.isValidTile(1, 1, 1, info)) {
throw new GeoLocationDataException(String.format("Invalid OSM user define tile server: %s", address));
}
return info;
}
}