Collection<OsmPrimitive> newSelection = new LinkedList<>(ds.getSelected());
List<Way> reuseWays = new ArrayList<>(),
replacedWays = new ArrayList<>();
boolean newNode = false;
Node n = null;
n = Main.map.mapView.getNearestNode(mousePos, OsmPrimitive.isSelectablePredicate);
if (ctrl) {
Iterator<Way> it = getCurrentDataSet().getSelectedWays().iterator();
if (it.hasNext()) {
// ctrl-click on node of selected way = reuse node despite of ctrl
if (!it.next().containsNode(n)) n = null;
} else {
n=null; // ctrl-click + no selected way = new node
}
}
if (n != null && !snapHelper.isActive()) {
// user clicked on node
if (selection.isEmpty() || wayIsFinished) {
// select the clicked node and do nothing else
// (this is just a convenience option so that people don't
// have to switch modes)
getCurrentDataSet().setSelected(n);
// If we extend/continue an existing way, select it already now to make it obvious
Way continueFrom = getWayForNode(n);
if (continueFrom != null) {
getCurrentDataSet().addSelected(continueFrom);
}
// The user explicitly selected a node, so let him continue drawing
wayIsFinished = false;
return;
}
} else {
EastNorth newEN;
if (n!=null) {
EastNorth foundPoint = n.getEastNorth();
// project found node to snapping line
newEN = snapHelper.getSnapPoint(foundPoint);
// do not add new node if there is some node within snapping distance
double tolerance = Main.map.mapView.getDist100Pixel() * toleranceMultiplier;
if (foundPoint.distance(newEN) > tolerance) {
n = new Node(newEN); // point != projected, so we create new node
newNode = true;
}
} else { // n==null, no node found in clicked area
EastNorth mouseEN = Main.map.mapView.getEastNorth(e.getX(), e.getY());
newEN = snapHelper.isSnapOn() ? snapHelper.getSnapPoint(mouseEN) : mouseEN;
n = new Node(newEN); //create node at clicked point
newNode = true;
}
snapHelper.unsetFixedMode();
}
if (newNode) {
if (n.getCoor().isOutSideWorld()) {
JOptionPane.showMessageDialog(
Main.parent,
tr("Cannot add a node outside of the world."),
tr("Warning"),
JOptionPane.WARNING_MESSAGE
);
return;
}
cmds.add(new AddCommand(n));
if (!ctrl) {
// Insert the node into all the nearby way segments
List<WaySegment> wss = Main.map.mapView.getNearestWaySegments(
Main.map.mapView.getPoint(n), OsmPrimitive.isSelectablePredicate);
if (snapHelper.isActive()) {
tryToMoveNodeOnIntersection(wss,n);
}
insertNodeIntoAllNearbySegments(wss, n, newSelection, cmds, replacedWays, reuseWays);
}
}
// now "n" is newly created or reused node that shoud be added to some way
// This part decides whether or not a "segment" (i.e. a connection) is made to an
// existing node.
// For a connection to be made, the user must either have a node selected (connection
// is made to that node), or he must have a way selected *and* one of the endpoints
// of that way must be the last used node (connection is made to last used node), or
// he must have a way and a node selected (connection is made to the selected node).
// If the above does not apply, the selection is cleared and a new try is started
boolean extendedWay = false;
boolean wayIsFinishedTemp = wayIsFinished;
wayIsFinished = false;
// don't draw lines if shift is held
if (!selection.isEmpty() && !shift) {
Node selectedNode = null;
Way selectedWay = null;
for (OsmPrimitive p : selection) {
if (p instanceof Node) {
if (selectedNode != null) {
// Too many nodes selected to do something useful
tryAgain(e);
return;
}
selectedNode = (Node) p;
} else if (p instanceof Way) {
if (selectedWay != null) {
// Too many ways selected to do something useful
tryAgain(e);
return;
}
selectedWay = (Way) p;
}
}
// the node from which we make a connection
Node n0 = findNodeToContinueFrom(selectedNode, selectedWay);
// We have a selection but it isn't suitable. Try again.
if(n0 == null) {
tryAgain(e);
return;
}