/* * Indoorhelper is a JOSM plug-in to support users when creating their own indoor maps. * Copyright (C) 2016 Erik Gruschka * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package model; import java.util.ArrayList; import java.util.List; import javax.swing.JOptionPane; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.command.ChangePropertyCommand; import org.openstreetmap.josm.data.osm.Filter; import org.openstreetmap.josm.data.osm.Filter.FilterPreferenceEntry; import org.openstreetmap.josm.data.osm.Tag; import org.openstreetmap.josm.gui.dialogs.FilterDialog; import org.openstreetmap.josm.gui.dialogs.FilterTableModel; import model.TagCatalog.IndoorObject; /** * Class for the data model which includes indoor data and * the functions to handle the plug-in * * @author egru */ public class IndoorHelperModel { private java.util.List<IndoorLevel> levelList; private int workingLevel; private int workingIndex; private TagCatalog tags; private PresetCounter counter; /** * Constructor for the {@link IndoorHelperModel} which sets the current * workingLevel to 0 and creates the {@link TagCatalog}. */ public IndoorHelperModel() { this.workingLevel = 0; this.levelList = new ArrayList<>(); this.tags = new TagCatalog(); this.counter = new PresetCounter(); } /** * Method to create a list of levels for the current building. * It also creates the filters which are needed to execute the indoor mapping. * minLevel should be lower than maxLevel or the same. * * @param minLevel the lowest level of the building * @param maxLevel the highest level of the building * @return boolean which indicates if the creation of the levelList was successful */ public boolean setBuildingLevels(int minLevel, int maxLevel) { if (minLevel < maxLevel) { for (int i = minLevel; i <= maxLevel; i++) { IndoorLevel level = new IndoorLevel(i); levelList.add(level); // Get the filter dialog FilterDialog filterDialog = Main.map.getToggleDialog(FilterDialog.class); if (filterDialog != null) { // Create a new filter //Filter filter = new Filter("\"indoor:level\"=\""+i+"\"", SearchMode.add, false, false, false); FilterPreferenceEntry entry = new FilterPreferenceEntry(); entry.case_sensitive = false; entry.enable = false; entry.hiding = false; entry.inverted = false; entry.mapCSS_search = false; entry.mode = "add"; entry.text = "\"indoor:level\"=\""+i+"\""; Filter filter = new Filter(entry); FilterTableModel filterTableModel = filterDialog.getFilterModel(); boolean exists = false; // Search if the filter exists already. for (Filter listFilter : filterTableModel.getFilters()) { if (listFilter.equals(filter)) { exists = true; } } // Only add the filter if it is not already in the filter dialog. if (exists == false) { filterTableModel.addFilter(filter); } } else { //Show error message if filter dialog is null. JOptionPane.showMessageDialog(null, "Filter Dialog is null.", "Error", JOptionPane.ERROR_MESSAGE); } } return true; } else if (minLevel == maxLevel) { IndoorLevel level = new IndoorLevel(minLevel); levelList.add(level); // Get the filter dialog FilterDialog filterDialog = Main.map.getToggleDialog(FilterDialog.class); if (filterDialog != null) { // Create a new filter //Filter filter = new Filter("\"indoor:level\"=\""+minLevel+"\"", SearchMode.add, false, false, false); FilterPreferenceEntry entry = new FilterPreferenceEntry(); entry.case_sensitive = false; entry.enable = false; entry.hiding = false; entry.inverted = false; entry.mapCSS_search = false; entry.mode = "add"; entry.text = "\"indoor:level\"=\""+minLevel+"\""; Filter filter = new Filter(entry); FilterTableModel filterTableModel = filterDialog.getFilterModel(); boolean exists = false; // Search if the filter exists already. for (Filter listFilter : filterTableModel.getFilters()) { if (listFilter.equals(filter)) { exists = true; } } // Only add the filter if it is not already in the filter dialog. if (exists == false) { filterTableModel.addFilter(filter); } } else { JOptionPane.showMessageDialog(null, "Filter Dialog is null.", "Error", JOptionPane.ERROR_MESSAGE); } return true; } return false; } /** * Getter for the levelList of the model. * * @return the levelList, or null if no levelList was created yet */ public java.util.List<IndoorLevel> getLevelList() { return this.levelList; } /** * Function to set the level the user wants to work on (with the level index) and activates the corresponding filter. * * @param index the index of the level the user wants to work on */ public void setWorkingLevel(int index) { this.workingIndex = index; this.workingLevel = this.getLevelNumberFromIndex(index); FilterDialog filterDialog = Main.map.getToggleDialog(FilterDialog.class); FilterTableModel filterTableModel = filterDialog.getFilterModel(); for (Filter filter : filterTableModel.getFilters()) { // disable the filter for the current level if (filter.text.equals("\"indoor:level\"=\""+workingLevel+"\"")) { filterTableModel.setValueAt(false, filterTableModel.getFilters().indexOf(filter), FilterTableModel.COL_ENABLED); filterTableModel.setValueAt(false, filterTableModel.getFilters().indexOf(filter), FilterTableModel.COL_HIDING); } else if (filter.text.startsWith("\"indoor:level\"=\"")) { filterTableModel.setValueAt(true, filterTableModel.getFilters().indexOf(filter), FilterTableModel.COL_ENABLED); filterTableModel.setValueAt(true, filterTableModel.getFilters().indexOf(filter), FilterTableModel.COL_HIDING); } } } /** * Function to get the current working level of the plug-in * * @return {@link Integer} which represents the current working level */ public int getWorkingLevel() { return this.workingLevel; } /** * Method to get the index of the current working level of the plug-in. * * @return {@link Integer} which represents the index */ public int getWorkingIndex() { return this.workingIndex; } /** * Returns the level number which is corresponding to a specific index. * * @param index index of the level * @return a level number as an {@link Integer} */ public int getLevelNumberFromIndex(int index) { return levelList.get(index).getLevelNumber(); } /** * Function to set the nameTag of a specific level. * * @param levelNumber number of the level * @param levelName tag which the user wants to set * @return boolean which indicates if the level was found in the levelList */ public void setLevelName(int levelIndex, String levelName) { if ((levelName.length() > 0) && (levelName != null)) { levelList.get(levelIndex).setNameTag(levelName); } } /** * Function to get a tag-set out of the {@link TagCatalog}. * * @param object the {@link IndoorObject} from which you want to get the tag-set * @return a {@link List} of {@link Tag}s */ public List<Tag> getObjectTags(TagCatalog.IndoorObject object) { return this.tags.getTags(object); } /** * Method which adds the selected tag-set to the currently selected OSM data. * It also adds the level tag corresponding to the current working level. * * @param object the object which defines the tag-set you want to add * @param userTags the tags which are given by the user input */ public void addTagsToOSM(IndoorObject object, List<Tag> userTags) { if (!Main.getLayerManager().getEditDataSet().selectionEmpty() && !Main.main.getInProgressSelection().isEmpty()) { List<Tag> tags = this.getObjectTags(object); tags.addAll(userTags); tags.add(new Tag("indoor:level", Integer.toString(workingLevel))); if (!this.getLevelList().get(workingIndex).hasEmptyName()) { tags.add(this.getLevelList().get(workingIndex).getNameTag()); } // Increment the counter for the presets this.counter.count(object); //Add the tags to the current selection for (Tag t : tags) { Main.main.undoRedo.add(new ChangePropertyCommand(Main.main.getInProgressSelection(), t.getKey(), t.getValue())); } } else if (Main.getLayerManager().getEditDataSet().selectionEmpty()) { JOptionPane.showMessageDialog(null, "No data selected.", "Error", JOptionPane.ERROR_MESSAGE); } } /** * Method which adds the selected tag-set to the currently selected OSM data. * It also adds the level tag corresponding to the current working level. * * @param object the object which defines the tag-set you want to add */ public void addTagsToOSM(IndoorObject object) { if (!Main.getLayerManager().getEditDataSet().selectionEmpty() && !Main.main.getInProgressSelection().isEmpty()) { List<Tag> tags = this.getObjectTags(object); tags.add(new Tag("indoor:level", Integer.toString(workingLevel))); // Increment the counter for the presets this.counter.count(object); //Add the tags to the current selection for (Tag t : tags) { Main.main.undoRedo.add(new ChangePropertyCommand(Main.main.getInProgressSelection(), t.getKey(), t.getValue())); } } else if (Main.getLayerManager().getEditDataSet().selectionEmpty()) { JOptionPane.showMessageDialog(null, "No data selected.", "Error", JOptionPane.ERROR_MESSAGE); } } /** * Returns the current ranking of the preset counter, which includes the 4 most used items. * * @return a list of the 4 most used IndoorObjects */ public List<IndoorObject> getPresetRanking() { return counter.getRanking(); } }