Search in sources :

Example 1 with Relation

use of org.openstreetmap.josm.data.osm.Relation in project josm by JOSM.

the class SplitWayCommand method analyseSplit.

static Analysis analyseSplit(Way way, Way wayToKeep, List<Way> newWays) {
    Collection<Command> commandList = new ArrayList<>();
    Collection<String> nowarnroles = Config.getPref().getList("way.split.roles.nowarn", Arrays.asList("outer", "inner", "forward", "backward", "north", "south", "east", "west"));
    // Change the original way
    final List<Node> changedWayNodes = wayToKeep.getNodes();
    commandList.add(new ChangeNodesCommand(way, changedWayNodes));
    for (Way wayToAdd : newWays) {
        commandList.add(new AddCommand(way.getDataSet(), wayToAdd));
    }
    List<RelationAnalysis> relationAnalyses = new ArrayList<>();
    EnumSet<WarningType> warnings = EnumSet.noneOf(WarningType.class);
    int numberOfRelations = 0;
    for (Relation r : OsmPrimitive.getParentRelations(Collections.singleton(way))) {
        if (!r.isUsable()) {
            continue;
        }
        numberOfRelations++;
        boolean isSimpleCase = true;
        Relation c = null;
        String type = Optional.ofNullable(r.get("type")).orElse("");
        // Known types of ordered relations.
        boolean isOrderedRelation = "route".equals(type) || "multipolygon".equals(type) || "boundary".equals(type);
        for (int ir = 0; ir < r.getMembersCount(); ir++) {
            RelationMember rm = r.getMember(ir);
            if (rm.getMember() == way) {
                boolean insert = true;
                if (relationSpecialTypes.containsKey(type) && "restriction".equals(relationSpecialTypes.get(type))) {
                    RelationInformation rValue = treatAsRestriction(r, rm, c, newWays, way, changedWayNodes);
                    if (rValue.warnme)
                        warnings.add(WarningType.GENERIC);
                    insert = rValue.insert;
                    // Value.relation is null or contains a modified copy
                    c = rValue.relation;
                } else if (!isOrderedRelation) {
                    // Warn the user when relations that are not a route or multipolygon are modified as a result
                    // of splitting up the way, because we can't tell if this might break anything.
                    warnings.add(WarningType.GENERIC);
                }
                if (insert) {
                    if (c == null) {
                        c = new Relation(r);
                    }
                    if (rm.hasRole() && !nowarnroles.contains(rm.getRole())) {
                        warnings.add(WarningType.ROLE);
                    }
                    // Attempt to determine the direction the ways in the relation are ordered.
                    Direction direction = Direction.UNKNOWN;
                    Set<Way> missingWays = new HashSet<>();
                    if (isOrderedRelation) {
                        if (way.lastNode() == way.firstNode()) {
                            // Self-closing way.
                            direction = Direction.IRRELEVANT;
                        } else {
                            // and can even cause the wrong direction to be guessed (with closed loops).
                            if (ir - 1 >= 0 && r.getMember(ir - 1).isWay()) {
                                Way w = r.getMember(ir - 1).getWay();
                                if (w.isIncomplete())
                                    missingWays.add(w);
                                else {
                                    if (w.lastNode() == way.firstNode() || w.firstNode() == way.firstNode()) {
                                        direction = Direction.FORWARDS;
                                    } else if (w.firstNode() == way.lastNode() || w.lastNode() == way.lastNode()) {
                                        direction = Direction.BACKWARDS;
                                    }
                                }
                            }
                            if (ir + 1 < r.getMembersCount() && r.getMember(ir + 1).isWay()) {
                                Way w = r.getMember(ir + 1).getWay();
                                if (w.isIncomplete())
                                    missingWays.add(w);
                                else {
                                    if (w.lastNode() == way.firstNode() || w.firstNode() == way.firstNode()) {
                                        direction = Direction.BACKWARDS;
                                    } else if (w.firstNode() == way.lastNode() || w.lastNode() == way.lastNode()) {
                                        direction = Direction.FORWARDS;
                                    }
                                }
                            }
                            if (direction == Direction.UNKNOWN && missingWays.isEmpty()) {
                                // we cannot detect the direction and no way is missing.
                                // We can safely assume that the direction doesn't matter.
                                direction = Direction.IRRELEVANT;
                            }
                        }
                    } else {
                        int k = 1;
                        while (ir - k >= 0 || ir + k < r.getMembersCount()) {
                            if (ir - k >= 0 && r.getMember(ir - k).isWay()) {
                                Way w = r.getMember(ir - k).getWay();
                                if (w.lastNode() == way.firstNode() || w.firstNode() == way.firstNode()) {
                                    direction = Direction.FORWARDS;
                                } else if (w.firstNode() == way.lastNode() || w.lastNode() == way.lastNode()) {
                                    direction = Direction.BACKWARDS;
                                }
                                break;
                            }
                            if (ir + k < r.getMembersCount() && r.getMember(ir + k).isWay()) {
                                Way w = r.getMember(ir + k).getWay();
                                if (w.lastNode() == way.firstNode() || w.firstNode() == way.firstNode()) {
                                    direction = Direction.BACKWARDS;
                                } else if (w.firstNode() == way.lastNode() || w.lastNode() == way.lastNode()) {
                                    direction = Direction.FORWARDS;
                                }
                                break;
                            }
                            k++;
                        }
                    }
                    if (direction == Direction.UNKNOWN) {
                    // We don't have enough information to determine the order of the new ways in this relation.
                    // This may cause relations to be saved with the two new way sections in reverse order.
                    // 
                    // This often breaks routes.
                    // 
                    } else {
                        missingWays = Collections.emptySet();
                    }
                    relationAnalyses.add(new RelationAnalysis(c, rm, direction, missingWays));
                    isSimpleCase = false;
                }
            }
        }
        if (c != null && isSimpleCase) {
            if (!r.getMembers().equals(c.getMembers())) {
                commandList.add(new ChangeMembersCommand(r, new ArrayList<>(c.getMembers())));
            }
            // see #19885
            c.setMembers(null);
        }
    }
    return new Analysis(relationAnalyses, commandList, warnings, numberOfRelations);
}
Also used : Node(org.openstreetmap.josm.data.osm.Node) ArrayList(java.util.ArrayList) Way(org.openstreetmap.josm.data.osm.Way) Relation(org.openstreetmap.josm.data.osm.Relation) RelationMember(org.openstreetmap.josm.data.osm.RelationMember) HashSet(java.util.HashSet)

Example 2 with Relation

use of org.openstreetmap.josm.data.osm.Relation in project josm by JOSM.

the class ConflictResolver method buildResolveCommand.

/**
 * Builds the resolution command(s) for the resolved conflicts in this ConflictResolver
 *
 * @return the resolution command
 */
public Command buildResolveCommand() {
    List<Command> commands = new ArrayList<>();
    if (tagMerger.getModel().getNumResolvedConflicts() > 0) {
        commands.add(tagMerger.getModel().buildResolveCommand(conflict));
    }
    commands.addAll(propertiesMerger.getModel().buildResolveCommand(conflict));
    if (my instanceof Way && nodeListMerger.getModel().isFrozen()) {
        commands.add(nodeListMerger.getModel().buildResolveCommand(conflict));
    } else if (my instanceof Relation && relationMemberMerger.getModel().isFrozen()) {
        commands.add(relationMemberMerger.getModel().buildResolveCommand(conflict));
    }
    if (isResolvedCompletely()) {
        commands.add(new VersionConflictResolveCommand(conflict));
        commands.add(new ModifiedConflictResolveCommand(conflict));
    }
    return new SequenceCommand(tr("Conflict Resolution"), commands);
}
Also used : Relation(org.openstreetmap.josm.data.osm.Relation) ModifiedConflictResolveCommand(org.openstreetmap.josm.command.conflict.ModifiedConflictResolveCommand) ModifiedConflictResolveCommand(org.openstreetmap.josm.command.conflict.ModifiedConflictResolveCommand) Command(org.openstreetmap.josm.command.Command) VersionConflictResolveCommand(org.openstreetmap.josm.command.conflict.VersionConflictResolveCommand) SequenceCommand(org.openstreetmap.josm.command.SequenceCommand) SequenceCommand(org.openstreetmap.josm.command.SequenceCommand) VersionConflictResolveCommand(org.openstreetmap.josm.command.conflict.VersionConflictResolveCommand) ArrayList(java.util.ArrayList) Way(org.openstreetmap.josm.data.osm.Way)

Example 3 with Relation

use of org.openstreetmap.josm.data.osm.Relation in project josm by JOSM.

the class PropertiesDialog method editMembership.

/**
 * This simply fires up an {@link RelationEditor} for the relation shown; everything else
 * is the editor's business.
 *
 * @param row position
 */
private void editMembership(int row) {
    Relation relation = (Relation) membershipData.getValueAt(row, 0);
    MainApplication.getMap().relationListDialog.selectRelation(relation);
    OsmDataLayer layer = MainApplication.getLayerManager().getActiveDataLayer();
    if (!layer.isLocked()) {
        List<RelationMember> members = ((MemberInfo) membershipData.getValueAt(row, 1)).role.stream().filter(rm -> rm instanceof RelationMember).map(rm -> (RelationMember) rm).collect(Collectors.toList());
        RelationEditor.getEditor(layer, relation, members).setVisible(true);
    }
}
Also used : Arrays(java.util.Arrays) EditRelationAction(org.openstreetmap.josm.actions.relation.EditRelationAction) ExtendedDialog(org.openstreetmap.josm.gui.ExtendedDialog) TableCellRenderer(javax.swing.table.TableCellRenderer) DeleteRelationsAction(org.openstreetmap.josm.actions.relation.DeleteRelationsAction) DataSelectionListener(org.openstreetmap.josm.data.osm.DataSelectionListener) FireMode(org.openstreetmap.josm.data.osm.event.DatasetEventManager.FireMode) JosmTextField(org.openstreetmap.josm.gui.widgets.JosmTextField) Territories(org.openstreetmap.josm.tools.Territories) Map(java.util.Map) FilterField(org.openstreetmap.josm.gui.widgets.FilterField) Relation(org.openstreetmap.josm.data.osm.Relation) EnumSet(java.util.EnumSet) KeyStroke(javax.swing.KeyStroke) ChangePropertyCommand(org.openstreetmap.josm.command.ChangePropertyCommand) AlphanumComparator(org.openstreetmap.josm.tools.AlphanumComparator) Set(java.util.Set) Utils(org.openstreetmap.josm.tools.Utils) KeyEvent(java.awt.event.KeyEvent) Component(java.awt.Component) TableRowSorter(javax.swing.table.TableRowSorter) SideButton(org.openstreetmap.josm.gui.SideButton) HighlightHelper(org.openstreetmap.josm.gui.util.HighlightHelper) DefaultTableCellRenderer(javax.swing.table.DefaultTableCellRenderer) AbstractAction(javax.swing.AbstractAction) DataSetListenerAdapter(org.openstreetmap.josm.data.osm.event.DataSetListenerAdapter) InputMapUtils(org.openstreetmap.josm.tools.InputMapUtils) TaginfoRegionalInstance(org.openstreetmap.josm.tools.TaginfoRegionalInstance) SearchCompiler(org.openstreetmap.josm.data.osm.search.SearchCompiler) GridBagLayout(java.awt.GridBagLayout) RowSorterEvent(javax.swing.event.RowSorterEvent) IRelation(org.openstreetmap.josm.data.osm.IRelation) JPanel(javax.swing.JPanel) ListSelectionModel(javax.swing.ListSelectionModel) TableColumnModel(javax.swing.table.TableColumnModel) Way(org.openstreetmap.josm.data.osm.Way) MainApplication(org.openstreetmap.josm.gui.MainApplication) Shortcut(org.openstreetmap.josm.tools.Shortcut) DatasetEventManager(org.openstreetmap.josm.data.osm.event.DatasetEventManager) Logging(org.openstreetmap.josm.tools.Logging) IRelationMember(org.openstreetmap.josm.data.osm.IRelationMember) TaggingPresetHandler(org.openstreetmap.josm.gui.tagging.presets.TaggingPresetHandler) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) LatLon(org.openstreetmap.josm.data.coor.LatLon) ConditionalOptionPaneUtil(org.openstreetmap.josm.gui.ConditionalOptionPaneUtil) Container(java.awt.Container) DefaultNameFormatter(org.openstreetmap.josm.data.osm.DefaultNameFormatter) PreferenceChangeEvent(org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent) ToggleDialog(org.openstreetmap.josm.gui.dialogs.ToggleDialog) SearchSetting(org.openstreetmap.josm.data.osm.search.SearchSetting) RowSorterListener(javax.swing.event.RowSorterListener) Node(org.openstreetmap.josm.data.osm.Node) ActiveLayerChangeEvent(org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent) MouseEvent(java.awt.event.MouseEvent) JScrollPane(javax.swing.JScrollPane) TreeMap(java.util.TreeMap) Tags(org.openstreetmap.josm.data.osm.Tags) TaggingPresetListener(org.openstreetmap.josm.gui.tagging.presets.TaggingPresetListener) PopupMenuLauncher(org.openstreetmap.josm.gui.widgets.PopupMenuLauncher) DisableShortcutsOnFocusGainedTextField(org.openstreetmap.josm.gui.widgets.DisableShortcutsOnFocusGainedTextField) OsmData(org.openstreetmap.josm.data.osm.OsmData) ListSelectionListener(javax.swing.event.ListSelectionListener) TaggingPreset(org.openstreetmap.josm.gui.tagging.presets.TaggingPreset) GBC(org.openstreetmap.josm.tools.GBC) Point(java.awt.Point) HelpUtil(org.openstreetmap.josm.gui.help.HelpUtil) RelationPopupMenus(org.openstreetmap.josm.gui.dialogs.relation.RelationPopupMenus) CompileSearchTextDecorator(org.openstreetmap.josm.gui.widgets.CompileSearchTextDecorator) JosmAction(org.openstreetmap.josm.actions.JosmAction) TaggingPresetType(org.openstreetmap.josm.gui.tagging.presets.TaggingPresetType) AbstractTag2LinkPopupListener(org.openstreetmap.josm.gui.util.AbstractTag2LinkPopupListener) MouseAdapter(java.awt.event.MouseAdapter) RelationEditor(org.openstreetmap.josm.gui.dialogs.relation.RelationEditor) ListSelectionEvent(javax.swing.event.ListSelectionEvent) TableModel(javax.swing.table.TableModel) DefaultTableModel(javax.swing.table.DefaultTableModel) TaggingPresets(org.openstreetmap.josm.gui.tagging.presets.TaggingPresets) Font(java.awt.Font) Collection(java.util.Collection) TableHelper(org.openstreetmap.josm.gui.util.TableHelper) DataSet(org.openstreetmap.josm.data.osm.DataSet) ChangeMembersCommand(org.openstreetmap.josm.command.ChangeMembersCommand) Collectors(java.util.stream.Collectors) ClipboardUtils(org.openstreetmap.josm.gui.datatransfer.ClipboardUtils) AbstractPrimitive(org.openstreetmap.josm.data.osm.AbstractPrimitive) List(java.util.List) PopupMenuEvent(javax.swing.event.PopupMenuEvent) ActiveLayerChangeListener(org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener) Entry(java.util.Map.Entry) JTable(javax.swing.JTable) OsmDataManager(org.openstreetmap.josm.data.osm.OsmDataManager) OsmDataLayer(org.openstreetmap.josm.gui.layer.OsmDataLayer) I18n.tr(org.openstreetmap.josm.tools.I18n.tr) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) RelationMember(org.openstreetmap.josm.data.osm.RelationMember) ImageProvider(org.openstreetmap.josm.tools.ImageProvider) Config(org.openstreetmap.josm.spi.preferences.Config) HashSet(java.util.HashSet) KeyValueVisitor(org.openstreetmap.josm.data.osm.KeyValueVisitor) JMenuItem(javax.swing.JMenuItem) UndoRedoHandler(org.openstreetmap.josm.data.UndoRedoHandler) IPrimitive(org.openstreetmap.josm.data.osm.IPrimitive) Command(org.openstreetmap.josm.command.Command) JComponent(javax.swing.JComponent) OsmPrimitive(org.openstreetmap.josm.data.osm.OsmPrimitive) JPopupMenu(javax.swing.JPopupMenu) DuplicateRelationAction(org.openstreetmap.josm.actions.relation.DuplicateRelationAction) ActionEvent(java.awt.event.ActionEvent) JLabel(javax.swing.JLabel) PopupMenuHandler(org.openstreetmap.josm.gui.PopupMenuHandler) AbstractDatasetChangedEvent(org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent) BooleanProperty(org.openstreetmap.josm.data.preferences.BooleanProperty) Collections(java.util.Collections) Tag(org.openstreetmap.josm.data.osm.Tag) SelectionEventManager(org.openstreetmap.josm.data.osm.event.SelectionEventManager) Relation(org.openstreetmap.josm.data.osm.Relation) IRelation(org.openstreetmap.josm.data.osm.IRelation) IRelationMember(org.openstreetmap.josm.data.osm.IRelationMember) RelationMember(org.openstreetmap.josm.data.osm.RelationMember) OsmDataLayer(org.openstreetmap.josm.gui.layer.OsmDataLayer)

Example 4 with Relation

use of org.openstreetmap.josm.data.osm.Relation in project josm by JOSM.

the class PropertiesDialog method createSearchSetting.

static SearchSetting createSearchSetting(String key, Collection<? extends IPrimitive> sel, boolean sameType) {
    String sep = "";
    StringBuilder s = new StringBuilder();
    Set<String> consideredTokens = new TreeSet<>();
    for (IPrimitive p : sel) {
        String val = p.get(key);
        if (val == null || (!sameType && consideredTokens.contains(val))) {
            continue;
        }
        String t = "";
        if (!sameType) {
            t = "";
        } else if (p instanceof Node) {
            t = "type:node ";
        } else if (p instanceof Way) {
            t = "type:way ";
        } else if (p instanceof Relation) {
            t = "type:relation ";
        }
        String token = new StringBuilder(t).append(val).toString();
        if (consideredTokens.add(token)) {
            s.append(sep).append('(').append(t).append(SearchCompiler.buildSearchStringForTag(key, val)).append(')');
            sep = " OR ";
        }
    }
    final SearchSetting ss = new SearchSetting();
    ss.text = s.toString();
    ss.caseSensitive = true;
    return ss;
}
Also used : Relation(org.openstreetmap.josm.data.osm.Relation) IRelation(org.openstreetmap.josm.data.osm.IRelation) TreeSet(java.util.TreeSet) Node(org.openstreetmap.josm.data.osm.Node) IPrimitive(org.openstreetmap.josm.data.osm.IPrimitive) Way(org.openstreetmap.josm.data.osm.Way) SearchSetting(org.openstreetmap.josm.data.osm.search.SearchSetting)

Example 5 with Relation

use of org.openstreetmap.josm.data.osm.Relation in project josm by JOSM.

the class GenericRelationEditor method addPrimitivesToRelation.

/**
 * Adds primitives to a given relation.
 * @param orig The relation to modify
 * @param primitivesToAdd The primitives to add as relation members
 * @return The resulting command
 * @throws IllegalArgumentException if orig is null
 */
public static Command addPrimitivesToRelation(final Relation orig, Collection<? extends OsmPrimitive> primitivesToAdd) {
    CheckParameterUtil.ensureParameterNotNull(orig, "orig");
    try {
        final Collection<TaggingPreset> presets = TaggingPresets.getMatchingPresets(EnumSet.of(TaggingPresetType.forPrimitive(orig)), orig.getKeys(), false);
        Relation target = new Relation(orig);
        boolean modified = false;
        for (OsmPrimitive p : primitivesToAdd) {
            if (p instanceof Relation) {
                List<Relation> loop = RelationChecker.checkAddMember(target, (Relation) p);
                if (!loop.isEmpty() && loop.get(0).equals(loop.get(loop.size() - 1))) {
                    warnOfCircularReferences(p, loop);
                    continue;
                }
            } else if (MemberTableModel.hasMembersReferringTo(target.getMembers(), Collections.singleton(p)) && !confirmAddingPrimitive(p)) {
                continue;
            }
            final Set<String> roles = findSuggestedRoles(presets, p);
            target.addMember(new RelationMember(roles.size() == 1 ? roles.iterator().next() : "", p));
            modified = true;
        }
        List<RelationMember> members = new ArrayList<>(target.getMembers());
        // see #19885
        target.setMembers(null);
        return modified ? new ChangeMembersCommand(orig, members) : null;
    } catch (AddAbortException ign) {
        Logging.trace(ign);
        return null;
    }
}
Also used : ChangeMembersCommand(org.openstreetmap.josm.command.ChangeMembersCommand) ArrayList(java.util.ArrayList) Relation(org.openstreetmap.josm.data.osm.Relation) RelationMember(org.openstreetmap.josm.data.osm.RelationMember) OsmPrimitive(org.openstreetmap.josm.data.osm.OsmPrimitive) TaggingPreset(org.openstreetmap.josm.gui.tagging.presets.TaggingPreset)

Aggregations

Relation (org.openstreetmap.josm.data.osm.Relation)494 Test (org.junit.jupiter.api.Test)267 RelationMember (org.openstreetmap.josm.data.osm.RelationMember)218 Way (org.openstreetmap.josm.data.osm.Way)216 Node (org.openstreetmap.josm.data.osm.Node)186 DataSet (org.openstreetmap.josm.data.osm.DataSet)166 OsmPrimitive (org.openstreetmap.josm.data.osm.OsmPrimitive)160 ArrayList (java.util.ArrayList)107 List (java.util.List)57 Collection (java.util.Collection)55 LatLon (org.openstreetmap.josm.data.coor.LatLon)50 HashSet (java.util.HashSet)47 Collectors (java.util.stream.Collectors)43 TestError (org.openstreetmap.josm.data.validation.TestError)43 Map (java.util.Map)42 OsmDataLayer (org.openstreetmap.josm.gui.layer.OsmDataLayer)42 Command (org.openstreetmap.josm.command.Command)41 Collections (java.util.Collections)39 I18n.tr (org.openstreetmap.josm.tools.I18n.tr)39 SequenceCommand (org.openstreetmap.josm.command.SequenceCommand)37