This is the implementation of my comment to bug #1313 [1]. When you move
nodes, they snap to other existing nodes, which is a comfortable thing
if you want to connect roads at existing nodes. Currently, when you do
this, you end up keeping both nodes at the same position and no real
connection between the roads.
This patch comes into action when you are done moving a single node. It
scans the document for other visible* nodes at the same position. If
there are any, it shows a message box asking whether the nodes shall be
merged. If you say yes, all nodes found at that exact position are
merged into the first node that was found that has already been there.
Usually this is one node and you're merging two nodes then. (But if
there have already been multiple nodes, it will be corrected silently.)
The merging is adapted from the existing Merge Nodes command and gets
its own undo item.
*) It only checks for visible nodes. So for the check to work, you need
to have the relevant layers enabled. I assume this is always the case as
you won't be editing the map blindly. OTOH it will ignore GPX nodes if
that layer is hidden. The snapping code also only takes visible nodes,
and so does my patch. (Code adapted from there.)
[1] http://trac.openstreetmap.org/ticket/1313
--
Yves Goergen "LonelyPixel" <[email protected]>
Visit my web laboratory at http://beta.unclassified.de
--- merkaartor\Interaction\MoveTrackPointInteraction.cpp.orig Fri Jan 02
23:21:05 2009
+++ merkaartor\Interaction\MoveTrackPointInteraction.cpp Sun Jan 04
18:06:46 2009
@@ -13,6 +13,7 @@
#include <QtGui/QCursor>
#include <QtGui/QMouseEvent>
#include <QtGui/QPixmap>
+#include <QMessageBox>
#include <vector>
@@ -75,7 +76,64 @@
else
theList->add(new
MoveTrackPointCommand(Moving[i],OriginalPosition[i]+Diff,
document()->getDirtyOrOriginLayer(Moving[i]->layer())));
}
+
document()->addHistory(theList);
+
+ // If moving a single node (not a track node), see if it got
dropped onto another node
+ if (Moving.size() == 1 && !Moving[0]->layer()->isTrack())
+ {
+ Coord newPos = OriginalPosition[0] + Diff;
+ std::vector<TrackPoint*> samePosPts;
+ for (VisibleFeatureIterator it(document());
!it.isEnd(); ++it)
+ {
+ TrackPoint* visPt =
dynamic_cast<TrackPoint*>(it.get());
+ if (visPt)
+ {
+ if (visPt == Moving[0])
+ continue;
+
+ if (visPt->position() == newPos)
+ {
+ samePosPts.push_back(visPt);
+ }
+ }
+ }
+ // Ensure the node being moved is at the end of the
list.
+ // (This is not the node that all nodes will be merged
into,
+ // they are always merged into a node that already was
at that position.)
+ samePosPts.push_back(Moving[0]);
+
+ if (samePosPts.size() > 1) // Ignore the node we're
moving, see if there are more
+ {
+ int ret = QMessageBox::question(view(),
+ MainWindow::tr("Nodes at the same
position found."),
+ MainWindow::tr("Do you want to merge
all nodes at the drop position?"),
+ QMessageBox::Yes | QMessageBox::No);
+ if (ret == QMessageBox::Yes)
+ {
+ // Merge all nodes from the same
position
+
+ // from
MainWindow::on_nodeMergeAction_triggered()
+ // Merge all nodes into the first node
that has been found (not the node being moved)
+ MapFeature* F = samePosPts[0];
+ // Make a separate undo command list
for this action
+ CommandList* theList2 = new
CommandList(MainWindow::tr("Merge Nodes into %1").arg(F->id()), F);
+
+ // from mergeNodes(theDocument,
theList, theProperties);
+ std::vector<MapFeature*> alt;
+ TrackPoint* merged = samePosPts[0];
+ alt.push_back(merged);
+ for (unsigned int i = 1; i <
samePosPts.size(); ++i) {
+
MapFeature::mergeTags(document(), theList2, merged, samePosPts[i]);
+ theList2->add(new
RemoveFeatureCommand(document(), samePosPts[i], alt));
+ }
+
+ document()->addHistory(theList2);
+ view()->properties()->setSelection(F);
+ }
+ }
+ }
+
view()->invalidate(true, false);
}
Moving.clear();
_______________________________________________
Merkaartor mailing list
[email protected]
http://lists.openstreetmap.org/listinfo/merkaartor