Changeset 33579 in osm for applications/editors/josm


Ignore:
Timestamp:
2017-08-27T22:22:31+02:00 (7 years ago)
Author:
donvip
Message:

update to JOSM 12678

Location:
applications/editors/josm/plugins
Files:
60 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/OSMRecPlugin/.settings/org.eclipse.jdt.ui.prefs

    r32358 r33579  
    1616sp_cleanup.convert_functional_interfaces=false
    1717sp_cleanup.convert_to_enhanced_for_loop=false
    18 sp_cleanup.correct_indentation=true
     18sp_cleanup.correct_indentation=false
    1919sp_cleanup.format_source_code=false
    2020sp_cleanup.format_source_code_changes_only=false
  • applications/editors/josm/plugins/OSMRecPlugin/build.xml

    r33524 r33579  
    33
    44    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    5     <property name="plugin.main.version" value="12663"/>
     5    <property name="plugin.main.version" value="12678"/>
    66    <property name="plugin.version" value="2.1"/>
    77
  • applications/editors/josm/plugins/OSMRecPlugin/src/org/openstreetmap/josm/plugins/osmrec/OSMRecPluginHelper.java

    r33525 r33579  
    107107//import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
    108108import org.openstreetmap.josm.gui.util.GuiHelper;
     109import org.openstreetmap.josm.gui.util.WindowGeometry;
    109110import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
    110111import org.openstreetmap.josm.io.XmlWriter;
     
    125126import org.openstreetmap.josm.tools.Logging;
    126127import org.openstreetmap.josm.tools.Shortcut;
    127 import org.openstreetmap.josm.tools.WindowGeometry;
    128128
    129129import com.vividsolutions.jts.geom.Coordinate;
     
    146146class OSMRecPluginHelper {
    147147
    148         private final DefaultTableModel tagData;
    149         private static Collection<String> fileHistory;
    150         private Map<File, Double> filesAndWeights = new HashMap<>();
    151         private boolean useCombinedModel;
    152 
    153         //the most recent file from history.
    154         //all necessary files will reside in a directory of this file
    155         private static String MAIN_PATH;
    156         private static String MODEL_PATH;
    157         private static String TEXTUAL_LIST_PATH;
    158         private static Map<String, List<String>> indirectClasses;
    159         private static Map<String, Integer> indirectClassesWithIDs;
    160         private static LanguageDetector languageDetector;
    161         private static String bestModelPath;
    162         private boolean modelWithClasses;
    163         private final String modelWithClassesPath;
    164         private boolean useCustomSVMModel = false;
    165         private String customSVMModelPath;
    166         private final String combinedModelClasses;
    167         private final String combinedModel;
    168 
    169         // Selection that we are editing by using both dialogs
    170         Collection<OsmPrimitive> sel;
    171 
    172         private String changedKey;
    173 
    174         Comparator<AutoCompletionListItem> defaultACItemComparator = new Comparator<AutoCompletionListItem>() {
    175                 @Override
    176                 public int compare(AutoCompletionListItem o1, AutoCompletionListItem o2) {
    177                         return String.CASE_INSENSITIVE_ORDER.compare(o1.getValue(), o2.getValue());
    178                 }
    179         };
    180 
    181         private String lastAddKey = null;
    182         private String lastAddValue = null;
    183 
    184         public static final int DEFAULT_LRU_TAGS_NUMBER = 5;
    185         public static final int MAX_LRU_TAGS_NUMBER = 30;
    186 
    187         // LRU cache for recently added tags (http://java-planet.blogspot.com/2005/08/how-to-set-up-simple-lru-cache-using.html)
    188         private final Map<Tag, Void> recentTags = new LinkedHashMap<Tag, Void>(MAX_LRU_TAGS_NUMBER+1, 1.1f, true) {
    189                 @Override
    190                 protected boolean removeEldestEntry(Map.Entry<Tag, Void> eldest) {
    191                         return size() > MAX_LRU_TAGS_NUMBER;
    192                 }
    193         };
    194 
    195         OSMRecPluginHelper(DefaultTableModel propertyData, Map<String, Map<String, Integer>> valueCount) {
    196                 this.tagData = propertyData;
    197                 fileHistory = Main.pref.getCollection("file-open.history");
    198                 if (!fileHistory.isEmpty()) {
    199                         MAIN_PATH = (String) fileHistory.toArray()[0];
    200                 } else {
    201                         MAIN_PATH = System.getProperty("user.home");
    202                 }
    203                 MODEL_PATH = new File(MAIN_PATH).getParentFile() + "/OSMRec_models";
    204                 TEXTUAL_LIST_PATH = MODEL_PATH + "/textualList.txt";
    205                 combinedModelClasses = MODEL_PATH + "/combinedModel.1";
    206                 combinedModel = MODEL_PATH + "/combinedModel.0";
    207                 bestModelPath = MODEL_PATH + "/best_model";
    208                 customSVMModelPath = bestModelPath;
    209                 modelWithClassesPath = MODEL_PATH + "/model_with_classes";
    210                 languageDetector = LanguageDetector.getInstance(MODEL_PATH + "/profiles");
    211 
    212                 SampleModelsExtractor sampleModelsExtractor = new SampleModelsExtractor();
    213 
    214                 sampleModelsExtractor.extractSampleSVMmodel("best_model", bestModelPath);
    215                 sampleModelsExtractor.extractSampleSVMmodel("model_with_classes", modelWithClassesPath);
    216         }
    217 
    218         /**
    219         * Open the add selection dialog and add a new key/value to the table (and to the dataset, of course).
    220         */
    221         public void addTag() {
    222                 changedKey = null;
    223                 sel = Main.main.getInProgressSelection();
    224                 if (sel == null || sel.isEmpty()) return;
    225 
    226                 final AddTagsDialog addDialog = new AddTagsDialog();
    227 
    228                 addDialog.showDialog();
    229 
    230                 addDialog.destroyActions();
    231                 if (addDialog.getValue() == 1)
    232                         addDialog.performTagAdding();
    233                 else
    234                         addDialog.undoAllTagsAdding();
    235         }
    236 
    237         /**
    238         * Edit the value in the tags table row.
    239         * @param row The row of the table from which the value is edited.
    240         * @param focusOnKey Determines if the initial focus should be set on key instead of value
    241         * @since 5653
    242         */
    243         public void editTag(final int row, boolean focusOnKey) {
    244                 changedKey = null;
    245                 sel = Main.main.getInProgressSelection();
    246                 String key = "";
    247 
    248                 @SuppressWarnings("unchecked")
    249                 Map<String, Integer> dumPar = new HashMap<>();
    250                 dumPar.put(" ", -1);
    251                 final TrainingDialog editDialog = new TrainingDialog(key, row,
    252                                 dumPar, focusOnKey);
    253                 editDialog.showDialog();
    254         }
    255 
    256         /**
    257         * If during last editProperty call user changed the key name, this key will be returned
    258         * Elsewhere, returns null.
    259         * @return The modified key, or {@code null}
    260         */
    261         public String getChangedKey() {
    262                 return changedKey;
    263         }
    264 
    265         /**
    266         * For a given key k, return a list of keys which are used as keys for
    267         * auto-completing values to increase the search space.
    268         * @param key the key k
    269         * @return a list of keys
    270         */
    271         private static List<String> getAutocompletionKeys(String key) {
    272                 if ("name".equals(key) || "addr:street".equals(key))
    273                         return Arrays.asList("addr:street", "name");
    274                 else
    275                         return Arrays.asList(key);
    276         }
    277 
    278         /**
    279         * Load recently used tags from preferences if needed.
    280         */
    281         public void loadTagsIfNeeded() {
    282                 if (PROPERTY_REMEMBER_TAGS.get() && recentTags.isEmpty()) {
    283                         recentTags.clear();
    284                         Collection<String> c = Main.pref.getCollection("properties.recent-tags");
    285                         Iterator<String> it = c.iterator();
    286                         String key, value;
    287                         while (it.hasNext()) {
    288                                 key = it.next();
    289                                 value = it.next();
    290                                 recentTags.put(new Tag(key, value), null);
    291                         }
    292                 }
    293         }
    294 
    295         /**
    296         * Store recently used tags in preferences if needed.
    297         */
    298         public void saveTagsIfNeeded() {
    299                 if (PROPERTY_REMEMBER_TAGS.get() && !recentTags.isEmpty()) {
    300                         List<String> c = new ArrayList<>(recentTags.size()*2);
    301                         for (Tag t: recentTags.keySet()) {
    302                                 c.add(t.getKey());
    303                                 c.add(t.getValue());
    304                         }
    305                         Main.pref.putCollection("properties.recent-tags", c);
    306                 }
    307         }
    308 
    309         /**
    310         * Warns user about a key being overwritten.
    311         * @param action The action done by the user. Must state what key is changed
    312         * @param togglePref  The preference to save the checkbox state to
    313         * @return {@code true} if the user accepts to overwrite key, {@code false} otherwise
    314         */
    315         private boolean warnOverwriteKey(String action, String togglePref) {
    316                 ExtendedDialog ed = new ExtendedDialog(
    317                                 Main.parent,
    318                                 tr("Overwrite key"),
    319                                 new String[]{tr("Replace"), tr("Cancel")});
    320                 ed.setButtonIcons(new String[]{"purge", "cancel"});
    321                 ed.setContent(action+"\n"+ tr("The new key is already used, overwrite values?"));
    322                 ed.setCancelButton(2);
    323                 ed.toggleEnable(togglePref);
    324                 ed.showDialog();
    325 
    326                 return ed.getValue() == 1;
    327         }
    328 
    329         public final class TrainingDialog extends AbstractTagsDialog {
    330 
    331                 private static final int FIELD_COLUMNS = 4;
    332                 private final JTextField inputFileField;
    333                 private final JLabel inputFileLabel;
    334                 private final JTextField topKField;
    335                 private final JTextField cParameterField;
    336                 private final JTextField frequencyField;
    337 
    338                 private final JButton fileBrowseButton;
    339                 private final JButton acceptConfigButton;
    340                 private JRadioButton frequencyButton;
    341                 private JRadioButton topKButton;
    342                 private JCheckBox cParameterCheckBox;
    343                 private final JButton resetConfigButton;
    344                 private String inputFileValue;
    345                 private Double cParameterValue = 0.0;
    346                 private Integer topKvalue = 0;
    347                 private Integer frequencyValue = 0;
    348                 private boolean crossValidateFlag;
    349                 private final JButton startTrainingButton;
    350                 private final JLabel cErrorMessageLabel;
    351                 private final JLabel topKErrorMessageLabel;
    352                 private final JLabel inputFileErrorMessageLabel;
    353                 private final JLabel frequencyErrorMessageLabel;
    354                 private final JProgressBar trainingProgressBar;
    355                 private final JRadioButton byAreaRadioButton;
    356                 private final JRadioButton byTimeRadioButton;
    357                 private final JLabel userNameLabel;
    358                 private final JTextField userNameField;
    359                 private final JTextField daysField;
    360                 private final JLabel daysLabel;
    361                 private final JCheckBox trainFromUserCheckBox;
    362                 private final JPanel userHistoryPanel;
    363                 private Integer daysValue;
    364                 private String usernameValue;
    365                 private TrainWorker trainWorker;
    366                 private UserDataExtractAndTrainWorker userDataExtractAndTrainWorker;
    367 
    368                 private TrainingDialog(String key, int row, Map<String, Integer> map, final boolean initialFocusOnKey) {
    369                         super(Main.parent, tr("Training process configuration"), new String[] {tr("Cancel")});
    370 
    371                         setButtonIcons(new String[] {"ok", "cancel"});
    372                         setCancelButton(2);
    373 
    374                         JPanel mainPanel = new JPanel(new BorderLayout(10, 10));   //6,6
    375                         JPanel configPanel = new JPanel(new BorderLayout(10, 10));  //6,6    //at NORTH of mainPanel
    376                         JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));    //NORTH at config panel
    377                         JPanel paramPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));    //WEST at config panel //config panel has EAST free
    378 
    379                         JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));    //SOUTH at config panel
    380                         userHistoryPanel = new JPanel(); //CENTER of config
    381 
    382                         trainingProgressBar = new JProgressBar(0, 100);
    383 
    384                         ButtonGroup paramGroup = new ButtonGroup();
    385                         ButtonGroup userGroup = new ButtonGroup();
    386                         inputFileLabel = new JLabel();
    387                         inputFileField = new JTextField();
    388                         cParameterField = new JTextField();
    389                         topKField = new JTextField();
    390                         frequencyField = new JTextField();
    391 
    392                         cParameterCheckBox = new JCheckBox("Define C parameter");
    393                         topKButton = new JRadioButton("Top-K terms");
    394                         frequencyButton = new JRadioButton("Max-Frequency");
    395                         fileBrowseButton = new JButton();
    396                         acceptConfigButton = new JButton("Accept Configuration");
    397                         resetConfigButton = new JButton("Reset Configuration/Cancel training");
    398                         startTrainingButton = new JButton("Train Model");
    399 
    400                         inputFileErrorMessageLabel = new JLabel("");
    401                         cErrorMessageLabel = new JLabel("");
    402                         topKErrorMessageLabel = new JLabel("");
    403                         frequencyErrorMessageLabel = new JLabel("");
    404 
    405                         trainFromUserCheckBox = new JCheckBox("Train Model From User");
    406                         byAreaRadioButton = new JRadioButton("By Area");
    407                         byTimeRadioButton = new JRadioButton("By Time");
    408                         userNameLabel = new JLabel("Username:");
    409                         userNameField = new JTextField();
    410 
    411                         daysLabel = new JLabel("Days: ");
    412                         daysField = new JTextField();
    413 
    414                         cParameterCheckBox.setSelected(true);
    415                         userHistoryPanel.setEnabled(false);
    416                         byAreaRadioButton.setEnabled(false);
    417                         byAreaRadioButton.setSelected(true);
    418                         byTimeRadioButton.setEnabled(false);
    419                         userNameLabel.setEnabled(false);
    420                         userNameField.setEnabled(false);
    421                         daysLabel.setEnabled(false);
    422                         daysField.setEnabled(false);
    423                         userNameField.setColumns(FIELD_COLUMNS);
    424                         daysField.setColumns(FIELD_COLUMNS);
    425 
    426                         Collection<String> fileHistory = Main.pref.getCollection("file-open.history");
    427                         if (!fileHistory.isEmpty()) {
    428                                 inputFileField.setText(MAIN_PATH);
    429                         }
    430 
    431                         fileBrowseButton.setText("...");
    432                         inputFileLabel.setText("OSM filepath: ");
    433                         inputFileErrorMessageLabel.setForeground(Color.RED);
    434                         inputFileErrorMessageLabel.setText("");
    435                         topKField.setText("50");
    436                         frequencyField.setText("200");
    437                         cParameterField.setText("0.01");
    438 
    439                         cParameterField.setColumns(FIELD_COLUMNS);
    440                         cParameterField.setEditable(false);
    441                         cParameterField.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
    442                         cErrorMessageLabel.setForeground(Color.RED);
    443                         cErrorMessageLabel.setMinimumSize(new Dimension(150, 10));
    444 
    445                         topKButton.setSelected(true);
    446                         topKField.setColumns(FIELD_COLUMNS);
    447                         topKField.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
    448                         topKErrorMessageLabel.setForeground(Color.RED);
    449 
    450                         frequencyField.setEditable(false);
    451                         frequencyField.setColumns(FIELD_COLUMNS);
    452                         frequencyField.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
    453                         frequencyErrorMessageLabel.setForeground(Color.RED);
    454 
    455                         fileBrowseButton.addActionListener(new java.awt.event.ActionListener() {
    456                                 @Override
    457                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    458                                         inputFileChooserButtonActionPerformed(evt);
    459                                 }
    460                         });
    461                         topKButton.addActionListener(new java.awt.event.ActionListener() {
    462                                 @Override
    463                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    464                                         if (topKButton.isSelected()) {
    465                                                 frequencyField.setEditable(false);
    466                                                 topKField.setEditable(true);
    467                                         } else {
    468                                                 frequencyField.setEditable(true);
    469                                                 topKField.setEditable(false);
    470                                         }
    471                                 }
    472                         });
    473                         frequencyButton.addActionListener(new java.awt.event.ActionListener() {
    474                                 @Override
    475                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    476                                         if (frequencyButton.isSelected()) {
    477                                                 topKField.setEditable(false);
    478                                                 frequencyField.setEditable(true);
    479                                         } else {
    480                                                 topKField.setEditable(true);
    481                                                 frequencyField.setEditable(false);
    482                                         }
    483                                 }
    484                         });
    485                         cParameterCheckBox.addActionListener(new java.awt.event.ActionListener() {
    486                                 @Override
    487                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    488                                         if (cParameterCheckBox.isSelected()) {
    489                                                 cParameterField.setEditable(true);
    490                                         } else {
    491                                                 cParameterField.setEditable(false);
    492                                         }
    493                                 }
    494                         });
    495                         acceptConfigButton.addActionListener(new java.awt.event.ActionListener() {
    496                                 @Override
    497                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    498                                         acceptConfigButtonActionPerformed(evt);
    499                                 }
    500                         });
    501                         resetConfigButton.addActionListener(new java.awt.event.ActionListener() {
    502                                 @Override
    503                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    504                                         resetConfigButtonActionPerformed();
    505                                 }
    506                         });
    507 
    508                         startTrainingButton.addActionListener(new java.awt.event.ActionListener() {
    509                                 @Override
    510                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    511                                         if (!acceptConfigButton.isEnabled()) {
    512                                                 startTraining();
    513                                         } else {
    514                                                 System.out.println("Set values first!");
    515                                         }
    516                                 }
    517                         });
    518 
    519                         trainFromUserCheckBox.addActionListener(new java.awt.event.ActionListener() {
    520                                 @Override
    521                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    522                                         if (trainFromUserCheckBox.isSelected()) {
    523                                                 userHistoryPanel.setEnabled(true);
    524                                                 byAreaRadioButton.setEnabled(true);
    525                                                 byTimeRadioButton.setEnabled(true);
    526                                                 userNameLabel.setEnabled(true);
    527                                                 userNameField.setEnabled(true);
    528                                                 daysLabel.setEnabled(true);
    529                                                 daysField.setEnabled(true);
    530                                         } else {
    531                                                 userHistoryPanel.setEnabled(false);
    532                                                 byAreaRadioButton.setEnabled(false);
    533                                                 byTimeRadioButton.setEnabled(false);
    534                                                 userNameLabel.setEnabled(false);
    535                                                 userNameField.setEnabled(false);
    536                                                 daysLabel.setEnabled(false);
    537                                                 daysField.setEnabled(false);
    538                                         }
    539                                 }
    540                         });
    541 
    542                         byAreaRadioButton.addActionListener(new java.awt.event.ActionListener() {
    543                                 @Override
    544                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    545                                         if (byAreaRadioButton.isSelected()) {
    546                                                 daysField.setEditable(false);
    547                                         } else {
    548                                                 daysField.setEditable(true);
    549                                         }
    550                                 }
    551                         });
    552 
    553                         byTimeRadioButton.addActionListener(new java.awt.event.ActionListener() {
    554                                 @Override
    555                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    556                                         if (byTimeRadioButton.isSelected()) {
    557                                                 daysField.setEditable(true);
    558                                         } else {
    559                                                 daysField.setEditable(false);
    560                                         }
    561                                 }
    562                         });
    563 
    564                         //grouplayout for input panel
    565                         buildInputPanelGroupLayout(inputPanel);
    566 
    567                         //grouplayout for param panel
    568                         buildParamPanelGroupLayout(paramPanel);
    569 
    570                         inputPanel.add(inputFileLabel);
    571                         inputPanel.add(inputFileField);
    572                         inputPanel.add(fileBrowseButton);
    573                         inputPanel.add(inputFileErrorMessageLabel);
    574 
    575                         paramGroup.add(topKButton);
    576                         paramGroup.add(frequencyButton);
    577 
    578                         paramPanel.add(cParameterCheckBox);
    579                         paramPanel.add(cParameterField);
    580                         paramPanel.add(cErrorMessageLabel);
    581                         paramPanel.add(topKButton);
    582                         paramPanel.add(topKField);
    583                         paramPanel.add(topKErrorMessageLabel);
    584                         paramPanel.add(frequencyButton);
    585                         paramPanel.add(frequencyField);
    586                         paramPanel.add(frequencyErrorMessageLabel);
    587 
    588                         southPanel.add(acceptConfigButton);
    589                         southPanel.add(resetConfigButton);
    590                         southPanel.add(trainFromUserCheckBox);
    591 
    592                         userGroup.add(byAreaRadioButton);
    593                         userGroup.add(byTimeRadioButton);
    594                         userHistoryPanel.add(byAreaRadioButton);
    595                         userHistoryPanel.add(byTimeRadioButton);
    596                         userHistoryPanel.add(daysLabel);
    597                         userHistoryPanel.add(daysField);
    598                         userHistoryPanel.add(userNameLabel);
    599                         userHistoryPanel.add(userNameField);
    600 
    601                         //grouplayout for user history panel
    602                         /*
     148    private final DefaultTableModel tagData;
     149    private static Collection<String> fileHistory;
     150    private Map<File, Double> filesAndWeights = new HashMap<>();
     151    private boolean useCombinedModel;
     152
     153    //the most recent file from history.
     154    //all necessary files will reside in a directory of this file
     155    private static String MAIN_PATH;
     156    private static String MODEL_PATH;
     157    private static String TEXTUAL_LIST_PATH;
     158    private static Map<String, List<String>> indirectClasses;
     159    private static Map<String, Integer> indirectClassesWithIDs;
     160    private static LanguageDetector languageDetector;
     161    private static String bestModelPath;
     162    private boolean modelWithClasses;
     163    private final String modelWithClassesPath;
     164    private boolean useCustomSVMModel = false;
     165    private String customSVMModelPath;
     166    private final String combinedModelClasses;
     167    private final String combinedModel;
     168
     169    // Selection that we are editing by using both dialogs
     170    Collection<OsmPrimitive> sel;
     171
     172    private String changedKey;
     173
     174    Comparator<AutoCompletionListItem> defaultACItemComparator = new Comparator<AutoCompletionListItem>() {
     175        @Override
     176        public int compare(AutoCompletionListItem o1, AutoCompletionListItem o2) {
     177            return String.CASE_INSENSITIVE_ORDER.compare(o1.getValue(), o2.getValue());
     178        }
     179    };
     180
     181    private String lastAddKey = null;
     182    private String lastAddValue = null;
     183
     184    public static final int DEFAULT_LRU_TAGS_NUMBER = 5;
     185    public static final int MAX_LRU_TAGS_NUMBER = 30;
     186
     187    // LRU cache for recently added tags (http://java-planet.blogspot.com/2005/08/how-to-set-up-simple-lru-cache-using.html)
     188    private final Map<Tag, Void> recentTags = new LinkedHashMap<Tag, Void>(MAX_LRU_TAGS_NUMBER+1, 1.1f, true) {
     189        @Override
     190        protected boolean removeEldestEntry(Map.Entry<Tag, Void> eldest) {
     191            return size() > MAX_LRU_TAGS_NUMBER;
     192        }
     193    };
     194
     195    OSMRecPluginHelper(DefaultTableModel propertyData, Map<String, Map<String, Integer>> valueCount) {
     196        this.tagData = propertyData;
     197        fileHistory = Main.pref.getCollection("file-open.history");
     198        if (!fileHistory.isEmpty()) {
     199            MAIN_PATH = (String) fileHistory.toArray()[0];
     200        } else {
     201            MAIN_PATH = System.getProperty("user.home");
     202        }
     203        MODEL_PATH = new File(MAIN_PATH).getParentFile() + "/OSMRec_models";
     204        TEXTUAL_LIST_PATH = MODEL_PATH + "/textualList.txt";
     205        combinedModelClasses = MODEL_PATH + "/combinedModel.1";
     206        combinedModel = MODEL_PATH + "/combinedModel.0";
     207        bestModelPath = MODEL_PATH + "/best_model";
     208        customSVMModelPath = bestModelPath;
     209        modelWithClassesPath = MODEL_PATH + "/model_with_classes";
     210        languageDetector = LanguageDetector.getInstance(MODEL_PATH + "/profiles");
     211
     212        SampleModelsExtractor sampleModelsExtractor = new SampleModelsExtractor();
     213
     214        sampleModelsExtractor.extractSampleSVMmodel("best_model", bestModelPath);
     215        sampleModelsExtractor.extractSampleSVMmodel("model_with_classes", modelWithClassesPath);
     216    }
     217
     218    /**
     219    * Open the add selection dialog and add a new key/value to the table (and to the dataset, of course).
     220    */
     221    public void addTag() {
     222        changedKey = null;
     223        sel = Main.main.getInProgressSelection();
     224        if (sel == null || sel.isEmpty()) return;
     225
     226        final AddTagsDialog addDialog = new AddTagsDialog();
     227
     228        addDialog.showDialog();
     229
     230        addDialog.destroyActions();
     231        if (addDialog.getValue() == 1)
     232            addDialog.performTagAdding();
     233        else
     234            addDialog.undoAllTagsAdding();
     235    }
     236
     237    /**
     238    * Edit the value in the tags table row.
     239    * @param row The row of the table from which the value is edited.
     240    * @param focusOnKey Determines if the initial focus should be set on key instead of value
     241    * @since 5653
     242    */
     243    public void editTag(final int row, boolean focusOnKey) {
     244        changedKey = null;
     245        sel = Main.main.getInProgressSelection();
     246        String key = "";
     247
     248        @SuppressWarnings("unchecked")
     249        Map<String, Integer> dumPar = new HashMap<>();
     250        dumPar.put(" ", -1);
     251        final TrainingDialog editDialog = new TrainingDialog(key, row,
     252                dumPar, focusOnKey);
     253        editDialog.showDialog();
     254    }
     255
     256    /**
     257    * If during last editProperty call user changed the key name, this key will be returned
     258    * Elsewhere, returns null.
     259    * @return The modified key, or {@code null}
     260    */
     261    public String getChangedKey() {
     262        return changedKey;
     263    }
     264
     265    /**
     266    * For a given key k, return a list of keys which are used as keys for
     267    * auto-completing values to increase the search space.
     268    * @param key the key k
     269    * @return a list of keys
     270    */
     271    private static List<String> getAutocompletionKeys(String key) {
     272        if ("name".equals(key) || "addr:street".equals(key))
     273            return Arrays.asList("addr:street", "name");
     274        else
     275            return Arrays.asList(key);
     276    }
     277
     278    /**
     279    * Load recently used tags from preferences if needed.
     280    */
     281    public void loadTagsIfNeeded() {
     282        if (PROPERTY_REMEMBER_TAGS.get() && recentTags.isEmpty()) {
     283            recentTags.clear();
     284            Collection<String> c = Main.pref.getCollection("properties.recent-tags");
     285            Iterator<String> it = c.iterator();
     286            String key, value;
     287            while (it.hasNext()) {
     288                key = it.next();
     289                value = it.next();
     290                recentTags.put(new Tag(key, value), null);
     291            }
     292        }
     293    }
     294
     295    /**
     296    * Store recently used tags in preferences if needed.
     297    */
     298    public void saveTagsIfNeeded() {
     299        if (PROPERTY_REMEMBER_TAGS.get() && !recentTags.isEmpty()) {
     300            List<String> c = new ArrayList<>(recentTags.size()*2);
     301            for (Tag t: recentTags.keySet()) {
     302                c.add(t.getKey());
     303                c.add(t.getValue());
     304            }
     305            Main.pref.putCollection("properties.recent-tags", c);
     306        }
     307    }
     308
     309    /**
     310    * Warns user about a key being overwritten.
     311    * @param action The action done by the user. Must state what key is changed
     312    * @param togglePref  The preference to save the checkbox state to
     313    * @return {@code true} if the user accepts to overwrite key, {@code false} otherwise
     314    */
     315    private boolean warnOverwriteKey(String action, String togglePref) {
     316        ExtendedDialog ed = new ExtendedDialog(
     317                Main.parent,
     318                tr("Overwrite key"),
     319                new String[]{tr("Replace"), tr("Cancel")});
     320        ed.setButtonIcons(new String[]{"purge", "cancel"});
     321        ed.setContent(action+"\n"+ tr("The new key is already used, overwrite values?"));
     322        ed.setCancelButton(2);
     323        ed.toggleEnable(togglePref);
     324        ed.showDialog();
     325
     326        return ed.getValue() == 1;
     327    }
     328
     329    public final class TrainingDialog extends AbstractTagsDialog {
     330
     331        private static final int FIELD_COLUMNS = 4;
     332        private final JTextField inputFileField;
     333        private final JLabel inputFileLabel;
     334        private final JTextField topKField;
     335        private final JTextField cParameterField;
     336        private final JTextField frequencyField;
     337
     338        private final JButton fileBrowseButton;
     339        private final JButton acceptConfigButton;
     340        private JRadioButton frequencyButton;
     341        private JRadioButton topKButton;
     342        private JCheckBox cParameterCheckBox;
     343        private final JButton resetConfigButton;
     344        private String inputFileValue;
     345        private Double cParameterValue = 0.0;
     346        private Integer topKvalue = 0;
     347        private Integer frequencyValue = 0;
     348        private boolean crossValidateFlag;
     349        private final JButton startTrainingButton;
     350        private final JLabel cErrorMessageLabel;
     351        private final JLabel topKErrorMessageLabel;
     352        private final JLabel inputFileErrorMessageLabel;
     353        private final JLabel frequencyErrorMessageLabel;
     354        private final JProgressBar trainingProgressBar;
     355        private final JRadioButton byAreaRadioButton;
     356        private final JRadioButton byTimeRadioButton;
     357        private final JLabel userNameLabel;
     358        private final JTextField userNameField;
     359        private final JTextField daysField;
     360        private final JLabel daysLabel;
     361        private final JCheckBox trainFromUserCheckBox;
     362        private final JPanel userHistoryPanel;
     363        private Integer daysValue;
     364        private String usernameValue;
     365        private TrainWorker trainWorker;
     366        private UserDataExtractAndTrainWorker userDataExtractAndTrainWorker;
     367
     368        private TrainingDialog(String key, int row, Map<String, Integer> map, final boolean initialFocusOnKey) {
     369            super(Main.parent, tr("Training process configuration"), new String[] {tr("Cancel")});
     370
     371            setButtonIcons(new String[] {"ok", "cancel"});
     372            setCancelButton(2);
     373
     374            JPanel mainPanel = new JPanel(new BorderLayout(10, 10));   //6,6
     375            JPanel configPanel = new JPanel(new BorderLayout(10, 10));  //6,6    //at NORTH of mainPanel
     376            JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));    //NORTH at config panel
     377            JPanel paramPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));    //WEST at config panel //config panel has EAST free
     378
     379            JPanel southPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));    //SOUTH at config panel
     380            userHistoryPanel = new JPanel(); //CENTER of config
     381
     382            trainingProgressBar = new JProgressBar(0, 100);
     383
     384            ButtonGroup paramGroup = new ButtonGroup();
     385            ButtonGroup userGroup = new ButtonGroup();
     386            inputFileLabel = new JLabel();
     387            inputFileField = new JTextField();
     388            cParameterField = new JTextField();
     389            topKField = new JTextField();
     390            frequencyField = new JTextField();
     391
     392            cParameterCheckBox = new JCheckBox("Define C parameter");
     393            topKButton = new JRadioButton("Top-K terms");
     394            frequencyButton = new JRadioButton("Max-Frequency");
     395            fileBrowseButton = new JButton();
     396            acceptConfigButton = new JButton("Accept Configuration");
     397            resetConfigButton = new JButton("Reset Configuration/Cancel training");
     398            startTrainingButton = new JButton("Train Model");
     399
     400            inputFileErrorMessageLabel = new JLabel("");
     401            cErrorMessageLabel = new JLabel("");
     402            topKErrorMessageLabel = new JLabel("");
     403            frequencyErrorMessageLabel = new JLabel("");
     404
     405            trainFromUserCheckBox = new JCheckBox("Train Model From User");
     406            byAreaRadioButton = new JRadioButton("By Area");
     407            byTimeRadioButton = new JRadioButton("By Time");
     408            userNameLabel = new JLabel("Username:");
     409            userNameField = new JTextField();
     410
     411            daysLabel = new JLabel("Days: ");
     412            daysField = new JTextField();
     413
     414            cParameterCheckBox.setSelected(true);
     415            userHistoryPanel.setEnabled(false);
     416            byAreaRadioButton.setEnabled(false);
     417            byAreaRadioButton.setSelected(true);
     418            byTimeRadioButton.setEnabled(false);
     419            userNameLabel.setEnabled(false);
     420            userNameField.setEnabled(false);
     421            daysLabel.setEnabled(false);
     422            daysField.setEnabled(false);
     423            userNameField.setColumns(FIELD_COLUMNS);
     424            daysField.setColumns(FIELD_COLUMNS);
     425
     426            Collection<String> fileHistory = Main.pref.getCollection("file-open.history");
     427            if (!fileHistory.isEmpty()) {
     428                inputFileField.setText(MAIN_PATH);
     429            }
     430
     431            fileBrowseButton.setText("...");
     432            inputFileLabel.setText("OSM filepath: ");
     433            inputFileErrorMessageLabel.setForeground(Color.RED);
     434            inputFileErrorMessageLabel.setText("");
     435            topKField.setText("50");
     436            frequencyField.setText("200");
     437            cParameterField.setText("0.01");
     438
     439            cParameterField.setColumns(FIELD_COLUMNS);
     440            cParameterField.setEditable(false);
     441            cParameterField.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
     442            cErrorMessageLabel.setForeground(Color.RED);
     443            cErrorMessageLabel.setMinimumSize(new Dimension(150, 10));
     444
     445            topKButton.setSelected(true);
     446            topKField.setColumns(FIELD_COLUMNS);
     447            topKField.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
     448            topKErrorMessageLabel.setForeground(Color.RED);
     449
     450            frequencyField.setEditable(false);
     451            frequencyField.setColumns(FIELD_COLUMNS);
     452            frequencyField.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
     453            frequencyErrorMessageLabel.setForeground(Color.RED);
     454
     455            fileBrowseButton.addActionListener(new java.awt.event.ActionListener() {
     456                @Override
     457                public void actionPerformed(java.awt.event.ActionEvent evt) {
     458                    inputFileChooserButtonActionPerformed(evt);
     459                }
     460            });
     461            topKButton.addActionListener(new java.awt.event.ActionListener() {
     462                @Override
     463                public void actionPerformed(java.awt.event.ActionEvent evt) {
     464                    if (topKButton.isSelected()) {
     465                        frequencyField.setEditable(false);
     466                        topKField.setEditable(true);
     467                    } else {
     468                        frequencyField.setEditable(true);
     469                        topKField.setEditable(false);
     470                    }
     471                }
     472            });
     473            frequencyButton.addActionListener(new java.awt.event.ActionListener() {
     474                @Override
     475                public void actionPerformed(java.awt.event.ActionEvent evt) {
     476                    if (frequencyButton.isSelected()) {
     477                        topKField.setEditable(false);
     478                        frequencyField.setEditable(true);
     479                    } else {
     480                        topKField.setEditable(true);
     481                        frequencyField.setEditable(false);
     482                    }
     483                }
     484            });
     485            cParameterCheckBox.addActionListener(new java.awt.event.ActionListener() {
     486                @Override
     487                public void actionPerformed(java.awt.event.ActionEvent evt) {
     488                    if (cParameterCheckBox.isSelected()) {
     489                        cParameterField.setEditable(true);
     490                    } else {
     491                        cParameterField.setEditable(false);
     492                    }
     493                }
     494            });
     495            acceptConfigButton.addActionListener(new java.awt.event.ActionListener() {
     496                @Override
     497                public void actionPerformed(java.awt.event.ActionEvent evt) {
     498                    acceptConfigButtonActionPerformed(evt);
     499                }
     500            });
     501            resetConfigButton.addActionListener(new java.awt.event.ActionListener() {
     502                @Override
     503                public void actionPerformed(java.awt.event.ActionEvent evt) {
     504                    resetConfigButtonActionPerformed();
     505                }
     506            });
     507
     508            startTrainingButton.addActionListener(new java.awt.event.ActionListener() {
     509                @Override
     510                public void actionPerformed(java.awt.event.ActionEvent evt) {
     511                    if (!acceptConfigButton.isEnabled()) {
     512                        startTraining();
     513                    } else {
     514                        System.out.println("Set values first!");
     515                    }
     516                }
     517            });
     518
     519            trainFromUserCheckBox.addActionListener(new java.awt.event.ActionListener() {
     520                @Override
     521                public void actionPerformed(java.awt.event.ActionEvent evt) {
     522                    if (trainFromUserCheckBox.isSelected()) {
     523                        userHistoryPanel.setEnabled(true);
     524                        byAreaRadioButton.setEnabled(true);
     525                        byTimeRadioButton.setEnabled(true);
     526                        userNameLabel.setEnabled(true);
     527                        userNameField.setEnabled(true);
     528                        daysLabel.setEnabled(true);
     529                        daysField.setEnabled(true);
     530                    } else {
     531                        userHistoryPanel.setEnabled(false);
     532                        byAreaRadioButton.setEnabled(false);
     533                        byTimeRadioButton.setEnabled(false);
     534                        userNameLabel.setEnabled(false);
     535                        userNameField.setEnabled(false);
     536                        daysLabel.setEnabled(false);
     537                        daysField.setEnabled(false);
     538                    }
     539                }
     540            });
     541
     542            byAreaRadioButton.addActionListener(new java.awt.event.ActionListener() {
     543                @Override
     544                public void actionPerformed(java.awt.event.ActionEvent evt) {
     545                    if (byAreaRadioButton.isSelected()) {
     546                        daysField.setEditable(false);
     547                    } else {
     548                        daysField.setEditable(true);
     549                    }
     550                }
     551            });
     552
     553            byTimeRadioButton.addActionListener(new java.awt.event.ActionListener() {
     554                @Override
     555                public void actionPerformed(java.awt.event.ActionEvent evt) {
     556                    if (byTimeRadioButton.isSelected()) {
     557                        daysField.setEditable(true);
     558                    } else {
     559                        daysField.setEditable(false);
     560                    }
     561                }
     562            });
     563
     564            //grouplayout for input panel
     565            buildInputPanelGroupLayout(inputPanel);
     566
     567            //grouplayout for param panel
     568            buildParamPanelGroupLayout(paramPanel);
     569
     570            inputPanel.add(inputFileLabel);
     571            inputPanel.add(inputFileField);
     572            inputPanel.add(fileBrowseButton);
     573            inputPanel.add(inputFileErrorMessageLabel);
     574
     575            paramGroup.add(topKButton);
     576            paramGroup.add(frequencyButton);
     577
     578            paramPanel.add(cParameterCheckBox);
     579            paramPanel.add(cParameterField);
     580            paramPanel.add(cErrorMessageLabel);
     581            paramPanel.add(topKButton);
     582            paramPanel.add(topKField);
     583            paramPanel.add(topKErrorMessageLabel);
     584            paramPanel.add(frequencyButton);
     585            paramPanel.add(frequencyField);
     586            paramPanel.add(frequencyErrorMessageLabel);
     587
     588            southPanel.add(acceptConfigButton);
     589            southPanel.add(resetConfigButton);
     590            southPanel.add(trainFromUserCheckBox);
     591
     592            userGroup.add(byAreaRadioButton);
     593            userGroup.add(byTimeRadioButton);
     594            userHistoryPanel.add(byAreaRadioButton);
     595            userHistoryPanel.add(byTimeRadioButton);
     596            userHistoryPanel.add(daysLabel);
     597            userHistoryPanel.add(daysField);
     598            userHistoryPanel.add(userNameLabel);
     599            userHistoryPanel.add(userNameField);
     600
     601            //grouplayout for user history panel
     602            /*
    603603                userNameLabel       userField
    604604                arearadiobutton
    605605                timeradiobutton     daysLabel   daysField
    606                         */
    607                         buildUserHistoryPanelGroupLayout();
    608 
    609                         configPanel.add(inputPanel, BorderLayout.NORTH);
    610                         configPanel.add(userHistoryPanel, BorderLayout.EAST);
    611                         configPanel.add(paramPanel, BorderLayout.WEST);
    612                         configPanel.add(southPanel, BorderLayout.SOUTH);
    613 
    614                         userHistoryPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
    615                                         .createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE), "Train by user History"));
    616                         paramPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
    617                                         .createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE), "SVM Configuration"));
    618                         inputPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
    619                         configPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
    620 
    621                         mainPanel.add(configPanel, BorderLayout.NORTH);
    622                         mainPanel.add(startTrainingButton, BorderLayout.CENTER);
    623                         mainPanel.add(trainingProgressBar, BorderLayout.SOUTH);
    624 
    625                         AutoCompletionManager autocomplete = MainApplication.getLayerManager().getEditLayer().data.getAutoCompletionManager();
    626                         List<AutoCompletionListItem> keyList = autocomplete.getKeys();
    627                         Collections.sort(keyList, defaultACItemComparator);
    628 
    629                         setContent(mainPanel, false);
    630                 }
    631 
    632                 private void buildInputPanelGroupLayout(JPanel inputPanel) {
    633                         GroupLayout inputGroupLayout = new GroupLayout(inputPanel);
    634                         inputPanel.setLayout(inputGroupLayout);
    635                         inputGroupLayout.setAutoCreateGaps(true);
    636                         inputGroupLayout.setAutoCreateContainerGaps(true);
    637 
    638                         GroupLayout.SequentialGroup inputHorGroup = inputGroupLayout.createSequentialGroup();
    639                         inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(inputFileLabel).
    640                                         addComponent(inputFileErrorMessageLabel));
    641                         inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(inputFileField));
    642                         inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(fileBrowseButton));
    643                         inputGroupLayout.setHorizontalGroup(inputHorGroup);
    644 
    645                         GroupLayout.SequentialGroup inputVerGroup = inputGroupLayout.createSequentialGroup();
    646                         inputVerGroup.addGroup(inputGroupLayout.createParallelGroup(Alignment.LEADING).addComponent(inputFileLabel).
    647                                         addComponent(inputFileField).addComponent(fileBrowseButton));
    648                         inputVerGroup.addGroup(inputGroupLayout.createParallelGroup(Alignment.LEADING).
    649                                         addComponent(inputFileErrorMessageLabel));
    650                         inputGroupLayout.setVerticalGroup(inputVerGroup);
    651                 }
    652 
    653                 private void buildParamPanelGroupLayout(JPanel paramPanel) {
    654                         GroupLayout paramGroupLayout = new GroupLayout(paramPanel);
    655                         paramPanel.setLayout(paramGroupLayout);
    656                         paramGroupLayout.setAutoCreateGaps(true);
    657                         paramGroupLayout.setAutoCreateContainerGaps(true);
    658 
    659                         GroupLayout.SequentialGroup paramHorGroup = paramGroupLayout.createSequentialGroup();
    660                         paramHorGroup.addGroup(paramGroupLayout.createParallelGroup().addComponent(topKButton).
    661                                         addComponent(frequencyButton).addComponent(cParameterCheckBox));
    662                         paramHorGroup.addGroup(paramGroupLayout.createParallelGroup().addComponent(cParameterField).
    663                                         addComponent(topKField).addComponent(frequencyField));
    664                         paramHorGroup.addGroup(paramGroupLayout.createParallelGroup().addComponent(cErrorMessageLabel).
    665                                         addComponent(topKErrorMessageLabel).addComponent(frequencyErrorMessageLabel));
    666                         paramGroupLayout.setHorizontalGroup(paramHorGroup);
    667 
    668                         GroupLayout.SequentialGroup paramVerGroup = paramGroupLayout.createSequentialGroup();
    669                         paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).
    670                                         addComponent(cParameterCheckBox).addComponent(cParameterField).addComponent(cErrorMessageLabel));
    671                         paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).addComponent(topKButton).
    672                                         addComponent(topKField).addComponent(topKErrorMessageLabel));
    673                         paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).
    674                                         addComponent(frequencyButton).addComponent(frequencyField).addComponent(frequencyErrorMessageLabel));
    675                         paramGroupLayout.setVerticalGroup(paramVerGroup);
    676                 }
    677 
    678                 private void buildUserHistoryPanelGroupLayout() {
    679                         GroupLayout userHistoryGroupLayout = new GroupLayout(userHistoryPanel);
    680                         userHistoryPanel.setLayout(userHistoryGroupLayout);
    681                         userHistoryGroupLayout.setAutoCreateGaps(true);
    682                         userHistoryGroupLayout.setAutoCreateContainerGaps(true);
    683                         userHistoryGroupLayout.linkSize(SwingConstants.HORIZONTAL, userNameField, daysLabel, daysField);
    684 
    685                         GroupLayout.SequentialGroup userHistoryHorGroup = userHistoryGroupLayout.createSequentialGroup();
    686 
    687                         userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(userNameLabel)
    688                                         .addComponent(byAreaRadioButton).addComponent(byTimeRadioButton));
    689                         userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(userNameField)
    690                                         .addComponent(daysLabel));
    691                         userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(daysField));
    692                         userHistoryGroupLayout.setHorizontalGroup(userHistoryHorGroup);
    693 
    694                         GroupLayout.SequentialGroup userHistoryVerGroup = userHistoryGroupLayout.createSequentialGroup();
    695                         userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
    696                                         addComponent(userNameLabel).addComponent(userNameField));
    697                         userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
    698                                         addComponent(byAreaRadioButton));
    699                         userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
    700                                         addComponent(byTimeRadioButton).addComponent(daysLabel).addComponent(daysField));
    701                         userHistoryGroupLayout.setVerticalGroup(userHistoryVerGroup);
    702                 }
    703 
    704                 private void inputFileChooserButtonActionPerformed(ActionEvent evt) {
    705                         try {
    706                                 final File file = new File(inputFileField.getText());
    707                                 final JFileChooser fileChooser = new JFileChooser(file);
    708 
    709                                 final int returnVal = fileChooser.showOpenDialog(this);
    710                                 if (returnVal == JFileChooser.APPROVE_OPTION) {
    711                                         inputFileField.setText(fileChooser.getSelectedFile().getAbsolutePath());
    712                                 }
    713                         } catch (RuntimeException ex) {
    714                                 Logging.warn(ex);
    715                         }
    716                 }
    717 
    718                 private void acceptConfigButtonActionPerformed(ActionEvent evt) {
    719                         //parse values
    720                         inputFileValue = inputFileField.getText();
    721 
    722                         if (!new File(inputFileValue).exists()) {
    723                                 inputFileErrorMessageLabel.setText("OSM file does not exist");
    724                                 resetConfigButtonActionPerformed();
    725                                 return;
    726                         }
    727 
    728                         if (cParameterCheckBox.isSelected()) {
    729                                 String c = cParameterField.getText();
    730                                 try {
    731                                         cParameterValue = Double.parseDouble(c.replace(",", "."));
    732                                         cErrorMessageLabel.setText("");
    733                                 } catch (NumberFormatException ex) {
    734                                         cErrorMessageLabel.setText("Must be a number!");
    735                                         System.out.println("c must be a number!" + ex); //make empty textLabel beside c param to notify errors
    736                                         resetConfigButtonActionPerformed();
    737                                         return;
    738                                 }
    739                                 crossValidateFlag = false;
    740                         } else {
    741                                 crossValidateFlag = true;
    742                         }
    743 
    744                         if (topKButton.isSelected()) {
    745                                 String k = topKField.getText();
    746                                 try {
    747                                         topKvalue = Integer.parseInt(k);
    748                                         topKErrorMessageLabel.setText("");
    749                                 } catch (NumberFormatException ex) {
    750                                         topKErrorMessageLabel.setText("Must be an Integer!");
    751                                         resetConfigButtonActionPerformed();
    752                                         return;
    753                                 }
    754                         } else {
    755                                 String f = frequencyField.getText();
    756                                 try {
    757                                         frequencyValue = Integer.parseInt(f);
    758                                         frequencyErrorMessageLabel.setText("");
    759                                 } catch (NumberFormatException ex) {
    760                                         frequencyErrorMessageLabel.setText("Must be an Integer!");
    761                                         resetConfigButtonActionPerformed();
    762                                         return;
    763                                 }
    764                         }
    765 
    766                         if (trainFromUserCheckBox.isSelected()) {
    767                                 usernameValue = userNameField.getText();
    768                                 if (byTimeRadioButton.isSelected()) {
    769                                         try {
    770                                                 daysValue = Integer.parseInt(daysField.getText());
    771                                         } catch (NumberFormatException ex) {
    772                                                 daysField.setText("Integer!");
    773                                                 Logging.warn(ex);
    774                                         }
    775                                 }
    776 
    777                                 userHistoryPanel.setEnabled(false);
    778                                 byAreaRadioButton.setEnabled(false);
    779                                 byTimeRadioButton.setEnabled(false);
    780                                 userNameLabel.setEnabled(false);
    781                                 userNameField.setEnabled(false);
    782                                 daysLabel.setEnabled(false);
    783                                 daysField.setEnabled(false);
    784                         }
    785 
    786                         System.out.println("Running configuration:" + "\nC parameter: " + cParameterValue +" \ntopK: " + topKvalue
    787                                         + "\nMax Frequency: " + frequencyValue + "\nCross Validate?: " + crossValidateFlag);
    788 
    789                         trainFromUserCheckBox.setEnabled(false);
    790                         inputFileField.setEditable(false);
    791                         cParameterField.setEditable(false);
    792                         topKField.setEditable(false);
    793                         frequencyField.setEditable(false);
    794                         cParameterCheckBox.setEnabled(false);
    795                         topKButton.setEnabled(false);
    796                         frequencyButton.setEnabled(false);
    797                         acceptConfigButton.setEnabled(false);
    798                         fileBrowseButton.setEnabled(false);
    799                 }
    800 
    801                 private void resetConfigButtonActionPerformed() {
    802                         if (trainWorker != null) {
    803                                 try {
    804                                         trainWorker.cancel(true);
    805                                 } catch (CancellationException ex) {
    806                                         startTrainingButton.setEnabled(true);
    807                                         System.out.println(ex);
    808                                 }
    809                         }
    810                         if (userDataExtractAndTrainWorker != null) {
    811                                 try {
    812                                         userDataExtractAndTrainWorker.cancel(true);
    813                                 } catch (CancellationException ex) {
    814                                         startTrainingButton.setEnabled(true);
    815                                         System.out.println(ex);
    816                                 }
    817                         }
    818                         inputFileField.setEditable(true);
    819                         cParameterField.setEditable(true);
    820                         topKField.setEditable(true);
    821                         frequencyField.setEditable(true);
    822                         cParameterCheckBox.setEnabled(true);
    823                         topKButton.setEnabled(true);
    824                         frequencyButton.setEnabled(true);
    825                         acceptConfigButton.setEnabled(true);
    826                         fileBrowseButton.setEnabled(true);
    827                         trainFromUserCheckBox.setEnabled(true);
    828 
    829                         if (trainFromUserCheckBox.isSelected()) {
    830                                 userHistoryPanel.setEnabled(true);
    831                                 byAreaRadioButton.setEnabled(true);
    832                                 byTimeRadioButton.setEnabled(true);
    833                                 userNameLabel.setEnabled(true);
    834                                 userNameField.setEnabled(true);
    835                                 daysLabel.setEnabled(true);
    836                                 daysField.setEnabled(true);
    837                         }
    838                 }
    839 
    840                 private void startTraining() {
    841                         startTrainingButton.setEnabled(false);
    842 
    843                         if (trainFromUserCheckBox.isSelected()) { //if user training. train by area or days
    844                                 EventQueue.invokeLater(new Runnable() {
    845                                         @Override
    846                                         public void run() {
    847 
    848                                                 userDataExtractAndTrainWorker = new UserDataExtractAndTrainWorker(inputFileValue, usernameValue, daysValue,
    849                                                                 byAreaRadioButton.isSelected(), crossValidateFlag, cParameterValue, topKvalue, frequencyValue,
    850                                                                 topKButton.isSelected(), languageDetector);
    851 
    852                                                 userDataExtractAndTrainWorker.addPropertyChangeListener(new PropertyChangeListener() {
    853                                                         @Override
    854                                                         public void propertyChange(PropertyChangeEvent evt) {
    855                                                                 if ("progress".equals(evt.getPropertyName())) {
    856                                                                         int progress = (Integer) evt.getNewValue();
    857                                                                         trainingProgressBar.setValue(progress);
    858                                                                         if (progress == 100) {
    859                                                                                 startTrainingButton.setEnabled(true);
    860                                                                         }
    861                                                                 }
    862                                                         }
    863                                                 });
    864 
    865                                                 try {
    866                                                         System.out.println("executing userDataExtractAndTrainWorker Thread..");
    867                                                         userDataExtractAndTrainWorker.execute();
    868                                                 } catch (Exception ex) {
    869                                                         Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
    870                                                 }
    871                                         }
    872                                 });
    873                         } else {
    874                                 EventQueue.invokeLater(new Runnable() {
    875                                         @Override
    876                                         public void run() {
    877                                                 trainWorker = new TrainWorker(inputFileValue, crossValidateFlag, cParameterValue, topKvalue, frequencyValue,
    878                                                                 topKButton.isSelected(), languageDetector);
    879 
    880                                                 trainWorker.addPropertyChangeListener(new PropertyChangeListener() {
    881                                                         @Override
    882                                                         public void propertyChange(PropertyChangeEvent evt) {
    883                                                                 if ("progress".equals(evt.getPropertyName())) {
    884                                                                         int progress = (Integer) evt.getNewValue();
    885                                                                         trainingProgressBar.setValue(progress);
    886                                                                         if (progress == 100) {
    887                                                                                 startTrainingButton.setEnabled(true);
    888                                                                         }
    889                                                                 }
    890                                                         }
    891                                                 });
    892 
    893                                                 try {
    894                                                         trainWorker.execute();
    895                                                 } catch (Exception ex) {
    896                                                         Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
    897                                                 }
    898                                         }
    899                                 });
    900                         }
    901                 }
    902         }
    903 
    904         public static final BooleanProperty PROPERTY_FIX_TAG_LOCALE =
    905                         new BooleanProperty("properties.fix-tag-combobox-locale", false);
    906         public static final BooleanProperty PROPERTY_REMEMBER_TAGS =
    907                         new BooleanProperty("properties.remember-recently-added-tags", true);
    908         public static final IntegerProperty PROPERTY_RECENT_TAGS_NUMBER =
    909                         new IntegerProperty("properties.recently-added-tags", DEFAULT_LRU_TAGS_NUMBER);
    910 
    911         abstract static class AbstractTagsDialog extends ExtendedDialog {
    912                 AutoCompletingComboBox keys;
    913                 AutoCompletingComboBox values;
    914 
    915                 AbstractTagsDialog(Component parent, String title, String[] buttonTexts) {
    916                         super(parent, title, buttonTexts);
    917                         addMouseListener(new PopupMenuLauncher(popupMenu));
    918                 }
    919 
    920                 @Override
    921                 public void setupDialog() {
    922                         super.setupDialog();
    923                         final Dimension size = getSize();
    924                         // Set resizable only in width
    925                         setMinimumSize(size);
    926                         setPreferredSize(size);
    927                         // setMaximumSize does not work, and never worked, but still it seems not to bother Oracle to fix this 10-year-old bug
    928                         // https://bugs.openjdk.java.net/browse/JDK-6200438
    929                         // https://bugs.openjdk.java.net/browse/JDK-6464548
    930 
    931                         setRememberWindowGeometry(getClass().getName() + ".geometry",
    932                                         WindowGeometry.centerInWindow(Main.parent, size));
    933                 }
    934 
    935                 @Override
    936                 public void setVisible(boolean visible) {
    937                         // Do not want dialog to be resizable in height, as its size may increase each time because of the recently added tags
    938                         // So need to modify the stored geometry (size part only) in order to use the automatic positioning mechanism
    939                         if (visible) {
    940                                 WindowGeometry geometry = initWindowGeometry();
    941                                 Dimension storedSize = geometry.getSize();
    942                                 Dimension size = getSize();
    943                                 if (!storedSize.equals(size)) {
    944                                         if (storedSize.width < size.width) {
    945                                                 storedSize.width = size.width;
    946                                         }
    947                                         if (storedSize.height != size.height) {
    948                                                 storedSize.height = size.height;
    949                                         }
    950                                         rememberWindowGeometry(geometry);
    951                                 }
    952                                 if (keys != null) {
    953                                         keys.setFixedLocale(PROPERTY_FIX_TAG_LOCALE.get());
    954                                 }
    955                         }
    956                         super.setVisible(visible);
    957                 }
    958 
    959                 /**
    960                 * Create a focus handling adapter and apply in to the editor component of value
    961                 * autocompletion box.
    962                 * @param autocomplete Manager handling the autocompletion
    963                 * @param comparator Class to decide what values are offered on autocompletion
    964                 * @return The created adapter
    965                 */
    966                 protected FocusAdapter addFocusAdapter(final AutoCompletionManager autocomplete, final Comparator<AutoCompletionListItem> comparator) {
    967                         // get the combo box' editor component
    968                         JTextComponent editor = (JTextComponent) values.getEditor().getEditorComponent();
    969                         // Refresh the values model when focus is gained
    970                         FocusAdapter focus = new FocusAdapter() {
    971                                 @Override
    972                                 public void focusGained(FocusEvent e) {
    973                                         String key = keys.getEditor().getItem().toString();
    974 
    975                                         List<AutoCompletionListItem> valueList = autocomplete.getValues(getAutocompletionKeys(key));
    976                                         Collections.sort(valueList, comparator);
    977 
    978                                         values.setPossibleACItems(valueList);
    979                                         values.getEditor().selectAll();
    980                                 }
    981                         };
    982                         editor.addFocusListener(focus);
    983                         return focus;
    984                 }
    985 
    986                 protected JPopupMenu popupMenu = new JPopupMenu() {
    987                         JCheckBoxMenuItem fixTagLanguageCb = new JCheckBoxMenuItem(
    988                                         new AbstractAction(tr("Use English language for tag by default")) {
    989                                                 @Override
    990                                                 public void actionPerformed(ActionEvent e) {
    991                                                         boolean sel = ((JCheckBoxMenuItem) e.getSource()).getState();
    992                                                         PROPERTY_FIX_TAG_LOCALE.put(sel);
    993                                                 }
    994                                         });
    995                         {
    996                                 add(fixTagLanguageCb);
    997                                 fixTagLanguageCb.setState(PROPERTY_FIX_TAG_LOCALE.get());
    998                         }
    999                 };
    1000         }
    1001 
    1002         class ModelSettingsDialog extends JPanel {
    1003 
    1004                 private final JLabel chooseModelLabel;
    1005                 private final JButton chooseModelButton;
    1006                 private final JTextField chooseModelTextField;
    1007 
    1008                 private final DefaultListModel<String> combinationDefaultListModel = new DefaultListModel<>();
    1009                 private final JList<String> modelCombinationList = new JList<>(combinationDefaultListModel);
    1010                 private final JPanel modelCombinationPanel;
    1011                 private final JPanel weightsPanel;
    1012                 private final JCheckBox useModelCombinationCheckbox;
    1013                 private final JButton acceptWeightsButton;
    1014                 private final JButton resetWeightsButton;
    1015                 private final JButton removeSelectedModelButton;
    1016                 private Map<JTextField, String> weightFieldsAndPaths = new HashMap<>();
    1017                 private final Map<String, Double> normalizedPathsAndWeights = new HashMap<>();
    1018                 private final JOptionPane pane;
    1019                 private final JDialog dlg;
    1020                 private final JPanel mainPanel;
    1021                 private final JPanel singleSelectionPanel;
    1022                 private final JPanel setResetWeightsPanel;
    1023                 private final JScrollPane combinationScrollPane;
    1024                 private final JScrollPane singleSelectionScrollPane;
    1025                 private final TitledBorder modelTitle;
    1026                 private final TitledBorder weightTitle;
    1027                 private final TitledBorder combineTitle;
    1028                 private final Dimension singleSelectionDimension;
    1029                 private final Dimension modelCombinationDimension;
    1030                 private final Dimension mainPanelDimension;
    1031 
    1032                 ModelSettingsDialog(Collection<OsmPrimitive> sel1, final AddTagsDialog addDialog) {
    1033 
    1034                         loadPreviousCombinedSVMModel();
    1035                         singleSelectionDimension = new Dimension(470, 70);
    1036                         modelCombinationDimension = new Dimension(450, 250);
    1037                         mainPanelDimension = new Dimension(600, 350);
    1038 
    1039                         //------- <NORTH of main> ---------//
    1040                         mainPanel = new JPanel(new BorderLayout(10, 10));
    1041                         singleSelectionPanel = new JPanel(new BorderLayout(10, 10));
    1042                         setResetWeightsPanel = new JPanel();
    1043 
    1044                         chooseModelLabel = new JLabel("Choose a Model:");
    1045                         chooseModelTextField = new JTextField();
    1046                         chooseModelButton = new JButton("...");
    1047                         chooseModelTextField.setText(MODEL_PATH);
    1048 
    1049                         singleSelectionPanel.add(chooseModelLabel, BorderLayout.NORTH);
    1050                         singleSelectionPanel.add(chooseModelTextField, BorderLayout.WEST);
    1051                         singleSelectionPanel.add(chooseModelButton, BorderLayout.EAST);
    1052 
    1053                         singleSelectionScrollPane = new JScrollPane(singleSelectionPanel);
    1054                         singleSelectionScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
    1055                         singleSelectionScrollPane.setPreferredSize(singleSelectionDimension);
    1056 
    1057                         //------- </NORTH of main> ---------//
    1058 
    1059                         //------- <WEST of main> ---------//
    1060                         modelCombinationList.setFixedCellHeight(20);
    1061                         modelCombinationList.setEnabled(false);
    1062                         modelCombinationPanel = new JPanel(new BorderLayout(10, 10));
    1063 
    1064                         weightsPanel = new JPanel();
    1065                         weightsPanel.setLayout(new BoxLayout(weightsPanel, BoxLayout.Y_AXIS));
    1066                         weightsPanel.setEnabled(false);
    1067 
    1068 
    1069                         acceptWeightsButton = new JButton("Set Weights/Normalize");
    1070                         resetWeightsButton = new JButton("Reset Weights");
    1071                         removeSelectedModelButton = new JButton("Remove Selected");
    1072                         setResetWeightsPanel.add(acceptWeightsButton);
    1073                         setResetWeightsPanel.add(resetWeightsButton);
    1074                         setResetWeightsPanel.add(removeSelectedModelButton);
    1075                         removeSelectedModelButton.setEnabled(false);
    1076                         acceptWeightsButton.setEnabled(false);
    1077                         resetWeightsButton.setEnabled(false);
    1078 
    1079                         modelCombinationPanel.add(modelCombinationList, BorderLayout.CENTER);
    1080                         modelCombinationPanel.add(weightsPanel, BorderLayout.EAST);
    1081                         modelCombinationPanel.add(setResetWeightsPanel, BorderLayout.SOUTH);
    1082 
    1083                         combinationScrollPane = new JScrollPane(modelCombinationPanel);
    1084 
    1085                         combinationScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
    1086                         combinationScrollPane.setPreferredSize(modelCombinationDimension);   //new Dimension(450, 250) // w/h
    1087 
    1088                         //------- </WEST of main> ---------//
    1089 
    1090                         //------- <SOUTH of main> ---------//
    1091                         useModelCombinationCheckbox = new JCheckBox("Combine different models?");
    1092 
    1093                         //------- </SOUTH of main> ---------//
    1094 
    1095                         //------- <Borders> ---------//
    1096                         modelTitle = BorderFactory.createTitledBorder("Models");
    1097                         weightTitle = BorderFactory.createTitledBorder("W");
    1098                         combineTitle = BorderFactory.createTitledBorder("Combine Models");
    1099                         modelCombinationList.setBorder(modelTitle);
    1100                         weightsPanel.setBorder(weightTitle);
    1101 
    1102                         for (Entry<JTextField, String> entry : weightFieldsAndPaths.entrySet()) {
    1103                                 combinationDefaultListModel.addElement(entry.getValue());
    1104 
    1105                                 JTextField weightTextField = new JTextField("0.00");
    1106                                 weightTextField.setMaximumSize(new Dimension(80, 20));
    1107                                 weightsPanel.add(entry.getKey());
    1108                         }
    1109 
    1110                         //modelCombinationPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
    1111                         modelCombinationPanel.setBorder(combineTitle);
    1112                         singleSelectionPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
    1113                         //------- </Borders> ---------//
    1114 
    1115                         chooseModelButton.addActionListener(new java.awt.event.ActionListener() {
    1116                                 @Override
    1117                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    1118                                         modelChooserButtonActionPerformed(evt);
    1119                                 }
    1120                         });
    1121 
    1122                         useModelCombinationCheckbox.addActionListener(new java.awt.event.ActionListener() {
    1123                                 @Override
    1124                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    1125                                         userCombinationCheckboxActionPerformed(evt);
    1126                                 }
    1127                         });
    1128 
    1129                         acceptWeightsButton.addActionListener(new java.awt.event.ActionListener() {
    1130                                 @Override
    1131                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    1132                                         acceptWeightsButtonActionPerformed(evt);
    1133                                 }
    1134                         });
    1135 
    1136                         resetWeightsButton.addActionListener(new java.awt.event.ActionListener() {
    1137                                 @Override
    1138                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    1139                                         resetWeightsButtonActionPerformed(evt);
    1140                                 }
    1141                         });
    1142 
    1143                         removeSelectedModelButton.addActionListener(new java.awt.event.ActionListener() {
    1144                                 @Override
    1145                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    1146                                         removeSelectedModelButtonActionPerformed(evt);
    1147                                 }
    1148                         });
    1149                         mainPanel.add(singleSelectionScrollPane, BorderLayout.NORTH);
    1150                         mainPanel.add(combinationScrollPane, BorderLayout.CENTER);
    1151                         mainPanel.add(useModelCombinationCheckbox, BorderLayout.SOUTH);
    1152 
    1153                         mainPanel.setPreferredSize(mainPanelDimension);
    1154 
    1155                         this.add(mainPanel);
    1156 
    1157                         pane = new JOptionPane(this, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
    1158                                 @Override
    1159                                 public void setValue(Object newValue) {
    1160                                         super.setValue(newValue);
    1161                                         if (newValue instanceof Integer && (int) newValue == 0 && useModelCombinationCheckbox.isSelected()) {
    1162                                                 System.out.println("model settings button value: " + newValue);
    1163                                                 System.out.println("\nUSE COMBINED MODEL\n");
    1164                                                 useCombinedModel = true;
    1165                                                 useCustomSVMModel = false;
    1166 
    1167                                                 addDialog.loadSVMmodel();
    1168                                                 addDialog.createOSMObject(sel);
    1169                                                 saveCombinedModel();
    1170                                                 dlg.setVisible(false);
    1171                                         } else if (newValue instanceof Integer && (int) newValue == -1 && useModelCombinationCheckbox.isSelected()) {
    1172                                                 System.out.println("model settings button value: " + newValue);
    1173                                                 useCombinedModel = false;
    1174                                                 useCustomSVMModel = false;
    1175                                                 System.out.println("Use combined model");
    1176 
    1177                                                 addDialog.loadSVMmodel();
    1178                                                 addDialog.createOSMObject(sel);
    1179                                                 dlg.setVisible(false);
    1180                                         } else if (newValue instanceof Integer && (int) newValue == 0 && !useModelCombinationCheckbox.isSelected()) {
    1181                                                 System.out.println("model settings button value: " + newValue);
    1182                                                 System.out.println("Don t use combined model, use custom model");
    1183                                                 useCombinedModel = false;
    1184                                                 useCustomSVMModel = true;
    1185                                                 addDialog.loadSVMmodel();
    1186                                                 addDialog.createOSMObject(sel);
    1187                                                 dlg.setVisible(false);
    1188                                         } else if (newValue instanceof Integer && (int) newValue == -1 && !useModelCombinationCheckbox.isSelected()) {
    1189                                                 System.out.println("model settings button value: " + newValue);
    1190                                                 System.out.println("Don t use combined model, use custom model");
    1191                                                 useCombinedModel = false;
    1192                                                 useCustomSVMModel = false;
    1193                                                 addDialog.loadSVMmodel();
    1194                                                 addDialog.createOSMObject(sel);
    1195                                                 dlg.setVisible(false);
    1196                                         } else if (newValue == null || newValue.equals("uninitializedValue")) {
    1197                                                 System.out.println("uninitializedValue, do nothing");
    1198                                         }
    1199                                 }
    1200                         };
    1201 
    1202                         dlg = pane.createDialog(Main.parent, tr("Model Settings"));
    1203                         dlg.setVisible(true);
    1204                 }
    1205 
    1206                 public void makeVisible(boolean visible) {
    1207                         dlg.setVisible(true);
    1208                 }
    1209 
    1210                 private void modelChooserButtonActionPerformed(ActionEvent evt) {
    1211 
    1212                         try {
    1213                                 final File file = new File(chooseModelTextField.getText());
    1214                                 final JFileChooser fileChooser = new JFileChooser(file);
    1215 
    1216                                 final int returnVal = fileChooser.showOpenDialog(this);
    1217                                 if (returnVal == JFileChooser.APPROVE_OPTION) {
    1218                                         chooseModelTextField.setText(fileChooser.getSelectedFile().getAbsolutePath());
    1219                                         useCustomSVMModel = true;
    1220                                         customSVMModelPath = fileChooser.getSelectedFile().getAbsolutePath();
    1221                                 }
    1222 
    1223                                 if (useModelCombinationCheckbox.isSelected()) {
    1224                                         String svmModelPath = fileChooser.getSelectedFile().getAbsolutePath();
    1225                                         String svmModelText;
    1226                                         if (System.getProperty("os.name").contains("ux")) {
    1227                                                 if (svmModelPath.contains("/")) {
    1228                                                         svmModelText = svmModelPath.substring(svmModelPath.lastIndexOf("/"));
    1229                                                 } else {
    1230                                                         svmModelText = svmModelPath;
    1231                                                 }
    1232                                         } else {
    1233                                                 if (svmModelPath.contains("\\")) {
    1234                                                         svmModelText = svmModelPath.substring(svmModelPath.lastIndexOf("\\"));
    1235                                                 } else {
    1236                                                         svmModelText = svmModelPath;
    1237                                                 }
    1238                                         }
    1239                                         combinationDefaultListModel.addElement(svmModelText);
    1240                                         JTextField weightTextField = new JTextField("0.00");
    1241                                         weightFieldsAndPaths.put(weightTextField, svmModelPath);
    1242                                         System.out.println("weights size: " + weightFieldsAndPaths.size());
    1243 
    1244                                         weightTextField.setMaximumSize(new Dimension(80, 20));
    1245                                         weightsPanel.add(weightTextField);
    1246                                         //add additional textbox
    1247                                 }
    1248                         } catch (RuntimeException ex) {
    1249                                 Logging.warn(ex);
    1250                         }
    1251                 }
    1252 
    1253                 private void userCombinationCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
    1254 
    1255                         if (useModelCombinationCheckbox.isSelected()) {
    1256                                 useCombinedModel = true;
    1257                                 useCustomSVMModel = false; //reseting the selected custom SVM model only here
    1258                                 removeSelectedModelButton.setEnabled(true);
    1259                                 acceptWeightsButton.setEnabled(true);
    1260                                 resetWeightsButton.setEnabled(true);
    1261 
    1262                                 chooseModelTextField.setEnabled(false);
    1263                                 modelCombinationList.setEnabled(true);
    1264                                 weightsPanel.setEnabled(true);
    1265                                 Component[] weightPanelComponents = weightsPanel.getComponents();
    1266                                 for (Component weightPanelComponent : weightPanelComponents) {
    1267                                         weightPanelComponent.setEnabled(true);
    1268                                 }
    1269                         } else {
    1270                                 useCombinedModel = false;
    1271                                 useCustomSVMModel = true;
    1272                                 removeSelectedModelButton.setEnabled(false);
    1273                                 acceptWeightsButton.setEnabled(false);
    1274                                 resetWeightsButton.setEnabled(false);
    1275 
    1276                                 chooseModelTextField.setEnabled(true);
    1277                                 modelCombinationList.setEnabled(false);
    1278                                 weightsPanel.setEnabled(false);
    1279                                 Component[] weightPanelComponents = weightsPanel.getComponents();
    1280                                 for (Component weightPanelComponent : weightPanelComponents) {
    1281                                         weightPanelComponent.setEnabled(false);
    1282                                 }
    1283                         }
    1284                 }
    1285 
    1286                 private void acceptWeightsButtonActionPerformed(ActionEvent evt) {
    1287                         int weightsCount = 0;
    1288                         removeSelectedModelButton.setEnabled(false);
    1289                         double weightSum = 0;
    1290                         for (JTextField weightField : weightFieldsAndPaths.keySet()) {
    1291                                 if (weightField.getText().equals("")) {
    1292                                         weightField.setText("0.00");
    1293                                 }
    1294 
    1295                                 try {
    1296                                         //TODO replace "," with "." to parse doubles with commas
    1297                                         Double weightValue = Double.parseDouble(weightField.getText());
    1298 
    1299                                         weightValue = Math.abs(weightValue);
    1300                                         weightSum += weightValue;
    1301                                 } catch (NumberFormatException ex) {
    1302                                         Logging.warn(ex);
    1303                                 }
    1304                                 weightsCount++;
    1305                         }
    1306 
    1307                         if (!filesAndWeights.isEmpty()) {
    1308                                 filesAndWeights.clear();
    1309                         }
    1310 
    1311                         for (JTextField weightField : weightFieldsAndPaths.keySet()) {
    1312                                 try {
    1313                                         Double weightValue = Double.parseDouble(weightField.getText());
    1314 
    1315                                         weightValue = Math.abs(weightValue)/weightSum; //normalize
    1316 
    1317                                         if (weightSum == 0) {
    1318                                                 weightValue = 1.0/weightsCount;
    1319                                         }
    1320 
    1321                                         weightField.setText(new DecimalFormat("#.##").format(weightValue));
    1322                                         normalizedPathsAndWeights.put(weightFieldsAndPaths.get(weightField), weightValue);
    1323                                         filesAndWeights.put(new File(weightFieldsAndPaths.get(weightField)), weightValue);
    1324                                         System.out.println("normalized: " + weightFieldsAndPaths.get(weightField) + "->" + weightValue);
    1325                                         weightField.setEnabled(false);
    1326 
    1327                                 } catch (NumberFormatException ex) {
    1328                                         Logging.warn(ex);
    1329                                 }
    1330                         }
    1331 
    1332                         useCombinedModel = true;
    1333                         useCustomSVMModel = false;
    1334                 }
    1335 
    1336                 private void resetWeightsButtonActionPerformed(ActionEvent evt) {
    1337                         removeSelectedModelButton.setEnabled(true);
    1338                         for (JTextField weightField : weightFieldsAndPaths.keySet()) {
    1339                                 weightField.setEnabled(true);
    1340                         }
    1341                 }
    1342 
    1343                 private void removeSelectedModelButtonActionPerformed(ActionEvent evt) {
    1344                         int index = modelCombinationList.getSelectedIndex();
    1345                         String modelToBeRemoved = combinationDefaultListModel.get(index);
    1346                         combinationDefaultListModel.remove(index);
    1347                         System.out.println("model to be removed: " + modelToBeRemoved);
    1348 
    1349                         Iterator<Entry<JTextField, String>> it = weightFieldsAndPaths.entrySet().iterator();
    1350                         while (it.hasNext()) {
    1351                                 Entry<JTextField, String> en = it.next();
    1352                                 if (en.getValue().equals(modelToBeRemoved)) {
    1353                                         it.remove();
    1354                                 }
    1355                         }
    1356                         System.out.println("model to be removed: " + modelToBeRemoved);
    1357 
    1358                         weightsPanel.remove(index);
    1359                         weightsPanel.revalidate();
    1360                         weightsPanel.repaint();
    1361                 }
    1362 
    1363                 @SuppressWarnings("unchecked")
    1364                 private void loadPreviousCombinedSVMModel() {
    1365                         File combinedModelClassesFile = new File(combinedModelClasses);
    1366 
    1367                         if (combinedModelClassesFile.exists()) {
    1368                                 FileInputStream fileIn = null;
    1369                                 ObjectInputStream in = null;
    1370                                 try {
    1371                                         fileIn = new FileInputStream(combinedModelClassesFile);
    1372                                         in = new ObjectInputStream(fileIn);
    1373                                         weightFieldsAndPaths = (Map<JTextField, String>) in.readObject();
    1374                                 } catch (FileNotFoundException ex) {
    1375                                         Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
    1376                                 } catch (IOException | ClassNotFoundException ex) {
    1377                                         Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
    1378                                 } finally {
    1379                                         try {
    1380                                                 if (in != null) {
    1381                                                         in.close();
    1382                                                 }
    1383                                                 if (fileIn != null) {
    1384                                                         fileIn.close();
    1385                                                 }
    1386 
    1387                                         } catch (IOException ex) {
    1388                                                 Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
    1389                                         }
    1390                                 }
    1391                         } else {
    1392                                 try {
    1393                                         combinedModelClassesFile.createNewFile();
    1394                                 } catch (IOException ex) {
    1395                                         Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
    1396                                 }
    1397                         }
    1398                 }
    1399 
    1400                 private void saveCombinedModel() {
    1401                         try (FileOutputStream fileOut = new FileOutputStream(combinedModelClasses);
    1402                                         ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
    1403                                 out.writeObject(weightFieldsAndPaths);
    1404                         } catch (IOException e) {
    1405                                 System.out.println("serialize error" + e);
    1406                         }
    1407                 }
    1408         }
    1409 
    1410         class AddTagsDialog extends AbstractTagsDialog {
    1411                 List<JosmAction> recentTagsActions = new ArrayList<>();
    1412 
    1413                 // Counter of added commands for possible undo
    1414                 private int commandCount;
    1415                 private final JLabel recommendedClassesLabel;
    1416                 private final JButton modelSettingsButton;
    1417                 private final JButton addAndContinueButton;
    1418                 private final DefaultListModel<String> model;
    1419                 private final JList<String> categoryList;
    1420                 private Model modelSVM;
    1421                 private int modelSVMLabelSize;
    1422                 private int[] modelSVMLabels;
    1423                 private Map<String, String> mappings;
    1424                 private Map<String, Integer> mapperWithIDs;
    1425                 private Map<Integer, String> idsWithMappings;
    1426                 private List<String> textualList = new ArrayList<>();
    1427                 private final JCheckBox useTagsCheckBox;
    1428                 private ModelSettingsDialog modelSettingsDialog;
    1429                 private static final int RECOMMENDATIONS_SIZE = 10;
    1430 
    1431                 AddTagsDialog() {
    1432                         super(Main.parent, tr("Add value?"), new String[] {tr("OK"), tr("Cancel")});
    1433                         setButtonIcons(new String[] {"ok", "cancel"});
    1434                         setCancelButton(2);
    1435                         configureContextsensitiveHelp("/Dialog/AddValue", true /* show help button */);
    1436                         final AddTagsDialog addTagsDialog = this;
    1437 
    1438                         loadOntology();
    1439                         //if the user did not train a model by running the training process
    1440                         //the list does not exist in a file and so we load the default list from the jar.
    1441 
    1442                         System.out.println("path for textual: " + TEXTUAL_LIST_PATH);
    1443                         File textualListFile = new File(TEXTUAL_LIST_PATH);
    1444                         if (textualListFile.exists()) {
    1445                                 loadTextualList(textualListFile);
    1446                         } else {
    1447                                 loadDefaultTextualList();
    1448                         }
    1449 
    1450                         //if training process has not been performed, we use two sample SVM models, extracted from the jar
    1451 
    1452                         JPanel splitPanel = new JPanel(new BorderLayout(10, 10));
    1453                         JPanel mainPanel = new JPanel(new GridBagLayout()); //original panel, will be wrapped by the splitPanel
    1454                         JPanel recommendPanel = new JPanel(new BorderLayout(10, 10));   //will contain listPanel, action panel
    1455                         JPanel listPanel = new JPanel(new BorderLayout(10, 10)); //class recommend label, recommendation list
    1456                         JPanel actionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); //model selection buttons or configuration
    1457 
    1458                         addAndContinueButton = new JButton("Add and continue");
    1459                         modelSettingsButton = new JButton("Model Settings");
    1460                         useTagsCheckBox = new JCheckBox("Predict using tags");
    1461                         recommendedClassesLabel = new JLabel("Recommended Classes:");
    1462 
    1463                         addAndContinueButton.addActionListener(new java.awt.event.ActionListener() {
    1464                                 @Override
    1465                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    1466                                         String selectedClass = categoryList.getSelectedValue();
    1467                                         addAndContinueButtonActionPerformed(evt, selectedClass);
    1468 
    1469                                         //reconstruct vector for instance and use the model that was trained with classes here
    1470 
    1471                                         List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
    1472                                         OsmPrimitive s;
    1473 
    1474                                         //get a simple selection
    1475                                         if (!osmPrimitiveSelection.isEmpty()) {
    1476                                                 s = osmPrimitiveSelection.get(0);
    1477                                                 if (s.getInterestingTags().isEmpty()) {
    1478                                                         //load original model
    1479                                                         modelWithClasses = false;
    1480                                                         loadSVMmodel();
    1481                                                         createOSMObject(sel); //create object without class features
    1482                                                 } else {
    1483                                                         //recommend using tags: set the checkbox selected to avoid confusing the user
    1484                                                         useTagsCheckBox.setSelected(true);
    1485 
    1486                                                         if (useTagsCheckBox.isSelected()) {
    1487                                                                 //load model with classes
    1488                                                                 modelWithClasses = true;
    1489                                                                 loadSVMmodel();
    1490                                                                 createOSMObject(sel); //create object including class features
    1491                                                         } else {
    1492                                                                 modelWithClasses = false;
    1493                                                                 loadSVMmodel();
    1494                                                                 createOSMObject(sel); //create object including class features
    1495                                                         }
    1496                                                 }
    1497                                         }
    1498                                 }
    1499                         });
    1500 
    1501                         modelSettingsButton.addActionListener(new java.awt.event.ActionListener() {
    1502                                 @Override
    1503                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    1504                                         if (modelSettingsDialog == null) {
    1505                                                 System.out.println("new modelSettingsDialog");
    1506                                                 modelSettingsDialog = new ModelSettingsDialog(sel, addTagsDialog);
    1507                                         } else {
    1508                                                 System.out.println("set modelSettingsDialog visible");
    1509                                                 modelSettingsDialog.makeVisible(true);
    1510                                         }
    1511                                 }
    1512                         });
    1513 
    1514                         useTagsCheckBox.addActionListener(new java.awt.event.ActionListener() {
    1515                                 @Override
    1516                                 public void actionPerformed(java.awt.event.ActionEvent evt) {
    1517                                         List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
    1518                                         OsmPrimitive s;
    1519                                         if (!osmPrimitiveSelection.isEmpty()) {
    1520                                                 s = osmPrimitiveSelection.get(0);
    1521                                                 if (s.getInterestingTags().isEmpty()) {
    1522                                                         //load original model
    1523                                                         modelWithClasses = false;
    1524                                                         loadSVMmodel();
    1525                                                         createOSMObject(sel); //create object without class features
    1526                                                 } else {
    1527                                                         //useTagsCheckBox
    1528                                                         if (useTagsCheckBox.isSelected()) {
    1529                                                                 //load model with classes
    1530                                                                 modelWithClasses = true;
    1531                                                                 loadSVMmodel();
    1532                                                                 createOSMObject(sel); //create object including class features
    1533                                                         } else {
    1534                                                                 modelWithClasses = false;
    1535                                                                 loadSVMmodel();
    1536                                                                 createOSMObject(sel); //create object including class features
    1537                                                         }
    1538                                                 }
    1539                                         }
    1540                                 }
    1541                         });
    1542 
    1543                         keys = new AutoCompletingComboBox();
    1544                         values = new AutoCompletingComboBox();
    1545 
    1546                         mainPanel.add(new JLabel("<html>"+trn("This will change up to {0} object.",
    1547                                         "This will change up to {0} objects.", sel.size(), sel.size())
    1548                         +"<br><br>"+tr("Please select a key")), GBC.eol().fill(GBC.HORIZONTAL));
    1549 
    1550                         AutoCompletionManager autocomplete = MainApplication.getLayerManager().getEditLayer().data.getAutoCompletionManager();
    1551                         List<AutoCompletionListItem> keyList = autocomplete.getKeys();
    1552 
    1553                         AutoCompletionListItem itemToSelect = null;
    1554                         // remove the object's tag keys from the list
    1555                         Iterator<AutoCompletionListItem> iter = keyList.iterator();
    1556                         while (iter.hasNext()) {
    1557                                 AutoCompletionListItem item = iter.next();
    1558                                 if (item.getValue().equals(lastAddKey)) {
    1559                                         itemToSelect = item;
    1560                                 }
    1561                                 for (int i = 0; i < tagData.getRowCount(); ++i) {
    1562                                         if (item.getValue().equals(tagData.getValueAt(i, 0))) {
    1563                                                 if (itemToSelect == item) {
    1564                                                         itemToSelect = null;
    1565                                                 }
    1566                                                 iter.remove();
    1567                                                 break;
    1568                                         }
    1569                                 }
    1570                         }
    1571 
    1572                         Collections.sort(keyList, defaultACItemComparator);
    1573                         keys.setPossibleACItems(keyList);
    1574                         keys.setEditable(true);
    1575 
    1576                         mainPanel.add(keys, GBC.eop().fill());
    1577                         mainPanel.add(new JLabel(tr("Please select a value")), GBC.eol());
    1578 
    1579                         model = new DefaultListModel<>();
    1580 
    1581                         parseTagsMappedToClasses();
    1582 
    1583                         List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
    1584                         OsmPrimitive s;
    1585                         //get a simple selection
    1586                         if (!osmPrimitiveSelection.isEmpty()) {
    1587                                 s = osmPrimitiveSelection.get(0);
    1588                                 File modelDirectory = new File(MODEL_PATH);
    1589                                 String modelWithClassesPath = modelDirectory.getAbsolutePath() + "/model_with_classes";
    1590                                 File modelWithClassesFile = new File(modelWithClassesPath);
    1591                                 if (s.getInterestingTags().isEmpty() || !modelWithClassesFile.exists()) {
    1592                                         modelWithClasses = false;
    1593                                         loadSVMmodel(); //load original model
    1594                                         createOSMObject(sel); //create object without class features
    1595                                 } else {
    1596                                         //recommend using tags: set the checkbox selected to avoid confusing the user
    1597                                         useTagsCheckBox.setSelected(true);
    1598                                         modelWithClasses = true;
    1599                                         loadSVMmodel(); //load model with classes
    1600                                         createOSMObject(sel); //create object including class features
    1601                                 }
    1602                         }
    1603 
    1604                         categoryList = new JList<>(model);
    1605 
    1606                         ListSelectionListener listSelectionListener = new ListSelectionListener() {
    1607                                 @Override
    1608                                 public void valueChanged(ListSelectionEvent listSelectionEvent) {
    1609                                         if (!listSelectionEvent.getValueIsAdjusting()) { //This prevents double events
    1610 
    1611                                                 String selectedClass = categoryList.getSelectedValue();
    1612 
    1613                                                 if (selectedClass != null) { //null check, because the model is cleared after a new recommendation
    1614                                                         //tags become unselected
    1615                                                         if ((selectedClass.indexOf(" ")+1) > 0) {
    1616                                                                 //add both key + value in tags
    1617                                                                 String keyTag = selectedClass.substring(0, selectedClass.indexOf(" "));
    1618                                                                 String valueTag = selectedClass.substring(selectedClass.indexOf(" ")+1, selectedClass.length());
    1619                                                                 keys.setSelectedItem(keyTag); //adding selected tags to textBoxes
    1620                                                                 values.setSelectedItem(valueTag);
    1621                                                         } else {
    1622                                                                 //value does not have a value, add the key tag only
    1623                                                                 String keyTag = selectedClass; //test it
    1624                                                                 keys.setSelectedItem(keyTag);
    1625                                                                 values.setSelectedItem("");
    1626                                                         }
    1627                                                 }
    1628                                         }
    1629                                 }
    1630                         };
    1631 
    1632                         categoryList.addListSelectionListener(listSelectionListener);
    1633                         categoryList.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
    1634                         categoryList.setModel(model);
    1635 
    1636                         values.setEditable(true);
    1637                         mainPanel.add(values, GBC.eop().fill());
    1638                         if (itemToSelect != null) {
    1639                                 keys.setSelectedItem(itemToSelect);
    1640                                 if (lastAddValue != null) {
    1641                                         values.setSelectedItem(lastAddValue);
    1642                                 }
    1643                         }
    1644 
    1645                         FocusAdapter focus = addFocusAdapter(autocomplete, defaultACItemComparator);
    1646                         // fire focus event in advance or otherwise the popup list will be too small at first
    1647                         focus.focusGained(null);
    1648 
    1649                         int recentTagsToShow = PROPERTY_RECENT_TAGS_NUMBER.get();
    1650                         if (recentTagsToShow > MAX_LRU_TAGS_NUMBER) {
    1651                                 recentTagsToShow = MAX_LRU_TAGS_NUMBER;
    1652                         }
    1653 
    1654                         suggestRecentlyAddedTags(mainPanel, recentTagsToShow, focus);
    1655 
    1656                         mainPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
    1657                         listPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
    1658                         splitPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
    1659 
    1660                         listPanel.add(recommendedClassesLabel, BorderLayout.NORTH);
    1661                         listPanel.add(categoryList, BorderLayout.SOUTH);
    1662                         actionsPanel.add(addAndContinueButton);
    1663                         actionsPanel.add(modelSettingsButton);
    1664                         actionsPanel.add(useTagsCheckBox);
    1665 
    1666                         recommendPanel.add(actionsPanel, BorderLayout.WEST);
    1667                         recommendPanel.add(listPanel, BorderLayout.NORTH);
    1668 
    1669                         splitPanel.add(mainPanel, BorderLayout.WEST);
    1670                         splitPanel.add(recommendPanel, BorderLayout.EAST);
    1671 
    1672                         setContent(splitPanel, false);
    1673 
    1674                         popupMenu.add(new AbstractAction(tr("Set number of recently added tags")) {
    1675                                 @Override
    1676                                 public void actionPerformed(ActionEvent e) {
    1677                                         selectNumberOfTags();
    1678                                 }
    1679                         });
    1680                         JCheckBoxMenuItem rememberLastTags = new JCheckBoxMenuItem(
    1681                                         new AbstractAction(tr("Remember last used tags after a restart")) {
    1682                                                 @Override
    1683                                                 public void actionPerformed(ActionEvent e) {
    1684                                                         boolean sel = ((JCheckBoxMenuItem) e.getSource()).getState();
    1685                                                         PROPERTY_REMEMBER_TAGS.put(sel);
    1686                                                         if (sel) saveTagsIfNeeded();
    1687                                                 }
    1688                                         });
    1689                         rememberLastTags.setState(PROPERTY_REMEMBER_TAGS.get());
    1690                         popupMenu.add(rememberLastTags);
    1691                 }
    1692 
    1693                 private void addAndContinueButtonActionPerformed(ActionEvent evt, String selectedClass) {
    1694                         performTagAdding();
    1695                 }
    1696 
    1697                 private void selectNumberOfTags() {
    1698                         String s = JOptionPane.showInputDialog(this, tr("Please enter the number of recently added tags to display"));
    1699                         if (s != null) try {
    1700                                 int v = Integer.parseInt(s);
    1701                                 if (v >= 0 && v <= MAX_LRU_TAGS_NUMBER) {
    1702                                         PROPERTY_RECENT_TAGS_NUMBER.put(v);
    1703                                         return;
    1704                                 }
    1705                         } catch (NumberFormatException ex) {
    1706                                 Logging.warn(ex);
    1707                         }
    1708                         JOptionPane.showMessageDialog(this, tr("Please enter integer number between 0 and {0}", MAX_LRU_TAGS_NUMBER));
    1709                 }
    1710 
    1711                 private void suggestRecentlyAddedTags(JPanel mainPanel, int tagsToShow, final FocusAdapter focus) {
    1712                         if (!(tagsToShow > 0 && !recentTags.isEmpty()))
    1713                                 return;
    1714 
    1715                         mainPanel.add(new JLabel(tr("Recently added tags")), GBC.eol());
    1716 
    1717                         int count = 1;
    1718                         // We store the maximum number (9) of recent tags to allow dynamic change of number of tags shown in the preferences.
    1719                         // This implies to iterate in descending order,
    1720                         // as the oldest elements will only be removed after we reach the maximum numbern and not the number of tags to show.
    1721                         // However, as Set does not allow to iterate in descending order,
    1722                         // we need to copy its elements into a List we can access in reverse order.
    1723                         List<Tag> tags = new LinkedList<>(recentTags.keySet());
    1724                         for (int i = tags.size()-1; i >= 0 && count <= tagsToShow; i--, count++) {
    1725                                 final Tag t = tags.get(i);
    1726                                 // Create action for reusing the tag, with keyboard shortcut Ctrl+(1-5)
    1727                                 String scKey = "properties:recent:"+count;
    1728                                 String scsKey = "properties:recent:shift:"+count;
    1729                                 Shortcut sc = Shortcut.registerShortcut(scKey, tr("Choose recent tag {0}", count), KeyEvent.VK_0+count, Shortcut.CTRL);
    1730                                 final JosmAction action = new JosmAction(scKey, null, tr("Use this tag again"), sc, false) {
    1731                                         @Override
    1732                                         public void actionPerformed(ActionEvent e) {
    1733                                                 keys.setSelectedItem(t.getKey());
    1734                                                 // fix #7951, #8298 - update list of values before setting value (?)
    1735                                                 focus.focusGained(null);
    1736                                                 values.setSelectedItem(t.getValue());
    1737                                         }
    1738                                 };
    1739                                 Shortcut scs = Shortcut.registerShortcut(scsKey, tr("Apply recent tag {0}", count), KeyEvent.VK_0+count, Shortcut.CTRL_SHIFT);
    1740                                 final JosmAction actionShift = new JosmAction(scsKey, null, tr("Use this tag again"), scs, false) {
    1741                                         @Override
    1742                                         public void actionPerformed(ActionEvent e) {
    1743                                                 action.actionPerformed(null);
    1744                                                 performTagAdding();
    1745                                         }
    1746                                 };
    1747                                 recentTagsActions.add(action);
    1748                                 recentTagsActions.add(actionShift);
    1749                                 disableTagIfNeeded(t, action);
    1750                                 // Find and display icon
    1751                                 ImageIcon icon = MapPaintStyles.getNodeIcon(t, false); // Filters deprecated icon
    1752                                 if (icon == null) {
    1753                                         // If no icon found in map style look at presets
    1754                                         Map<String, String> map = new HashMap<>();
    1755                                         map.put(t.getKey(), t.getValue());
    1756                                         // If still nothing display an empty icon
    1757                                         if (icon == null) {
    1758                                                 icon = new ImageIcon(new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB));
    1759                                         }
    1760                                 }
    1761                                 GridBagConstraints gbc = new GridBagConstraints();
    1762                                 gbc.ipadx = 5;
    1763                                 mainPanel.add(new JLabel(action.isEnabled() ? icon : GuiHelper.getDisabledIcon(icon)), gbc);
    1764                                 // Create tag label
    1765                                 final String color = action.isEnabled() ? "" : "; color:gray";
    1766                                 final JLabel tagLabel = new JLabel("<html>"
    1767                                                 + "<style>td{border:1px solid gray; font-weight:normal"+color+"}</style>"
    1768                                                 + "<table><tr><td>" + XmlWriter.encode(t.toString(), true) + "</td></tr></table></html>");
    1769                                 if (action.isEnabled()) {
    1770                                         // Register action
    1771                                         mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sc.getKeyStroke(), scKey);
    1772                                         mainPanel.getActionMap().put(scKey, action);
    1773                                         mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(scs.getKeyStroke(), scsKey);
    1774                                         mainPanel.getActionMap().put(scsKey, actionShift);
    1775                                         // Make the tag label clickable and set tooltip to the action description (this displays also the keyboard shortcut)
    1776                                         tagLabel.setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION));
    1777                                         tagLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    1778                                         tagLabel.addMouseListener(new MouseAdapter() {
    1779                                                 @Override
    1780                                                 public void mouseClicked(MouseEvent e) {
    1781                                                         action.actionPerformed(null);
    1782                                                         // add tags and close window on double-click
    1783 
    1784                                                         if (e.getClickCount() > 1) {
    1785                                                                 buttonAction(0, null); // emulate OK click and close the dialog
    1786                                                         }
    1787                                                         // add tags on Shift-Click
    1788                                                         if (e.isShiftDown()) {
    1789                                                                 performTagAdding();
    1790                                                         }
    1791                                                 }
    1792                                         });
    1793                                 } else {
    1794                                         // Disable tag label
    1795                                         tagLabel.setEnabled(false);
    1796                                         // Explain in the tooltip why
    1797                                         tagLabel.setToolTipText(tr("The key ''{0}'' is already used", t.getKey()));
    1798                                 }
    1799                                 // Finally add label to the resulting panel
    1800                                 JPanel tagPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
    1801                                 tagPanel.add(tagLabel);
    1802                                 mainPanel.add(tagPanel, GBC.eol().fill(GBC.HORIZONTAL));
    1803                         }
    1804                 }
    1805 
    1806                 public void destroyActions() {
    1807                         for (JosmAction action : recentTagsActions) {
    1808                                 action.destroy();
    1809                         }
    1810                 }
    1811 
    1812                 /**
    1813                 * Read tags from comboboxes and add it to all selected objects
    1814                 */
    1815                 public final void performTagAdding() {
    1816                         String key = Tag.removeWhiteSpaces(keys.getEditor().getItem().toString());
    1817                         String value = Tag.removeWhiteSpaces(values.getEditor().getItem().toString());
    1818                         if (key.isEmpty() || value.isEmpty()) return;
    1819                         for (OsmPrimitive osm: sel) {
    1820                                 String val = osm.get(key);
    1821                                 if (val != null && !val.equals(value)) {
    1822                                         if (!warnOverwriteKey(tr("You changed the value of ''{0}'' from ''{1}'' to ''{2}''.", key, val, value),
    1823                                                         "overwriteAddKey"))
    1824                                                 return;
    1825                                         break;
    1826                                 }
    1827                         }
    1828                         lastAddKey = key;
    1829                         lastAddValue = value;
    1830                         recentTags.put(new Tag(key, value), null);
    1831                         AutoCompletionManager.rememberUserInput(key, value, false);
    1832                         commandCount++;
    1833                         MainApplication.undoRedo.add(new ChangePropertyCommand(sel, key, value));
    1834                         changedKey = key;
    1835                 }
    1836 
    1837                 public void undoAllTagsAdding() {
    1838                         MainApplication.undoRedo.undo(commandCount);
    1839                 }
    1840 
    1841                 private void disableTagIfNeeded(final Tag t, final JosmAction action) {
    1842                         // Disable action if its key is already set on the object (the key being absent from the keys list for this reason
    1843                         // performing this action leads to autocomplete to the next key (see #7671 comments)
    1844                         for (int j = 0; j < tagData.getRowCount(); ++j) {
    1845                                 if (t.getKey().equals(tagData.getValueAt(j, 0))) {
    1846                                         action.setEnabled(false);
    1847                                         break;
    1848                                 }
    1849                         }
    1850                 }
    1851 
    1852                 private void loadSVMmodel() {
    1853                         File modelDirectory = new File(MODEL_PATH);
    1854                         File modelFile;
    1855                         if (useCombinedModel) {
    1856                                 if (filesAndWeights.isEmpty()) {
    1857                                         System.out.println("No models selected! Loading defaults..");
    1858                                         if (modelWithClasses) {
    1859                                                 System.out.println("Using default/last model with classes: " + modelDirectory.getAbsolutePath() + "/model_with_classes");
    1860                                                 modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
    1861                                                 try {
    1862                                                         System.out.println("try to load model: " + modelFile.getAbsolutePath());
    1863                                                         modelSVM = Model.load(modelFile);
    1864                                                         System.out.println("model loaded!");
    1865 
    1866                                                 } catch (IOException ex) {
    1867                                                         Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
    1868                                                 }
    1869                                                 modelSVMLabelSize = modelSVM.getLabels().length;
    1870                                                 modelSVMLabels = modelSVM.getLabels();
    1871                                         } else {
    1872                                                 System.out.println("Using default/last model without classes: " + modelDirectory.getAbsolutePath() + "/best_model");
    1873                                                 modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
    1874                                                 try {
    1875                                                         System.out.println("try to load model: " + modelFile.getAbsolutePath());
    1876                                                         modelSVM = Model.load(modelFile);
    1877                                                         System.out.println("model loaded!");
    1878 
    1879                                                 } catch (IOException ex) {
    1880                                                         Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
    1881                                                 }
    1882                                                 modelSVMLabelSize = modelSVM.getLabels().length;
    1883                                                 modelSVMLabels = modelSVM.getLabels();
    1884                                         }
    1885                                 }
    1886                                 if (modelWithClasses) { //check filenames to define if model with classes is selected
    1887                                         System.out.println("Using combined model with classes");
    1888                                         useCombinedSVMmodels(sel, true);
    1889                                 } else {
    1890                                         System.out.println("Using combined model without classes");
    1891                                         useCombinedSVMmodels(sel, false);
    1892                                 }
    1893                         } else if (useCustomSVMModel) {
    1894                                 System.out.println("custom path: " + customSVMModelPath);
    1895                                 File checkExistance = new File(customSVMModelPath);
    1896                                 if (checkExistance.exists() && checkExistance.isFile()) {
    1897                                         if (modelWithClasses) {
    1898                                                 System.out.println("Using custom model with classes: ");
    1899                                                 if (customSVMModelPath.endsWith(".0")) {
    1900                                                         String customSVMModelPathWithClasses = customSVMModelPath.substring(0, customSVMModelPath.length() - 2) + ".1";
    1901 
    1902                                                         modelFile = new File(customSVMModelPathWithClasses);
    1903                                                         System.out.println(customSVMModelPathWithClasses);
    1904                                                 } else {
    1905                                                         modelFile = new File(customSVMModelPath);
    1906                                                 }
    1907                                         } else {
    1908                                                 System.out.println("Using custom model without classes");
    1909                                                 if (customSVMModelPath.endsWith(".1")) {
    1910                                                         String customSVMModelPathWithoutClasses = customSVMModelPath.substring(0, customSVMModelPath.length() - 2) + ".0";
    1911                                                         modelFile = new File(customSVMModelPathWithoutClasses);
    1912                                                         System.out.println(customSVMModelPathWithoutClasses);
    1913                                                 } else {
    1914                                                         modelFile = new File(customSVMModelPath);
    1915                                                 }
    1916                                         }
    1917                                         try {
    1918                                                 System.out.println("try to load model: " + modelFile.getAbsolutePath());
    1919                                                 modelSVM = Model.load(modelFile);
    1920                                                 System.out.println("model loaded!");
    1921 
    1922                                         } catch (IOException ex) {
    1923                                                 Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
    1924                                         }
    1925                                         modelSVMLabelSize = modelSVM.getLabels().length;
    1926                                         modelSVMLabels = modelSVM.getLabels();
    1927 
    1928                                 } else {
    1929                                         //user chose to use a custom model, but did not provide a path to a model:
    1930                                         if (modelWithClasses) {
    1931                                                 System.out.println("Using default/last model with classes");
    1932                                                 modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
    1933                                         } else {
    1934                                                 System.out.println("Using default/last model without classes");
    1935                                                 modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
    1936                                         }
    1937 
    1938                                         try {
    1939                                                 System.out.println("try to load model: " + modelFile.getAbsolutePath());
    1940                                                 modelSVM = Model.load(modelFile);
    1941                                                 System.out.println("model loaded!");
    1942 
    1943                                         } catch (IOException ex) {
    1944                                                 Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
    1945                                         }
    1946                                         modelSVMLabelSize = modelSVM.getLabels().length;
    1947                                         modelSVMLabels = modelSVM.getLabels();
    1948 
    1949                                 }
    1950                         } else {
    1951                                 if (modelWithClasses) {
    1952                                         System.out.println("Using default/last model with classes");
    1953                                         modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
    1954                                 } else {
    1955                                         System.out.println("Using default/last model without classes");
    1956                                         modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
    1957                                 }
    1958 
    1959                                 try {
    1960                                         System.out.println("try to load model: " + modelFile.getAbsolutePath());
    1961                                         modelSVM = Model.load(modelFile);
    1962                                         System.out.println("model loaded!");
    1963 
    1964                                 } catch (IOException ex) {
    1965                                         Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
    1966                                 }
    1967                                 modelSVMLabelSize = modelSVM.getLabels().length;
    1968                                 modelSVMLabels = modelSVM.getLabels();
    1969                         }
    1970                 }
    1971 
    1972                 private void useCombinedSVMmodels(Collection<OsmPrimitive> sel, boolean useClassFeatures) {
    1973                         System.out.println("The system will combine " + filesAndWeights.size() + " SVM models.");
    1974 
    1975                         MathTransform transform = null;
    1976                         GeometryFactory geometryFactory = new GeometryFactory();
    1977                         CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
    1978                         CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
    1979                         try {
    1980                                 transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
    1981 
    1982                         } catch (FactoryException ex) {
    1983                                 Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
    1984                         }
    1985 
    1986                         OSMWay selectedInstance;
    1987                         List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
    1988                         OsmPrimitive s;
    1989 
    1990                         //get a simple selection
    1991                         if (!osmPrimitiveSelection.isEmpty()) {
    1992                                 s = osmPrimitiveSelection.get(0);
    1993                         } else {
    1994                                 return;
    1995                         }
    1996 
    1997                         selectedInstance = new OSMWay();
    1998                         for (Way selectedWay : s.getDataSet().getSelectedWays()) {
    1999                                 List<Node> selectedWayNodes = selectedWay.getNodes();
    2000                                 for (Node node : selectedWayNodes) {
    2001                                         node.getCoor();
    2002                                         if (node.isLatLonKnown()) {
    2003                                                 double lat = node.getCoor().lat();
    2004                                                 double lon = node.getCoor().lon();
    2005 
    2006                                                 Coordinate sourceCoordinate = new Coordinate(lon, lat);
    2007                                                 Coordinate targetGeometry = null;
    2008                                                 try {
    2009                                                         targetGeometry = JTS.transform(sourceCoordinate, null, transform);
    2010                                                 } catch (MismatchedDimensionException | TransformException ex) {
    2011                                                         Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
    2012                                                 }
    2013 
    2014                                                 Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
    2015                                                 selectedInstance.addNodeGeometry(geom);
    2016                                         }
    2017                                 }
    2018                         }
    2019                         Geometry fullGeom = geometryFactory.buildGeometry(selectedInstance.getNodeGeometries());
    2020                         if ((selectedInstance.getNodeGeometries().size() > 3) &&
    2021                                         selectedInstance.getNodeGeometries().get(0).equals(selectedInstance.getNodeGeometries()
    2022                                                         .get(selectedInstance.getNodeGeometries().size()-1))) {
    2023                                 //checks if the beginning and ending node are the same and the number of nodes are more than 3.
    2024                                 //the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
    2025                                 LinearRing linear = geometryFactory.createLinearRing(fullGeom.getCoordinates());
    2026                                 Polygon poly = new Polygon(linear, null, geometryFactory);
    2027                                 selectedInstance.setGeometry(poly);
    2028 
    2029                                 System.out.println("\n\npolygon");
    2030                         } else if (selectedInstance.getNodeGeometries().size() > 1) {
    2031                                 //it is an open geometry with more than one nodes, make it linestring
    2032                                 System.out.println("\n\nlinestring");
    2033                                 LineString lineString = geometryFactory.createLineString(fullGeom.getCoordinates());
    2034                                 selectedInstance.setGeometry(lineString);
    2035                         } else { //we assume all the rest geometries are points
    2036                                 System.out.println("\n\npoint");
    2037                                 Point point = geometryFactory.createPoint(fullGeom.getCoordinate());
    2038                                 selectedInstance.setGeometry(point);
    2039                         }
    2040 
    2041                         Map<String, String> selectedTags = s.getInterestingTags();
    2042                         selectedInstance.setAllTags(selectedTags);
    2043 
    2044                         //construct vector
    2045                         if (selectedInstance != null) {
    2046                                 int id;
    2047 
    2048                                 OSMClassification classifier = new OSMClassification();
    2049                                 classifier.calculateClasses(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
    2050 
    2051                                 if (useClassFeatures) {
    2052                                         ClassFeatures classFeatures = new ClassFeatures();
    2053                                         classFeatures.createClassFeatures(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
    2054                                         id = 1422;
    2055                                 } else {
    2056                                         id = 1;
    2057                                 }
    2058 
    2059                                 GeometryFeatures geometryFeatures = new GeometryFeatures(id);
    2060                                 geometryFeatures.createGeometryFeatures(selectedInstance);
    2061                                 id = geometryFeatures.getLastID();
    2062                                 TextualFeatures textualFeatures = new TextualFeatures(id, textualList, languageDetector);
    2063                                 textualFeatures.createTextualFeatures(selectedInstance);
    2064 
    2065                                 List<FeatureNode> featureNodeList = selectedInstance.getFeatureNodeList();
    2066 
    2067                                 FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
    2068 
    2069                                 int i = 0;
    2070                                 for (FeatureNode featureNode : featureNodeList) {
    2071                                         featureNodeArray[i] = featureNode;
    2072                                         i++;
    2073                                 }
    2074                                 FeatureNode[] testInstance2 = featureNodeArray;
    2075 
    2076                                 //compute prediction list for every model
    2077                                 int[] ranks = new int[10];
    2078 
    2079                                 for (int l = 0; l < 10; l++) {
    2080                                         ranks[l] = 10-l; //init from 10 to 1
    2081                                 }
    2082 
    2083                                 Map<String, Double> scoreMap = new HashMap<>();
    2084 
    2085                                 Map<File, Double> alignedFilesAndWeights = getAlignedModels(filesAndWeights);
    2086 
    2087                                 for (File modelFile : alignedFilesAndWeights.keySet()) {
    2088 
    2089                                         try {
    2090                                                 modelSVM = Model.load(modelFile);
    2091                                         } catch (IOException ex) {
    2092                                                 Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
    2093                                         }
    2094                                         modelSVMLabelSize = modelSVM.getLabels().length;
    2095                                         modelSVMLabels = modelSVM.getLabels();
    2096 
    2097                                         Map<Integer, Integer> mapLabelsToIDs = new HashMap<>();
    2098                                         for (int h = 0; h < modelSVMLabelSize; h++) {
    2099                                                 mapLabelsToIDs.put(modelSVMLabels[h], h);
    2100                                         }
    2101                                         double[] scores = new double[modelSVMLabelSize];
    2102                                         Linear.predictValues(modelSVM, testInstance2, scores);
    2103 
    2104                                         Map<Double, Integer> scoresValues = new HashMap<>();
    2105                                         for (int h = 0; h < scores.length; h++) {
    2106                                                 scoresValues.put(scores[h], h);
    2107                                         }
    2108 
    2109                                         Arrays.sort(scores);
    2110                                         int predicted1 = modelSVMLabels[scoresValues.get(scores[scores.length-1])];
    2111                                         int predicted2 = modelSVMLabels[scoresValues.get(scores[scores.length-2])];
    2112                                         int predicted3 = modelSVMLabels[scoresValues.get(scores[scores.length-3])];
    2113                                         int predicted4 = modelSVMLabels[scoresValues.get(scores[scores.length-4])];
    2114                                         int predicted5 = modelSVMLabels[scoresValues.get(scores[scores.length-5])];
    2115                                         int predicted6 = modelSVMLabels[scoresValues.get(scores[scores.length-6])];
    2116                                         int predicted7 = modelSVMLabels[scoresValues.get(scores[scores.length-7])];
    2117                                         int predicted8 = modelSVMLabels[scoresValues.get(scores[scores.length-8])];
    2118                                         int predicted9 = modelSVMLabels[scoresValues.get(scores[scores.length-9])];
    2119                                         int predicted10 = modelSVMLabels[scoresValues.get(scores[scores.length-10])];
    2120 
    2121                                         String[] predictedTags = new String[10];
    2122                                         for (Map.Entry<String, Integer> entry : mapperWithIDs.entrySet()) {
    2123 
    2124                                                 if (entry.getValue().equals(predicted1)) {
    2125                                                         predictedTags[0] = entry.getKey();
    2126                                                 } else if (entry.getValue().equals(predicted2)) {
    2127                                                         predictedTags[1] = entry.getKey();
    2128                                                 } else if (entry.getValue().equals(predicted3)) {
    2129                                                         predictedTags[2] = entry.getKey();
    2130                                                 } else if (entry.getValue().equals(predicted4)) {
    2131                                                         predictedTags[3] = entry.getKey();
    2132                                                 } else if (entry.getValue().equals(predicted5)) {
    2133                                                         predictedTags[4] = entry.getKey();
    2134                                                 } else if (entry.getValue().equals(predicted6)) {
    2135                                                         predictedTags[5] = entry.getKey();
    2136                                                 } else if (entry.getValue().equals(predicted7)) {
    2137                                                         predictedTags[6] = entry.getKey();
    2138                                                 } else if (entry.getValue().equals(predicted8)) {
    2139                                                         predictedTags[7] = entry.getKey();
    2140                                                 } else if (entry.getValue().equals(predicted9)) {
    2141                                                         predictedTags[8] = entry.getKey();
    2142                                                 } else if (entry.getValue().equals(predicted10)) {
    2143                                                         predictedTags[9] = entry.getKey();
    2144                                                 }
    2145                                         }
    2146                                         //clearing model, to add the new computed classes in jlist
    2147                                         model.clear();
    2148                                         for (Map.Entry<String, String> tag : mappings.entrySet()) {
    2149 
    2150                                                 for (int k = 0; k < 10; k++) {
    2151                                                         if (tag.getValue().equals(predictedTags[k])) {
    2152                                                                 predictedTags[k] = tag.getKey();
    2153                                                                 model.addElement(tag.getKey());
    2154                                                         }
    2155                                                 }
    2156                                         }
    2157                                         System.out.println("combined, predicted classes: " + Arrays.toString(predictedTags));
    2158 
    2159                                         for (int r = 0; r < ranks.length; r++) {
    2160                                                 String predictedTag = predictedTags[r];
    2161                                                 Double currentWeight = alignedFilesAndWeights.get(modelFile);
    2162                                                 double finalRank = ranks[r]*currentWeight;
    2163 
    2164                                                 if (scoreMap.containsKey(predictedTag)) {
    2165                                                         Double scoreToAdd = scoreMap.get(predictedTag);
    2166                                                         scoreMap.put(predictedTag, finalRank+scoreToAdd);
    2167                                                 } else {
    2168                                                         scoreMap.put(predictedTag, finalRank);
    2169                                                 }
    2170                                                 //add final weight - predicted tag
    2171                                         }
    2172                                 } //files iter
    2173                                 model.clear();
    2174                                 List<Double> scoresList = new ArrayList<>(scoreMap.values());
    2175                                 Collections.sort(scoresList, Collections.reverseOrder());
    2176 
    2177                                 for (Double sco : scoresList) {
    2178                                         if (model.size() > 9) {
    2179                                                 break;
    2180                                         }
    2181                                         for (Map.Entry<String, Double> scoreEntry : scoreMap.entrySet()) {
    2182                                                 if (scoreEntry.getValue().equals(sco)) {
    2183                                                         model.addElement(scoreEntry.getKey());
    2184                                                 }
    2185                                         }
    2186                                 }
    2187                         }
    2188                 }
    2189 
    2190                 private void createOSMObject(Collection<OsmPrimitive> sel) {
    2191 
    2192                         MathTransform transform = null;
    2193                         GeometryFactory geometryFactory = new GeometryFactory();
    2194                         CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
    2195                         CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
    2196                         try {
    2197                                 transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
    2198 
    2199                         } catch (FactoryException ex) {
    2200                                 Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
    2201                         }
    2202 
    2203                         //fire an error to the user if he has multiple selection from map
    2204 
    2205                         //we consider simple (one instance) selection, so we get the first of the sel list
    2206 
    2207                         OSMWay selectedInstance;
    2208                         List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
    2209                         OsmPrimitive s;
    2210 
    2211                         //get a simple selection
    2212                         if (!osmPrimitiveSelection.isEmpty()) {
    2213                                 s = osmPrimitiveSelection.get(0);
    2214                         } else {
    2215                                 return;
    2216                         }
    2217 
    2218                         selectedInstance = new OSMWay();
    2219                         for (Way selectedWay : s.getDataSet().getSelectedWays()) {
    2220                                 List<Node> selectedWayNodes = selectedWay.getNodes();
    2221                                 for (Node node : selectedWayNodes) {
    2222                                         node.getCoor();
    2223                                         if (node.isLatLonKnown()) {
    2224                                                 double lat = node.getCoor().lat();
    2225                                                 double lon = node.getCoor().lon();
    2226 
    2227                                                 Coordinate sourceCoordinate = new Coordinate(lon, lat);
    2228                                                 Coordinate targetGeometry = null;
    2229                                                 try {
    2230                                                         targetGeometry = JTS.transform(sourceCoordinate, null, transform);
    2231                                                 } catch (MismatchedDimensionException | TransformException ex) {
    2232                                                         Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
    2233                                                 }
    2234 
    2235                                                 Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
    2236                                                 selectedInstance.addNodeGeometry(geom);
    2237                                         }
    2238                                 }
    2239                         }
    2240                         Geometry fullGeom = geometryFactory.buildGeometry(selectedInstance.getNodeGeometries());
    2241 
    2242                         System.out.println("number of nodes: " + selectedInstance.getNodeGeometries().size());
    2243 
    2244                         if ((selectedInstance.getNodeGeometries().size() > 3) &&
    2245                                         selectedInstance.getNodeGeometries().get(0).equals(selectedInstance.getNodeGeometries()
    2246                                                         .get(selectedInstance.getNodeGeometries().size()-1))) {
    2247                                 //checks if the beginning and ending node are the same and the number of nodes are more than 3.
    2248                                 //the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
    2249                                 LinearRing linear = geometryFactory.createLinearRing(fullGeom.getCoordinates());
    2250                                 Polygon poly = new Polygon(linear, null, geometryFactory);
    2251                                 selectedInstance.setGeometry(poly);
    2252 
    2253                                 System.out.println("\n\npolygon");
    2254                         } else if (selectedInstance.getNodeGeometries().size() > 1) {
    2255                                 //it is an open geometry with more than one nodes, make it linestring
    2256                                 System.out.println("\n\nlinestring");
    2257                                 LineString lineString = geometryFactory.createLineString(fullGeom.getCoordinates());
    2258                                 selectedInstance.setGeometry(lineString);
    2259                         } else { //we assume all the rest geometries are points
    2260                                 System.out.println("\n\npoint");
    2261                                 Point point = geometryFactory.createPoint(fullGeom.getCoordinate());
    2262                                 selectedInstance.setGeometry(point);
    2263                         }
    2264 
    2265                         Map<String, String> selectedTags = s.getInterestingTags();
    2266                         selectedInstance.setAllTags(selectedTags);
    2267 
    2268                         //construct vector here
    2269                         if (selectedInstance != null) {
    2270                                 int id;
    2271                                 if (mappings == null) {
    2272                                         System.out.println("null mappings ERROR");
    2273                                 }
    2274 
    2275                                 OSMClassification classifier = new OSMClassification();
    2276                                 classifier.calculateClasses(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
    2277 
    2278                                 if (modelWithClasses) {
    2279                                         ClassFeatures classFeatures = new ClassFeatures();
    2280                                         classFeatures.createClassFeatures(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
    2281                                         id = 1422;
    2282                                 } else {
    2283                                         id = 1;
    2284                                 }
    2285 
    2286                                 GeometryFeatures geometryFeatures = new GeometryFeatures(id);
    2287                                 geometryFeatures.createGeometryFeatures(selectedInstance);
    2288                                 id = geometryFeatures.getLastID();
    2289                                 TextualFeatures textualFeatures = new TextualFeatures(id, textualList, languageDetector);
    2290                                 textualFeatures.createTextualFeatures(selectedInstance);
    2291 
    2292                                 List<FeatureNode> featureNodeList = selectedInstance.getFeatureNodeList();
    2293                                 System.out.println(featureNodeList);
    2294 
    2295                                 FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
    2296 
    2297                                 int i = 0;
    2298                                 for (FeatureNode featureNode : featureNodeList) {
    2299                                         featureNodeArray[i] = featureNode;
    2300                                         i++;
    2301                                 }
    2302                                 FeatureNode[] testInstance2 = featureNodeArray;
    2303 
    2304                                 Map<Integer, Integer> mapLabelsToIDs = new HashMap<>();
    2305                                 for (int h = 0; h < modelSVMLabelSize; h++) {
    2306                                         mapLabelsToIDs.put(modelSVMLabels[h], h);
    2307                                 }
    2308 
    2309                                 double[] scores = new double[modelSVMLabelSize];
    2310                                 Linear.predictValues(modelSVM, testInstance2, scores);
    2311 
    2312                                 Map<Double, Integer> scoresValues = new HashMap<>();
    2313                                 for (int h = 0; h < scores.length; h++) {
    2314                                         scoresValues.put(scores[h], h);
    2315                                 }
    2316 
    2317                                 Arrays.sort(scores);
    2318 
    2319                                 int[] preds = new int[RECOMMENDATIONS_SIZE];
    2320                                 for (int p = 0; p < RECOMMENDATIONS_SIZE; p++) {
    2321                                         preds[p] = modelSVMLabels[scoresValues.get(scores[scores.length-(p+1)])];
    2322                                 }
    2323                                 String[] predictedTags2 = new String[RECOMMENDATIONS_SIZE];
    2324 
    2325                                 for (int p = 0; p < RECOMMENDATIONS_SIZE; p++) {
    2326                                         if (idsWithMappings.containsKey(preds[p])) {
    2327                                                 predictedTags2[p] = idsWithMappings.get(preds[p]);
    2328                                         }
    2329                                 }
    2330 
    2331                                 //clearing model, to add the new computed classes in jlist
    2332                                 model.clear();
    2333                                 for (Map.Entry<String, String> tag : mappings.entrySet()) {
    2334                                         for (int k = 0; k < 10; k++) {
    2335                                                 if (tag.getValue().equals(predictedTags2[k])) {
    2336                                                         predictedTags2[k] = tag.getKey();
    2337                                                         model.addElement(tag.getKey());
    2338                                                 }
    2339                                         }
    2340                                 }
    2341                                 System.out.println("Optimized - create OSMObject, predicted classes: " + Arrays.toString(predictedTags2));
    2342                         }
    2343                 }
    2344 
    2345                 private void parseTagsMappedToClasses() {
    2346 
    2347                         InputStream tagsToClassesMapping = TrainWorker.class.getResourceAsStream("/resources/files/Map");
    2348                         Mapper mapper = new Mapper();
    2349                         try {
    2350                                 mapper.parseFile(tagsToClassesMapping);
    2351 
    2352                         } catch (FileNotFoundException ex) {
    2353                                 Logger.getLogger(Mapper.class.getName()).log(Level.SEVERE, null, ex);
    2354                         }
    2355                         mappings = mapper.getMappings();
    2356                         mapperWithIDs = mapper.getMappingsWithIDs();
    2357                         idsWithMappings = mapper.getIDsWithMappings();
    2358                 }
    2359 
    2360                 private void loadTextualList(File textualListFile) {
    2361 
    2362                         Scanner input = null;
    2363 
    2364                         try {
    2365                                 input = new Scanner(textualListFile);
    2366                         } catch (FileNotFoundException ex) {
    2367                                 Logging.warn(ex);
    2368                         }
    2369                         while (input.hasNext()) {
    2370                                 String nextLine = input.nextLine();
    2371                                 textualList.add(nextLine);
    2372                         }
    2373                         System.out.println("Textual List parsed from file successfully." + textualList);
    2374                 }
    2375 
    2376                 private void loadDefaultTextualList() {
    2377 
    2378                         InputStream textualListStream = TrainWorker.class.getResourceAsStream("/resources/files/textualList.txt");
    2379                         TextualStatistics textualStatistics = new TextualStatistics();
    2380                         textualStatistics.parseTextualList(textualListStream);
    2381                         textualList = textualStatistics.getTextualList();
    2382                         System.out.println("Default Textual List parsed from file successfully." + textualList);
    2383                 }
    2384 
    2385                 private void loadOntology() {
    2386                         InputStream ontologyStream = TrainWorker.class.getResourceAsStream("/resources/files/owl.xml");
    2387                         Ontology ontology = new Ontology(ontologyStream);
    2388                         indirectClasses = ontology.getIndirectClasses();
    2389                         indirectClassesWithIDs = ontology.getIndirectClassesIDs();
    2390                 }
    2391 
    2392                 private Map<File, Double> getAlignedModels(Map<File, Double> filesAndWeights) {
    2393                         Map<File, Double> alignedFilesAndWeights = new HashMap<>();
    2394                         if (modelWithClasses) {
    2395                                 for (Entry<File, Double> entry : filesAndWeights.entrySet()) {
    2396                                         String absolutePath = entry.getKey().getAbsolutePath();
    2397                                         if (absolutePath.endsWith(".0")) {
    2398                                                 String newPath = absolutePath.substring(0, absolutePath.length()-2) + ".1";
    2399                                                 File alignedFile = new File(newPath);
    2400                                                 if (alignedFile.exists()) {
    2401                                                         alignedFilesAndWeights.put(alignedFile, entry.getValue());
    2402                                                 }
    2403                                         } else {
    2404                                                 alignedFilesAndWeights.put(entry.getKey(), entry.getValue());
    2405                                         }
    2406                                 }
    2407                         } else {
    2408                                 for (Entry<File, Double> entry : filesAndWeights.entrySet()) {
    2409                                         String absolutePath = entry.getKey().getAbsolutePath();
    2410                                         if (absolutePath.endsWith(".1")) {
    2411                                                 String newPath = absolutePath.substring(0, absolutePath.length()-2) + ".0";
    2412                                                 File alignedFile = new File(newPath);
    2413                                                 if (alignedFile.exists()) {
    2414                                                         alignedFilesAndWeights.put(alignedFile, entry.getValue());
    2415                                                 }
    2416                                         } else {
    2417                                                 alignedFilesAndWeights.put(entry.getKey(), entry.getValue());
    2418                                         }
    2419                                 }
    2420                         }
    2421                         return alignedFilesAndWeights;
    2422                 }
    2423         }
     606            */
     607            buildUserHistoryPanelGroupLayout();
     608
     609            configPanel.add(inputPanel, BorderLayout.NORTH);
     610            configPanel.add(userHistoryPanel, BorderLayout.EAST);
     611            configPanel.add(paramPanel, BorderLayout.WEST);
     612            configPanel.add(southPanel, BorderLayout.SOUTH);
     613
     614            userHistoryPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
     615                    .createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE), "Train by user History"));
     616            paramPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
     617                    .createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE), "SVM Configuration"));
     618            inputPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
     619            configPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
     620
     621            mainPanel.add(configPanel, BorderLayout.NORTH);
     622            mainPanel.add(startTrainingButton, BorderLayout.CENTER);
     623            mainPanel.add(trainingProgressBar, BorderLayout.SOUTH);
     624
     625            AutoCompletionManager autocomplete = MainApplication.getLayerManager().getEditLayer().data.getAutoCompletionManager();
     626            List<AutoCompletionListItem> keyList = autocomplete.getKeys();
     627            Collections.sort(keyList, defaultACItemComparator);
     628
     629            setContent(mainPanel, false);
     630        }
     631
     632        private void buildInputPanelGroupLayout(JPanel inputPanel) {
     633            GroupLayout inputGroupLayout = new GroupLayout(inputPanel);
     634            inputPanel.setLayout(inputGroupLayout);
     635            inputGroupLayout.setAutoCreateGaps(true);
     636            inputGroupLayout.setAutoCreateContainerGaps(true);
     637
     638            GroupLayout.SequentialGroup inputHorGroup = inputGroupLayout.createSequentialGroup();
     639            inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(inputFileLabel).
     640                    addComponent(inputFileErrorMessageLabel));
     641            inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(inputFileField));
     642            inputHorGroup.addGroup(inputGroupLayout.createParallelGroup().addComponent(fileBrowseButton));
     643            inputGroupLayout.setHorizontalGroup(inputHorGroup);
     644
     645            GroupLayout.SequentialGroup inputVerGroup = inputGroupLayout.createSequentialGroup();
     646            inputVerGroup.addGroup(inputGroupLayout.createParallelGroup(Alignment.LEADING).addComponent(inputFileLabel).
     647                    addComponent(inputFileField).addComponent(fileBrowseButton));
     648            inputVerGroup.addGroup(inputGroupLayout.createParallelGroup(Alignment.LEADING).
     649                    addComponent(inputFileErrorMessageLabel));
     650            inputGroupLayout.setVerticalGroup(inputVerGroup);
     651        }
     652
     653        private void buildParamPanelGroupLayout(JPanel paramPanel) {
     654            GroupLayout paramGroupLayout = new GroupLayout(paramPanel);
     655            paramPanel.setLayout(paramGroupLayout);
     656            paramGroupLayout.setAutoCreateGaps(true);
     657            paramGroupLayout.setAutoCreateContainerGaps(true);
     658
     659            GroupLayout.SequentialGroup paramHorGroup = paramGroupLayout.createSequentialGroup();
     660            paramHorGroup.addGroup(paramGroupLayout.createParallelGroup().addComponent(topKButton).
     661                    addComponent(frequencyButton).addComponent(cParameterCheckBox));
     662            paramHorGroup.addGroup(paramGroupLayout.createParallelGroup().addComponent(cParameterField).
     663                    addComponent(topKField).addComponent(frequencyField));
     664            paramHorGroup.addGroup(paramGroupLayout.createParallelGroup().addComponent(cErrorMessageLabel).
     665                    addComponent(topKErrorMessageLabel).addComponent(frequencyErrorMessageLabel));
     666            paramGroupLayout.setHorizontalGroup(paramHorGroup);
     667
     668            GroupLayout.SequentialGroup paramVerGroup = paramGroupLayout.createSequentialGroup();
     669            paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).
     670                    addComponent(cParameterCheckBox).addComponent(cParameterField).addComponent(cErrorMessageLabel));
     671            paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).addComponent(topKButton).
     672                    addComponent(topKField).addComponent(topKErrorMessageLabel));
     673            paramVerGroup.addGroup(paramGroupLayout.createParallelGroup(Alignment.BASELINE).
     674                    addComponent(frequencyButton).addComponent(frequencyField).addComponent(frequencyErrorMessageLabel));
     675            paramGroupLayout.setVerticalGroup(paramVerGroup);
     676        }
     677
     678        private void buildUserHistoryPanelGroupLayout() {
     679            GroupLayout userHistoryGroupLayout = new GroupLayout(userHistoryPanel);
     680            userHistoryPanel.setLayout(userHistoryGroupLayout);
     681            userHistoryGroupLayout.setAutoCreateGaps(true);
     682            userHistoryGroupLayout.setAutoCreateContainerGaps(true);
     683            userHistoryGroupLayout.linkSize(SwingConstants.HORIZONTAL, userNameField, daysLabel, daysField);
     684
     685            GroupLayout.SequentialGroup userHistoryHorGroup = userHistoryGroupLayout.createSequentialGroup();
     686
     687            userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(userNameLabel)
     688                    .addComponent(byAreaRadioButton).addComponent(byTimeRadioButton));
     689            userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(userNameField)
     690                    .addComponent(daysLabel));
     691            userHistoryHorGroup.addGroup(userHistoryGroupLayout.createParallelGroup().addComponent(daysField));
     692            userHistoryGroupLayout.setHorizontalGroup(userHistoryHorGroup);
     693
     694            GroupLayout.SequentialGroup userHistoryVerGroup = userHistoryGroupLayout.createSequentialGroup();
     695            userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
     696                    addComponent(userNameLabel).addComponent(userNameField));
     697            userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
     698                    addComponent(byAreaRadioButton));
     699            userHistoryVerGroup.addGroup(userHistoryGroupLayout.createParallelGroup(Alignment.BASELINE).
     700                    addComponent(byTimeRadioButton).addComponent(daysLabel).addComponent(daysField));
     701            userHistoryGroupLayout.setVerticalGroup(userHistoryVerGroup);
     702        }
     703
     704        private void inputFileChooserButtonActionPerformed(ActionEvent evt) {
     705            try {
     706                final File file = new File(inputFileField.getText());
     707                final JFileChooser fileChooser = new JFileChooser(file);
     708
     709                final int returnVal = fileChooser.showOpenDialog(this);
     710                if (returnVal == JFileChooser.APPROVE_OPTION) {
     711                    inputFileField.setText(fileChooser.getSelectedFile().getAbsolutePath());
     712                }
     713            } catch (RuntimeException ex) {
     714                Logging.warn(ex);
     715            }
     716        }
     717
     718        private void acceptConfigButtonActionPerformed(ActionEvent evt) {
     719            //parse values
     720            inputFileValue = inputFileField.getText();
     721
     722            if (!new File(inputFileValue).exists()) {
     723                inputFileErrorMessageLabel.setText("OSM file does not exist");
     724                resetConfigButtonActionPerformed();
     725                return;
     726            }
     727
     728            if (cParameterCheckBox.isSelected()) {
     729                String c = cParameterField.getText();
     730                try {
     731                    cParameterValue = Double.parseDouble(c.replace(",", "."));
     732                    cErrorMessageLabel.setText("");
     733                } catch (NumberFormatException ex) {
     734                    cErrorMessageLabel.setText("Must be a number!");
     735                    System.out.println("c must be a number!" + ex); //make empty textLabel beside c param to notify errors
     736                    resetConfigButtonActionPerformed();
     737                    return;
     738                }
     739                crossValidateFlag = false;
     740            } else {
     741                crossValidateFlag = true;
     742            }
     743
     744            if (topKButton.isSelected()) {
     745                String k = topKField.getText();
     746                try {
     747                    topKvalue = Integer.parseInt(k);
     748                    topKErrorMessageLabel.setText("");
     749                } catch (NumberFormatException ex) {
     750                    topKErrorMessageLabel.setText("Must be an Integer!");
     751                    resetConfigButtonActionPerformed();
     752                    return;
     753                }
     754            } else {
     755                String f = frequencyField.getText();
     756                try {
     757                    frequencyValue = Integer.parseInt(f);
     758                    frequencyErrorMessageLabel.setText("");
     759                } catch (NumberFormatException ex) {
     760                    frequencyErrorMessageLabel.setText("Must be an Integer!");
     761                    resetConfigButtonActionPerformed();
     762                    return;
     763                }
     764            }
     765
     766            if (trainFromUserCheckBox.isSelected()) {
     767                usernameValue = userNameField.getText();
     768                if (byTimeRadioButton.isSelected()) {
     769                    try {
     770                        daysValue = Integer.parseInt(daysField.getText());
     771                    } catch (NumberFormatException ex) {
     772                        daysField.setText("Integer!");
     773                        Logging.warn(ex);
     774                    }
     775                }
     776
     777                userHistoryPanel.setEnabled(false);
     778                byAreaRadioButton.setEnabled(false);
     779                byTimeRadioButton.setEnabled(false);
     780                userNameLabel.setEnabled(false);
     781                userNameField.setEnabled(false);
     782                daysLabel.setEnabled(false);
     783                daysField.setEnabled(false);
     784            }
     785
     786            System.out.println("Running configuration:" + "\nC parameter: " + cParameterValue +" \ntopK: " + topKvalue
     787                    + "\nMax Frequency: " + frequencyValue + "\nCross Validate?: " + crossValidateFlag);
     788
     789            trainFromUserCheckBox.setEnabled(false);
     790            inputFileField.setEditable(false);
     791            cParameterField.setEditable(false);
     792            topKField.setEditable(false);
     793            frequencyField.setEditable(false);
     794            cParameterCheckBox.setEnabled(false);
     795            topKButton.setEnabled(false);
     796            frequencyButton.setEnabled(false);
     797            acceptConfigButton.setEnabled(false);
     798            fileBrowseButton.setEnabled(false);
     799        }
     800
     801        private void resetConfigButtonActionPerformed() {
     802            if (trainWorker != null) {
     803                try {
     804                    trainWorker.cancel(true);
     805                } catch (CancellationException ex) {
     806                    startTrainingButton.setEnabled(true);
     807                    System.out.println(ex);
     808                }
     809            }
     810            if (userDataExtractAndTrainWorker != null) {
     811                try {
     812                    userDataExtractAndTrainWorker.cancel(true);
     813                } catch (CancellationException ex) {
     814                    startTrainingButton.setEnabled(true);
     815                    System.out.println(ex);
     816                }
     817            }
     818            inputFileField.setEditable(true);
     819            cParameterField.setEditable(true);
     820            topKField.setEditable(true);
     821            frequencyField.setEditable(true);
     822            cParameterCheckBox.setEnabled(true);
     823            topKButton.setEnabled(true);
     824            frequencyButton.setEnabled(true);
     825            acceptConfigButton.setEnabled(true);
     826            fileBrowseButton.setEnabled(true);
     827            trainFromUserCheckBox.setEnabled(true);
     828
     829            if (trainFromUserCheckBox.isSelected()) {
     830                userHistoryPanel.setEnabled(true);
     831                byAreaRadioButton.setEnabled(true);
     832                byTimeRadioButton.setEnabled(true);
     833                userNameLabel.setEnabled(true);
     834                userNameField.setEnabled(true);
     835                daysLabel.setEnabled(true);
     836                daysField.setEnabled(true);
     837            }
     838        }
     839
     840        private void startTraining() {
     841            startTrainingButton.setEnabled(false);
     842
     843            if (trainFromUserCheckBox.isSelected()) { //if user training. train by area or days
     844                EventQueue.invokeLater(new Runnable() {
     845                    @Override
     846                    public void run() {
     847
     848                        userDataExtractAndTrainWorker = new UserDataExtractAndTrainWorker(inputFileValue, usernameValue, daysValue,
     849                                byAreaRadioButton.isSelected(), crossValidateFlag, cParameterValue, topKvalue, frequencyValue,
     850                                topKButton.isSelected(), languageDetector);
     851
     852                        userDataExtractAndTrainWorker.addPropertyChangeListener(new PropertyChangeListener() {
     853                            @Override
     854                            public void propertyChange(PropertyChangeEvent evt) {
     855                                if ("progress".equals(evt.getPropertyName())) {
     856                                    int progress = (Integer) evt.getNewValue();
     857                                    trainingProgressBar.setValue(progress);
     858                                    if (progress == 100) {
     859                                        startTrainingButton.setEnabled(true);
     860                                    }
     861                                }
     862                            }
     863                        });
     864
     865                        try {
     866                            System.out.println("executing userDataExtractAndTrainWorker Thread..");
     867                            userDataExtractAndTrainWorker.execute();
     868                        } catch (Exception ex) {
     869                            Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
     870                        }
     871                    }
     872                });
     873            } else {
     874                EventQueue.invokeLater(new Runnable() {
     875                    @Override
     876                    public void run() {
     877                        trainWorker = new TrainWorker(inputFileValue, crossValidateFlag, cParameterValue, topKvalue, frequencyValue,
     878                                topKButton.isSelected(), languageDetector);
     879
     880                        trainWorker.addPropertyChangeListener(new PropertyChangeListener() {
     881                            @Override
     882                            public void propertyChange(PropertyChangeEvent evt) {
     883                                if ("progress".equals(evt.getPropertyName())) {
     884                                    int progress = (Integer) evt.getNewValue();
     885                                    trainingProgressBar.setValue(progress);
     886                                    if (progress == 100) {
     887                                        startTrainingButton.setEnabled(true);
     888                                    }
     889                                }
     890                            }
     891                        });
     892
     893                        try {
     894                            trainWorker.execute();
     895                        } catch (Exception ex) {
     896                            Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
     897                        }
     898                    }
     899                });
     900            }
     901        }
     902    }
     903
     904    public static final BooleanProperty PROPERTY_FIX_TAG_LOCALE =
     905            new BooleanProperty("properties.fix-tag-combobox-locale", false);
     906    public static final BooleanProperty PROPERTY_REMEMBER_TAGS =
     907            new BooleanProperty("properties.remember-recently-added-tags", true);
     908    public static final IntegerProperty PROPERTY_RECENT_TAGS_NUMBER =
     909            new IntegerProperty("properties.recently-added-tags", DEFAULT_LRU_TAGS_NUMBER);
     910
     911    abstract static class AbstractTagsDialog extends ExtendedDialog {
     912        AutoCompletingComboBox keys;
     913        AutoCompletingComboBox values;
     914
     915        AbstractTagsDialog(Component parent, String title, String[] buttonTexts) {
     916            super(parent, title, buttonTexts);
     917            addMouseListener(new PopupMenuLauncher(popupMenu));
     918        }
     919
     920        @Override
     921        public void setupDialog() {
     922            super.setupDialog();
     923            final Dimension size = getSize();
     924            // Set resizable only in width
     925            setMinimumSize(size);
     926            setPreferredSize(size);
     927            // setMaximumSize does not work, and never worked, but still it seems not to bother Oracle to fix this 10-year-old bug
     928            // https://bugs.openjdk.java.net/browse/JDK-6200438
     929            // https://bugs.openjdk.java.net/browse/JDK-6464548
     930
     931            setRememberWindowGeometry(getClass().getName() + ".geometry",
     932                    WindowGeometry.centerInWindow(Main.parent, size));
     933        }
     934
     935        @Override
     936        public void setVisible(boolean visible) {
     937            // Do not want dialog to be resizable in height, as its size may increase each time because of the recently added tags
     938            // So need to modify the stored geometry (size part only) in order to use the automatic positioning mechanism
     939            if (visible) {
     940                WindowGeometry geometry = initWindowGeometry();
     941                Dimension storedSize = geometry.getSize();
     942                Dimension size = getSize();
     943                if (!storedSize.equals(size)) {
     944                    if (storedSize.width < size.width) {
     945                        storedSize.width = size.width;
     946                    }
     947                    if (storedSize.height != size.height) {
     948                        storedSize.height = size.height;
     949                    }
     950                    rememberWindowGeometry(geometry);
     951                }
     952                if (keys != null) {
     953                    keys.setFixedLocale(PROPERTY_FIX_TAG_LOCALE.get());
     954                }
     955            }
     956            super.setVisible(visible);
     957        }
     958
     959        /**
     960        * Create a focus handling adapter and apply in to the editor component of value
     961        * autocompletion box.
     962        * @param autocomplete Manager handling the autocompletion
     963        * @param comparator Class to decide what values are offered on autocompletion
     964        * @return The created adapter
     965        */
     966        protected FocusAdapter addFocusAdapter(final AutoCompletionManager autocomplete, final Comparator<AutoCompletionListItem> comparator) {
     967            // get the combo box' editor component
     968            JTextComponent editor = (JTextComponent) values.getEditor().getEditorComponent();
     969            // Refresh the values model when focus is gained
     970            FocusAdapter focus = new FocusAdapter() {
     971                @Override
     972                public void focusGained(FocusEvent e) {
     973                    String key = keys.getEditor().getItem().toString();
     974
     975                    List<AutoCompletionListItem> valueList = autocomplete.getValues(getAutocompletionKeys(key));
     976                    Collections.sort(valueList, comparator);
     977
     978                    values.setPossibleACItems(valueList);
     979                    values.getEditor().selectAll();
     980                }
     981            };
     982            editor.addFocusListener(focus);
     983            return focus;
     984        }
     985
     986        protected JPopupMenu popupMenu = new JPopupMenu() {
     987            JCheckBoxMenuItem fixTagLanguageCb = new JCheckBoxMenuItem(
     988                    new AbstractAction(tr("Use English language for tag by default")) {
     989                        @Override
     990                        public void actionPerformed(ActionEvent e) {
     991                            boolean sel = ((JCheckBoxMenuItem) e.getSource()).getState();
     992                            PROPERTY_FIX_TAG_LOCALE.put(sel);
     993                        }
     994                    });
     995            {
     996                add(fixTagLanguageCb);
     997                fixTagLanguageCb.setState(PROPERTY_FIX_TAG_LOCALE.get());
     998            }
     999        };
     1000    }
     1001
     1002    class ModelSettingsDialog extends JPanel {
     1003
     1004        private final JLabel chooseModelLabel;
     1005        private final JButton chooseModelButton;
     1006        private final JTextField chooseModelTextField;
     1007
     1008        private final DefaultListModel<String> combinationDefaultListModel = new DefaultListModel<>();
     1009        private final JList<String> modelCombinationList = new JList<>(combinationDefaultListModel);
     1010        private final JPanel modelCombinationPanel;
     1011        private final JPanel weightsPanel;
     1012        private final JCheckBox useModelCombinationCheckbox;
     1013        private final JButton acceptWeightsButton;
     1014        private final JButton resetWeightsButton;
     1015        private final JButton removeSelectedModelButton;
     1016        private Map<JTextField, String> weightFieldsAndPaths = new HashMap<>();
     1017        private final Map<String, Double> normalizedPathsAndWeights = new HashMap<>();
     1018        private final JOptionPane pane;
     1019        private final JDialog dlg;
     1020        private final JPanel mainPanel;
     1021        private final JPanel singleSelectionPanel;
     1022        private final JPanel setResetWeightsPanel;
     1023        private final JScrollPane combinationScrollPane;
     1024        private final JScrollPane singleSelectionScrollPane;
     1025        private final TitledBorder modelTitle;
     1026        private final TitledBorder weightTitle;
     1027        private final TitledBorder combineTitle;
     1028        private final Dimension singleSelectionDimension;
     1029        private final Dimension modelCombinationDimension;
     1030        private final Dimension mainPanelDimension;
     1031
     1032        ModelSettingsDialog(Collection<OsmPrimitive> sel1, final AddTagsDialog addDialog) {
     1033
     1034            loadPreviousCombinedSVMModel();
     1035            singleSelectionDimension = new Dimension(470, 70);
     1036            modelCombinationDimension = new Dimension(450, 250);
     1037            mainPanelDimension = new Dimension(600, 350);
     1038
     1039            //------- <NORTH of main> ---------//
     1040            mainPanel = new JPanel(new BorderLayout(10, 10));
     1041            singleSelectionPanel = new JPanel(new BorderLayout(10, 10));
     1042            setResetWeightsPanel = new JPanel();
     1043
     1044            chooseModelLabel = new JLabel("Choose a Model:");
     1045            chooseModelTextField = new JTextField();
     1046            chooseModelButton = new JButton("...");
     1047            chooseModelTextField.setText(MODEL_PATH);
     1048
     1049            singleSelectionPanel.add(chooseModelLabel, BorderLayout.NORTH);
     1050            singleSelectionPanel.add(chooseModelTextField, BorderLayout.WEST);
     1051            singleSelectionPanel.add(chooseModelButton, BorderLayout.EAST);
     1052
     1053            singleSelectionScrollPane = new JScrollPane(singleSelectionPanel);
     1054            singleSelectionScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
     1055            singleSelectionScrollPane.setPreferredSize(singleSelectionDimension);
     1056
     1057            //------- </NORTH of main> ---------//
     1058
     1059            //------- <WEST of main> ---------//
     1060            modelCombinationList.setFixedCellHeight(20);
     1061            modelCombinationList.setEnabled(false);
     1062            modelCombinationPanel = new JPanel(new BorderLayout(10, 10));
     1063
     1064            weightsPanel = new JPanel();
     1065            weightsPanel.setLayout(new BoxLayout(weightsPanel, BoxLayout.Y_AXIS));
     1066            weightsPanel.setEnabled(false);
     1067
     1068
     1069            acceptWeightsButton = new JButton("Set Weights/Normalize");
     1070            resetWeightsButton = new JButton("Reset Weights");
     1071            removeSelectedModelButton = new JButton("Remove Selected");
     1072            setResetWeightsPanel.add(acceptWeightsButton);
     1073            setResetWeightsPanel.add(resetWeightsButton);
     1074            setResetWeightsPanel.add(removeSelectedModelButton);
     1075            removeSelectedModelButton.setEnabled(false);
     1076            acceptWeightsButton.setEnabled(false);
     1077            resetWeightsButton.setEnabled(false);
     1078
     1079            modelCombinationPanel.add(modelCombinationList, BorderLayout.CENTER);
     1080            modelCombinationPanel.add(weightsPanel, BorderLayout.EAST);
     1081            modelCombinationPanel.add(setResetWeightsPanel, BorderLayout.SOUTH);
     1082
     1083            combinationScrollPane = new JScrollPane(modelCombinationPanel);
     1084
     1085            combinationScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
     1086            combinationScrollPane.setPreferredSize(modelCombinationDimension);   //new Dimension(450, 250) // w/h
     1087
     1088            //------- </WEST of main> ---------//
     1089
     1090            //------- <SOUTH of main> ---------//
     1091            useModelCombinationCheckbox = new JCheckBox("Combine different models?");
     1092
     1093            //------- </SOUTH of main> ---------//
     1094
     1095            //------- <Borders> ---------//
     1096            modelTitle = BorderFactory.createTitledBorder("Models");
     1097            weightTitle = BorderFactory.createTitledBorder("W");
     1098            combineTitle = BorderFactory.createTitledBorder("Combine Models");
     1099            modelCombinationList.setBorder(modelTitle);
     1100            weightsPanel.setBorder(weightTitle);
     1101
     1102            for (Entry<JTextField, String> entry : weightFieldsAndPaths.entrySet()) {
     1103                combinationDefaultListModel.addElement(entry.getValue());
     1104
     1105                JTextField weightTextField = new JTextField("0.00");
     1106                weightTextField.setMaximumSize(new Dimension(80, 20));
     1107                weightsPanel.add(entry.getKey());
     1108            }
     1109
     1110            //modelCombinationPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
     1111            modelCombinationPanel.setBorder(combineTitle);
     1112            singleSelectionPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
     1113            //------- </Borders> ---------//
     1114
     1115            chooseModelButton.addActionListener(new java.awt.event.ActionListener() {
     1116                @Override
     1117                public void actionPerformed(java.awt.event.ActionEvent evt) {
     1118                    modelChooserButtonActionPerformed(evt);
     1119                }
     1120            });
     1121
     1122            useModelCombinationCheckbox.addActionListener(new java.awt.event.ActionListener() {
     1123                @Override
     1124                public void actionPerformed(java.awt.event.ActionEvent evt) {
     1125                    userCombinationCheckboxActionPerformed(evt);
     1126                }
     1127            });
     1128
     1129            acceptWeightsButton.addActionListener(new java.awt.event.ActionListener() {
     1130                @Override
     1131                public void actionPerformed(java.awt.event.ActionEvent evt) {
     1132                    acceptWeightsButtonActionPerformed(evt);
     1133                }
     1134            });
     1135
     1136            resetWeightsButton.addActionListener(new java.awt.event.ActionListener() {
     1137                @Override
     1138                public void actionPerformed(java.awt.event.ActionEvent evt) {
     1139                    resetWeightsButtonActionPerformed(evt);
     1140                }
     1141            });
     1142
     1143            removeSelectedModelButton.addActionListener(new java.awt.event.ActionListener() {
     1144                @Override
     1145                public void actionPerformed(java.awt.event.ActionEvent evt) {
     1146                    removeSelectedModelButtonActionPerformed(evt);
     1147                }
     1148            });
     1149            mainPanel.add(singleSelectionScrollPane, BorderLayout.NORTH);
     1150            mainPanel.add(combinationScrollPane, BorderLayout.CENTER);
     1151            mainPanel.add(useModelCombinationCheckbox, BorderLayout.SOUTH);
     1152
     1153            mainPanel.setPreferredSize(mainPanelDimension);
     1154
     1155            this.add(mainPanel);
     1156
     1157            pane = new JOptionPane(this, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION) {
     1158                @Override
     1159                public void setValue(Object newValue) {
     1160                    super.setValue(newValue);
     1161                    if (newValue instanceof Integer && (int) newValue == 0 && useModelCombinationCheckbox.isSelected()) {
     1162                        System.out.println("model settings button value: " + newValue);
     1163                        System.out.println("\nUSE COMBINED MODEL\n");
     1164                        useCombinedModel = true;
     1165                        useCustomSVMModel = false;
     1166
     1167                        addDialog.loadSVMmodel();
     1168                        addDialog.createOSMObject(sel);
     1169                        saveCombinedModel();
     1170                        dlg.setVisible(false);
     1171                    } else if (newValue instanceof Integer && (int) newValue == -1 && useModelCombinationCheckbox.isSelected()) {
     1172                        System.out.println("model settings button value: " + newValue);
     1173                        useCombinedModel = false;
     1174                        useCustomSVMModel = false;
     1175                        System.out.println("Use combined model");
     1176
     1177                        addDialog.loadSVMmodel();
     1178                        addDialog.createOSMObject(sel);
     1179                        dlg.setVisible(false);
     1180                    } else if (newValue instanceof Integer && (int) newValue == 0 && !useModelCombinationCheckbox.isSelected()) {
     1181                        System.out.println("model settings button value: " + newValue);
     1182                        System.out.println("Don t use combined model, use custom model");
     1183                        useCombinedModel = false;
     1184                        useCustomSVMModel = true;
     1185                        addDialog.loadSVMmodel();
     1186                        addDialog.createOSMObject(sel);
     1187                        dlg.setVisible(false);
     1188                    } else if (newValue instanceof Integer && (int) newValue == -1 && !useModelCombinationCheckbox.isSelected()) {
     1189                        System.out.println("model settings button value: " + newValue);
     1190                        System.out.println("Don t use combined model, use custom model");
     1191                        useCombinedModel = false;
     1192                        useCustomSVMModel = false;
     1193                        addDialog.loadSVMmodel();
     1194                        addDialog.createOSMObject(sel);
     1195                        dlg.setVisible(false);
     1196                    } else if (newValue == null || newValue.equals("uninitializedValue")) {
     1197                        System.out.println("uninitializedValue, do nothing");
     1198                    }
     1199                }
     1200            };
     1201
     1202            dlg = pane.createDialog(Main.parent, tr("Model Settings"));
     1203            dlg.setVisible(true);
     1204        }
     1205
     1206        public void makeVisible(boolean visible) {
     1207            dlg.setVisible(true);
     1208        }
     1209
     1210        private void modelChooserButtonActionPerformed(ActionEvent evt) {
     1211
     1212            try {
     1213                final File file = new File(chooseModelTextField.getText());
     1214                final JFileChooser fileChooser = new JFileChooser(file);
     1215
     1216                final int returnVal = fileChooser.showOpenDialog(this);
     1217                if (returnVal == JFileChooser.APPROVE_OPTION) {
     1218                    chooseModelTextField.setText(fileChooser.getSelectedFile().getAbsolutePath());
     1219                    useCustomSVMModel = true;
     1220                    customSVMModelPath = fileChooser.getSelectedFile().getAbsolutePath();
     1221                }
     1222
     1223                if (useModelCombinationCheckbox.isSelected()) {
     1224                    String svmModelPath = fileChooser.getSelectedFile().getAbsolutePath();
     1225                    String svmModelText;
     1226                    if (System.getProperty("os.name").contains("ux")) {
     1227                        if (svmModelPath.contains("/")) {
     1228                            svmModelText = svmModelPath.substring(svmModelPath.lastIndexOf("/"));
     1229                        } else {
     1230                            svmModelText = svmModelPath;
     1231                        }
     1232                    } else {
     1233                        if (svmModelPath.contains("\\")) {
     1234                            svmModelText = svmModelPath.substring(svmModelPath.lastIndexOf("\\"));
     1235                        } else {
     1236                            svmModelText = svmModelPath;
     1237                        }
     1238                    }
     1239                    combinationDefaultListModel.addElement(svmModelText);
     1240                    JTextField weightTextField = new JTextField("0.00");
     1241                    weightFieldsAndPaths.put(weightTextField, svmModelPath);
     1242                    System.out.println("weights size: " + weightFieldsAndPaths.size());
     1243
     1244                    weightTextField.setMaximumSize(new Dimension(80, 20));
     1245                    weightsPanel.add(weightTextField);
     1246                    //add additional textbox
     1247                }
     1248            } catch (RuntimeException ex) {
     1249                Logging.warn(ex);
     1250            }
     1251        }
     1252
     1253        private void userCombinationCheckboxActionPerformed(java.awt.event.ActionEvent evt) {
     1254
     1255            if (useModelCombinationCheckbox.isSelected()) {
     1256                useCombinedModel = true;
     1257                useCustomSVMModel = false; //reseting the selected custom SVM model only here
     1258                removeSelectedModelButton.setEnabled(true);
     1259                acceptWeightsButton.setEnabled(true);
     1260                resetWeightsButton.setEnabled(true);
     1261
     1262                chooseModelTextField.setEnabled(false);
     1263                modelCombinationList.setEnabled(true);
     1264                weightsPanel.setEnabled(true);
     1265                Component[] weightPanelComponents = weightsPanel.getComponents();
     1266                for (Component weightPanelComponent : weightPanelComponents) {
     1267                    weightPanelComponent.setEnabled(true);
     1268                }
     1269            } else {
     1270                useCombinedModel = false;
     1271                useCustomSVMModel = true;
     1272                removeSelectedModelButton.setEnabled(false);
     1273                acceptWeightsButton.setEnabled(false);
     1274                resetWeightsButton.setEnabled(false);
     1275
     1276                chooseModelTextField.setEnabled(true);
     1277                modelCombinationList.setEnabled(false);
     1278                weightsPanel.setEnabled(false);
     1279                Component[] weightPanelComponents = weightsPanel.getComponents();
     1280                for (Component weightPanelComponent : weightPanelComponents) {
     1281                    weightPanelComponent.setEnabled(false);
     1282                }
     1283            }
     1284        }
     1285
     1286        private void acceptWeightsButtonActionPerformed(ActionEvent evt) {
     1287            int weightsCount = 0;
     1288            removeSelectedModelButton.setEnabled(false);
     1289            double weightSum = 0;
     1290            for (JTextField weightField : weightFieldsAndPaths.keySet()) {
     1291                if (weightField.getText().equals("")) {
     1292                    weightField.setText("0.00");
     1293                }
     1294
     1295                try {
     1296                    //TODO replace "," with "." to parse doubles with commas
     1297                    Double weightValue = Double.parseDouble(weightField.getText());
     1298
     1299                    weightValue = Math.abs(weightValue);
     1300                    weightSum += weightValue;
     1301                } catch (NumberFormatException ex) {
     1302                    Logging.warn(ex);
     1303                }
     1304                weightsCount++;
     1305            }
     1306
     1307            if (!filesAndWeights.isEmpty()) {
     1308                filesAndWeights.clear();
     1309            }
     1310
     1311            for (JTextField weightField : weightFieldsAndPaths.keySet()) {
     1312                try {
     1313                    Double weightValue = Double.parseDouble(weightField.getText());
     1314
     1315                    weightValue = Math.abs(weightValue)/weightSum; //normalize
     1316
     1317                    if (weightSum == 0) {
     1318                        weightValue = 1.0/weightsCount;
     1319                    }
     1320
     1321                    weightField.setText(new DecimalFormat("#.##").format(weightValue));
     1322                    normalizedPathsAndWeights.put(weightFieldsAndPaths.get(weightField), weightValue);
     1323                    filesAndWeights.put(new File(weightFieldsAndPaths.get(weightField)), weightValue);
     1324                    System.out.println("normalized: " + weightFieldsAndPaths.get(weightField) + "->" + weightValue);
     1325                    weightField.setEnabled(false);
     1326
     1327                } catch (NumberFormatException ex) {
     1328                    Logging.warn(ex);
     1329                }
     1330            }
     1331
     1332            useCombinedModel = true;
     1333            useCustomSVMModel = false;
     1334        }
     1335
     1336        private void resetWeightsButtonActionPerformed(ActionEvent evt) {
     1337            removeSelectedModelButton.setEnabled(true);
     1338            for (JTextField weightField : weightFieldsAndPaths.keySet()) {
     1339                weightField.setEnabled(true);
     1340            }
     1341        }
     1342
     1343        private void removeSelectedModelButtonActionPerformed(ActionEvent evt) {
     1344            int index = modelCombinationList.getSelectedIndex();
     1345            String modelToBeRemoved = combinationDefaultListModel.get(index);
     1346            combinationDefaultListModel.remove(index);
     1347            System.out.println("model to be removed: " + modelToBeRemoved);
     1348
     1349            Iterator<Entry<JTextField, String>> it = weightFieldsAndPaths.entrySet().iterator();
     1350            while (it.hasNext()) {
     1351                Entry<JTextField, String> en = it.next();
     1352                if (en.getValue().equals(modelToBeRemoved)) {
     1353                    it.remove();
     1354                }
     1355            }
     1356            System.out.println("model to be removed: " + modelToBeRemoved);
     1357
     1358            weightsPanel.remove(index);
     1359            weightsPanel.revalidate();
     1360            weightsPanel.repaint();
     1361        }
     1362
     1363        @SuppressWarnings("unchecked")
     1364        private void loadPreviousCombinedSVMModel() {
     1365            File combinedModelClassesFile = new File(combinedModelClasses);
     1366
     1367            if (combinedModelClassesFile.exists()) {
     1368                FileInputStream fileIn = null;
     1369                ObjectInputStream in = null;
     1370                try {
     1371                    fileIn = new FileInputStream(combinedModelClassesFile);
     1372                    in = new ObjectInputStream(fileIn);
     1373                    weightFieldsAndPaths = (Map<JTextField, String>) in.readObject();
     1374                } catch (FileNotFoundException ex) {
     1375                    Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
     1376                } catch (IOException | ClassNotFoundException ex) {
     1377                    Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
     1378                } finally {
     1379                    try {
     1380                        if (in != null) {
     1381                            in.close();
     1382                        }
     1383                        if (fileIn != null) {
     1384                            fileIn.close();
     1385                        }
     1386
     1387                    } catch (IOException ex) {
     1388                        Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
     1389                    }
     1390                }
     1391            } else {
     1392                try {
     1393                    combinedModelClassesFile.createNewFile();
     1394                } catch (IOException ex) {
     1395                    Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
     1396                }
     1397            }
     1398        }
     1399
     1400        private void saveCombinedModel() {
     1401            try (FileOutputStream fileOut = new FileOutputStream(combinedModelClasses);
     1402                    ObjectOutputStream out = new ObjectOutputStream(fileOut)) {
     1403                out.writeObject(weightFieldsAndPaths);
     1404            } catch (IOException e) {
     1405                System.out.println("serialize error" + e);
     1406            }
     1407        }
     1408    }
     1409
     1410    class AddTagsDialog extends AbstractTagsDialog {
     1411        List<JosmAction> recentTagsActions = new ArrayList<>();
     1412
     1413        // Counter of added commands for possible undo
     1414        private int commandCount;
     1415        private final JLabel recommendedClassesLabel;
     1416        private final JButton modelSettingsButton;
     1417        private final JButton addAndContinueButton;
     1418        private final DefaultListModel<String> model;
     1419        private final JList<String> categoryList;
     1420        private Model modelSVM;
     1421        private int modelSVMLabelSize;
     1422        private int[] modelSVMLabels;
     1423        private Map<String, String> mappings;
     1424        private Map<String, Integer> mapperWithIDs;
     1425        private Map<Integer, String> idsWithMappings;
     1426        private List<String> textualList = new ArrayList<>();
     1427        private final JCheckBox useTagsCheckBox;
     1428        private ModelSettingsDialog modelSettingsDialog;
     1429        private static final int RECOMMENDATIONS_SIZE = 10;
     1430
     1431        AddTagsDialog() {
     1432            super(Main.parent, tr("Add value?"), new String[] {tr("OK"), tr("Cancel")});
     1433            setButtonIcons(new String[] {"ok", "cancel"});
     1434            setCancelButton(2);
     1435            configureContextsensitiveHelp("/Dialog/AddValue", true /* show help button */);
     1436            final AddTagsDialog addTagsDialog = this;
     1437
     1438            loadOntology();
     1439            //if the user did not train a model by running the training process
     1440            //the list does not exist in a file and so we load the default list from the jar.
     1441
     1442            System.out.println("path for textual: " + TEXTUAL_LIST_PATH);
     1443            File textualListFile = new File(TEXTUAL_LIST_PATH);
     1444            if (textualListFile.exists()) {
     1445                loadTextualList(textualListFile);
     1446            } else {
     1447                loadDefaultTextualList();
     1448            }
     1449
     1450            //if training process has not been performed, we use two sample SVM models, extracted from the jar
     1451
     1452            JPanel splitPanel = new JPanel(new BorderLayout(10, 10));
     1453            JPanel mainPanel = new JPanel(new GridBagLayout()); //original panel, will be wrapped by the splitPanel
     1454            JPanel recommendPanel = new JPanel(new BorderLayout(10, 10));   //will contain listPanel, action panel
     1455            JPanel listPanel = new JPanel(new BorderLayout(10, 10)); //class recommend label, recommendation list
     1456            JPanel actionsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); //model selection buttons or configuration
     1457
     1458            addAndContinueButton = new JButton("Add and continue");
     1459            modelSettingsButton = new JButton("Model Settings");
     1460            useTagsCheckBox = new JCheckBox("Predict using tags");
     1461            recommendedClassesLabel = new JLabel("Recommended Classes:");
     1462
     1463            addAndContinueButton.addActionListener(new java.awt.event.ActionListener() {
     1464                @Override
     1465                public void actionPerformed(java.awt.event.ActionEvent evt) {
     1466                    String selectedClass = categoryList.getSelectedValue();
     1467                    addAndContinueButtonActionPerformed(evt, selectedClass);
     1468
     1469                    //reconstruct vector for instance and use the model that was trained with classes here
     1470
     1471                    List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
     1472                    OsmPrimitive s;
     1473
     1474                    //get a simple selection
     1475                    if (!osmPrimitiveSelection.isEmpty()) {
     1476                        s = osmPrimitiveSelection.get(0);
     1477                        if (s.getInterestingTags().isEmpty()) {
     1478                            //load original model
     1479                            modelWithClasses = false;
     1480                            loadSVMmodel();
     1481                            createOSMObject(sel); //create object without class features
     1482                        } else {
     1483                            //recommend using tags: set the checkbox selected to avoid confusing the user
     1484                            useTagsCheckBox.setSelected(true);
     1485
     1486                            if (useTagsCheckBox.isSelected()) {
     1487                                //load model with classes
     1488                                modelWithClasses = true;
     1489                                loadSVMmodel();
     1490                                createOSMObject(sel); //create object including class features
     1491                            } else {
     1492                                modelWithClasses = false;
     1493                                loadSVMmodel();
     1494                                createOSMObject(sel); //create object including class features
     1495                            }
     1496                        }
     1497                    }
     1498                }
     1499            });
     1500
     1501            modelSettingsButton.addActionListener(new java.awt.event.ActionListener() {
     1502                @Override
     1503                public void actionPerformed(java.awt.event.ActionEvent evt) {
     1504                    if (modelSettingsDialog == null) {
     1505                        System.out.println("new modelSettingsDialog");
     1506                        modelSettingsDialog = new ModelSettingsDialog(sel, addTagsDialog);
     1507                    } else {
     1508                        System.out.println("set modelSettingsDialog visible");
     1509                        modelSettingsDialog.makeVisible(true);
     1510                    }
     1511                }
     1512            });
     1513
     1514            useTagsCheckBox.addActionListener(new java.awt.event.ActionListener() {
     1515                @Override
     1516                public void actionPerformed(java.awt.event.ActionEvent evt) {
     1517                    List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
     1518                    OsmPrimitive s;
     1519                    if (!osmPrimitiveSelection.isEmpty()) {
     1520                        s = osmPrimitiveSelection.get(0);
     1521                        if (s.getInterestingTags().isEmpty()) {
     1522                            //load original model
     1523                            modelWithClasses = false;
     1524                            loadSVMmodel();
     1525                            createOSMObject(sel); //create object without class features
     1526                        } else {
     1527                            //useTagsCheckBox
     1528                            if (useTagsCheckBox.isSelected()) {
     1529                                //load model with classes
     1530                                modelWithClasses = true;
     1531                                loadSVMmodel();
     1532                                createOSMObject(sel); //create object including class features
     1533                            } else {
     1534                                modelWithClasses = false;
     1535                                loadSVMmodel();
     1536                                createOSMObject(sel); //create object including class features
     1537                            }
     1538                        }
     1539                    }
     1540                }
     1541            });
     1542
     1543            keys = new AutoCompletingComboBox();
     1544            values = new AutoCompletingComboBox();
     1545
     1546            mainPanel.add(new JLabel("<html>"+trn("This will change up to {0} object.",
     1547                    "This will change up to {0} objects.", sel.size(), sel.size())
     1548            +"<br><br>"+tr("Please select a key")), GBC.eol().fill(GBC.HORIZONTAL));
     1549
     1550            AutoCompletionManager autocomplete = MainApplication.getLayerManager().getEditLayer().data.getAutoCompletionManager();
     1551            List<AutoCompletionListItem> keyList = autocomplete.getKeys();
     1552
     1553            AutoCompletionListItem itemToSelect = null;
     1554            // remove the object's tag keys from the list
     1555            Iterator<AutoCompletionListItem> iter = keyList.iterator();
     1556            while (iter.hasNext()) {
     1557                AutoCompletionListItem item = iter.next();
     1558                if (item.getValue().equals(lastAddKey)) {
     1559                    itemToSelect = item;
     1560                }
     1561                for (int i = 0; i < tagData.getRowCount(); ++i) {
     1562                    if (item.getValue().equals(tagData.getValueAt(i, 0))) {
     1563                        if (itemToSelect == item) {
     1564                            itemToSelect = null;
     1565                        }
     1566                        iter.remove();
     1567                        break;
     1568                    }
     1569                }
     1570            }
     1571
     1572            Collections.sort(keyList, defaultACItemComparator);
     1573            keys.setPossibleACItems(keyList);
     1574            keys.setEditable(true);
     1575
     1576            mainPanel.add(keys, GBC.eop().fill());
     1577            mainPanel.add(new JLabel(tr("Please select a value")), GBC.eol());
     1578
     1579            model = new DefaultListModel<>();
     1580
     1581            parseTagsMappedToClasses();
     1582
     1583            List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
     1584            OsmPrimitive s;
     1585            //get a simple selection
     1586            if (!osmPrimitiveSelection.isEmpty()) {
     1587                s = osmPrimitiveSelection.get(0);
     1588                File modelDirectory = new File(MODEL_PATH);
     1589                String modelWithClassesPath = modelDirectory.getAbsolutePath() + "/model_with_classes";
     1590                File modelWithClassesFile = new File(modelWithClassesPath);
     1591                if (s.getInterestingTags().isEmpty() || !modelWithClassesFile.exists()) {
     1592                    modelWithClasses = false;
     1593                    loadSVMmodel(); //load original model
     1594                    createOSMObject(sel); //create object without class features
     1595                } else {
     1596                    //recommend using tags: set the checkbox selected to avoid confusing the user
     1597                    useTagsCheckBox.setSelected(true);
     1598                    modelWithClasses = true;
     1599                    loadSVMmodel(); //load model with classes
     1600                    createOSMObject(sel); //create object including class features
     1601                }
     1602            }
     1603
     1604            categoryList = new JList<>(model);
     1605
     1606            ListSelectionListener listSelectionListener = new ListSelectionListener() {
     1607                @Override
     1608                public void valueChanged(ListSelectionEvent listSelectionEvent) {
     1609                    if (!listSelectionEvent.getValueIsAdjusting()) { //This prevents double events
     1610
     1611                        String selectedClass = categoryList.getSelectedValue();
     1612
     1613                        if (selectedClass != null) { //null check, because the model is cleared after a new recommendation
     1614                            //tags become unselected
     1615                            if ((selectedClass.indexOf(" ")+1) > 0) {
     1616                                //add both key + value in tags
     1617                                String keyTag = selectedClass.substring(0, selectedClass.indexOf(" "));
     1618                                String valueTag = selectedClass.substring(selectedClass.indexOf(" ")+1, selectedClass.length());
     1619                                keys.setSelectedItem(keyTag); //adding selected tags to textBoxes
     1620                                values.setSelectedItem(valueTag);
     1621                            } else {
     1622                                //value does not have a value, add the key tag only
     1623                                String keyTag = selectedClass; //test it
     1624                                keys.setSelectedItem(keyTag);
     1625                                values.setSelectedItem("");
     1626                            }
     1627                        }
     1628                    }
     1629                }
     1630            };
     1631
     1632            categoryList.addListSelectionListener(listSelectionListener);
     1633            categoryList.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
     1634            categoryList.setModel(model);
     1635
     1636            values.setEditable(true);
     1637            mainPanel.add(values, GBC.eop().fill());
     1638            if (itemToSelect != null) {
     1639                keys.setSelectedItem(itemToSelect);
     1640                if (lastAddValue != null) {
     1641                    values.setSelectedItem(lastAddValue);
     1642                }
     1643            }
     1644
     1645            FocusAdapter focus = addFocusAdapter(autocomplete, defaultACItemComparator);
     1646            // fire focus event in advance or otherwise the popup list will be too small at first
     1647            focus.focusGained(null);
     1648
     1649            int recentTagsToShow = PROPERTY_RECENT_TAGS_NUMBER.get();
     1650            if (recentTagsToShow > MAX_LRU_TAGS_NUMBER) {
     1651                recentTagsToShow = MAX_LRU_TAGS_NUMBER;
     1652            }
     1653
     1654            suggestRecentlyAddedTags(mainPanel, recentTagsToShow, focus);
     1655
     1656            mainPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
     1657            listPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
     1658            splitPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.GRAY, Color.WHITE));
     1659
     1660            listPanel.add(recommendedClassesLabel, BorderLayout.NORTH);
     1661            listPanel.add(categoryList, BorderLayout.SOUTH);
     1662            actionsPanel.add(addAndContinueButton);
     1663            actionsPanel.add(modelSettingsButton);
     1664            actionsPanel.add(useTagsCheckBox);
     1665
     1666            recommendPanel.add(actionsPanel, BorderLayout.WEST);
     1667            recommendPanel.add(listPanel, BorderLayout.NORTH);
     1668
     1669            splitPanel.add(mainPanel, BorderLayout.WEST);
     1670            splitPanel.add(recommendPanel, BorderLayout.EAST);
     1671
     1672            setContent(splitPanel, false);
     1673
     1674            popupMenu.add(new AbstractAction(tr("Set number of recently added tags")) {
     1675                @Override
     1676                public void actionPerformed(ActionEvent e) {
     1677                    selectNumberOfTags();
     1678                }
     1679            });
     1680            JCheckBoxMenuItem rememberLastTags = new JCheckBoxMenuItem(
     1681                    new AbstractAction(tr("Remember last used tags after a restart")) {
     1682                        @Override
     1683                        public void actionPerformed(ActionEvent e) {
     1684                            boolean sel = ((JCheckBoxMenuItem) e.getSource()).getState();
     1685                            PROPERTY_REMEMBER_TAGS.put(sel);
     1686                            if (sel) saveTagsIfNeeded();
     1687                        }
     1688                    });
     1689            rememberLastTags.setState(PROPERTY_REMEMBER_TAGS.get());
     1690            popupMenu.add(rememberLastTags);
     1691        }
     1692
     1693        private void addAndContinueButtonActionPerformed(ActionEvent evt, String selectedClass) {
     1694            performTagAdding();
     1695        }
     1696
     1697        private void selectNumberOfTags() {
     1698            String s = JOptionPane.showInputDialog(this, tr("Please enter the number of recently added tags to display"));
     1699            if (s != null) try {
     1700                int v = Integer.parseInt(s);
     1701                if (v >= 0 && v <= MAX_LRU_TAGS_NUMBER) {
     1702                    PROPERTY_RECENT_TAGS_NUMBER.put(v);
     1703                    return;
     1704                }
     1705            } catch (NumberFormatException ex) {
     1706                Logging.warn(ex);
     1707            }
     1708            JOptionPane.showMessageDialog(this, tr("Please enter integer number between 0 and {0}", MAX_LRU_TAGS_NUMBER));
     1709        }
     1710
     1711        private void suggestRecentlyAddedTags(JPanel mainPanel, int tagsToShow, final FocusAdapter focus) {
     1712            if (!(tagsToShow > 0 && !recentTags.isEmpty()))
     1713                return;
     1714
     1715            mainPanel.add(new JLabel(tr("Recently added tags")), GBC.eol());
     1716
     1717            int count = 1;
     1718            // We store the maximum number (9) of recent tags to allow dynamic change of number of tags shown in the preferences.
     1719            // This implies to iterate in descending order,
     1720            // as the oldest elements will only be removed after we reach the maximum numbern and not the number of tags to show.
     1721            // However, as Set does not allow to iterate in descending order,
     1722            // we need to copy its elements into a List we can access in reverse order.
     1723            List<Tag> tags = new LinkedList<>(recentTags.keySet());
     1724            for (int i = tags.size()-1; i >= 0 && count <= tagsToShow; i--, count++) {
     1725                final Tag t = tags.get(i);
     1726                // Create action for reusing the tag, with keyboard shortcut Ctrl+(1-5)
     1727                String scKey = "properties:recent:"+count;
     1728                String scsKey = "properties:recent:shift:"+count;
     1729                Shortcut sc = Shortcut.registerShortcut(scKey, tr("Choose recent tag {0}", count), KeyEvent.VK_0+count, Shortcut.CTRL);
     1730                final JosmAction action = new JosmAction(scKey, null, tr("Use this tag again"), sc, false) {
     1731                    @Override
     1732                    public void actionPerformed(ActionEvent e) {
     1733                        keys.setSelectedItem(t.getKey());
     1734                        // fix #7951, #8298 - update list of values before setting value (?)
     1735                        focus.focusGained(null);
     1736                        values.setSelectedItem(t.getValue());
     1737                    }
     1738                };
     1739                Shortcut scs = Shortcut.registerShortcut(scsKey, tr("Apply recent tag {0}", count), KeyEvent.VK_0+count, Shortcut.CTRL_SHIFT);
     1740                final JosmAction actionShift = new JosmAction(scsKey, null, tr("Use this tag again"), scs, false) {
     1741                    @Override
     1742                    public void actionPerformed(ActionEvent e) {
     1743                        action.actionPerformed(null);
     1744                        performTagAdding();
     1745                    }
     1746                };
     1747                recentTagsActions.add(action);
     1748                recentTagsActions.add(actionShift);
     1749                disableTagIfNeeded(t, action);
     1750                // Find and display icon
     1751                ImageIcon icon = MapPaintStyles.getNodeIcon(t, false); // Filters deprecated icon
     1752                if (icon == null) {
     1753                    // If no icon found in map style look at presets
     1754                    Map<String, String> map = new HashMap<>();
     1755                    map.put(t.getKey(), t.getValue());
     1756                    // If still nothing display an empty icon
     1757                    if (icon == null) {
     1758                        icon = new ImageIcon(new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB));
     1759                    }
     1760                }
     1761                GridBagConstraints gbc = new GridBagConstraints();
     1762                gbc.ipadx = 5;
     1763                mainPanel.add(new JLabel(action.isEnabled() ? icon : GuiHelper.getDisabledIcon(icon)), gbc);
     1764                // Create tag label
     1765                final String color = action.isEnabled() ? "" : "; color:gray";
     1766                final JLabel tagLabel = new JLabel("<html>"
     1767                        + "<style>td{border:1px solid gray; font-weight:normal"+color+"}</style>"
     1768                        + "<table><tr><td>" + XmlWriter.encode(t.toString(), true) + "</td></tr></table></html>");
     1769                if (action.isEnabled()) {
     1770                    // Register action
     1771                    mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sc.getKeyStroke(), scKey);
     1772                    mainPanel.getActionMap().put(scKey, action);
     1773                    mainPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(scs.getKeyStroke(), scsKey);
     1774                    mainPanel.getActionMap().put(scsKey, actionShift);
     1775                    // Make the tag label clickable and set tooltip to the action description (this displays also the keyboard shortcut)
     1776                    tagLabel.setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION));
     1777                    tagLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
     1778                    tagLabel.addMouseListener(new MouseAdapter() {
     1779                        @Override
     1780                        public void mouseClicked(MouseEvent e) {
     1781                            action.actionPerformed(null);
     1782                            // add tags and close window on double-click
     1783
     1784                            if (e.getClickCount() > 1) {
     1785                                buttonAction(0, null); // emulate OK click and close the dialog
     1786                            }
     1787                            // add tags on Shift-Click
     1788                            if (e.isShiftDown()) {
     1789                                performTagAdding();
     1790                            }
     1791                        }
     1792                    });
     1793                } else {
     1794                    // Disable tag label
     1795                    tagLabel.setEnabled(false);
     1796                    // Explain in the tooltip why
     1797                    tagLabel.setToolTipText(tr("The key ''{0}'' is already used", t.getKey()));
     1798                }
     1799                // Finally add label to the resulting panel
     1800                JPanel tagPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0));
     1801                tagPanel.add(tagLabel);
     1802                mainPanel.add(tagPanel, GBC.eol().fill(GBC.HORIZONTAL));
     1803            }
     1804        }
     1805
     1806        public void destroyActions() {
     1807            for (JosmAction action : recentTagsActions) {
     1808                action.destroy();
     1809            }
     1810        }
     1811
     1812        /**
     1813        * Read tags from comboboxes and add it to all selected objects
     1814        */
     1815        public final void performTagAdding() {
     1816            String key = Tag.removeWhiteSpaces(keys.getEditor().getItem().toString());
     1817            String value = Tag.removeWhiteSpaces(values.getEditor().getItem().toString());
     1818            if (key.isEmpty() || value.isEmpty()) return;
     1819            for (OsmPrimitive osm: sel) {
     1820                String val = osm.get(key);
     1821                if (val != null && !val.equals(value)) {
     1822                    if (!warnOverwriteKey(tr("You changed the value of ''{0}'' from ''{1}'' to ''{2}''.", key, val, value),
     1823                            "overwriteAddKey"))
     1824                        return;
     1825                    break;
     1826                }
     1827            }
     1828            lastAddKey = key;
     1829            lastAddValue = value;
     1830            recentTags.put(new Tag(key, value), null);
     1831            AutoCompletionManager.rememberUserInput(key, value, false);
     1832            commandCount++;
     1833            MainApplication.undoRedo.add(new ChangePropertyCommand(sel, key, value));
     1834            changedKey = key;
     1835        }
     1836
     1837        public void undoAllTagsAdding() {
     1838            MainApplication.undoRedo.undo(commandCount);
     1839        }
     1840
     1841        private void disableTagIfNeeded(final Tag t, final JosmAction action) {
     1842            // Disable action if its key is already set on the object (the key being absent from the keys list for this reason
     1843            // performing this action leads to autocomplete to the next key (see #7671 comments)
     1844            for (int j = 0; j < tagData.getRowCount(); ++j) {
     1845                if (t.getKey().equals(tagData.getValueAt(j, 0))) {
     1846                    action.setEnabled(false);
     1847                    break;
     1848                }
     1849            }
     1850        }
     1851
     1852        private void loadSVMmodel() {
     1853            File modelDirectory = new File(MODEL_PATH);
     1854            File modelFile;
     1855            if (useCombinedModel) {
     1856                if (filesAndWeights.isEmpty()) {
     1857                    System.out.println("No models selected! Loading defaults..");
     1858                    if (modelWithClasses) {
     1859                        System.out.println("Using default/last model with classes: " + modelDirectory.getAbsolutePath() + "/model_with_classes");
     1860                        modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
     1861                        try {
     1862                            System.out.println("try to load model: " + modelFile.getAbsolutePath());
     1863                            modelSVM = Model.load(modelFile);
     1864                            System.out.println("model loaded!");
     1865
     1866                        } catch (IOException ex) {
     1867                            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
     1868                        }
     1869                        modelSVMLabelSize = modelSVM.getLabels().length;
     1870                        modelSVMLabels = modelSVM.getLabels();
     1871                    } else {
     1872                        System.out.println("Using default/last model without classes: " + modelDirectory.getAbsolutePath() + "/best_model");
     1873                        modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
     1874                        try {
     1875                            System.out.println("try to load model: " + modelFile.getAbsolutePath());
     1876                            modelSVM = Model.load(modelFile);
     1877                            System.out.println("model loaded!");
     1878
     1879                        } catch (IOException ex) {
     1880                            Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
     1881                        }
     1882                        modelSVMLabelSize = modelSVM.getLabels().length;
     1883                        modelSVMLabels = modelSVM.getLabels();
     1884                    }
     1885                }
     1886                if (modelWithClasses) { //check filenames to define if model with classes is selected
     1887                    System.out.println("Using combined model with classes");
     1888                    useCombinedSVMmodels(sel, true);
     1889                } else {
     1890                    System.out.println("Using combined model without classes");
     1891                    useCombinedSVMmodels(sel, false);
     1892                }
     1893            } else if (useCustomSVMModel) {
     1894                System.out.println("custom path: " + customSVMModelPath);
     1895                File checkExistance = new File(customSVMModelPath);
     1896                if (checkExistance.exists() && checkExistance.isFile()) {
     1897                    if (modelWithClasses) {
     1898                        System.out.println("Using custom model with classes: ");
     1899                        if (customSVMModelPath.endsWith(".0")) {
     1900                            String customSVMModelPathWithClasses = customSVMModelPath.substring(0, customSVMModelPath.length() - 2) + ".1";
     1901
     1902                            modelFile = new File(customSVMModelPathWithClasses);
     1903                            System.out.println(customSVMModelPathWithClasses);
     1904                        } else {
     1905                            modelFile = new File(customSVMModelPath);
     1906                        }
     1907                    } else {
     1908                        System.out.println("Using custom model without classes");
     1909                        if (customSVMModelPath.endsWith(".1")) {
     1910                            String customSVMModelPathWithoutClasses = customSVMModelPath.substring(0, customSVMModelPath.length() - 2) + ".0";
     1911                            modelFile = new File(customSVMModelPathWithoutClasses);
     1912                            System.out.println(customSVMModelPathWithoutClasses);
     1913                        } else {
     1914                            modelFile = new File(customSVMModelPath);
     1915                        }
     1916                    }
     1917                    try {
     1918                        System.out.println("try to load model: " + modelFile.getAbsolutePath());
     1919                        modelSVM = Model.load(modelFile);
     1920                        System.out.println("model loaded!");
     1921
     1922                    } catch (IOException ex) {
     1923                        Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
     1924                    }
     1925                    modelSVMLabelSize = modelSVM.getLabels().length;
     1926                    modelSVMLabels = modelSVM.getLabels();
     1927
     1928                } else {
     1929                    //user chose to use a custom model, but did not provide a path to a model:
     1930                    if (modelWithClasses) {
     1931                        System.out.println("Using default/last model with classes");
     1932                        modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
     1933                    } else {
     1934                        System.out.println("Using default/last model without classes");
     1935                        modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
     1936                    }
     1937
     1938                    try {
     1939                        System.out.println("try to load model: " + modelFile.getAbsolutePath());
     1940                        modelSVM = Model.load(modelFile);
     1941                        System.out.println("model loaded!");
     1942
     1943                    } catch (IOException ex) {
     1944                        Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
     1945                    }
     1946                    modelSVMLabelSize = modelSVM.getLabels().length;
     1947                    modelSVMLabels = modelSVM.getLabels();
     1948
     1949                }
     1950            } else {
     1951                if (modelWithClasses) {
     1952                    System.out.println("Using default/last model with classes");
     1953                    modelFile = new File(modelDirectory.getAbsolutePath() + "/model_with_classes");
     1954                } else {
     1955                    System.out.println("Using default/last model without classes");
     1956                    modelFile = new File(modelDirectory.getAbsolutePath() + "/best_model");
     1957                }
     1958
     1959                try {
     1960                    System.out.println("try to load model: " + modelFile.getAbsolutePath());
     1961                    modelSVM = Model.load(modelFile);
     1962                    System.out.println("model loaded!");
     1963
     1964                } catch (IOException ex) {
     1965                    Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
     1966                }
     1967                modelSVMLabelSize = modelSVM.getLabels().length;
     1968                modelSVMLabels = modelSVM.getLabels();
     1969            }
     1970        }
     1971
     1972        private void useCombinedSVMmodels(Collection<OsmPrimitive> sel, boolean useClassFeatures) {
     1973            System.out.println("The system will combine " + filesAndWeights.size() + " SVM models.");
     1974
     1975            MathTransform transform = null;
     1976            GeometryFactory geometryFactory = new GeometryFactory();
     1977            CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
     1978            CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
     1979            try {
     1980                transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
     1981
     1982            } catch (FactoryException ex) {
     1983                Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
     1984            }
     1985
     1986            OSMWay selectedInstance;
     1987            List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
     1988            OsmPrimitive s;
     1989
     1990            //get a simple selection
     1991            if (!osmPrimitiveSelection.isEmpty()) {
     1992                s = osmPrimitiveSelection.get(0);
     1993            } else {
     1994                return;
     1995            }
     1996
     1997            selectedInstance = new OSMWay();
     1998            for (Way selectedWay : s.getDataSet().getSelectedWays()) {
     1999                List<Node> selectedWayNodes = selectedWay.getNodes();
     2000                for (Node node : selectedWayNodes) {
     2001                    node.getCoor();
     2002                    if (node.isLatLonKnown()) {
     2003                        double lat = node.getCoor().lat();
     2004                        double lon = node.getCoor().lon();
     2005
     2006                        Coordinate sourceCoordinate = new Coordinate(lon, lat);
     2007                        Coordinate targetGeometry = null;
     2008                        try {
     2009                            targetGeometry = JTS.transform(sourceCoordinate, null, transform);
     2010                        } catch (MismatchedDimensionException | TransformException ex) {
     2011                            Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
     2012                        }
     2013
     2014                        Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
     2015                        selectedInstance.addNodeGeometry(geom);
     2016                    }
     2017                }
     2018            }
     2019            Geometry fullGeom = geometryFactory.buildGeometry(selectedInstance.getNodeGeometries());
     2020            if ((selectedInstance.getNodeGeometries().size() > 3) &&
     2021                    selectedInstance.getNodeGeometries().get(0).equals(selectedInstance.getNodeGeometries()
     2022                            .get(selectedInstance.getNodeGeometries().size()-1))) {
     2023                //checks if the beginning and ending node are the same and the number of nodes are more than 3.
     2024                //the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
     2025                LinearRing linear = geometryFactory.createLinearRing(fullGeom.getCoordinates());
     2026                Polygon poly = new Polygon(linear, null, geometryFactory);
     2027                selectedInstance.setGeometry(poly);
     2028
     2029                System.out.println("\n\npolygon");
     2030            } else if (selectedInstance.getNodeGeometries().size() > 1) {
     2031                //it is an open geometry with more than one nodes, make it linestring
     2032                System.out.println("\n\nlinestring");
     2033                LineString lineString = geometryFactory.createLineString(fullGeom.getCoordinates());
     2034                selectedInstance.setGeometry(lineString);
     2035            } else { //we assume all the rest geometries are points
     2036                System.out.println("\n\npoint");
     2037                Point point = geometryFactory.createPoint(fullGeom.getCoordinate());
     2038                selectedInstance.setGeometry(point);
     2039            }
     2040
     2041            Map<String, String> selectedTags = s.getInterestingTags();
     2042            selectedInstance.setAllTags(selectedTags);
     2043
     2044            //construct vector
     2045            if (selectedInstance != null) {
     2046                int id;
     2047
     2048                OSMClassification classifier = new OSMClassification();
     2049                classifier.calculateClasses(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
     2050
     2051                if (useClassFeatures) {
     2052                    ClassFeatures classFeatures = new ClassFeatures();
     2053                    classFeatures.createClassFeatures(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
     2054                    id = 1422;
     2055                } else {
     2056                    id = 1;
     2057                }
     2058
     2059                GeometryFeatures geometryFeatures = new GeometryFeatures(id);
     2060                geometryFeatures.createGeometryFeatures(selectedInstance);
     2061                id = geometryFeatures.getLastID();
     2062                TextualFeatures textualFeatures = new TextualFeatures(id, textualList, languageDetector);
     2063                textualFeatures.createTextualFeatures(selectedInstance);
     2064
     2065                List<FeatureNode> featureNodeList = selectedInstance.getFeatureNodeList();
     2066
     2067                FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
     2068
     2069                int i = 0;
     2070                for (FeatureNode featureNode : featureNodeList) {
     2071                    featureNodeArray[i] = featureNode;
     2072                    i++;
     2073                }
     2074                FeatureNode[] testInstance2 = featureNodeArray;
     2075
     2076                //compute prediction list for every model
     2077                int[] ranks = new int[10];
     2078
     2079                for (int l = 0; l < 10; l++) {
     2080                    ranks[l] = 10-l; //init from 10 to 1
     2081                }
     2082
     2083                Map<String, Double> scoreMap = new HashMap<>();
     2084
     2085                Map<File, Double> alignedFilesAndWeights = getAlignedModels(filesAndWeights);
     2086
     2087                for (File modelFile : alignedFilesAndWeights.keySet()) {
     2088
     2089                    try {
     2090                        modelSVM = Model.load(modelFile);
     2091                    } catch (IOException ex) {
     2092                        Logger.getLogger(TrainWorker.class.getName()).log(Level.SEVERE, null, ex);
     2093                    }
     2094                    modelSVMLabelSize = modelSVM.getLabels().length;
     2095                    modelSVMLabels = modelSVM.getLabels();
     2096
     2097                    Map<Integer, Integer> mapLabelsToIDs = new HashMap<>();
     2098                    for (int h = 0; h < modelSVMLabelSize; h++) {
     2099                        mapLabelsToIDs.put(modelSVMLabels[h], h);
     2100                    }
     2101                    double[] scores = new double[modelSVMLabelSize];
     2102                    Linear.predictValues(modelSVM, testInstance2, scores);
     2103
     2104                    Map<Double, Integer> scoresValues = new HashMap<>();
     2105                    for (int h = 0; h < scores.length; h++) {
     2106                        scoresValues.put(scores[h], h);
     2107                    }
     2108
     2109                    Arrays.sort(scores);
     2110                    int predicted1 = modelSVMLabels[scoresValues.get(scores[scores.length-1])];
     2111                    int predicted2 = modelSVMLabels[scoresValues.get(scores[scores.length-2])];
     2112                    int predicted3 = modelSVMLabels[scoresValues.get(scores[scores.length-3])];
     2113                    int predicted4 = modelSVMLabels[scoresValues.get(scores[scores.length-4])];
     2114                    int predicted5 = modelSVMLabels[scoresValues.get(scores[scores.length-5])];
     2115                    int predicted6 = modelSVMLabels[scoresValues.get(scores[scores.length-6])];
     2116                    int predicted7 = modelSVMLabels[scoresValues.get(scores[scores.length-7])];
     2117                    int predicted8 = modelSVMLabels[scoresValues.get(scores[scores.length-8])];
     2118                    int predicted9 = modelSVMLabels[scoresValues.get(scores[scores.length-9])];
     2119                    int predicted10 = modelSVMLabels[scoresValues.get(scores[scores.length-10])];
     2120
     2121                    String[] predictedTags = new String[10];
     2122                    for (Map.Entry<String, Integer> entry : mapperWithIDs.entrySet()) {
     2123
     2124                        if (entry.getValue().equals(predicted1)) {
     2125                            predictedTags[0] = entry.getKey();
     2126                        } else if (entry.getValue().equals(predicted2)) {
     2127                            predictedTags[1] = entry.getKey();
     2128                        } else if (entry.getValue().equals(predicted3)) {
     2129                            predictedTags[2] = entry.getKey();
     2130                        } else if (entry.getValue().equals(predicted4)) {
     2131                            predictedTags[3] = entry.getKey();
     2132                        } else if (entry.getValue().equals(predicted5)) {
     2133                            predictedTags[4] = entry.getKey();
     2134                        } else if (entry.getValue().equals(predicted6)) {
     2135                            predictedTags[5] = entry.getKey();
     2136                        } else if (entry.getValue().equals(predicted7)) {
     2137                            predictedTags[6] = entry.getKey();
     2138                        } else if (entry.getValue().equals(predicted8)) {
     2139                            predictedTags[7] = entry.getKey();
     2140                        } else if (entry.getValue().equals(predicted9)) {
     2141                            predictedTags[8] = entry.getKey();
     2142                        } else if (entry.getValue().equals(predicted10)) {
     2143                            predictedTags[9] = entry.getKey();
     2144                        }
     2145                    }
     2146                    //clearing model, to add the new computed classes in jlist
     2147                    model.clear();
     2148                    for (Map.Entry<String, String> tag : mappings.entrySet()) {
     2149
     2150                        for (int k = 0; k < 10; k++) {
     2151                            if (tag.getValue().equals(predictedTags[k])) {
     2152                                predictedTags[k] = tag.getKey();
     2153                                model.addElement(tag.getKey());
     2154                            }
     2155                        }
     2156                    }
     2157                    System.out.println("combined, predicted classes: " + Arrays.toString(predictedTags));
     2158
     2159                    for (int r = 0; r < ranks.length; r++) {
     2160                        String predictedTag = predictedTags[r];
     2161                        Double currentWeight = alignedFilesAndWeights.get(modelFile);
     2162                        double finalRank = ranks[r]*currentWeight;
     2163
     2164                        if (scoreMap.containsKey(predictedTag)) {
     2165                            Double scoreToAdd = scoreMap.get(predictedTag);
     2166                            scoreMap.put(predictedTag, finalRank+scoreToAdd);
     2167                        } else {
     2168                            scoreMap.put(predictedTag, finalRank);
     2169                        }
     2170                        //add final weight - predicted tag
     2171                    }
     2172                } //files iter
     2173                model.clear();
     2174                List<Double> scoresList = new ArrayList<>(scoreMap.values());
     2175                Collections.sort(scoresList, Collections.reverseOrder());
     2176
     2177                for (Double sco : scoresList) {
     2178                    if (model.size() > 9) {
     2179                        break;
     2180                    }
     2181                    for (Map.Entry<String, Double> scoreEntry : scoreMap.entrySet()) {
     2182                        if (scoreEntry.getValue().equals(sco)) {
     2183                            model.addElement(scoreEntry.getKey());
     2184                        }
     2185                    }
     2186                }
     2187            }
     2188        }
     2189
     2190        private void createOSMObject(Collection<OsmPrimitive> sel) {
     2191
     2192            MathTransform transform = null;
     2193            GeometryFactory geometryFactory = new GeometryFactory();
     2194            CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
     2195            CoordinateReferenceSystem targetCRS = DefaultGeocentricCRS.CARTESIAN;
     2196            try {
     2197                transform = CRS.findMathTransform(sourceCRS, targetCRS, true);
     2198
     2199            } catch (FactoryException ex) {
     2200                Logger.getLogger(OSMRecPluginHelper.class.getName()).log(Level.SEVERE, null, ex);
     2201            }
     2202
     2203            //fire an error to the user if he has multiple selection from map
     2204
     2205            //we consider simple (one instance) selection, so we get the first of the sel list
     2206
     2207            OSMWay selectedInstance;
     2208            List<OsmPrimitive> osmPrimitiveSelection = new ArrayList<>(sel);
     2209            OsmPrimitive s;
     2210
     2211            //get a simple selection
     2212            if (!osmPrimitiveSelection.isEmpty()) {
     2213                s = osmPrimitiveSelection.get(0);
     2214            } else {
     2215                return;
     2216            }
     2217
     2218            selectedInstance = new OSMWay();
     2219            for (Way selectedWay : s.getDataSet().getSelectedWays()) {
     2220                List<Node> selectedWayNodes = selectedWay.getNodes();
     2221                for (Node node : selectedWayNodes) {
     2222                    node.getCoor();
     2223                    if (node.isLatLonKnown()) {
     2224                        double lat = node.getCoor().lat();
     2225                        double lon = node.getCoor().lon();
     2226
     2227                        Coordinate sourceCoordinate = new Coordinate(lon, lat);
     2228                        Coordinate targetGeometry = null;
     2229                        try {
     2230                            targetGeometry = JTS.transform(sourceCoordinate, null, transform);
     2231                        } catch (MismatchedDimensionException | TransformException ex) {
     2232                            Logger.getLogger(OSMParser.class.getName()).log(Level.SEVERE, null, ex);
     2233                        }
     2234
     2235                        Geometry geom = geometryFactory.createPoint(new Coordinate(targetGeometry));
     2236                        selectedInstance.addNodeGeometry(geom);
     2237                    }
     2238                }
     2239            }
     2240            Geometry fullGeom = geometryFactory.buildGeometry(selectedInstance.getNodeGeometries());
     2241
     2242            System.out.println("number of nodes: " + selectedInstance.getNodeGeometries().size());
     2243
     2244            if ((selectedInstance.getNodeGeometries().size() > 3) &&
     2245                    selectedInstance.getNodeGeometries().get(0).equals(selectedInstance.getNodeGeometries()
     2246                            .get(selectedInstance.getNodeGeometries().size()-1))) {
     2247                //checks if the beginning and ending node are the same and the number of nodes are more than 3.
     2248                //the nodes must be more than 3, because jts does not allow a construction of a linear ring with less points.
     2249                LinearRing linear = geometryFactory.createLinearRing(fullGeom.getCoordinates());
     2250                Polygon poly = new Polygon(linear, null, geometryFactory);
     2251                selectedInstance.setGeometry(poly);
     2252
     2253                System.out.println("\n\npolygon");
     2254            } else if (selectedInstance.getNodeGeometries().size() > 1) {
     2255                //it is an open geometry with more than one nodes, make it linestring
     2256                System.out.println("\n\nlinestring");
     2257                LineString lineString = geometryFactory.createLineString(fullGeom.getCoordinates());
     2258                selectedInstance.setGeometry(lineString);
     2259            } else { //we assume all the rest geometries are points
     2260                System.out.println("\n\npoint");
     2261                Point point = geometryFactory.createPoint(fullGeom.getCoordinate());
     2262                selectedInstance.setGeometry(point);
     2263            }
     2264
     2265            Map<String, String> selectedTags = s.getInterestingTags();
     2266            selectedInstance.setAllTags(selectedTags);
     2267
     2268            //construct vector here
     2269            if (selectedInstance != null) {
     2270                int id;
     2271                if (mappings == null) {
     2272                    System.out.println("null mappings ERROR");
     2273                }
     2274
     2275                OSMClassification classifier = new OSMClassification();
     2276                classifier.calculateClasses(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
     2277
     2278                if (modelWithClasses) {
     2279                    ClassFeatures classFeatures = new ClassFeatures();
     2280                    classFeatures.createClassFeatures(selectedInstance, mappings, mapperWithIDs, indirectClasses, indirectClassesWithIDs);
     2281                    id = 1422;
     2282                } else {
     2283                    id = 1;
     2284                }
     2285
     2286                GeometryFeatures geometryFeatures = new GeometryFeatures(id);
     2287                geometryFeatures.createGeometryFeatures(selectedInstance);
     2288                id = geometryFeatures.getLastID();
     2289                TextualFeatures textualFeatures = new TextualFeatures(id, textualList, languageDetector);
     2290                textualFeatures.createTextualFeatures(selectedInstance);
     2291
     2292                List<FeatureNode> featureNodeList = selectedInstance.getFeatureNodeList();
     2293                System.out.println(featureNodeList);
     2294
     2295                FeatureNode[] featureNodeArray = new FeatureNode[featureNodeList.size()];
     2296
     2297                int i = 0;
     2298                for (FeatureNode featureNode : featureNodeList) {
     2299                    featureNodeArray[i] = featureNode;
     2300                    i++;
     2301                }
     2302                FeatureNode[] testInstance2 = featureNodeArray;
     2303
     2304                Map<Integer, Integer> mapLabelsToIDs = new HashMap<>();
     2305                for (int h = 0; h < modelSVMLabelSize; h++) {
     2306                    mapLabelsToIDs.put(modelSVMLabels[h], h);
     2307                }
     2308
     2309                double[] scores = new double[modelSVMLabelSize];
     2310                Linear.predictValues(modelSVM, testInstance2, scores);
     2311
     2312                Map<Double, Integer> scoresValues = new HashMap<>();
     2313                for (int h = 0; h < scores.length; h++) {
     2314                    scoresValues.put(scores[h], h);
     2315                }
     2316
     2317                Arrays.sort(scores);
     2318
     2319                int[] preds = new int[RECOMMENDATIONS_SIZE];
     2320                for (int p = 0; p < RECOMMENDATIONS_SIZE; p++) {
     2321                    preds[p] = modelSVMLabels[scoresValues.get(scores[scores.length-(p+1)])];
     2322                }
     2323                String[] predictedTags2 = new String[RECOMMENDATIONS_SIZE];
     2324
     2325                for (int p = 0; p < RECOMMENDATIONS_SIZE; p++) {
     2326                    if (idsWithMappings.containsKey(preds[p])) {
     2327                        predictedTags2[p] = idsWithMappings.get(preds[p]);
     2328                    }
     2329                }
     2330
     2331                //clearing model, to add the new computed classes in jlist
     2332                model.clear();
     2333                for (Map.Entry<String, String> tag : mappings.entrySet()) {
     2334                    for (int k = 0; k < 10; k++) {
     2335                        if (tag.getValue().equals(predictedTags2[k])) {
     2336                            predictedTags2[k] = tag.getKey();
     2337                            model.addElement(tag.getKey());
     2338                        }
     2339                    }
     2340                }
     2341                System.out.println("Optimized - create OSMObject, predicted classes: " + Arrays.toString(predictedTags2));
     2342            }
     2343        }
     2344
     2345        private void parseTagsMappedToClasses() {
     2346
     2347            InputStream tagsToClassesMapping = TrainWorker.class.getResourceAsStream("/resources/files/Map");
     2348            Mapper mapper = new Mapper();
     2349            try {
     2350                mapper.parseFile(tagsToClassesMapping);
     2351
     2352            } catch (FileNotFoundException ex) {
     2353                Logger.getLogger(Mapper.class.getName()).log(Level.SEVERE, null, ex);
     2354            }
     2355            mappings = mapper.getMappings();
     2356            mapperWithIDs = mapper.getMappingsWithIDs();
     2357            idsWithMappings = mapper.getIDsWithMappings();
     2358        }
     2359
     2360        private void loadTextualList(File textualListFile) {
     2361
     2362            Scanner input = null;
     2363
     2364            try {
     2365                input = new Scanner(textualListFile);
     2366            } catch (FileNotFoundException ex) {
     2367                Logging.warn(ex);
     2368            }
     2369            while (input.hasNext()) {
     2370                String nextLine = input.nextLine();
     2371                textualList.add(nextLine);
     2372            }
     2373            System.out.println("Textual List parsed from file successfully." + textualList);
     2374        }
     2375
     2376        private void loadDefaultTextualList() {
     2377
     2378            InputStream textualListStream = TrainWorker.class.getResourceAsStream("/resources/files/textualList.txt");
     2379            TextualStatistics textualStatistics = new TextualStatistics();
     2380            textualStatistics.parseTextualList(textualListStream);
     2381            textualList = textualStatistics.getTextualList();
     2382            System.out.println("Default Textual List parsed from file successfully." + textualList);
     2383        }
     2384
     2385        private void loadOntology() {
     2386            InputStream ontologyStream = TrainWorker.class.getResourceAsStream("/resources/files/owl.xml");
     2387            Ontology ontology = new Ontology(ontologyStream);
     2388            indirectClasses = ontology.getIndirectClasses();
     2389            indirectClassesWithIDs = ontology.getIndirectClassesIDs();
     2390        }
     2391
     2392        private Map<File, Double> getAlignedModels(Map<File, Double> filesAndWeights) {
     2393            Map<File, Double> alignedFilesAndWeights = new HashMap<>();
     2394            if (modelWithClasses) {
     2395                for (Entry<File, Double> entry : filesAndWeights.entrySet()) {
     2396                    String absolutePath = entry.getKey().getAbsolutePath();
     2397                    if (absolutePath.endsWith(".0")) {
     2398                        String newPath = absolutePath.substring(0, absolutePath.length()-2) + ".1";
     2399                        File alignedFile = new File(newPath);
     2400                        if (alignedFile.exists()) {
     2401                            alignedFilesAndWeights.put(alignedFile, entry.getValue());
     2402                        }
     2403                    } else {
     2404                        alignedFilesAndWeights.put(entry.getKey(), entry.getValue());
     2405                    }
     2406                }
     2407            } else {
     2408                for (Entry<File, Double> entry : filesAndWeights.entrySet()) {
     2409                    String absolutePath = entry.getKey().getAbsolutePath();
     2410                    if (absolutePath.endsWith(".1")) {
     2411                        String newPath = absolutePath.substring(0, absolutePath.length()-2) + ".0";
     2412                        File alignedFile = new File(newPath);
     2413                        if (alignedFile.exists()) {
     2414                            alignedFilesAndWeights.put(alignedFile, entry.getValue());
     2415                        }
     2416                    } else {
     2417                        alignedFilesAndWeights.put(entry.getKey(), entry.getValue());
     2418                    }
     2419                }
     2420            }
     2421            return alignedFilesAndWeights;
     2422        }
     2423    }
    24242424}
  • applications/editors/josm/plugins/native-password-manager/.settings/org.eclipse.jdt.core.prefs

    r32699 r33579  
    33org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
    44org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
     5org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
    56org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
     7org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
    68org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
     9org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
    710org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
    811org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
     
    4548org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
    4649org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
    47 org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
     50org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
    4851org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
    4952org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
     
    5154org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
    5255org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
     56org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
    5357org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
    5458org.eclipse.jdt.core.compiler.problem.nullReference=warning
     
    5761org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
    5862org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
     63org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
    5964org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
    6065org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
     
    7378org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
    7479org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
     80org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
    7581org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
    7682org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
     
    7985org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
    8086org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
     87org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
     88org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
     89org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
    8190org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
    8291org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
     
    8695org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
    8796org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
     97org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
    8898org.eclipse.jdt.core.compiler.problem.unusedImport=warning
    8999org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
  • applications/editors/josm/plugins/native-password-manager/build.xml

    r32680 r33579  
    55    <property name="commit.message" value="Commit message"/>
    66    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    7     <property name="plugin.main.version" value="10580"/>
     7    <property name="plugin.main.version" value="12678"/>
    88    <property name="plugin.author" value="Paul Hartmann"/>
    99    <property name="plugin.class" value="org.openstreetmap.josm.plugins.npm.NPMPlugin"/>
  • applications/editors/josm/plugins/native-password-manager/src/org/netbeans/modules/keyring/fallback/FallbackProvider.java

    r30822 r33579  
    100100    }
    101101
     102    @Override
    102103    public char[] read(String key) {
    103104        byte[] ciphertext = prefs.getByteArray(key, null);
     
    113114    }
    114115
     116    @Override
    115117    public void save(String key, char[] password, String description) {
    116118        _save(key, password, description);
     
    126128    }
    127129
     130    @Override
    128131    public void delete(String key) {
    129132        prefs.remove(key);
  • applications/editors/josm/plugins/native-password-manager/src/org/netbeans/modules/keyring/mac/MacProvider.java

    r30822 r33579  
    5353    private static final Logger LOG = Logger.getLogger(MacProvider.class.getName());
    5454
     55    @Override
    5556    public boolean enabled() {
    5657        return true; // test elsewhere if we are on a mac
    5758    }
    5859
     60    @Override
    5961    public char[] read(String key) {
    6062        try {
     
    7678    }
    7779
     80    @Override
    7881    public void save(String key, char[] password, String description) {
    7982        try {
     
    98101    }
    99102
     103    @Override
    100104    public void delete(String key) {
    101105        try {
  • applications/editors/josm/plugins/native-password-manager/src/org/openstreetmap/josm/plugins/npm/InitializationWizard.java

    r30822 r33579  
    4444import org.openstreetmap.josm.data.oauth.OAuthToken;
    4545import org.openstreetmap.josm.gui.preferences.server.ProxyPreferencesPanel;
     46import org.openstreetmap.josm.gui.util.WindowGeometry;
    4647import org.openstreetmap.josm.gui.widgets.HtmlPanel;
     48import org.openstreetmap.josm.io.OsmApi;
    4749import org.openstreetmap.josm.io.auth.CredentialsAgentException;
    4850import org.openstreetmap.josm.io.auth.CredentialsManager;
    49 import org.openstreetmap.josm.io.OsmApi;
    5051import org.openstreetmap.josm.tools.ImageProvider;
    5152import org.openstreetmap.josm.tools.PlatformHookOsx;
    5253import org.openstreetmap.josm.tools.PlatformHookUnixoid;
    5354import org.openstreetmap.josm.tools.PlatformHookWindows;
    54 import org.openstreetmap.josm.tools.WindowGeometry;
    5555
    5656public class InitializationWizard extends JDialog {
  • applications/editors/josm/plugins/pdfimport/build.xml

    r33569 r33579  
    44    <property name="commit.message" value="Initial pdfimport version"/>
    55    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    6     <property name="plugin.main.version" value="12675"/>
     6    <property name="plugin.main.version" value="12678"/>
    77   
    88    <!-- Configure these properties (replace "..." accordingly).
  • applications/editors/josm/plugins/pdfimport/src/pdfimport/LoadPdfDialog.java

    r33569 r33579  
    6060import org.openstreetmap.josm.gui.progress.ProgressRenderer;
    6161import org.openstreetmap.josm.gui.progress.swing.SwingRenderingProgressMonitor;
     62import org.openstreetmap.josm.gui.util.WindowGeometry;
    6263import org.openstreetmap.josm.tools.ImageProvider;
    6364import org.openstreetmap.josm.tools.Logging;
    64 import org.openstreetmap.josm.tools.WindowGeometry;
    6565
    6666import pdfimport.pdfbox.PdfBoxParser;
  • applications/editors/josm/plugins/print/build.xml

    r33237 r33579  
    55    <property name="commit.message" value="Added a field to specify the map scale."/>
    66    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    7     <property name="plugin.main.version" value="11905"/>
     7    <property name="plugin.main.version" value="12678"/>
    88
    99    <property name="plugin.author" value="Kai Pastor"/>
  • applications/editors/josm/plugins/print/src/org/openstreetmap/josm/plugins/print/PrintDialog.java

    r33237 r33579  
    5959import org.openstreetmap.gui.jmapviewer.tilesources.AbstractOsmTileSource;
    6060import org.openstreetmap.josm.Main;
     61import org.openstreetmap.josm.gui.MainApplication;
     62import org.openstreetmap.josm.gui.util.WindowGeometry;
    6163import org.openstreetmap.josm.tools.GBC;
     64import org.openstreetmap.josm.tools.Logging;
    6265import org.openstreetmap.josm.tools.Utils;
    63 import org.openstreetmap.josm.tools.WindowGeometry;
    6466
    6567/**
     
    233235                            printPreview.repaint();
    234236                        } catch (ParseException e) {
    235                             Main.error(e);
     237                            Logging.error(e);
    236238                        }
    237239                    }
     
    261263                            printPreview.repaint();
    262264                        } catch (ParseException e) {
    263                             Main.error(e);
     265                            Logging.error(e);
    264266                        }
    265267                    }
     
    343345        JScrollPane previewPane = new JScrollPane(printPreview,
    344346                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    345         previewPane.setPreferredSize(Main.main != null ? Main.map.mapView.getSize() : new Dimension(210, 297));
     347        previewPane.setPreferredSize(MainApplication.getMap() != null ? MainApplication.getMap().mapView.getSize() : new Dimension(210, 297));
    346348        add(previewPane, GBC.std(0, 0).span(1, GBC.RELATIVE).fill().weight(5.0, 5.0));
    347349
     
    479481            } else if (!ignoredAttributes.contains(a.getName())) {
    480482                // TODO: Add support for DateTimeSyntax, SetOfIntegerSyntax, ResolutionSyntax if needed
    481                 Main.warn("Print request attribute not supported: "+a.getName() +": "+a.getCategory()+" - "+a.toString());
     483                Logging.warn("Print request attribute not supported: "+a.getName() +": "+a.getCategory()+" - "+a.toString());
    482484            }
    483485            if (setting != null) {
     
    531533            return realClass.getConstructor(int.class).newInstance(Integer.parseInt(value));
    532534        } else {
    533             Main.warn("Attribute syntax not supported: "+syntax);
     535            Logging.warn("Attribute syntax not supported: "+syntax);
    534536        }
    535537        return null;
     
    544546                }
    545547            } catch (PrinterException | ReflectiveOperationException e) {
    546                 Main.warn(e.getClass().getSimpleName()+": "+e.getMessage());
     548                Logging.warn(e.getClass().getSimpleName()+": "+e.getMessage());
    547549            }
    548550        }
     
    551553                attrs.add(unmarshallPrintSetting(setting));
    552554            } catch (ReflectiveOperationException e) {
    553                 Main.warn(e.getClass().getSimpleName()+": "+e.getMessage());
     555                Logging.warn(e.getClass().getSimpleName()+": "+e.getMessage());
    554556            }
    555557        }
  • applications/editors/josm/plugins/print/src/org/openstreetmap/josm/plugins/print/PrintPlugin.java

    r33102 r33579  
    77
    88import org.openstreetmap.josm.Main;
     9import org.openstreetmap.josm.gui.MainApplication;
    910import org.openstreetmap.josm.gui.MapFrame;
    1011import org.openstreetmap.josm.plugins.Plugin;
     
    4142        super(info);
    4243
    43         JMenu fileMenu = Main.main.menu.fileMenu;
     44        JMenu fileMenu = MainApplication.getMenu().fileMenu;
    4445        int pos = fileMenu.getItemCount();
    4546        do {
  • applications/editors/josm/plugins/print/src/org/openstreetmap/josm/plugins/print/PrintPreview.java

    r33062 r33579  
    1919import javax.swing.RepaintManager;
    2020
    21 import org.openstreetmap.josm.Main;
     21import org.openstreetmap.josm.tools.Logging;
    2222
    2323/**
     
    281281            } catch (PrinterException e) {
    282282                // should never happen since we are not printing
    283                 Main.error(e);
     283                Logging.error(e);
    284284            }
    285285        } else {
  • applications/editors/josm/plugins/print/src/org/openstreetmap/josm/plugins/print/PrintableLayerManager.java

    r33237 r33579  
    77import java.util.List;
    88
    9 import org.openstreetmap.josm.Main;
    109import org.openstreetmap.josm.data.osm.DataSet;
     10import org.openstreetmap.josm.gui.MainApplication;
    1111import org.openstreetmap.josm.gui.layer.Layer;
    1212import org.openstreetmap.josm.gui.layer.MainLayerManager;
     
    1515public class PrintableLayerManager extends MainLayerManager {
    1616
    17     private static final MainLayerManager layerManager = Main.getLayerManager();
     17    private static final MainLayerManager layerManager = MainApplication.getLayerManager();
    1818
    1919    @Override
  • applications/editors/josm/plugins/print/src/org/openstreetmap/josm/plugins/print/PrintableMapView.java

    r33260 r33579  
    2525import org.openstreetmap.josm.data.Bounds;
    2626import org.openstreetmap.josm.data.SystemOfMeasurement;
     27import org.openstreetmap.josm.gui.MainApplication;
    2728import org.openstreetmap.josm.gui.MapView;
    2829import org.openstreetmap.josm.gui.layer.Layer;
     
    122123        if (dim.width != width || dim.height != height) {
    123124            super.setSize(width, height);
    124             zoomTo(Main.map.mapView.getRealBounds());
     125            zoomTo(MainApplication.getMap().mapView.getRealBounds());
    125126            rezoomToFixedScale();
    126127        }
     
    135136        if (dim.width != newSize.width || dim.height != newSize.height) {
    136137            super.setSize(newSize);
    137             zoomTo(Main.map.mapView.getRealBounds());
     138            zoomTo(MainApplication.getMap().mapView.getRealBounds());
    138139            rezoomToFixedScale();
    139140        }
  • applications/editors/josm/plugins/roadsigns/build.xml

    r32680 r33579  
    44    <property name="commit.message" value=""/>
    55    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    6     <property name="plugin.main.version" value="10580"/>
     6    <property name="plugin.main.version" value="12678"/>
    77
    88    <!--
  • applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/RoadSignInputDialog.java

    r33179 r33579  
    6868import org.openstreetmap.josm.data.osm.OsmPrimitive;
    6969import org.openstreetmap.josm.gui.ExtendedDialog;
     70import org.openstreetmap.josm.gui.MainApplication;
     71import org.openstreetmap.josm.gui.util.WindowGeometry;
    7072import org.openstreetmap.josm.gui.widgets.MultiSplitLayout.Divider;
    7173import org.openstreetmap.josm.gui.widgets.MultiSplitLayout.Leaf;
     
    7779import org.openstreetmap.josm.plugins.roadsigns.Sign.Tag;
    7880import org.openstreetmap.josm.tools.GBC;
     81import org.openstreetmap.josm.tools.Logging;
    7982import org.openstreetmap.josm.tools.OpenBrowser;
    8083import org.openstreetmap.josm.tools.Pair;
    81 import org.openstreetmap.josm.tools.WindowGeometry;
    8284
    8385/**
     
    134136    protected void buttonAction(int i, ActionEvent evt) {
    135137        if (i == 0) { // OK Button
    136             Collection<OsmPrimitive> selPrim = Main.getLayerManager().getEditDataSet().getSelected();
     138            Collection<OsmPrimitive> selPrim = MainApplication.getLayerManager().getEditDataSet().getSelected();
    137139            if (!selPrim.isEmpty()) {
    138140                Main.pref.put("plugin.roadsigns.addTrafficSignTag", addTrafficSignTag.isSelected());
     
    140142                Command cmd = createCommand(selPrim);
    141143                if (cmd != null) {
    142                     Main.main.undoRedo.add(cmd);
     144                    MainApplication.undoRedo.add(cmd);
    143145                }
    144146            }
     
    159161                    xmlenc.writeObject(model);
    160162                } catch (FileNotFoundException ex) {
    161                     Main.warn("unable to write dialog layout: "+ex);
     163                    Logging.warn("unable to write dialog layout: "+ex);
    162164                }
    163165            }
  • applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/javacc/ParseException.java

    r23192 r33579  
    9797   * gets displayed.
    9898   */
     99  @Override
    99100  public String getMessage() {
    100101    if (!specialConstructor) {
  • applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/javacc/Token.java

    r21967 r33579  
    9191   * Returns the image.
    9292   */
     93  @Override
    9394  public String toString()
    9495  {
  • applications/editors/josm/plugins/roadsigns/src/org/openstreetmap/josm/plugins/roadsigns/javacc/TokenMgrError.java

    r23192 r33579  
    115115    * from this method for such cases in the release version of your parser.
    116116    */
     117   @Override
    117118   public String getMessage() {
    118119      return super.getMessage();
  • applications/editors/josm/plugins/tageditor/build.xml

    r32680 r33579  
    22<project name="tageditor" default="dist" basedir=".">
    33    <property name="commit.message" value="Tageditor:  help shortcut parser, rebuild"/>
    4     <property name="plugin.main.version" value="10580"/>
     4    <property name="plugin.main.version" value="12678"/>
    55   
    66        <property name="plugin.author" value="Karl Guggisberg"/>
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/TagEditorDialog.java

    r33016 r33579  
    3131import org.openstreetmap.josm.data.osm.OsmPrimitive;
    3232import org.openstreetmap.josm.data.osm.Tag;
     33import org.openstreetmap.josm.gui.MainApplication;
    3334import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
    3435import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
    3536import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
     37import org.openstreetmap.josm.gui.util.WindowGeometry;
    3638import org.openstreetmap.josm.plugins.tageditor.ac.AutoCompletionListViewer;
    3739import org.openstreetmap.josm.plugins.tageditor.editor.TagEditor;
     
    4244import org.openstreetmap.josm.plugins.tageditor.tagspec.ui.TabularTagSelector;
    4345import org.openstreetmap.josm.tools.ImageProvider;
    44 import org.openstreetmap.josm.tools.WindowGeometry;
    4546
    4647/**
     
    282283        tagEditor.getModel().clearAppliedPresets();
    283284        tagEditor.getModel().initFromJOSMSelection();
    284         autocomplete = Main.getLayerManager().getEditLayer().data.getAutoCompletionManager();
     285        autocomplete = MainApplication.getLayerManager().getEditLayer().data.getAutoCompletionManager();
    285286        tagEditor.setAutoCompletionManager(autocomplete);
    286287        getModel().ensureOneTag();
     
    319320            setVisible(false);
    320321            tagEditor.getModel().updateJOSMSelection();
    321             DataSet ds = Main.getLayerManager().getEditDataSet();
     322            DataSet ds = MainApplication.getLayerManager().getEditDataSet();
    322323            ds.fireSelectionChanged();
    323324            Main.parent.repaint(); // repaint all - drawing could have been changed
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/TagEditorPlugin.java

    r30488 r33579  
    22package org.openstreetmap.josm.plugins.tageditor;
    33
    4 import org.openstreetmap.josm.Main;
     4import org.openstreetmap.josm.gui.MainApplication;
    55import org.openstreetmap.josm.gui.MainMenu;
    66import org.openstreetmap.josm.plugins.Plugin;
     
    99public class TagEditorPlugin extends Plugin {
    1010    LaunchAction action;
    11    
     11
    1212    /**
    13      * constructor 
     13     * constructor
    1414     */
    1515    public TagEditorPlugin(PluginInformation info) {
    1616        super(info);
    1717        action = new LaunchAction();
    18         MainMenu.add(Main.main.menu.editMenu, action);
     18        MainMenu.add(MainApplication.getMenu().editMenu, action);
    1919    }
    2020}
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/ac/AutoCompletionContext.java

    r32508 r33579  
    22package org.openstreetmap.josm.plugins.tageditor.ac;
    33
    4 import org.openstreetmap.josm.Main;
    54import org.openstreetmap.josm.data.osm.DataSet;
     5import org.openstreetmap.josm.gui.MainApplication;
    66
    77public class AutoCompletionContext {
     
    1616
    1717    public void initFromJOSMSelection() {
    18         DataSet ds = Main.getLayerManager().getEditDataSet();
     18        DataSet ds = MainApplication.getLayerManager().getEditDataSet();
    1919        selectionIncludesNodes = !ds.getSelectedNodes().isEmpty();
    2020        selectionIncludesWays = !ds.getSelectedWays().isEmpty();
  • applications/editors/josm/plugins/tageditor/src/org/openstreetmap/josm/plugins/tageditor/editor/TagEditorModel.java

    r33016 r33579  
    1010import javax.swing.DefaultListSelectionModel;
    1111
    12 import org.openstreetmap.josm.Main;
    1312import org.openstreetmap.josm.command.Command;
    1413import org.openstreetmap.josm.command.SequenceCommand;
    1514import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1615import org.openstreetmap.josm.data.osm.Tag;
     16import org.openstreetmap.josm.gui.MainApplication;
    1717import org.openstreetmap.josm.gui.tagging.TagModel;
    1818import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
     
    147147    public void updateJOSMSelection() {
    148148        ArrayList<Command> commands = new ArrayList<>();
    149         Collection<OsmPrimitive> selection = Main.getLayerManager().getEditDataSet().getSelected();
     149        Collection<OsmPrimitive> selection = MainApplication.getLayerManager().getEditDataSet().getSelected();
    150150        if (selection == null)
    151151            return;
     
    167167
    168168        // executes the commands and adds them to the undo/redo chains
    169         Main.main.undoRedo.add(command);
     169        MainApplication.undoRedo.add(command);
    170170    }
    171171
     
    174174     */
    175175    public void initFromJOSMSelection() {
    176         Collection<OsmPrimitive> selection = Main.getLayerManager().getEditDataSet().getSelected();
     176        Collection<OsmPrimitive> selection = MainApplication.getLayerManager().getEditDataSet().getSelected();
    177177        clear();
    178178        for (OsmPrimitive element : selection) {
  • applications/editors/josm/plugins/terracer/build.xml

    r32680 r33579  
    22<project name="terracer" default="dist" basedir=".">
    33    <property name="commit.message" value="applied #j5760 (patch by robome) - Order of housenumbers not correct"/>
    4     <property name="plugin.main.version" value="10580"/>
     4    <property name="plugin.main.version" value="12678"/>
    55    <property name="plugin.author" value="Matt Amos"/>
    66    <property name="plugin.class" value="terracer.TerracerPlugin"/>
  • applications/editors/josm/plugins/terracer/src/terracer/HouseNumberInputDialog.java

    r33077 r33579  
    2828import org.openstreetmap.josm.data.osm.Way;
    2929import org.openstreetmap.josm.gui.ExtendedDialog;
     30import org.openstreetmap.josm.gui.MainApplication;
    3031import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingComboBox;
    3132import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionListItem;
     33import org.openstreetmap.josm.gui.util.WindowGeometry;
    3234import org.openstreetmap.josm.tools.GBC;
    33 import org.openstreetmap.josm.tools.WindowGeometry;
    3435
    3536/**
     
    310311
    311312        if (buildingComboBox == null) {
    312             final List<AutoCompletionListItem> values = Main.getLayerManager().getEditDataSet().getAutoCompletionManager().getValues("building");
     313            final List<AutoCompletionListItem> values = MainApplication
     314                .getLayerManager().getEditDataSet().getAutoCompletionManager().getValues("building");
    313315
    314316            buildingComboBox = new AutoCompletingComboBox();
     
    362364    TreeSet<String> createAutoCompletionInfo() {
    363365        final TreeSet<String> names = new TreeSet<>();
    364         for (OsmPrimitive osm : Main.getLayerManager().getEditDataSet()
     366        for (OsmPrimitive osm : MainApplication.getLayerManager().getEditDataSet()
    365367                .allNonDeletedPrimitives()) {
    366368            if (osm.getKeys() != null && osm.keySet().contains("highway")
  • applications/editors/josm/plugins/terracer/src/terracer/HouseNumberInputHandler.java

    r33077 r33579  
    2626import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingComboBox;
    2727import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionListItem;
     28import org.openstreetmap.josm.tools.Logging;
    2829import org.openstreetmap.josm.tools.UserCancelException;
    2930
     
    300301                            doKeepOutline(), buildingType());
    301302                    } catch (UserCancelException ex) {
    302                         Main.trace(ex);
     303                        Logging.trace(ex);
    303304                    }
    304305
  • applications/editors/josm/plugins/terracer/src/terracer/ReverseTerraceAction.java

    r33077 r33579  
    2121import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2222import org.openstreetmap.josm.data.osm.Way;
     23import org.openstreetmap.josm.gui.MainApplication;
    2324import org.openstreetmap.josm.tools.Shortcut;
    2425
     
    4849    /**
    4950     * Breadth-first searches based on the selection while the selection is a way
    50      * with a building=* tag and then applies the addr:housenumber tag in reverse
    51      * order.
     51     * with a building=* tag and then applies the addr:housenumber tag in reverse order.
    5252     */
     53    @Override
    5354    public void actionPerformed(ActionEvent e) {
    54         Collection<Way> selectedWays = Main.getLayerManager().getEditDataSet().getSelectedWays();
     55        Collection<Way> selectedWays = MainApplication.getLayerManager().getEditDataSet().getSelectedWays();
    5556
    5657        // Set to keep track of all the nodes that have been visited - that is: if
     
    123124        }
    124125
    125         Main.main.undoRedo.add(new SequenceCommand(tr("Reverse Terrace"), commands));
    126         Main.getLayerManager().getEditDataSet().setSelected(orderedWays);
     126        MainApplication.undoRedo.add(new SequenceCommand(tr("Reverse Terrace"), commands));
     127        MainApplication.getLayerManager().getEditDataSet().setSelected(orderedWays);
    127128    }
    128129
  • applications/editors/josm/plugins/terracer/src/terracer/TerracerAction.java

    r33077 r33579  
    3838import org.openstreetmap.josm.data.osm.Way;
    3939import org.openstreetmap.josm.gui.ExtendedDialog;
     40import org.openstreetmap.josm.gui.MainApplication;
    4041import org.openstreetmap.josm.gui.conflict.tags.CombinePrimitiveResolverDialog;
     42import org.openstreetmap.josm.tools.Logging;
    4143import org.openstreetmap.josm.tools.Pair;
    4244import org.openstreetmap.josm.tools.Shortcut;
     
    178180
    179181        } catch (InvalidUserInputException ex) {
    180             Main.warn("Terracer: "+ex.getMessage());
     182            Logging.warn("Terracer: "+ex.getMessage());
    181183            new ExtendedDialog(Main.parent, tr("Invalid selection"), new String[] {"OK"})
    182184                .setButtonIcons(new String[] {"ok"}).setIcon(JOptionPane.INFORMATION_MESSAGE)
     
    191193
    192194        // Try to find an associatedStreet relation that could be reused from housenumbers, outline and street.
    193         Set<OsmPrimitive> candidates = new HashSet<OsmPrimitive>(housenumbers);
     195        Set<OsmPrimitive> candidates = new HashSet<>(housenumbers);
    194196        candidates.add(outline);
    195197        if (street != null) {
     
    203205            if (associatedStreets.size() > 1) {
    204206                // TODO: Deal with multiple associated Streets
    205                 Main.warn("Terracer: Found "+associatedStreets.size()+" associatedStreet relations. Considering the first one only.");
     207                Logging.warn("Terracer: Found "+associatedStreets.size()+" associatedStreet relations. Considering the first one only.");
    206208            }
    207209        }
     
    218220                        housenumbers, streetname, associatedStreet != null, false, "yes");
    219221            } catch (UserCancelException ex) {
    220                 Main.trace(ex);
     222                Logging.trace(ex);
    221223            } finally {
    222224                this.commands.clear();
     
    245247     *            number nodes
    246248     */
    247     class HousenumberNodeComparator implements Comparator<Node> {
     249    static class HousenumberNodeComparator implements Comparator<Node> {
    248250        private final Pattern pat = Pattern.compile("^(\\d+)\\s*(.*)");
    249251
     
    402404                }
    403405                if (!nodesToDelete.isEmpty())
    404                     this.commands.add(DeleteCommand.delete(Main.getLayerManager().getEditLayer(), nodesToDelete));
     406                    this.commands.add(DeleteCommand.delete(MainApplication.getLayerManager().getEditLayer(), nodesToDelete));
    405407            }
    406408        } else {
     
    413415        // Or should removing them also be an option?
    414416        if (!housenumbers.isEmpty()) {
    415             commands.add(DeleteCommand.delete(Main.getLayerManager().getEditLayer(),
     417            commands.add(DeleteCommand.delete(MainApplication.getLayerManager().getEditLayer(),
    416418                    housenumbers, true, true));
    417419        }
     
    425427        }
    426428
    427         Main.main.undoRedo.add(createTerracingCommand(outline));
     429        MainApplication.undoRedo.add(createTerracingCommand(outline));
    428430        if (nb <= 1 && street != null) {
    429431            // Select the way (for quick selection of a new house (with the same way))
    430             Main.getLayerManager().getEditDataSet().setSelected(street);
     432            MainApplication.getLayerManager().getEditDataSet().setSelected(street);
    431433        } else {
    432434            // Select the new building outlines (for quick reversing)
    433             Main.getLayerManager().getEditDataSet().setSelected(ways);
     435            MainApplication.getLayerManager().getEditDataSet().setSelected(ways);
    434436        }
    435437    }
     
    488490                        }
    489491                    } catch (UserCancelException e) {
    490                         Main.trace(e);
     492                        Logging.trace(e);
    491493                    }
    492494                }
  • applications/editors/josm/plugins/terracer/src/terracer/TerracerPlugin.java

    r33077 r33579  
    22package terracer;
    33
    4 import org.openstreetmap.josm.Main;
     4import org.openstreetmap.josm.gui.MainApplication;
    55import org.openstreetmap.josm.gui.MainMenu;
    66import org.openstreetmap.josm.plugins.Plugin;
     
    1616        super(info);
    1717
    18         MainMenu.add(Main.main.menu.moreToolsMenu, new TerracerAction());
    19         MainMenu.add(Main.main.menu.moreToolsMenu, new ReverseTerraceAction());
     18        MainMenu.add(MainApplication.getMenu().moreToolsMenu, new TerracerAction());
     19        MainMenu.add(MainApplication.getMenu().moreToolsMenu, new ReverseTerraceAction());
    2020    }
    2121}
  • applications/editors/josm/plugins/utilsplugin2/build.xml

    r33543 r33579  
    55    <property name="commit.message" value="[josm_utilsplugin2]: select boundary by double-click; multitagger table highlights"/>
    66    <!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
    7     <property name="plugin.main.version" value="12666"/>
     7    <property name="plugin.main.version" value="12678"/>
    88
    99    <property name="plugin.author" value="Kalle Lampila, Upliner, Zverik, akks, joshdoe and others"/>
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/UtilsPlugin2.java

    r33522 r33579  
    55import javax.swing.JMenuItem;
    66
    7 import org.openstreetmap.josm.Main;
    87import org.openstreetmap.josm.data.osm.search.SearchCompiler;
     8import org.openstreetmap.josm.gui.MainApplication;
    99import org.openstreetmap.josm.gui.MainMenu;
    1010import org.openstreetmap.josm.gui.MapFrame;
     
    9393        instance = this;
    9494
    95         JMenu editMenu = Main.main.menu.editMenu;
    96         JMenu toolsMenu = Main.main.menu.moreToolsMenu;
    97         JMenu dataMenu = Main.main.menu.dataMenu;
    98         JMenu selectionMenu = Main.main.menu.selectionMenu;
     95        JMenu editMenu = MainApplication.getMenu().editMenu;
     96        JMenu toolsMenu = MainApplication.getMenu().moreToolsMenu;
     97        JMenu dataMenu = MainApplication.getMenu().dataMenu;
     98        JMenu selectionMenu = MainApplication.getMenu().selectionMenu;
    9999
    100         copyTags = MainMenu.addAfter(editMenu, new CopyTagsAction(), false, Main.main.menu.copy);
     100        copyTags = MainMenu.addAfter(editMenu, new CopyTagsAction(), false, MainApplication.getMenu().copy);
    101101
    102102        addIntersections = MainMenu.add(toolsMenu, new AddIntersectionsAction());
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AddIntersectionsAction.java

    r32410 r33579  
    1515import javax.swing.JOptionPane;
    1616
    17 import org.openstreetmap.josm.Main;
    1817import org.openstreetmap.josm.actions.JosmAction;
    1918import org.openstreetmap.josm.command.AddCommand;
     
    2322import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2423import org.openstreetmap.josm.data.osm.Way;
     24import org.openstreetmap.josm.gui.MainApplication;
    2525import org.openstreetmap.josm.gui.Notification;
    2626import org.openstreetmap.josm.tools.Geometry;
     
    5656        Geometry.addIntersections(ways, false, cmds);
    5757        if (!cmds.isEmpty()) {
    58             Main.main.undoRedo.add(new SequenceCommand(tr("Add nodes at intersections"), cmds));
     58            MainApplication.undoRedo.add(new SequenceCommand(tr("Add nodes at intersections"), cmds));
    5959            Set<Node> nodes = new HashSet<>(10);
    6060            // find and select newly added nodes
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/AlignWayNodesAction.java

    r33328 r33579  
    1515import javax.swing.JOptionPane;
    1616
    17 import org.openstreetmap.josm.Main;
    1817import org.openstreetmap.josm.actions.JosmAction;
    1918import org.openstreetmap.josm.command.Command;
     
    2322import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2423import org.openstreetmap.josm.data.osm.Way;
     24import org.openstreetmap.josm.gui.MainApplication;
    2525import org.openstreetmap.josm.gui.Notification;
    2626import org.openstreetmap.josm.tools.Shortcut;
     
    128128
    129129        if (!commands.isEmpty())
    130             Main.main.undoRedo.add(new SequenceCommand(TITLE, commands));
     130            MainApplication.undoRedo.add(new SequenceCommand(TITLE, commands));
    131131    }
    132132
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/ExtractPointAction.java

    r32410 r33579  
    2424import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2525import org.openstreetmap.josm.data.osm.Way;
     26import org.openstreetmap.josm.gui.MainApplication;
    2627import org.openstreetmap.josm.gui.Notification;
    2728import org.openstreetmap.josm.tools.Shortcut;
     
    5657        List<Command> cmds = new LinkedList<>();
    5758
    58         Point p = Main.map.mapView.getMousePosition();
     59        Point p = MainApplication.getMap().mapView.getMousePosition();
    5960        if (p != null)
    60             cmds.add(new MoveCommand(nd, Main.map.mapView.getLatLon(p.x, p.y)));
     61            cmds.add(new MoveCommand(nd, MainApplication.getMap().mapView.getLatLon(p.x, p.y)));
    6162        List<OsmPrimitive> refs = nd.getReferrers();
    6263        cmds.add(new AddCommand(ndCopy));
     
    7172            }
    7273        }
    73         if (cmds.size() > 1) Main.main.undoRedo.add(new SequenceCommand(tr("Extract node from line"), cmds));
     74        if (cmds.size() > 1) MainApplication.undoRedo.add(new SequenceCommand(tr("Extract node from line"), cmds));
    7475    }
    7576
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/PasteRelationsAction.java

    r33123 r33579  
    2424import org.openstreetmap.josm.data.osm.Relation;
    2525import org.openstreetmap.josm.data.osm.RelationMember;
     26import org.openstreetmap.josm.gui.MainApplication;
    2627import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
    2728import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData;
     29import org.openstreetmap.josm.tools.Logging;
    2830import org.openstreetmap.josm.tools.Shortcut;
    2931
     
    5355            data = ((PrimitiveTransferData) ClipboardUtils.getClipboard().getData(PrimitiveTransferData.DATA_FLAVOR)).getDirectlyAdded();
    5456        } catch (UnsupportedFlavorException | IOException ex) {
    55             Main.warn(ex);
     57            Logging.warn(ex);
    5658        }
    5759        for (PrimitiveData pdata : data) {
     
    99101
    100102        if (!commands.isEmpty())
    101             Main.main.undoRedo.add(new SequenceCommand(TITLE, commands));
     103            MainApplication.undoRedo.add(new SequenceCommand(TITLE, commands));
    102104    }
    103105
     
    113115                    && ClipboardUtils.getClipboard().isDataFlavorAvailable(PrimitiveTransferData.DATA_FLAVOR));
    114116        } catch (IllegalStateException e) {
    115             Main.warn(e);
     117            Logging.warn(e);
    116118        } catch (NullPointerException e) {
    117119            // JDK-6322854: On Linux/X11, NPE can happen for unknown reasons, on all versions of Java
    118             Main.error(e);
     120            Logging.error(e);
    119121        }
    120122    }
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitObjectAction.java

    r32410 r33579  
    1818import javax.swing.JOptionPane;
    1919
    20 import org.openstreetmap.josm.Main;
    2120import org.openstreetmap.josm.actions.JosmAction;
    2221import org.openstreetmap.josm.actions.SplitWayAction;
     
    2524import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2625import org.openstreetmap.josm.data.osm.Way;
     26import org.openstreetmap.josm.gui.MainApplication;
    2727import org.openstreetmap.josm.gui.Notification;
    2828import org.openstreetmap.josm.tools.Shortcut;
     
    210210            SplitWayAction.SplitWayResult result = SplitWayAction.splitWay(
    211211                    getLayerManager().getEditLayer(), selectedWay, wayChunks, Collections.<OsmPrimitive>emptyList());
    212             Main.main.undoRedo.add(result.getCommand());
     212            MainApplication.undoRedo.add(result.getCommand());
    213213            if (splitWay != null)
    214                 Main.main.undoRedo.add(new DeleteCommand(splitWay));
     214                MainApplication.undoRedo.add(new DeleteCommand(splitWay));
    215215            getLayerManager().getEditDataSet().setSelected(result.getNewSelection());
    216216        }
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SplitOnIntersectionsAction.java

    r32410 r33579  
    1515import javax.swing.JOptionPane;
    1616
    17 import org.openstreetmap.josm.Main;
    1817import org.openstreetmap.josm.actions.JosmAction;
    1918import org.openstreetmap.josm.actions.SplitWayAction;
     
    2322import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2423import org.openstreetmap.josm.data.osm.Way;
     24import org.openstreetmap.josm.gui.MainApplication;
    2525import org.openstreetmap.josm.gui.Notification;
    2626import org.openstreetmap.josm.tools.Shortcut;
     
    9595
    9696        if (!list.isEmpty()) {
    97             Main.main.undoRedo.add(list.size() == 1 ? list.get(0) : new SequenceCommand(TITLE, list));
     97            MainApplication.undoRedo.add(list.size() == 1 ? list.get(0) : new SequenceCommand(TITLE, list));
    9898            getLayerManager().getEditDataSet().clearSelection();
    9999        }
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/SymmetryAction.java

    r32410 r33579  
    2222import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2323import org.openstreetmap.josm.data.osm.Way;
     24import org.openstreetmap.josm.gui.MainApplication;
    2425import org.openstreetmap.josm.gui.Notification;
    2526import org.openstreetmap.josm.tools.Shortcut;
     
    8788        }
    8889
    89         Main.main.undoRedo.add(new SequenceCommand(tr("Symmetry"), cmds));
    90         Main.map.repaint();
     90        MainApplication.undoRedo.add(new SequenceCommand(tr("Symmetry"), cmds));
     91        MainApplication.getMap().repaint();
    9192    }
    9293
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/TagBufferAction.java

    r32725 r33579  
    1515import java.util.function.Predicate;
    1616
    17 import org.openstreetmap.josm.Main;
    1817import org.openstreetmap.josm.actions.JosmAction;
    1918import org.openstreetmap.josm.command.ChangePropertyCommand;
     
    2120import org.openstreetmap.josm.command.SequenceCommand;
    2221import org.openstreetmap.josm.data.osm.OsmPrimitive;
     22import org.openstreetmap.josm.gui.MainApplication;
    2323import org.openstreetmap.josm.tools.Shortcut;
    2424import org.openstreetmap.josm.tools.SubclassFilteredCollection;
     
    6969
    7070        if (!commands.isEmpty())
    71             Main.main.undoRedo.add(new SequenceCommand(TITLE, commands));
     71            MainApplication.undoRedo.add(new SequenceCommand(TITLE, commands));
    7272    }
    7373
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/TagSourceAction.java

    r32410 r33579  
    1414import org.openstreetmap.josm.command.ChangePropertyCommand;
    1515import org.openstreetmap.josm.data.osm.OsmPrimitive;
     16import org.openstreetmap.josm.gui.MainApplication;
    1617import org.openstreetmap.josm.tools.Shortcut;
    1718
     
    4243            return;
    4344
    44         Main.main.undoRedo.add(new ChangePropertyCommand(selection, "source", source));
     45        MainApplication.undoRedo.add(new ChangePropertyCommand(selection, "source", source));
    4546    }
    4647
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/actions/UnGlueRelationAction.java

    r32410 r33579  
    2020import org.openstreetmap.josm.data.osm.Relation;
    2121import org.openstreetmap.josm.data.osm.Way;
     22import org.openstreetmap.josm.gui.MainApplication;
    2223import org.openstreetmap.josm.plugins.utilsplugin2.command.ChangeRelationMemberCommand;
    2324import org.openstreetmap.josm.tools.Shortcut;
     
    7980            // error message nothing to do
    8081        } else {
    81             Main.main.undoRedo.add(new SequenceCommand(tr("Unglued Relations"), cmds));
     82            MainApplication.undoRedo.add(new SequenceCommand(tr("Unglued Relations"), cmds));
    8283            //Set selection all primiteves (new and old)
    8384            newPrimitives.addAll(selection);
    8485            getLayerManager().getEditDataSet().setSelected(newPrimitives);
    85             Main.map.mapView.repaint();
     86            MainApplication.getMap().mapView.repaint();
    8687        }
    8788    }
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/curves/CurveAction.java

    r32410 r33579  
    1818import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1919import org.openstreetmap.josm.data.osm.Way;
     20import org.openstreetmap.josm.gui.MainApplication;
    2021import org.openstreetmap.josm.tools.Shortcut;
    2122
     
    5859        Collection<Command> cmds = CircleArcMaker.doCircleArc(selectedNodes, selectedWays, angleSeparation);
    5960        if (cmds != null)
    60             Main.main.undoRedo.add(new SequenceCommand("Create a curve", cmds));
     61            MainApplication.undoRedo.add(new SequenceCommand("Create a curve", cmds));
    6162    }
    6263
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/customurl/OpenPageAction.java

    r32410 r33579  
    1818import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1919import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
     20import org.openstreetmap.josm.gui.MainApplication;
     21import org.openstreetmap.josm.gui.MapView;
     22import org.openstreetmap.josm.tools.Logging;
    2023import org.openstreetmap.josm.tools.OpenBrowser;
    2124import org.openstreetmap.josm.tools.OsmUrlToBounds;
     
    5053            ChooseURLAction.showConfigDialog(true);
    5154
    52         LatLon center = Main.map.mapView.getLatLon(Main.map.mapView.getWidth()/2, Main.map.mapView.getHeight()/2);
     55        MapView mv = MainApplication.getMap().mapView;
     56        LatLon center = mv.getLatLon(mv.getWidth()/2, mv.getHeight()/2);
    5357
    5458        String addr = URLList.getSelectedURL();
     
    7074                    val = Double.toString(center.lon());
    7175                } else if (key.equals("#zoom")) {
    72                     val = Integer.toString(OsmUrlToBounds.getZoom(Main.map.mapView.getRealBounds()));
     76                    val = Integer.toString(OsmUrlToBounds.getZoom(MainApplication.getMap().mapView.getRealBounds()));
    7377                } else {
    7478                    if (p != null) {
     
    8387            }
    8488        } catch (UnsupportedEncodingException ex) {
    85             Main.error(ex, "Encoding error");
     89            Logging.log(Logging.LEVEL_ERROR, "Encoding error", ex);
    8690            return;
    8791        }
     
    9296            OpenBrowser.displayUrl(addr);
    9397        } catch (Exception ex) {
    94             Main.error(ex, "Can not open URL " + addr);
     98            Logging.log(Logging.LEVEL_ERROR, "Can not open URL " + addr, ex);
    9599        }
    96100    }
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/customurl/URLList.java

    r33124 r33579  
    1515import org.openstreetmap.josm.Main;
    1616import org.openstreetmap.josm.plugins.utilsplugin2.UtilsPlugin2;
     17import org.openstreetmap.josm.tools.Logging;
    1718
    1819public final class URLList {
     
    7879            }
    7980        } catch (IOException e) {
    80             Main.error(e);
     81            Logging.error(e);
    8182        }
    8283        return items;
     
    9394            }
    9495        } catch (IOException e) {
    95             Main.error(e);
     96            Logging.error(e);
    9697        } finally {
    9798            try {
     
    99100                    fw.close();
    100101            } catch (Exception e) {
    101                 Main.warn(e);
     102                Logging.warn(e);
    102103            }
    103104        }
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/latlon/LatLonAction.java

    r32725 r33579  
    1818import org.openstreetmap.josm.data.osm.Node;
    1919import org.openstreetmap.josm.data.osm.Way;
     20import org.openstreetmap.josm.gui.MainApplication;
    2021import org.openstreetmap.josm.tools.Shortcut;
    2122
     
    8081            cmds.add(new AddCommand(wnew));
    8182        }
    82         Main.main.undoRedo.add(new SequenceCommand(tr("Lat Lon tool"), cmds));
    83         Main.map.mapView.repaint();
     83        MainApplication.undoRedo.add(new SequenceCommand(tr("Lat Lon tool"), cmds));
     84        MainApplication.getMap().mapView.repaint();
    8485    }
    8586
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/latlon/LatLonDialog.java

    r32410 r33579  
    3636import org.openstreetmap.josm.data.coor.LatLon;
    3737import org.openstreetmap.josm.gui.ExtendedDialog;
     38import org.openstreetmap.josm.gui.util.WindowGeometry;
    3839import org.openstreetmap.josm.gui.widgets.HtmlPanel;
    3940import org.openstreetmap.josm.tools.GBC;
    40 import org.openstreetmap.josm.tools.WindowGeometry;
    4141
    4242public class LatLonDialog extends ExtendedDialog {
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/multitagger/MultiTagDialog.java

    r33522 r33579  
    4949import org.openstreetmap.josm.data.preferences.ColorProperty;
    5050import org.openstreetmap.josm.gui.ExtendedDialog;
     51import org.openstreetmap.josm.gui.MainApplication;
    5152import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    5253import org.openstreetmap.josm.gui.tagging.ac.AutoCompletingTextField;
     
    5556import org.openstreetmap.josm.gui.util.HighlightHelper;
    5657import org.openstreetmap.josm.gui.util.TableHelper;
     58import org.openstreetmap.josm.gui.util.WindowGeometry;
    5759import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
    5860import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
    5961import org.openstreetmap.josm.tools.GBC;
    6062import org.openstreetmap.josm.tools.ImageProvider;
    61 import org.openstreetmap.josm.tools.WindowGeometry;
     63import org.openstreetmap.josm.tools.Logging;
    6264
    6365/**
     
    138140                public void actionPerformed(ActionEvent e) {
    139141                    if (jt.isSelected()) tableModel.shownTypes.add(type); else tableModel.shownTypes.remove(type);
    140                     tableModel.updateData(Main.getLayerManager().getEditDataSet().getSelected());
     142                    tableModel.updateData(MainApplication.getLayerManager().getEditDataSet().getSelected());
    141143                }
    142144            });
     
    181183        @Override
    182184        public void mouseClicked(MouseEvent e) {
    183             if (e.getClickCount() > 1 && Main.isDisplayingMapView()) {
     185            if (e.getClickCount() > 1 && MainApplication.isDisplayingMapView()) {
    184186                AutoScaleAction.zoomTo(currentSelection);
    185187            }
     
    191193        public void valueChanged(ListSelectionEvent e) {
    192194            currentSelection = getSelectedPrimitives();
    193             if (currentSelection != null && Main.isDisplayingMapView()) {
     195            if (currentSelection != null && MainApplication.isDisplayingMapView()) {
    194196                if (highlightHelper.highlightOnly(currentSelection)) {
    195                     Main.map.mapView.repaint();
     197                    MainApplication.getMap().mapView.repaint();
    196198                }
    197199            }
     
    210212
    211213    private void initAutocompletion() {
    212         OsmDataLayer l = Main.getLayerManager().getEditLayer();
     214        OsmDataLayer l = MainApplication.getLayerManager().getEditLayer();
    213215        AutoCompletionManager autocomplete = l.data.getAutoCompletionManager();
    214216        for (int i = 0; i < tableModel.mainTags.length; i++) {
     
    227229            @Override
    228230            public void actionPerformed(ActionEvent e) {
    229                 if (Main.isDisplayingMapView()) {
     231                if (MainApplication.isDisplayingMapView()) {
    230232                    AutoScaleAction.zoomTo(currentSelection);
    231233                }
     
    235237            @Override
    236238            public void actionPerformed(ActionEvent e) {
    237                 Main.getLayerManager().getEditDataSet().setSelected(getSelectedPrimitives());
     239                MainApplication.getLayerManager().getEditDataSet().setSelected(getSelectedPrimitives());
    238240            }
    239241        });
     
    340342
    341343    private void specifyTagSet(String s) {
    342         Main.info("Multitagger tags="+s);
     344        Logging.info("Multitagger tags="+s);
    343345        tableModel.setupColumnsFromText(s);
    344346
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/multitagger/MultiTaggerTableModel.java

    r32410 r33579  
    1212import javax.swing.table.AbstractTableModel;
    1313
    14 import org.openstreetmap.josm.Main;
    1514import org.openstreetmap.josm.command.ChangePropertyCommand;
    1615import org.openstreetmap.josm.command.Command;
     
    2019import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
    2120import org.openstreetmap.josm.data.osm.Way;
     21import org.openstreetmap.josm.gui.MainApplication;
    2222import org.openstreetmap.josm.tools.Geometry;
    2323
     
    4949    public void setWatchSelection(boolean watchSelection) {
    5050        this.watchSelection = watchSelection;
    51         if (watchSelection && Main.getLayerManager().getEditLayer() != null)
    52             selectionChanged(Main.getLayerManager().getEditDataSet().getSelected());
     51        if (watchSelection && MainApplication.getLayerManager().getEditLayer() != null)
     52            selectionChanged(MainApplication.getLayerManager().getEditDataSet().getSelected());
    5353    }
    5454
     
    115115            Command cmd = new ChangePropertyCommand(sel, key, (String) value);
    116116            if (autoCommit) {
    117                 Main.main.undoRedo.add(cmd);
     117                MainApplication.undoRedo.add(cmd);
    118118            } else {
    119119                cmds.add(cmd);
     
    185185
    186186    void commit(String commandTitle) {
    187         Main.main.undoRedo.add(new SequenceCommand(commandTitle, cmds));
     187        MainApplication.undoRedo.add(new SequenceCommand(commandTitle, cmds));
    188188        cmds.clear();
    189189    }
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryAction.java

    r32410 r33579  
    1212import javax.swing.JOptionPane;
    1313
    14 import org.openstreetmap.josm.Main;
    1514import org.openstreetmap.josm.actions.JosmAction;
    1615import org.openstreetmap.josm.data.osm.OsmPrimitive;
     16import org.openstreetmap.josm.gui.MainApplication;
    1717import org.openstreetmap.josm.gui.Notification;
    1818import org.openstreetmap.josm.tools.Shortcut;
     
    5858                return;
    5959
    60             Main.main.undoRedo.add(replaceCommand);
     60            MainApplication.undoRedo.add(replaceCommand);
    6161        } catch (IllegalArgumentException ex) {
    6262            new Notification(
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceGeometryUtils.java

    r33522 r33579  
    3333import org.openstreetmap.josm.data.osm.TagCollection;
    3434import org.openstreetmap.josm.data.osm.Way;
     35import org.openstreetmap.josm.gui.MainApplication;
    3536import org.openstreetmap.josm.gui.Notification;
    3637import org.openstreetmap.josm.gui.conflict.tags.CombinePrimitiveResolverDialog;
     38import org.openstreetmap.josm.tools.Logging;
    3739import org.openstreetmap.josm.tools.UserCancelException;
    3840
     
    110112        // FIXME: handle different layers
    111113        List<Command> commands = new ArrayList<>();
    112         Command c = MergeNodesAction.mergeNodes(Main.getLayerManager().getEditLayer(), Arrays.asList(subjectNode, referenceNode), referenceNode);
     114        Command c = MergeNodesAction.mergeNodes(MainApplication.getLayerManager().getEditLayer(),
     115            Arrays.asList(subjectNode, referenceNode), referenceNode);
    113116        if (c == null) {
    114117            // User canceled
     
    197200        }
    198201
    199         Main.getLayerManager().getEditDataSet().setSelected(referenceObject);
     202        MainApplication.getLayerManager().getEditDataSet().setSelected(referenceObject);
    200203
    201204        return new ReplaceGeometryCommand(
     
    236239    public static ReplaceGeometryCommand buildReplaceWayCommand(Way subjectWay, Way referenceWay) {
    237240
    238         Area a = Main.getLayerManager().getEditDataSet().getDataSourceArea();
     241        Area a = MainApplication.getLayerManager().getEditDataSet().getDataSourceArea();
    239242        if (!isInArea(subjectWay, a) || !isInArea(referenceWay, a)) {
    240243            throw new ReplaceGeometryException(tr("The ways must be entirely within the downloaded area."));
     
    253256        } catch (UserCancelException e) {
    254257            // user canceled tag merge dialog
    255             Main.trace(e);
     258            Logging.trace(e);
    256259            return null;
    257260        }
     
    354357
    355358        // Remove geometry way from selection
    356         Main.getLayerManager().getEditDataSet().clearSelection(referenceWay);
     359        MainApplication.getLayerManager().getEditDataSet().clearSelection(referenceWay);
    357360
    358361        // And delete old geometry way
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/replacegeometry/ReplaceMembershipAction.java

    r33522 r33579  
    1515import javax.swing.JOptionPane;
    1616
    17 import org.openstreetmap.josm.Main;
    1817import org.openstreetmap.josm.actions.JosmAction;
    1918import org.openstreetmap.josm.command.ChangeCommand;
     
    2423import org.openstreetmap.josm.data.osm.RelationMember;
    2524import org.openstreetmap.josm.data.osm.RelationToChildReference;
     25import org.openstreetmap.josm.gui.MainApplication;
    2626import org.openstreetmap.josm.gui.Notification;
    2727import org.openstreetmap.josm.tools.MultiMap;
     
    4545        final int affectedRelations = command.getChildren().size();
    4646        if (affectedRelations > 0) {
    47             Main.main.undoRedo.add(command);
     47            MainApplication.undoRedo.add(command);
    4848            new Notification(trn("Replaced ''{0}'' by ''{1}'' in {2} relation", "Replaced ''{0}'' by ''{1}'' in {2} relations",
    4949                    affectedRelations,
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/ConnectedMatch.java

    r33522 r33579  
    66import java.util.Set;
    77
    8 import org.openstreetmap.josm.Main;
    98import org.openstreetmap.josm.data.osm.Node;
    109import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1110import org.openstreetmap.josm.data.osm.Way;
    1211import org.openstreetmap.josm.data.osm.search.SearchCompiler;
     12import org.openstreetmap.josm.gui.MainApplication;
    1313import org.openstreetmap.josm.plugins.utilsplugin2.selection.NodeWayUtils;
    1414
     
    3232        Set<Node> matchedNodes = new HashSet<>();
    3333        // find all ways that match the expression
    34         Collection<Way> allWays = Main.getLayerManager().getEditDataSet().getWays();
     34        Collection<Way> allWays = MainApplication.getLayerManager().getEditDataSet().getWays();
    3535        for (Way way : allWays) {
    3636            if (match.match(way)) {
     
    3939        }
    4040        // find all nodes that match the expression
    41         Collection<Node> allNodes = Main.getLayerManager().getEditDataSet().getNodes();
     41        Collection<Node> allNodes = MainApplication.getLayerManager().getEditDataSet().getNodes();
    4242        for (Node node : allNodes) {
    4343            if (match.match(node)) {
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/InsideMatch.java

    r33522 r33579  
    55import java.util.HashSet;
    66
    7 import org.openstreetmap.josm.Main;
    87import org.openstreetmap.josm.data.osm.OsmPrimitive;
    98import org.openstreetmap.josm.data.osm.Relation;
    109import org.openstreetmap.josm.data.osm.Way;
    1110import org.openstreetmap.josm.data.osm.search.SearchCompiler;
     11import org.openstreetmap.josm.gui.MainApplication;
    1212import org.openstreetmap.josm.plugins.utilsplugin2.selection.NodeWayUtils;
    1313
     
    2828        Collection<OsmPrimitive> matchedAreas = new HashSet<>();
    2929        // find all ways that match the expression
    30         Collection<Way> ways = Main.getLayerManager().getEditDataSet().getWays();
     30        Collection<Way> ways = MainApplication.getLayerManager().getEditDataSet().getWays();
    3131        for (Way way : ways) {
    3232            if (match.match(way)) {
     
    3535        }
    3636        // find all relations that match the expression
    37         Collection<Relation> rels = Main.getLayerManager().getEditDataSet().getRelations();
     37        Collection<Relation> rels = MainApplication.getLayerManager().getEditDataSet().getRelations();
    3838        for (Relation rel : rels) {
    3939            if (match.match(rel)) {
     
    4141            }
    4242        }
    43         inside = NodeWayUtils.selectAllInside(matchedAreas, Main.getLayerManager().getEditDataSet(), false);
     43        inside = NodeWayUtils.selectAllInside(matchedAreas, MainApplication.getLayerManager().getEditDataSet(), false);
    4444    }
    4545
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/search/IntersectingMatch.java

    r33522 r33579  
    66import java.util.Set;
    77
    8 import org.openstreetmap.josm.Main;
    98import org.openstreetmap.josm.data.osm.OsmPrimitive;
    109import org.openstreetmap.josm.data.osm.Way;
    1110import org.openstreetmap.josm.data.osm.search.SearchCompiler;
     11import org.openstreetmap.josm.gui.MainApplication;
    1212import org.openstreetmap.josm.plugins.utilsplugin2.selection.NodeWayUtils;
    1313
     
    3131        Collection<Way> matchedWays = new HashSet<>();
    3232        // find all ways that match the expression
    33         Collection<Way> allWays = Main.getLayerManager().getEditDataSet().getWays();
     33        Collection<Way> allWays = MainApplication.getLayerManager().getEditDataSet().getWays();
    3434        for (Way way : allWays) {
    3535            if (match.match(way)) {
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectBoundaryAction.java

    r33297 r33579  
    1414import javax.swing.JOptionPane;
    1515
    16 import org.openstreetmap.josm.Main;
    1716import org.openstreetmap.josm.actions.JosmAction;
    1817import org.openstreetmap.josm.actions.SelectByInternalPointAction;
     
    2120import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2221import org.openstreetmap.josm.data.osm.Way;
     22import org.openstreetmap.josm.gui.MainApplication;
    2323import org.openstreetmap.josm.gui.Notification;
    2424import org.openstreetmap.josm.tools.Shortcut;
     
    5858                    }
    5959                } else {
    60                     Point p = Main.map.mapView.getMousePosition();
    61                     SelectByInternalPointAction.performSelection(Main.map.mapView.getEastNorth(p.x, p.y), false, false);
     60                    Point p = MainApplication.getMap().mapView.getMousePosition();
     61                    SelectByInternalPointAction.performSelection(MainApplication.getMap().mapView.getEastNorth(p.x, p.y), false, false);
    6262                    return;
    6363                }
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModNodesAction.java

    r33297 r33579  
    1111import java.util.Set;
    1212
    13 import org.openstreetmap.josm.Main;
    1413import org.openstreetmap.josm.actions.JosmAction;
    1514import org.openstreetmap.josm.command.Command;
     
    1716import org.openstreetmap.josm.data.osm.Node;
    1817import org.openstreetmap.josm.data.osm.OsmPrimitive;
     18import org.openstreetmap.josm.gui.MainApplication;
    1919import org.openstreetmap.josm.tools.Shortcut;
    2020
     
    4242            Command cmd = null;
    4343
    44             if (Main.main.undoRedo.commands == null) return;
    45             int num = Main.main.undoRedo.commands.size();
     44            if (MainApplication.undoRedo.commands == null) return;
     45            int num = MainApplication.undoRedo.commands.size();
    4646            if (num == 0) return;
    4747            int k = 0, idx;
    4848            if (selection != null && !selection.isEmpty() && selection.hashCode() == lastHash) {
    4949                // we are selecting next command in history if nothing is selected
    50                 idx = Main.main.undoRedo.commands.indexOf(lastCmd);
     50                idx = MainApplication.undoRedo.commands.indexOf(lastCmd);
    5151            } else {
    5252                idx = num;
     
    5656            do {  //  select next history element
    5757                if (idx > 0) idx--; else idx = num-1;
    58                 cmd = Main.main.undoRedo.commands.get(idx);
     58                cmd = MainApplication.undoRedo.commands.get(idx);
    5959                Collection<? extends OsmPrimitive> pp = cmd.getParticipatingPrimitives();
    6060                nodes.clear();
  • applications/editors/josm/plugins/utilsplugin2/src/org/openstreetmap/josm/plugins/utilsplugin2/selection/SelectModWaysAction.java

    r33297 r33579  
    1111import java.util.Set;
    1212
    13 import org.openstreetmap.josm.Main;
    1413import org.openstreetmap.josm.actions.JosmAction;
    1514import org.openstreetmap.josm.command.Command;
     
    1817import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1918import org.openstreetmap.josm.data.osm.Way;
     19import org.openstreetmap.josm.gui.MainApplication;
    2020import org.openstreetmap.josm.tools.Shortcut;
    2121
     
    4343            Command cmd;
    4444
    45             if (Main.main.undoRedo.commands == null) return;
    46             int num = Main.main.undoRedo.commands.size();
     45            if (MainApplication.undoRedo.commands == null) return;
     46            int num = MainApplication.undoRedo.commands.size();
    4747            if (num == 0) return;
    4848            int k = 0, idx;
    4949            if (selection != null && !selection.isEmpty() && selection.hashCode() == lastHash) {
    5050                // we are selecting next command in history if nothing is selected
    51                 idx = Main.main.undoRedo.commands.indexOf(lastCmd);
     51                idx = MainApplication.undoRedo.commands.indexOf(lastCmd);
    5252            } else {
    5353                idx = num;
     
    5757            do {  //  select next history element
    5858                if (idx > 0) idx--; else idx = num-1;
    59                 cmd = Main.main.undoRedo.commands.get(idx);
     59                cmd = MainApplication.undoRedo.commands.get(idx);
    6060                Collection<? extends OsmPrimitive> pp = cmd.getParticipatingPrimitives();
    6161                ways.clear();
Note: See TracChangeset for help on using the changeset viewer.