Automatic tag correction

classic Classic list List threaded Threaded
33 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Automatic tag correction

Robin Rattay
Hi,

I've been playing around with JOSM for a bit as a pratice to improve my
Java skills.

One thing I noticed on the OSM lists and wiki, is the problem that some
tagging proposals aren't accepted because the suggested tags are
dependend on the direction of the way, for example tagging of features
that are different on the "left" and "right" side of the way, which
easily can lead to corrupted/wrong data if the way is reversed without
adjusting them.

That's why I've attemped implement a "tag corrector" feature, that
suggests corrections to tags when a way is reversed. Currently it covers
"oneway" and tags that start with "left:" or "right:" or end with
":left" and ":right", for example as used on borders.

I've set it up in a way that allows to use the functionalty elsewhere,
for example if there were a tag that where problematic when splitting a way.

I've attached a patch, with the hope that someone could give their
opinion on the idea in general and my implementation in particular.

A next step would be to have corrections of relations in a simular manner.

Robin

Index: src/org/openstreetmap/josm/actions/ReverseWayAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/ReverseWayAction.java (revision 682)
+++ src/org/openstreetmap/josm/actions/ReverseWayAction.java (working copy)
@@ -15,6 +15,7 @@
 import org.openstreetmap.josm.command.ChangeCommand;
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.data.corrector.ReverseWayTagCorrector;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -46,13 +47,20 @@
  tr("Please select at least one way."));
      return;
      }
-     Collection<Command> c = new LinkedList<Command>();
-     for (Way w : sel) {
-     Way wnew = new Way(w);
+
+     boolean updateProperties = false;
+ ReverseWayTagCorrector reverseWayTagCorrector = new ReverseWayTagCorrector();
+ Collection<Command> c = new LinkedList<Command>();
+ for (Way w : sel) {
+ Way wnew = new Way(w);
  Collections.reverse(wnew.nodes);
-     c.add(new ChangeCommand(w, wnew));
-     }
-     Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c));
-     Main.map.repaint();
+ updateProperties = reverseWayTagCorrector.execute(w) || updateProperties;
+ c.add(new ChangeCommand(w, wnew));
+ }
+ Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c));
+ if (updateProperties) {
+ // selectionChanged(Main.ds.getSelected());
+ }
+
     }
 }
Index: src/org/openstreetmap/josm/data/corrector/TagCorrection.java
===================================================================
--- src/org/openstreetmap/josm/data/corrector/TagCorrection.java (revision 0)
+++ src/org/openstreetmap/josm/data/corrector/TagCorrection.java (revision 0)
@@ -0,0 +1,41 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.corrector;
+
+public class TagCorrection {
+
+ private final String oldKey;
+ private final String newKey;
+ private final String oldValue;
+ private final String newValue;
+
+ public TagCorrection(String oldKey, String oldValue, String newKey, String newValue) {
+ this.oldKey = oldKey;
+ this.oldValue = oldValue;
+ this.newKey = oldKey;
+ this.newValue = newValue;
+ }
+
+ public String getOldKey() {
+     return oldKey;
+    }
+
+ public String getOldValue() {
+     return oldValue;
+    }
+
+ public String getNewKey() {
+     return newKey;
+    }
+
+ public String getNewValue() {
+     return newValue;
+    }
+
+ public boolean isKeyChanged() {
+ return !newKey.equals(oldKey);
+ }
+
+ public boolean isValueChanged() {
+ return !newValue.equals(oldValue);
+ }
+}
Index: src/org/openstreetmap/josm/data/corrector/ReverseWayTagCorrector.java
===================================================================
--- src/org/openstreetmap/josm/data/corrector/ReverseWayTagCorrector.java (revision 0)
+++ src/org/openstreetmap/josm/data/corrector/ReverseWayTagCorrector.java (revision 0)
@@ -0,0 +1,58 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.corrector;
+
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.openstreetmap.josm.data.osm.OSMUtils;
+import org.openstreetmap.josm.data.osm.Way;
+
+public class ReverseWayTagCorrector extends TagCorrector<Way> {
+
+ private static final Pattern leftRightStartRegex = Pattern.compile(
+        "^(left|right):.*", Pattern.CASE_INSENSITIVE);
+
+ private static final Pattern leftRightEndRegex = Pattern.compile(
+        "*.:(left|right)$", Pattern.CASE_INSENSITIVE);
+
+ @Override public boolean execute(Way way) {
+
+ ArrayList<TagCorrection> tagCorrections = new ArrayList<TagCorrection>();
+
+ for (String key : way.keySet()) {
+ String newKey = key;
+ String value = way.get(key);
+ String newValue = value;
+
+ if (key.equals("oneway")) {
+ if (value.equals("-1"))
+ newValue = "true";
+ else {
+ Boolean boolValue = OSMUtils.getOSMBoolean(value);
+ if (boolValue != null && boolValue.booleanValue()) {
+ newValue = "-1";
+ }
+ }
+ } else {
+ Matcher m = leftRightStartRegex.matcher(key);
+ if (!m.matches())
+ m = leftRightEndRegex.matcher(key);
+
+ if (m.matches()) {
+ String leftRight = m.group(1).toLowerCase();
+
+ newKey = key.substring(0, m.start(1)).concat(
+        leftRight.equals("left") ? "right" : "left")
+        .concat(key.substring(m.end(1)));
+ }
+ }
+
+ if (key != newKey || value != newValue)
+ tagCorrections.add(new TagCorrection(key, value, newKey, newValue));
+ }
+
+ return applyCorrections(tagCorrections, way);
+ }
+
+}
Index: src/org/openstreetmap/josm/data/corrector/TagCorrectionTable.java
===================================================================
--- src/org/openstreetmap/josm/data/corrector/TagCorrectionTable.java (revision 0)
+++ src/org/openstreetmap/josm/data/corrector/TagCorrectionTable.java (revision 0)
@@ -0,0 +1,35 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.corrector;
+
+import java.awt.Dimension;
+import java.util.List;
+
+import javax.swing.JTable;
+
+public class TagCorrectionTable extends JTable {
+
+ private static TagCorrectionTableModel tagCorrectionTableModel;
+
+ public static TagCorrectionTable create(List<TagCorrection> tagCorrections) {
+
+ tagCorrectionTableModel = new TagCorrectionTableModel(
+        tagCorrections);
+ TagCorrectionTable table = new TagCorrectionTable(tagCorrectionTableModel);
+ table.setPreferredScrollableViewportSize(
+ new Dimension(400,70)
+ );
+ table.getColumnModel().getColumn(4).setPreferredWidth(40);
+ table.setRowSelectionAllowed(false);
+
+ return table;
+ }
+
+ public TagCorrectionTable(TagCorrectionTableModel tagCorrectionTableModel) {
+    super(tagCorrectionTableModel);
+    }
+
+ public TagCorrectionTableModel getTagCorrectionTableModel() {
+ return tagCorrectionTableModel;
+ }
+
+}
Index: src/org/openstreetmap/josm/data/corrector/TagCorrectionTableModel.java
===================================================================
--- src/org/openstreetmap/josm/data/corrector/TagCorrectionTableModel.java (revision 0)
+++ src/org/openstreetmap/josm/data/corrector/TagCorrectionTableModel.java (revision 0)
@@ -0,0 +1,86 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.table.AbstractTableModel;
+
+public class TagCorrectionTableModel extends AbstractTableModel {
+
+ private List<TagCorrection> tagCorrections;
+
+ private boolean[] apply;
+
+ public TagCorrectionTableModel(List<TagCorrection> tagCorrections) {
+ this.tagCorrections = tagCorrections;
+ apply = new boolean[this.tagCorrections.size()];
+ Arrays.fill(apply, true);
+ }
+
+ @Override public int getColumnCount() {
+ return 5;
+ }
+
+ @Override public Class<?> getColumnClass(int columnIndex) {
+ if (columnIndex == 4)
+ return Boolean.class;
+ return String.class;
+ }
+
+ @Override public String getColumnName(int colIndex) {
+ switch (colIndex) {
+ case 0:
+ return tr("Old key");
+ case 1:
+ return tr("Old value");
+ case 2:
+ return tr("New key");
+ case 3:
+ return tr("New value");
+ case 4:
+ return tr("Apply?");
+ }
+ return null;
+ }
+
+ @Override public int getRowCount() {
+ return tagCorrections.size();
+ }
+
+ @Override public Object getValueAt(int rowIndex, int colIndex) {
+
+ TagCorrection tagCorrection = tagCorrections.get(rowIndex);
+
+ switch (colIndex) {
+ case 0:
+ return tagCorrection.getOldKey();
+ case 1:
+ return tagCorrection.getOldValue();
+ case 2:
+ return tagCorrection.getNewKey();
+ case 3:
+ return tagCorrection.getNewValue();
+ case 4:
+ return apply[rowIndex];
+ }
+ return null;
+ }
+
+ @Override public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return columnIndex == 4;
+ }
+
+ @Override public void setValueAt(Object aValue, int rowIndex,
+        int columnIndex) {
+ if (columnIndex == 4 && aValue instanceof Boolean)
+ apply[rowIndex] = (Boolean)aValue;
+ }
+
+ public boolean getApply(int i) {
+ return apply[i];
+ }
+}
Index: src/org/openstreetmap/josm/data/corrector/TagCorrector.java
===================================================================
--- src/org/openstreetmap/josm/data/corrector/TagCorrector.java (revision 0)
+++ src/org/openstreetmap/josm/data/corrector/TagCorrector.java (revision 0)
@@ -0,0 +1,48 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.List;
+
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+
+public abstract class TagCorrector<P extends OsmPrimitive> {
+
+ public abstract boolean execute(P primitive);
+
+ protected boolean applyCorrections(List<TagCorrection> tagCorrections, P primitive) {
+
+ boolean updated = false;
+
+ if (tagCorrections != null && tagCorrections.size() > 0) {
+
+ final TagCorrectionTable table = TagCorrectionTable.create(tagCorrections);
+ final JScrollPane pane = new JScrollPane(table);
+
+ int answer = JOptionPane.showConfirmDialog(Main.parent, pane,
+        tr("Select which keys should be changed."),
+        JOptionPane.OK_CANCEL_OPTION);
+
+ if (answer == JOptionPane.OK_OPTION) {
+ for (int i = 0; i < tagCorrections.size(); i++) {
+ if (table.getTagCorrectionTableModel().getApply(i)) {
+ TagCorrection tagCorrection = tagCorrections.get(i);
+ if (tagCorrection.isKeyChanged())
+ primitive.remove(tagCorrection.getOldKey());
+ primitive.put(tagCorrection.getNewKey(), tagCorrection
+        .getNewValue());
+ updated = true;
+ }
+ }
+ }
+ }
+
+ return updated;
+ }
+
+}
Index: src/org/openstreetmap/josm/data/osm/OSMUtils.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/OSMUtils.java (revision 0)
+++ src/org/openstreetmap/josm/data/osm/OSMUtils.java (revision 0)
@@ -0,0 +1,21 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Locale;
+
+public class OSMUtils {
+
+ static ArrayList<String> TRUE_VALUES = new ArrayList<String>(Arrays
+        .asList(new String[] { "true", "yes", "1", "on" }));
+ static ArrayList<String> FALSE_VALUES = new ArrayList<String>(Arrays
+        .asList(new String[] { "false", "no", "0", "off" }));
+
+ public static Boolean getOSMBoolean(String value) {
+ String lowerValue = value.toLowerCase(Locale.ENGLISH);
+ if (TRUE_VALUES.contains(lowerValue)) return Boolean.TRUE;
+ if (FALSE_VALUES.contains(lowerValue)) return Boolean.FALSE;
+ return null;
+ }
+}


_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Raphael Mack-2
Hi,

Am Sonntag, 6. Juli 2008 schrieb Robin Rattay:
> That's why I've attemped implement a "tag corrector" feature, that

I really like that feature and think we should include it.

> I've set it up in a way that allows to use the functionalty elsewhere,
[...]
> A next step would be to have corrections of relations in a simular
> manner.

Yes, but I fear, this is not possible in such a easy and straight forward
manner.

About your patch:
Class TagCorrection, is not the way data structures are implemented in JOSM
so far (atm there are public fields everywhere!), but I really like the
suggestion.

The TagCorrections don't seem to be undoable, right? - this should be
implemented.

There are some tags like cycleway=opposite_lane, these should be adapted
similar.

Maybe TagCorrectionTable should better be placed in the gui subpackage.

Rapha

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Dirk Stöcker
In reply to this post by Robin Rattay
On Sun, 6 Jul 2008, Robin Rattay wrote:

> I've attached a patch, with the hope that someone could give their
> opinion on the idea in general and my implementation in particular.

Idea in general is very nice. Implementation probably has some problems
to be fixed, but I'm not yet the one to comment on these :-)

Ciao
--
http://www.dstoecker.eu/ (PGP key available)

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Robin Rattay
Dirk Stöcker schrieb:
> Idea in general is very nice.

Thank you.

> Implementation probably has some problems
> to be fixed, but I'm not yet the one to comment on these :-)

Go ahead. I'll take any criticism.


Robin

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Robin Rattay
In reply to this post by Raphael Mack-2
Raphael Mack schrieb:
> Am Sonntag, 6. Juli 2008 schrieb Robin Rattay:
>> That's why I've attemped implement a "tag corrector" feature, that
>
> I really like that feature and think we should include it.

Thank you.

>> A next step would be to have corrections of relations in a simular
>> manner.
>
> Yes, but I fear, this is not possible in such a easy and straight forward
> manner.

True.

> About your patch:
> Class TagCorrection, is not the way data structures are implemented in JOSM
> so far (atm there are public fields everywhere!), but I really like the
> suggestion.

You mean I should use public fields? Well, the access methods *is* the
correct way :-) but on the other hand it's such a simple "record class"
so public fields are probably ok here.

> The TagCorrections don't seem to be undoable, right? - this should be
> implemented.

Not directly, but each use can implement it. For reverse way the
existing ChangeCommand is used, and in other cases a
ChangePropertyCommand can be used.

> There are some tags like cycleway=opposite_lane, these should be adapted
> similar.

Unfortunatly there is not opposite to that. If my feature catches on,
then we could define tags like cycleway:left=lane that can be corrected
to cycleway:right=lane.

> Maybe TagCorrectionTable should better be placed in the gui subpackage.

I considered that, but I prefered to keep all the corrector classes
together. Maybe it just should be moved out of the data package.

Thank you for your input!

Robin


_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Robin Rattay
In reply to this post by Raphael Mack-2
Raphael Mack schrieb:
> Am Sonntag, 6. Juli 2008 schrieben Sie:
>> You mean I should use public fields? Well, the access methods *is* the
>> correct way :-) but on the other hand it's such a simple "record class"
>> so public fields are probably ok here.
>
> No, actually not. I do think we should clean up josm code sooner or later.
> I really encourage to use the proper java way and completely omit public
> fields ;-)

Ah, ok.

>> Unfortunatly there is not opposite to that. If my feature catches on,
>> then we could define tags like cycleway:left=lane that can be corrected
>> to cycleway:right=lane.
>
> I would prefer such a much cleaner tagging style, but it's not in use
> actually..

Actually my suggestion is bad, since it's confusing when differentiating
between right-hand and left-hand driving.

>> I considered that, but I prefered to keep all the corrector classes
>> together. Maybe it just should be moved out of the data package.
>
> I don't know. I would have put it into the gui package, that's all. I
> perfectly can live with it all together.

My problem is, that only part of the corrector is actualy gui. There is
some logic in there that doesn't really belong into gui. Maybe I'd need
to separate logic und gui more.

Robin

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Frederik Ramm
Hi,

>>> You mean I should use public fields? Well, the access methods *is* the
>>> correct way :-) but on the other hand it's such a simple "record class"
>>> so public fields are probably ok here.

>> No, actually not. I do think we should clean up josm code sooner or later.
>> I really encourage to use the proper java way and completely omit public
>> fields ;-)

> Ah, ok.

Please do not flood JOSM with getters and setters. If anyone wants to
completely clean up JOSM they are free to do it - I agree that an
architectural review would make sense - but I would not like a mix of
the "traditional JOSM way" and the "textbook Java way" in the code.

The textbook Java way is to use getters and setters unless this is not
possible for some reason - even if you cannot imagine any situation
where they might be needed. The traditional JOSM way is to use public
members unless getters and setters are required right now.

Bye
Frederik

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Frederik Ramm
Hi,

> If anyone wants to
> completely clean up JOSM they are free to do it

... in their OWN repository or in a JOSM branch, not in JOSM trunk, I
should have added.

Bye
Frederik


_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Robin Rattay
In reply to this post by Frederik Ramm
Frederik Ramm schrieb:
> The textbook Java way is to use getters and setters unless this is not
> possible for some reason - even if you cannot imagine any situation
> where they might be needed. The traditional JOSM way is to use public
> members unless getters and setters are required right now.

Completely of topic: It's a pity that Java doesn't have "properties"
like many other OO languages in order to avoid trivial getters and setters.

Robin

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Dirk Stöcker
On Mon, 7 Jul 2008, Robin Rattay wrote:

Any updates to your patch?

Ciao
--
http://www.dstoecker.eu/ (PGP key available)

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Robin Rattay
Dirk Stöcker schrieb:
> Any updates to your patch?

I've cleaned it up a bit - and now the "left:"/"right:" accually works´:-)

I added a label to the dialog, but it needs to be changed so that it wraps.

I've got one problem, I couldn't solve yet: The properties editor
doesn't update yet, after the changes have been applied. Any suggestions
how to do that?

Robin

Index: src/org/openstreetmap/josm/actions/ReverseWayAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/ReverseWayAction.java (revision 682)
+++ src/org/openstreetmap/josm/actions/ReverseWayAction.java (working copy)
@@ -15,6 +15,7 @@
 import org.openstreetmap.josm.command.ChangeCommand;
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.corrector.ReverseWayTagCorrector;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -46,13 +47,16 @@
  tr("Please select at least one way."));
      return;
      }
-     Collection<Command> c = new LinkedList<Command>();
-     for (Way w : sel) {
-     Way wnew = new Way(w);
+
+ ReverseWayTagCorrector reverseWayTagCorrector = new ReverseWayTagCorrector();
+ Collection<Command> c = new LinkedList<Command>();
+ for (Way w : sel) {
+ Way wnew = new Way(w);
  Collections.reverse(wnew.nodes);
-     c.add(new ChangeCommand(w, wnew));
-     }
-     Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c));
-     Main.map.repaint();
+ reverseWayTagCorrector.execute(wnew);
+ c.add(new ChangeCommand(w, wnew));
+ }
+ Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c));
+ Main.map.repaint();
     }
 }
Index: src/org/openstreetmap/josm/corrector/TagCorrection.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrection.java (revision 0)
+++ src/org/openstreetmap/josm/corrector/TagCorrection.java (revision 0)
@@ -0,0 +1,41 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+public class TagCorrection {
+
+ private final String oldKey;
+ private final String newKey;
+ private final String oldValue;
+ private final String newValue;
+
+ public TagCorrection(String oldKey, String oldValue, String newKey, String newValue) {
+ this.oldKey = oldKey;
+ this.oldValue = oldValue;
+ this.newKey = newKey;
+ this.newValue = newValue;
+ }
+
+ public String getOldKey() {
+     return oldKey;
+    }
+
+ public String getOldValue() {
+     return oldValue;
+    }
+
+ public String getNewKey() {
+     return newKey;
+    }
+
+ public String getNewValue() {
+     return newValue;
+    }
+
+ public boolean isKeyChanged() {
+ return !newKey.equals(oldKey);
+ }
+
+ public boolean isValueChanged() {
+ return !newValue.equals(oldValue);
+ }
+}
Index: src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
===================================================================
--- src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java (revision 0)
+++ src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java (revision 0)
@@ -0,0 +1,63 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.openstreetmap.josm.data.osm.OSMUtils;
+import org.openstreetmap.josm.data.osm.Way;
+
+public class ReverseWayTagCorrector extends TagCorrector<Way> {
+
+ private static final Pattern leftRightStartRegex = Pattern.compile(
+        "^(left|right):.*", Pattern.CASE_INSENSITIVE);
+
+ private static final Pattern leftRightEndRegex = Pattern.compile(
+        ".*:(left|right)$", Pattern.CASE_INSENSITIVE);
+
+ @Override public boolean execute(Way way) {
+
+ ArrayList<TagCorrection> tagCorrections = new ArrayList<TagCorrection>();
+
+ for (String key : way.keySet()) {
+ String newKey = key;
+ String value = way.get(key);
+ String newValue = value;
+
+ if (key.equals("oneway")) {
+ if (value.equals("-1"))
+ newValue = "true";
+ else {
+ Boolean boolValue = OSMUtils.getOSMBoolean(value);
+ if (boolValue != null && boolValue.booleanValue()) {
+ newValue = "-1";
+ }
+ }
+ } else {
+ Matcher m = leftRightStartRegex.matcher(key);
+ if (!m.matches())
+ m = leftRightEndRegex.matcher(key);
+
+ if (m.matches()) {
+ String leftRight = m.group(1).toLowerCase();
+
+ newKey = key.substring(0, m.start(1)).concat(
+        leftRight.equals("left") ? "right" : "left")
+        .concat(key.substring(m.end(1)));
+ }
+ }
+
+ if (key != newKey || value != newValue)
+ tagCorrections.add(new TagCorrection(key, value, newKey,
+        newValue));
+ }
+
+ return applyCorrections(tagCorrections, way,
+        tr("When reverting this way, following changes to the "
+                + "properties are suggested, in order to maintain "
+                + "data consistency."));
+ }
+}
Index: src/org/openstreetmap/josm/corrector/TagCorrectionTable.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrectionTable.java (revision 0)
+++ src/org/openstreetmap/josm/corrector/TagCorrectionTable.java (revision 0)
@@ -0,0 +1,35 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import java.awt.Dimension;
+import java.util.List;
+
+import javax.swing.JTable;
+
+public class TagCorrectionTable extends JTable {
+
+ private static TagCorrectionTableModel tagCorrectionTableModel;
+
+ public static TagCorrectionTable create(List<TagCorrection> tagCorrections) {
+
+ tagCorrectionTableModel = new TagCorrectionTableModel(
+        tagCorrections);
+ TagCorrectionTable table = new TagCorrectionTable(tagCorrectionTableModel);
+ table.setPreferredScrollableViewportSize(
+ new Dimension(400,70)
+ );
+ table.getColumnModel().getColumn(4).setPreferredWidth(40);
+ table.setRowSelectionAllowed(false);
+
+ return table;
+ }
+
+ private TagCorrectionTable(TagCorrectionTableModel tagCorrectionTableModel) {
+    super(tagCorrectionTableModel);
+    }
+
+ public TagCorrectionTableModel getTagCorrectionTableModel() {
+ return tagCorrectionTableModel;
+ }
+
+}
Index: src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java (revision 0)
+++ src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java (revision 0)
@@ -0,0 +1,85 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.table.AbstractTableModel;
+
+public class TagCorrectionTableModel extends AbstractTableModel {
+
+ private List<TagCorrection> tagCorrections;
+
+ private boolean[] apply;
+
+ public TagCorrectionTableModel(List<TagCorrection> tagCorrections) {
+ this.tagCorrections = tagCorrections;
+ apply = new boolean[this.tagCorrections.size()];
+ Arrays.fill(apply, true);
+ }
+
+ @Override public int getColumnCount() {
+ return 5;
+ }
+
+ @Override public Class<?> getColumnClass(int columnIndex) {
+ if (columnIndex == 4)
+ return Boolean.class;
+ return String.class;
+ }
+
+ @Override public String getColumnName(int colIndex) {
+ switch (colIndex) {
+ case 0:
+ return tr("Old key");
+ case 1:
+ return tr("Old value");
+ case 2:
+ return tr("New key");
+ case 3:
+ return tr("New value");
+ case 4:
+ return tr("Apply?");
+ }
+ return null;
+ }
+
+ @Override public int getRowCount() {
+ return tagCorrections.size();
+ }
+
+ @Override public Object getValueAt(int rowIndex, int colIndex) {
+
+ TagCorrection tagCorrection = tagCorrections.get(rowIndex);
+
+ switch (colIndex) {
+ case 0:
+ return tagCorrection.getOldKey();
+ case 1:
+ return tagCorrection.getOldValue();
+ case 2:
+ return tagCorrection.getNewKey();
+ case 3:
+ return tagCorrection.getNewValue();
+ case 4:
+ return apply[rowIndex];
+ }
+ return null;
+ }
+
+ @Override public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return columnIndex == 4;
+ }
+
+ @Override public void setValueAt(Object aValue, int rowIndex,
+        int columnIndex) {
+ if (columnIndex == 4 && aValue instanceof Boolean)
+ apply[rowIndex] = (Boolean)aValue;
+ }
+
+ public boolean getApply(int i) {
+ return apply[i];
+ }
+}
Index: src/org/openstreetmap/josm/corrector/TagCorrector.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrector.java (revision 0)
+++ src/org/openstreetmap/josm/corrector/TagCorrector.java (revision 0)
@@ -0,0 +1,62 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Dimension;
+import java.awt.GridBagLayout;
+import java.util.List;
+
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JPanel;
+import javax.swing.JLabel;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.tools.GBC;
+
+public abstract class TagCorrector<P extends OsmPrimitive> {
+
+ public abstract boolean execute(P primitive);
+
+ protected boolean applyCorrections(List<TagCorrection> tagCorrections,
+        P primitive, String description) {
+
+ boolean updated = false;
+
+ if (tagCorrections != null && tagCorrections.size() > 0) {
+
+ final TagCorrectionTable table = TagCorrectionTable
+        .create(tagCorrections);
+ final JScrollPane scrollPane = new JScrollPane(table);
+
+     final JPanel p = new JPanel(new GridBagLayout());
+     final JLabel label1 = new JLabel(description);
+ p.add(label1, GBC.eol());
+     final JLabel label2 = new JLabel(tr("Please select which property changes you want to apply."));
+ p.add(label2, GBC.eol());
+     p.add(scrollPane, GBC.eol());
+
+ int answer = JOptionPane.showConfirmDialog(Main.parent, p,
+        tr("Automatic tag correction"),
+        JOptionPane.OK_CANCEL_OPTION);
+
+ if (answer == JOptionPane.OK_OPTION) {
+ for (int i = 0; i < tagCorrections.size(); i++) {
+ if (table.getTagCorrectionTableModel().getApply(i)) {
+ TagCorrection tagCorrection = tagCorrections.get(i);
+ if (tagCorrection.isKeyChanged())
+ primitive.remove(tagCorrection.getOldKey());
+ primitive.put(tagCorrection.getNewKey(), tagCorrection
+        .getNewValue());
+ updated = true;
+ }
+ }
+ }
+ }
+
+ return updated;
+ }
+
+}
Index: src/org/openstreetmap/josm/data/osm/OSMUtils.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/OSMUtils.java (revision 0)
+++ src/org/openstreetmap/josm/data/osm/OSMUtils.java (revision 0)
@@ -0,0 +1,21 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Locale;
+
+public class OSMUtils {
+
+ static ArrayList<String> TRUE_VALUES = new ArrayList<String>(Arrays
+        .asList(new String[] { "true", "yes", "1", "on" }));
+ static ArrayList<String> FALSE_VALUES = new ArrayList<String>(Arrays
+        .asList(new String[] { "false", "no", "0", "off" }));
+
+ public static Boolean getOSMBoolean(String value) {
+ String lowerValue = value.toLowerCase(Locale.ENGLISH);
+ if (TRUE_VALUES.contains(lowerValue)) return Boolean.TRUE;
+ if (FALSE_VALUES.contains(lowerValue)) return Boolean.FALSE;
+ return null;
+ }
+}


_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Dirk Stöcker
On Thu, 10 Jul 2008, Robin Rattay wrote:

> I've cleaned it up a bit - and now the "left:"/"right:" accually works´:-)
>
> I added a label to the dialog, but it needs to be changed so that it wraps.
>
> I've got one problem, I couldn't solve yet: The properties editor
> doesn't update yet, after the changes have been applied. Any suggestions
> how to do that?

Did you fix your problems. The reload is easy: You need to emit the
correct signal. Don't ask me which one or how :-)

P.S. I used your

src/org/openstreetmap/josm/data/osm/OSMUtils.java

as OsmUtils.java in my changes, so this part of the patch is no longer
required :-)

Ciao
--
http://www.dstoecker.eu/ (PGP key available)
_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Robin Rattay
Dirk Stöcker schrieb:
> Did you fix your problems. The reload is easy: You need to emit the
> correct signal. Don't ask me which one or how :-)

Yes, I've got it. I'll post a new patch tomorrow.

> P.S. I used your
>
> src/org/openstreetmap/josm/data/osm/OSMUtils.java
>
> as OsmUtils.java in my changes, so this part of the patch is no longer
> required :-)

Great :-)

Robin

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Robin Rattay
I wrote:
> Yes, I've got it. I'll post a new patch tomorrow.

Here we go. The changes since last time:

- Can be turned off by setting the advanced parameter
"tag-correction.reverse-way" to "false".

- Updated the dialog by adding a multiline label component, that I took
from a Java forum, to let the text wrap. I hope that's ok.

- The changes in the dialog are now highlighted in bold.

- The properties update now. I needed to add a public reference to
MapFrame in order to access the properties dialog to do that.

And Dirk (and everyboy else), if you've got any more remarks or
suggestions, please do go ahead.

Robin

Index: src/org/openstreetmap/josm/actions/ReverseWayAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/ReverseWayAction.java (revision 728)
+++ src/org/openstreetmap/josm/actions/ReverseWayAction.java (working copy)
@@ -15,6 +15,7 @@
 import org.openstreetmap.josm.command.ChangeCommand;
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.corrector.ReverseWayTagCorrector;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -46,13 +47,20 @@
  tr("Please select at least one way."));
      return;
      }
-     Collection<Command> c = new LinkedList<Command>();
-     for (Way w : sel) {
-     Way wnew = new Way(w);
+
+     boolean propertiesUpdated = false;
+ ReverseWayTagCorrector reverseWayTagCorrector = new ReverseWayTagCorrector();
+ Collection<Command> c = new LinkedList<Command>();
+ for (Way w : sel) {
+ Way wnew = new Way(w);
  Collections.reverse(wnew.nodes);
-     c.add(new ChangeCommand(w, wnew));
-     }
-     Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c));
-     Main.map.repaint();
+ if (Main.pref.getBoolean("tag-correction.reverse-way", true))
+ propertiesUpdated = reverseWayTagCorrector.execute(wnew) || propertiesUpdated;
+ c.add(new ChangeCommand(w, wnew));
+ }
+ Main.main.undoRedo.add(new SequenceCommand(tr("Reverse ways"), c));
+ if (propertiesUpdated)
+ Main.map.getPropertiesDialog().selectionChanged(Main.ds.getSelected());
+ Main.map.repaint();
     }
 }
Index: src/org/openstreetmap/josm/corrector/TagCorrection.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrection.java (revision 0)
+++ src/org/openstreetmap/josm/corrector/TagCorrection.java (revision 0)
@@ -0,0 +1,41 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+public class TagCorrection {
+
+ private final String oldKey;
+ private final String newKey;
+ private final String oldValue;
+ private final String newValue;
+
+ public TagCorrection(String oldKey, String oldValue, String newKey, String newValue) {
+ this.oldKey = oldKey;
+ this.oldValue = oldValue;
+ this.newKey = newKey;
+ this.newValue = newValue;
+ }
+
+ public String getOldKey() {
+     return oldKey;
+    }
+
+ public String getOldValue() {
+     return oldValue;
+    }
+
+ public String getNewKey() {
+     return newKey;
+    }
+
+ public String getNewValue() {
+     return newValue;
+    }
+
+ public boolean isKeyChanged() {
+ return !newKey.equals(oldKey);
+ }
+
+ public boolean isValueChanged() {
+ return !newValue.equals(oldValue);
+ }
+}
Index: src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
===================================================================
--- src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java (revision 0)
+++ src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java (revision 0)
@@ -0,0 +1,63 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.ArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.openstreetmap.josm.data.osm.OsmUtils;
+import org.openstreetmap.josm.data.osm.Way;
+
+public class ReverseWayTagCorrector extends TagCorrector<Way> {
+
+ private static final Pattern leftRightStartRegex = Pattern.compile(
+        "^(left|right):.*", Pattern.CASE_INSENSITIVE);
+
+ private static final Pattern leftRightEndRegex = Pattern.compile(
+        ".*:(left|right)$", Pattern.CASE_INSENSITIVE);
+
+ @Override public boolean execute(Way way) {
+
+ ArrayList<TagCorrection> tagCorrections = new ArrayList<TagCorrection>();
+
+ for (String key : way.keySet()) {
+ String newKey = key;
+ String value = way.get(key);
+ String newValue = value;
+
+ if (key.equals("oneway")) {
+ if (value.equals("-1"))
+ newValue = OsmUtils.trueval;
+ else {
+ Boolean boolValue = OsmUtils.getOsmBoolean(value);
+ if (boolValue != null && boolValue.booleanValue()) {
+ newValue = "-1";
+ }
+ }
+ } else {
+ Matcher m = leftRightStartRegex.matcher(key);
+ if (!m.matches())
+ m = leftRightEndRegex.matcher(key);
+
+ if (m.matches()) {
+ String leftRight = m.group(1).toLowerCase();
+
+ newKey = key.substring(0, m.start(1)).concat(
+        leftRight.equals("left") ? "right" : "left")
+        .concat(key.substring(m.end(1)));
+ }
+ }
+
+ if (key != newKey || value != newValue)
+ tagCorrections.add(new TagCorrection(key, value, newKey,
+        newValue));
+ }
+
+ return applyCorrections(tagCorrections, way,
+        tr("When reverting this way, following changes to the "
+                + "properties are suggested, in order to maintain "
+                + "data consistency."));
+ }
+}
Index: src/org/openstreetmap/josm/corrector/TagCorrectionTable.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrectionTable.java (revision 0)
+++ src/org/openstreetmap/josm/corrector/TagCorrectionTable.java (revision 0)
@@ -0,0 +1,67 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import java.awt.Dimension;
+import java.util.List;
+
+import javax.swing.JTable;
+import javax.swing.JLabel;
+import javax.swing.table.TableCellRenderer;
+import java.awt.Component;
+import java.awt.Font;
+
+public class TagCorrectionTable extends JTable {
+
+ public class BoldRenderer extends JLabel implements TableCellRenderer {
+
+ public Component getTableCellRendererComponent(JTable table,
+        Object value, boolean isSelected, boolean hasFocus, int row,
+        int column) {
+
+ Font f = getFont();
+ setFont(new Font(f.getName(), f.getStyle() | Font.BOLD, f.getSize()));
+
+ setText((String)value);
+
+ return this;
+ }
+ }
+
+ private static TableCellRenderer boldRenderer = null;
+
+ private static TagCorrectionTableModel tagCorrectionTableModel;
+
+ public static TagCorrectionTable create(List<TagCorrection> tagCorrections) {
+
+ tagCorrectionTableModel = new TagCorrectionTableModel(tagCorrections);
+ TagCorrectionTable table = new TagCorrectionTable(
+        tagCorrectionTableModel);
+ int lines = tagCorrections.size() > 10 ? 10 : tagCorrections.size();  
+ table.setPreferredScrollableViewportSize(new Dimension(400, lines * table.getRowHeight()));
+ table.getColumnModel().getColumn(4).setPreferredWidth(40);
+ table.setRowSelectionAllowed(false);
+
+ return table;
+ }
+
+ public TableCellRenderer getCellRenderer(int row, int column) {
+ TagCorrection tagCorrection = tagCorrectionTableModel.tagCorrections
+        .get(row);
+ if ((column == 2 && tagCorrection.isKeyChanged())
+        || (column == 3 && tagCorrection.isValueChanged())) {
+ if (boldRenderer == null)
+ boldRenderer = new BoldRenderer();
+ return boldRenderer;
+ }
+ return super.getCellRenderer(row, column);
+ }
+
+ private TagCorrectionTable(TagCorrectionTableModel tagCorrectionTableModel) {
+ super(tagCorrectionTableModel);
+ }
+
+ public TagCorrectionTableModel getTagCorrectionTableModel() {
+ return tagCorrectionTableModel;
+ }
+
+}
Index: src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java (revision 0)
+++ src/org/openstreetmap/josm/corrector/TagCorrectionTableModel.java (revision 0)
@@ -0,0 +1,85 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.table.AbstractTableModel;
+
+public class TagCorrectionTableModel extends AbstractTableModel {
+
+ List<TagCorrection> tagCorrections;
+
+ private boolean[] apply;
+
+ public TagCorrectionTableModel(List<TagCorrection> tagCorrections) {
+ this.tagCorrections = tagCorrections;
+ apply = new boolean[this.tagCorrections.size()];
+ Arrays.fill(apply, true);
+ }
+
+ @Override public int getColumnCount() {
+ return 5;
+ }
+
+ @Override public Class<?> getColumnClass(int columnIndex) {
+ if (columnIndex == 4)
+ return Boolean.class;
+ return String.class;
+ }
+
+ @Override public String getColumnName(int colIndex) {
+ switch (colIndex) {
+ case 0:
+ return tr("Old key");
+ case 1:
+ return tr("Old value");
+ case 2:
+ return tr("New key");
+ case 3:
+ return tr("New value");
+ case 4:
+ return tr("Apply?");
+ }
+ return null;
+ }
+
+ @Override public int getRowCount() {
+ return tagCorrections.size();
+ }
+
+ @Override public Object getValueAt(int rowIndex, int colIndex) {
+
+ TagCorrection tagCorrection = tagCorrections.get(rowIndex);
+
+ switch (colIndex) {
+ case 0:
+ return tagCorrection.getOldKey();
+ case 1:
+ return tagCorrection.getOldValue();
+ case 2:
+ return tagCorrection.getNewKey();
+ case 3:
+ return tagCorrection.getNewValue();
+ case 4:
+ return apply[rowIndex];
+ }
+ return null;
+ }
+
+ @Override public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return columnIndex == 4;
+ }
+
+ @Override public void setValueAt(Object aValue, int rowIndex,
+        int columnIndex) {
+ if (columnIndex == 4 && aValue instanceof Boolean)
+ apply[rowIndex] = (Boolean)aValue;
+ }
+
+ public boolean getApply(int i) {
+ return apply[i];
+ }
+}
Index: src/org/openstreetmap/josm/corrector/TagCorrector.java
===================================================================
--- src/org/openstreetmap/josm/corrector/TagCorrector.java (revision 0)
+++ src/org/openstreetmap/josm/corrector/TagCorrector.java (revision 0)
@@ -0,0 +1,67 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.corrector;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Dimension;
+import java.awt.GridBagLayout;
+import java.util.List;
+
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.gui.JMultilineLabel;
+import org.openstreetmap.josm.tools.GBC;
+
+public abstract class TagCorrector<P extends OsmPrimitive> {
+
+ public abstract boolean execute(P primitive);
+
+ protected boolean applyCorrections(List<TagCorrection> tagCorrections,
+        P primitive, String description) {
+
+ boolean updated = false;
+
+ if (tagCorrections != null && tagCorrections.size() > 0) {
+
+ final TagCorrectionTable table = TagCorrectionTable
+        .create(tagCorrections);
+ final JScrollPane scrollPane = new JScrollPane(table);
+
+     final JPanel p = new JPanel(new GridBagLayout());
+
+ final JMultilineLabel label1 = new JMultilineLabel(description);
+ label1.setMaxWidth(400);
+ p.add(label1, GBC.eop());
+
+ final JMultilineLabel label2 = new JMultilineLabel(tr("Please select which property changes you want to apply."));
+ label2.setMaxWidth(400);
+ p.add(label2, GBC.eop());
+     p.add(scrollPane, GBC.eol());
+
+ int answer = JOptionPane.showConfirmDialog(Main.parent, p,
+        tr("Automatic tag correction"),
+        JOptionPane.OK_CANCEL_OPTION);
+
+ if (answer == JOptionPane.OK_OPTION) {
+ for (int i = 0; i < tagCorrections.size(); i++) {
+ if (table.getTagCorrectionTableModel().getApply(i)) {
+ TagCorrection tagCorrection = tagCorrections.get(i);
+ if (tagCorrection.isKeyChanged())
+ primitive.remove(tagCorrection.getOldKey());
+ primitive.put(tagCorrection.getNewKey(), tagCorrection
+        .getNewValue());
+ updated = true;
+ }
+ }
+ }
+ }
+
+ return updated;
+ }
+
+}
Index: src/org/openstreetmap/josm/gui/JMultilineLabel.java
===================================================================
--- src/org/openstreetmap/josm/gui/JMultilineLabel.java (revision 0)
+++ src/org/openstreetmap/josm/gui/JMultilineLabel.java (revision 0)
@@ -0,0 +1,115 @@
+// License: GPL. For details, see LICENSE file.
+
+// This class was taken from
+// http://forum.java.sun.com/thread.jspa?threadID=459705&messageID=2104021
+// - Removed hardcoded margin
+// -  Added constructor
+
+package org.openstreetmap.josm.gui;
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.font.FontRenderContext;
+import java.awt.font.LineBreakMeasurer;
+import java.awt.font.TextAttribute;
+import java.text.AttributedCharacterIterator;
+import java.text.AttributedString;
+import java.awt.font.TextLayout;
+
+import javax.swing.JComponent;
+
+
+public class JMultilineLabel extends JComponent {
+    private String text;
+    private int maxWidth = Integer.MAX_VALUE;
+    private boolean justify;
+    private final FontRenderContext frc = new FontRenderContext(null, false, false);
+
+    public JMultilineLabel(String description) {
+    super();
+    setText(description);
+    }
+
+ private void morph() {
+        revalidate();
+        repaint();
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public void setText(String text) {
+        String old = this.text;
+        this.text = text;
+        firePropertyChange("text", old, this.text);
+        if ((old == null) ? text!=null : !old.equals(text))
+            morph();
+    }
+
+    public int getMaxWidth() {
+        return maxWidth;
+    }
+
+    public void setMaxWidth(int maxWidth) {
+        if (maxWidth <= 0)
+            throw new IllegalArgumentException();
+        int old = this.maxWidth;
+        this.maxWidth = maxWidth;
+        firePropertyChange("maxWidth", old, this.maxWidth);
+        if (old !=  this.maxWidth)
+            morph();
+    }
+
+    public boolean isJustified() {
+        return justify;
+    }
+
+    public void setJustified(boolean justify) {
+        boolean old = this.justify;
+        this.justify = justify;
+        firePropertyChange("justified", old, this.justify);
+        if (old != this.justify)
+            repaint();
+    }
+
+    public Dimension getPreferredSize() {
+        return paintOrGetSize(null, getMaxWidth());
+    }
+
+    public Dimension getMinimumSize() {
+        return getPreferredSize();
+    }
+
+    protected void paintComponent(Graphics g) {
+        super.paintComponent(g);
+        paintOrGetSize((Graphics2D)g, getWidth());
+    }
+
+    private Dimension paintOrGetSize(Graphics2D g, int width) {
+        Insets insets = getInsets();
+        width -= insets.left + insets.right;
+        float w = insets.left + insets.right;
+        float x = insets.left, y=insets.top;
+        if (width > 0 && text != null && text.length() > 0) {
+            AttributedString as = new AttributedString(getText());
+            as.addAttribute(TextAttribute.FONT, getFont());
+            AttributedCharacterIterator aci = as.getIterator();
+            LineBreakMeasurer lbm = new LineBreakMeasurer(aci, frc);
+            float max = 0;
+            while (lbm.getPosition() < aci.getEndIndex()) {
+                TextLayout textLayout = lbm.nextLayout(width);
+                if (g != null && isJustified() && textLayout.getVisibleAdvance() > 0.80 * width)
+                    textLayout = textLayout.getJustifiedLayout(width);
+                if (g != null)
+                    textLayout.draw(g, x, y + textLayout.getAscent());
+                y += textLayout.getDescent() + textLayout.getLeading() + textLayout.getAscent();
+                max = Math.max(max, textLayout.getVisibleAdvance());
+            }
+            w += max;
+        }
+        return new Dimension((int)Math.ceil(w), (int)Math.ceil(y) + insets.bottom);
+    }
+}
\ No newline at end of file
Index: src/org/openstreetmap/josm/gui/MapFrame.java
===================================================================
--- src/org/openstreetmap/josm/gui/MapFrame.java (revision 728)
+++ src/org/openstreetmap/josm/gui/MapFrame.java (working copy)
@@ -66,6 +66,7 @@
 
  public final ButtonGroup toolGroup = new ButtonGroup();
 
+ private PropertiesDialog propertiesDialog;
 
  public MapFrame() {
  setSize(400,400);
@@ -94,7 +95,7 @@
  toggleDialogs.setLayout(new BoxLayout(toggleDialogs, BoxLayout.Y_AXIS));
 
  addToggleDialog(new LayerListDialog(this));
- addToggleDialog(new PropertiesDialog(this));
+ addToggleDialog(propertiesDialog = new PropertiesDialog(this));
  addToggleDialog(new HistoryDialog());
  addToggleDialog(new SelectionListDialog());
  addToggleDialog(new UserListDialog());
@@ -187,4 +188,8 @@
  if (statusLine != null)
  panel.add(statusLine, BorderLayout.SOUTH);
  }
+
+ public final PropertiesDialog getPropertiesDialog() {
+     return propertiesDialog;
+    }
 }


_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Dirk Stöcker
Hello,

> And Dirk (and everyboy else), if you've got any more remarks or
> suggestions, please do go ahead.

Applied with some modifications. If someone is unhappy with parts of it,
he may fix them :-)

One request please: Fix your automatic correction, so auto-reverse during
"Join Ways" is recogniced also.

Ciao
--
http://www.dstoecker.eu/ (PGP key available)

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Robin Rattay
Dirk Stöcker schrieb:
> One request please: Fix your automatic correction, so auto-reverse during
> "Join Ways" is recogniced also.

I already considered this, however it leads to some usability problems:

It's impossible for the user to know which way is being reversed, so
it's diffcult to decide, which changes need to be applied.

(With the current implementation there is a simular problem, when
reversing several ways at once, but that happens not that often).

Also when joining ways there is a dialog for resoving property confict,
so that it's really impractical to have to correct the properties twice.

It probably whould be better to redesign the conflict resolution and
integrate it with the tag correction as cleanly as possible.

Robin

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Dirk Stöcker
On Fri, 18 Jul 2008, Robin Rattay wrote:

> I already considered this, however it leads to some usability problems:
>
> It's impossible for the user to know which way is being reversed, so
> it's diffcult to decide, which changes need to be applied.

In this case the request solves as a "be careful" warning. That is useful
enough.

> Also when joining ways there is a dialog for resoving property confict,
> so that it's really impractical to have to correct the properties twice.
>
> It probably whould be better to redesign the conflict resolution and
> integrate it with the tag correction as cleanly as possible.

Go on :-)

Ciao
--
http://www.dstoecker.eu/ (PGP key available)

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Frederik Ramm
In reply to this post by Dirk Stöcker
Hi,

Dirk Stöcker wrote:
>> And Dirk (and everyboy else), if you've got any more remarks or
>> suggestions, please do go ahead.
>
> Applied with some modifications. If someone is unhappy with parts of it,
> he may fix them :-)

While this is *generally* ok, it should not be used as an excuse to
break JOSM to the point where it doesn't compile anymore and then have
others clean up...

./org/openstreetmap/josm/corrector/TagCorrectionTableModel.java:23:
method does not override a method from its superclass
         @Override public int getColumnCount() {
          ^
./org/openstreetmap/josm/corrector/TagCorrectionTableModel.java:49:
method does not override a method from its superclass
         @Override public int getRowCount() {
          ^
./org/openstreetmap/josm/corrector/TagCorrectionTableModel.java:53:
method does not override a method from its superclass
         @Override public Object getValueAt(int rowIndex, int colIndex) {
          ^
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
3 errors

PLEASE do not check in code that does not compile with Java 1.5. (I
removed the "Override" statements. Please someone check whether these
methods are really needed... if they don't override something then who
calls them?)

Bye
Frederik

--
Frederik Ramm  ##  eMail [hidden email]  ##  N49°00'09" E008°23'33"

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Dirk Stöcker
On Sun, 20 Jul 2008, Frederik Ramm wrote:

> While this is *generally* ok, it should not be used as an excuse to
> break JOSM to the point where it doesn't compile anymore and then have
> others clean up...

Ooops. Worked here. I didn't mean to fix broken code, but rather to fix
it regarding improvements or different design aspects.

> PLEASE do not check in code that does not compile with Java 1.5. (I
> removed the "Override" statements. Please someone check whether these
> methods are really needed... if they don't override something then who
> calls them?)

Sometimes I have the feeling ant doesn't do proper dependency tracking
always. Can that be?

Or are the errors you corrected no problem with newer Java? In that case I
would need a way to at least get warnings in case such things occur. Is
there something like "--ansi" in C/C++ to test against different standard
variants?

Ciao
--
http://www.dstoecker.eu/ (PGP key available)

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
Reply | Threaded
Open this post in threaded view
|

Re: Automatic tag correction

Dirk Stöcker
In reply to this post by Frederik Ramm
On Sun, 20 Jul 2008, Frederik Ramm wrote:

> ./org/openstreetmap/josm/corrector/TagCorrectionTableModel.java:53:
> method does not override a method from its superclass
>         @Override public Object getValueAt(int rowIndex, int colIndex) {
...
> PLEASE do not check in code that does not compile with Java 1.5. (I
> removed the "Override" statements. Please someone check whether these
> methods are really needed... if they don't override something then who
> calls them?)

Hmm, I read about this a bit and now I'm totally confused. According to
this:

http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/table/AbstractTableModel.html

The functions, where you removed @Override are part of the Java 1.5, so
@Override should be correct.

Do I miss something here?

Ciao
--
http://www.dstoecker.eu/ (PGP key available)

_______________________________________________
josm-dev mailing list
[hidden email]
http://lists.openstreetmap.org/cgi-bin/mailman/listinfo/josm-dev
12