Search in sources :

Example 1 with Node

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

the class AddNodeAction method actionPerformed.

@Override
public void actionPerformed(ActionEvent e) {
    if (!isEnabled())
        return;
    // #17682 - Run the action later in EDT to make sure the KeyEvent triggering it is consumed before the dialog is shown
    SwingUtilities.invokeLater(() -> {
        LatLonDialog dialog = new LatLonDialog(MainApplication.getMainFrame(), tr("Add Node..."), ht("/Action/AddNode"));
        if (textLatLon != null) {
            dialog.setLatLonText(textLatLon);
        }
        if (textEastNorth != null) {
            dialog.setEastNorthText(textEastNorth);
        }
        dialog.showDialog();
        if (dialog.getValue() != 1)
            return;
        LatLon coordinates = dialog.getCoordinates();
        if (coordinates == null)
            return;
        textLatLon = dialog.getLatLonText();
        textEastNorth = dialog.getEastNorthText();
        Node nnew = new Node(coordinates);
        // add the node
        DataSet ds = getLayerManager().getEditDataSet();
        UndoRedoHandler.getInstance().add(new AddCommand(ds, nnew));
        ds.setSelected(nnew);
        MapView mapView = MainApplication.getMap().mapView;
        if (mapView != null && !mapView.getRealBounds().contains(nnew.getCoor())) {
            AutoScaleAction.zoomTo(Collections.<OsmPrimitive>singleton(nnew));
        }
    });
}
Also used : LatLon(org.openstreetmap.josm.data.coor.LatLon) DataSet(org.openstreetmap.josm.data.osm.DataSet) Node(org.openstreetmap.josm.data.osm.Node) MapView(org.openstreetmap.josm.gui.MapView) LatLonDialog(org.openstreetmap.josm.gui.dialogs.LatLonDialog) AddCommand(org.openstreetmap.josm.command.AddCommand)

Example 2 with Node

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

the class AlignInLineAction method getInvolvedLines.

/**
 * Get lines useful to do alignment of a single node
 * @param node Node to be aligned
 * @param refWays Ways where useful lines will be searched
 * @return List of useful lines
 * @throws InvalidSelection if a node got more than 4 neighbours (self-crossing way)
 */
private static List<Line> getInvolvedLines(Node node, List<Way> refWays) throws InvalidSelection {
    List<Line> lines = new ArrayList<>();
    List<Node> neighbors = new ArrayList<>();
    for (Way way : refWays) {
        List<Node> nodes = way.getNodes();
        neighbors.clear();
        for (int i = 1; i < nodes.size() - 1; i++) {
            if (nodes.get(i) == node) {
                neighbors.add(nodes.get(i - 1));
                neighbors.add(nodes.get(i + 1));
            }
        }
        if (neighbors.isEmpty())
            continue;
        else if (neighbors.size() == 2)
            // Non self crossing
            lines.add(new Line(neighbors.get(0), neighbors.get(1)));
        else if (neighbors.size() == 4) {
            // Self crossing, have to make 2 lines with 4 neighbors
            // see #9081 comment 6
            EastNorth c = node.getEastNorth();
            double[] angle = IntStream.range(0, 4).mapToDouble(i -> PolarCoor.computeAngle(neighbors.get(i).getEastNorth(), c)).toArray();
            double[] deltaAngle = new double[3];
            for (int i = 0; i < 3; i++) {
                deltaAngle[i] = angle[i + 1] - angle[0];
                if (deltaAngle[i] < 0)
                    deltaAngle[i] += 2 * Math.PI;
            }
            int nb = 0;
            if (deltaAngle[1] < deltaAngle[0])
                nb++;
            if (deltaAngle[2] < deltaAngle[0])
                nb++;
            if (nb == 1) {
                // Align along [neighbors[0], neighbors[1]] and [neighbors[0], neighbors[2]]
                lines.add(new Line(neighbors.get(0), neighbors.get(1)));
                lines.add(new Line(neighbors.get(2), neighbors.get(3)));
            } else {
                // Align along [neighbors[0], neighbors[2]] and [neighbors[1], neighbors[3]]
                lines.add(new Line(neighbors.get(0), neighbors.get(2)));
                lines.add(new Line(neighbors.get(1), neighbors.get(3)));
            }
        } else
            throw new InvalidSelection("cannot treat more than 4 neighbours, got " + neighbors.size());
    }
    return lines;
}
Also used : IntStream(java.util.stream.IntStream) PolarCoor(org.openstreetmap.josm.data.coor.PolarCoor) I18n.tr(org.openstreetmap.josm.tools.I18n.tr) MoveCommand(org.openstreetmap.josm.command.MoveCommand) Way(org.openstreetmap.josm.data.osm.Way) HashMap(java.util.HashMap) Shortcut(org.openstreetmap.josm.tools.Shortcut) Logging(org.openstreetmap.josm.tools.Logging) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Map(java.util.Map) UndoRedoHandler(org.openstreetmap.josm.data.UndoRedoHandler) Command(org.openstreetmap.josm.command.Command) OsmPrimitive(org.openstreetmap.josm.data.osm.OsmPrimitive) Collection(java.util.Collection) Set(java.util.Set) HelpUtil.ht(org.openstreetmap.josm.gui.help.HelpUtil.ht) SequenceCommand(org.openstreetmap.josm.command.SequenceCommand) DataSet(org.openstreetmap.josm.data.osm.DataSet) KeyEvent(java.awt.event.KeyEvent) JOptionPane(javax.swing.JOptionPane) ActionEvent(java.awt.event.ActionEvent) Collectors(java.util.stream.Collectors) Node(org.openstreetmap.josm.data.osm.Node) List(java.util.List) Notification(org.openstreetmap.josm.gui.Notification) EastNorth(org.openstreetmap.josm.data.coor.EastNorth) Node(org.openstreetmap.josm.data.osm.Node) ArrayList(java.util.ArrayList) EastNorth(org.openstreetmap.josm.data.coor.EastNorth) Way(org.openstreetmap.josm.data.osm.Way)

Example 3 with Node

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

the class AlignInLineAction method alignMultiWay.

/**
 * Align way in case of multiple way #6819
 * @param ways Collection of way to align
 * @return Command that perform action
 * @throws InvalidSelection if a polygon is selected, or if a node is used by 3 or more ways
 */
private static Command alignMultiWay(Collection<Way> ways) throws InvalidSelection {
    // Collect all nodes and compute line equation
    Set<Node> nodes = new HashSet<>();
    Map<Way, Line> lines = new HashMap<>();
    for (Way w : ways) {
        if (w.isClosed())
            throw new InvalidSelection(tr("Can not align a polygon. Abort."));
        if (!w.isEmpty()) {
            nodes.addAll(w.getNodes());
            lines.put(w, new Line(w));
        }
    }
    if (nodes.isEmpty()) {
        throw new InvalidSelection(tr("Intersection of three or more ways can not be solved. Abort."));
    }
    Collection<Command> cmds = new ArrayList<>(nodes.size());
    List<Way> referrers = new ArrayList<>(ways.size());
    for (Node n : nodes) {
        referrers.clear();
        for (OsmPrimitive o : n.getReferrers()) {
            if (ways.contains(o))
                referrers.add((Way) o);
        }
        if (referrers.size() == 1) {
            Way way = referrers.get(0);
            if (way.isFirstLastNode(n))
                continue;
            cmds.add(lines.get(way).projectionCommand(n));
        } else if (referrers.size() == 2) {
            cmds.add(lines.get(referrers.get(0)).intersectionCommand(n, lines.get(referrers.get(1))));
        } else
            throw new InvalidSelection(tr("Intersection of three or more ways can not be solved. Abort."));
    }
    return cmds.isEmpty() ? null : new SequenceCommand(tr("Align Nodes in Line"), cmds);
}
Also used : HashMap(java.util.HashMap) Node(org.openstreetmap.josm.data.osm.Node) ArrayList(java.util.ArrayList) Way(org.openstreetmap.josm.data.osm.Way) MoveCommand(org.openstreetmap.josm.command.MoveCommand) Command(org.openstreetmap.josm.command.Command) SequenceCommand(org.openstreetmap.josm.command.SequenceCommand) SequenceCommand(org.openstreetmap.josm.command.SequenceCommand) OsmPrimitive(org.openstreetmap.josm.data.osm.OsmPrimitive) HashSet(java.util.HashSet)

Example 4 with Node

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

the class CombineWayAction method actionPerformed.

@Override
public void actionPerformed(ActionEvent event) {
    final DataSet ds = getLayerManager().getEditDataSet();
    if (ds == null)
        return;
    Collection<Way> selectedWays = new LinkedHashSet<>(ds.getSelectedWays());
    selectedWays.removeIf(Way::isEmpty);
    if (selectedWays.size() < 2) {
        new Notification(tr("Please select at least two ways to combine.")).setIcon(JOptionPane.INFORMATION_MESSAGE).setDuration(Notification.TIME_SHORT).show();
        return;
    }
    // see #18083: check if we will combine ways at nodes outside of the download area
    Set<Node> endNodesOutside = new HashSet<>();
    for (Way w : selectedWays) {
        final Node[] endnodes = { w.firstNode(), w.lastNode() };
        for (Node n : endnodes) {
            if (!n.isNew() && n.isOutsideDownloadArea() && !endNodesOutside.add(n)) {
                new Notification(tr("Combine ways refused<br>" + "(A shared node is outside of the download area)")).setIcon(JOptionPane.INFORMATION_MESSAGE).show();
                return;
            }
        }
    }
    // combine and update gui
    Pair<Way, Command> combineResult;
    try {
        combineResult = combineWaysWorker(selectedWays);
    } catch (UserCancelException ex) {
        Logging.trace(ex);
        return;
    }
    if (combineResult == null)
        return;
    final Way selectedWay = combineResult.a;
    UndoRedoHandler.getInstance().add(combineResult.b);
    Test test = new OverlappingWays();
    test.startTest(null);
    test.visit(combineResult.a);
    test.endTest();
    if (test.getErrors().isEmpty()) {
        test = new SelfIntersectingWay();
        test.startTest(null);
        test.visit(combineResult.a);
        test.endTest();
    }
    if (!test.getErrors().isEmpty()) {
        new Notification(test.getErrors().get(0).getMessage()).setIcon(JOptionPane.WARNING_MESSAGE).setDuration(Notification.TIME_SHORT).show();
    }
    if (selectedWay != null) {
        GuiHelper.runInEDT(() -> ds.setSelected(selectedWay));
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) OverlappingWays(org.openstreetmap.josm.data.validation.tests.OverlappingWays) DataSet(org.openstreetmap.josm.data.osm.DataSet) Node(org.openstreetmap.josm.data.osm.Node) UserCancelException(org.openstreetmap.josm.tools.UserCancelException) Way(org.openstreetmap.josm.data.osm.Way) JoinedWay(org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.JoinedWay) SelfIntersectingWay(org.openstreetmap.josm.data.validation.tests.SelfIntersectingWay) Notification(org.openstreetmap.josm.gui.Notification) SelfIntersectingWay(org.openstreetmap.josm.data.validation.tests.SelfIntersectingWay) DeleteCommand(org.openstreetmap.josm.command.DeleteCommand) Command(org.openstreetmap.josm.command.Command) SequenceCommand(org.openstreetmap.josm.command.SequenceCommand) ChangeNodesCommand(org.openstreetmap.josm.command.ChangeNodesCommand) Test(org.openstreetmap.josm.data.validation.Test) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

Example 5 with Node

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

the class SplitWayCommand method buildSplitChunks.

/**
 * Splits the nodes of {@code wayToSplit} into a list of node sequences
 * which are separated at the nodes in {@code splitPoints}.
 *
 * This method displays warning messages if {@code wayToSplit} and/or
 * {@code splitPoints} aren't consistent.
 *
 * Returns null, if building the split chunks fails.
 *
 * @param wayToSplit the way to split. Must not be null.
 * @param splitPoints the nodes where the way is split. Must not be null.
 * @return the list of chunks
 */
public static List<List<Node>> buildSplitChunks(Way wayToSplit, List<Node> splitPoints) {
    CheckParameterUtil.ensureParameterNotNull(wayToSplit, "wayToSplit");
    CheckParameterUtil.ensureParameterNotNull(splitPoints, "splitPoints");
    Set<Node> nodeSet = new HashSet<>(splitPoints);
    List<List<Node>> wayChunks = new LinkedList<>();
    List<Node> currentWayChunk = new ArrayList<>();
    wayChunks.add(currentWayChunk);
    Iterator<Node> it = wayToSplit.getNodes().iterator();
    while (it.hasNext()) {
        Node currentNode = it.next();
        boolean atEndOfWay = currentWayChunk.isEmpty() || !it.hasNext();
        currentWayChunk.add(currentNode);
        if (nodeSet.contains(currentNode) && !atEndOfWay) {
            currentWayChunk = new ArrayList<>();
            currentWayChunk.add(currentNode);
            wayChunks.add(currentWayChunk);
        }
    }
    // Handle circular ways specially.
    // If you split at a circular way at two nodes, you just want to split
    // it at these points, not also at the former endpoint.
    // So if the last node is the same first node, join the last and the
    // first way chunk.
    List<Node> lastWayChunk = wayChunks.get(wayChunks.size() - 1);
    if (wayChunks.size() >= 2 && wayChunks.get(0).get(0) == lastWayChunk.get(lastWayChunk.size() - 1) && !nodeSet.contains(wayChunks.get(0).get(0))) {
        if (wayChunks.size() == 2) {
            warningNotifier.accept(tr("You must select two or more nodes to split a circular way."));
            return null;
        }
        lastWayChunk.remove(lastWayChunk.size() - 1);
        lastWayChunk.addAll(wayChunks.get(0));
        wayChunks.remove(wayChunks.size() - 1);
        wayChunks.set(0, lastWayChunk);
    }
    if (wayChunks.size() < 2) {
        if (wayChunks.get(0).get(0) == wayChunks.get(0).get(wayChunks.get(0).size() - 1)) {
            warningNotifier.accept(tr("You must select two or more nodes to split a circular way."));
        } else {
            warningNotifier.accept(tr("The way cannot be split at the selected nodes. (Hint: Select nodes in the middle of the way.)"));
        }
        return null;
    }
    return wayChunks;
}
Also used : Node(org.openstreetmap.josm.data.osm.Node) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) List(java.util.List) LinkedList(java.util.LinkedList) HashSet(java.util.HashSet)

Aggregations

Node (org.openstreetmap.josm.data.osm.Node)1107 Test (org.junit.jupiter.api.Test)621 Way (org.openstreetmap.josm.data.osm.Way)569 DataSet (org.openstreetmap.josm.data.osm.DataSet)449 OsmPrimitive (org.openstreetmap.josm.data.osm.OsmPrimitive)292 LatLon (org.openstreetmap.josm.data.coor.LatLon)273 ArrayList (java.util.ArrayList)272 Relation (org.openstreetmap.josm.data.osm.Relation)187 EastNorth (org.openstreetmap.josm.data.coor.EastNorth)138 List (java.util.List)136 RelationMember (org.openstreetmap.josm.data.osm.RelationMember)125 HashSet (java.util.HashSet)121 OsmDataLayer (org.openstreetmap.josm.gui.layer.OsmDataLayer)118 Command (org.openstreetmap.josm.command.Command)114 SequenceCommand (org.openstreetmap.josm.command.SequenceCommand)98 Collection (java.util.Collection)93 Collectors (java.util.stream.Collectors)91 Collections (java.util.Collections)76 LinkedList (java.util.LinkedList)70 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)68