[josm-dev] Difference between JOSM and JOSM-NG
Petr Nejedly
Petr.Nejedly at Sun.COM
Tue Aug 19 00:28:24 BST 2008
Till Amma napsal(a):
> It is good to know that there are two approaches right now. JOSM-ng for
> the guys liking encapsulated, design pattern driven code. And the existing
> JOSM providing a more loose access to fields making it easier to implement
> things.
<warning>Kind of marketing follows</warning>
Sorry, I couldn't resist: Ha ha ha.
Well, I just crossed the unglue plugin (just in time, project Czechia have
finished forests import, policy for roads adjacent to forest is to share nodes
and some mappers were concerned that such a thing is very hard to modify in josm)
and tried to reimplement the same functionality for -ng
I did it in few minutes and the code is nice, readable, stright and short.
The action body has around 40 lines including all the checks in -ng.
The splitting function alone in josm chimes in at ~73 lines with deep nested block,
with another 40 in checks. Well, I could rewrite the josm's version to be nicer
and shorter using back references visitor and so on, but it would still need to deal
with all the cloning of changed primitives and those change commands...
Ah, I know, it's called marketing. That part of in-this-thread-mentioned economy
which may actually lure more developers to given project, orthogonally to the real
shape of the code and so on.
So let me place a shameless plug here:
public @Override void perform(OsmLayer layer, DataSet ds, ActionEvent ae) {
CollectVisitor cv = layer.visitSelection(new CollectVisitor());
if (cv.getWays().size() > 0 || cv.getRelations().size() > 0 || cv.getNodes().size() != 1) {
JOptionPane.showMessageDialog(null, "The current selection cannot be used for unglueing.");
return;
}
Node splitPoint = cv.getNodes().iterator().next();
CollectVisitor refs = new CollectVisitor();
refs.visitCollection(splitPoint.getReferrers());
if (refs.getWays().size() < 2) {
JOptionPane.showMessageDialog(null, "You must select a node that is used by at least 2 ways.");
return;
}
List<Node> newNodes = new ArrayList<Node>();
Iterator<Way> ways = refs.getWays().iterator();
ways.next(); // leave the first way alone
// every other way get its own copy of the node
while (ways.hasNext()) {
Way act = ways.next();
Node copy = cloneNode(ds, splitPoint);
newNodes.add(copy);
List<Node> nodes = new ArrayList<Node>(act.getNodes());
Collections.replaceAll(nodes, splitPoint, copy);
act.setNodes(nodes);
}
// every relation using splitPoint gets all its clones as members with the same role
for (Relation rel : refs.getRelations()) {
String role = rel.getMembers().get(splitPoint);
for (Node n : newNodes) {
rel.addMember(n, role);
}
}
}
That's all. Please compare it with your copy of unglue plugin sources.
It is also fast even on huge dataset (no full-DataSet iteration. getReferers()
call is fast as well).
Oh, and it doesn't duplicate a node used several times by a single way. Should it?
(The original unglue would turn a closed way (abovementioned forest) into an unclosed
one in case you happened to be ungluing just the start=end node of the forest).
Does undo work after such an action? Sure!
Just commited to -ng, r9962
--
Petr "Nenik" Nejedly, NetBeans/Sun Microsystems, http://www.netbeans.org
355/113 -- Not the famous irrational number PI, but an incredible simulation!
More information about the josm-dev
mailing list