Changes in / [7499:7505] in josm
- Location:
- /trunk
- Files:
-
- 5 edited
-
data/tagging-preset.xsd (modified) (7 diffs)
-
src/org/openstreetmap/josm/data/osm/DataSet.java (modified) (5 diffs)
-
src/org/openstreetmap/josm/data/osm/DatasetConsistencyTest.java (modified) (12 diffs)
-
src/org/openstreetmap/josm/gui/tagging/TaggingPresetItems.java (modified) (3 diffs)
-
src/org/openstreetmap/josm/gui/widgets/JosmTextField.java (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
/trunk/data/tagging-preset.xsd
r7499 r7505 86 86 </complexType> 87 87 88 <complexType name="chunk"> 89 <sequence> 90 <choice minOccurs="1" maxOccurs="unbounded"> 91 <group ref="tns:optional_elements" /> 92 <element name="key" type="tns:key" /> 93 <element name="optional" type="tns:optional" minOccurs="0" /> 94 </choice> 95 </sequence> 96 <attribute name="id" type="ID" use="required" /> 97 </complexType> 98 99 <complexType name="reference"> 100 <attribute name="ref" type="IDREF" use="required" /> 101 </complexType> 102 103 <group name="optional_elements"> 88 <complexType name="chunk"> 89 <choice minOccurs="1" maxOccurs="1"> 90 <sequence> 91 <choice minOccurs="1" maxOccurs="unbounded"> 92 <group ref="tns:optional_elements" /> 93 <element name="key" type="tns:key" /> 94 <element name="optional" type="tns:optional" minOccurs="0" /> 95 </choice> 96 </sequence> 97 <sequence> 98 <!-- Cannot use tns:list_elements here because reference is present both in optional_elements and list_elements 99 so it violates cos-nonambig: Unique Particle Attribution : 100 <group ref="tns:list_elements" minOccurs="1" maxOccurs="unbounded" />--> 101 <element name="list_entry" type="tns:list_entry" minOccurs="1" maxOccurs="unbounded" /> 102 </sequence> 103 </choice> 104 <attribute name="id" type="ID" use="required" /> 105 </complexType> 106 107 <complexType name="reference"> 108 <attribute name="ref" type="IDREF" use="required" /> 109 </complexType> 110 111 <group name="optional_elements"> 104 112 <choice> 105 113 <element name="label" type="tns:label" /> … … 117 125 </group> 118 126 127 <group name="list_elements"> 128 <choice> 129 <element name="list_entry" type="tns:list_entry" /> 130 <element name="reference" type="tns:reference" /> 131 </choice> 132 </group> 133 119 134 <complexType name="key"> 120 135 <attribute name="key" type="string" use="required" /> … … 122 137 <attribute name="match" type="string" /> 123 138 </complexType> 124 125 139 126 140 <complexType name="link"> … … 179 193 <!-- use either list_entry's or a combination of values/display_values --> 180 194 <sequence> 181 < element name="list_entry" type="tns:list_entry" minOccurs="0" maxOccurs="unbounded" />195 <group ref="tns:list_elements" minOccurs="0" maxOccurs="unbounded" /> 182 196 </sequence> 183 197 <attribute name="key" type="string" use="required" /> … … 207 221 <!-- use either list_entry's or a combination of values/display_values --> 208 222 <sequence> 209 < element name="list_entry" type="tns:list_entry" minOccurs="0" maxOccurs="unbounded" />223 <group ref="tns:list_elements" minOccurs="0" maxOccurs="unbounded" /> 210 224 </sequence> 211 225 <attribute name="key" type="string" use="required" /> … … 216 230 <attribute name="values_context" type="string" /> 217 231 <attribute name="display_values" type="string" /> 218 <attribute name="values_searchable" type="boolean" />232 <attribute name="values_searchable" type="boolean" /> 219 233 <attribute name="default" type="string" /> 220 234 <attribute name="use_last_as_default" type="tns:last_default" /> … … 247 261 <attribute name="value_on" type="string" /> 248 262 <attribute name="value_off" type="string" /> 249 <attribute name="disable_off" type="boolean" />263 <attribute name="disable_off" type="boolean" /> 250 264 <attribute name="match" type="tns:match" /> 251 265 -
/trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
r7499 r7505 102 102 private static final int MAX_EVENTS = 1000; 103 103 104 private Storage<OsmPrimitive> allPrimitives = new Storage<>(new Storage.PrimitiveIdHash(), true); 105 private Map<PrimitiveId, OsmPrimitive> primitivesMap = allPrimitives.foreignKey(new Storage.PrimitiveIdHash()); 106 private CopyOnWriteArrayList<DataSetListener> listeners = new CopyOnWriteArrayList<>(); 104 private final Storage<OsmPrimitive> allPrimitives = new Storage<>(new Storage.PrimitiveIdHash(), true); 105 private final Map<PrimitiveId, OsmPrimitive> primitivesMap = allPrimitives.foreignKey(new Storage.PrimitiveIdHash()); 106 private final CopyOnWriteArrayList<DataSetListener> listeners = new CopyOnWriteArrayList<>(); 107 107 108 108 // provide means to highlight map elements that are not osm primitives … … 257 257 * conversion of the whole DataSet by iterating over this data structure. 258 258 */ 259 private QuadBuckets<Node> nodes = new QuadBuckets<>(); 259 private final QuadBuckets<Node> nodes = new QuadBuckets<>(); 260 260 261 261 private <T extends OsmPrimitive> Collection<T> getPrimitives(Predicate<OsmPrimitive> predicate) { … … 287 287 288 288 /** 289 * Determines if the given node can be retrieved in the data set through its bounding box. Useful for dataset consistency test. 290 * For efficiency reasons this method does not lock the dataset, you have to lock it manually. 291 * 292 * @param n The node to search 293 * @return {@code true} if {@code n} ban be retrieved in this data set, {@code false} otherwise 294 * @since 7501 295 */ 296 public boolean containsNode(Node n) { 297 return nodes.contains(n); 298 } 299 300 /** 289 301 * All ways (Streets etc.) in the DataSet. 290 302 * 291 303 * The way nodes are stored only in the way list. 292 304 */ 293 private QuadBuckets<Way> ways = new QuadBuckets<>(); 305 private final QuadBuckets<Way> ways = new QuadBuckets<>(); 294 306 295 307 /** … … 317 329 318 330 /** 331 * Determines if the given way can be retrieved in the data set through its bounding box. Useful for dataset consistency test. 332 * For efficiency reasons this method does not lock the dataset, you have to lock it manually. 333 * 334 * @param w The way to search 335 * @return {@code true} if {@code w} ban be retrieved in this data set, {@code false} otherwise 336 * @since 7501 337 */ 338 public boolean containsWay(Way w) { 339 return ways.contains(w); 340 } 341 342 /** 319 343 * All relations/relationships 320 344 */ 321 private Collection<Relation> relations = new ArrayList<>(); 345 private final Collection<Relation> relations = new ArrayList<>(); 322 346 323 347 /** … … 349 373 lock.readLock().unlock(); 350 374 } 375 } 376 377 /** 378 * Determines if the given relation can be retrieved in the data set through its bounding box. Useful for dataset consistency test. 379 * For efficiency reasons this method does not lock the dataset, you have to lock it manually. 380 * 381 * @param r The relation to search 382 * @return {@code true} if {@code r} ban be retrieved in this data set, {@code false} otherwise 383 * @since 7501 384 */ 385 public boolean containsRelation(Relation r) { 386 return relations.contains(r); 351 387 } 352 388 -
/trunk/src/org/openstreetmap/josm/data/osm/DatasetConsistencyTest.java
r7499 r7505 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.data.osm; 3 4 import static org.openstreetmap.josm.tools.I18n.tr; 3 5 4 6 import java.io.PrintWriter; … … 6 8 import java.io.Writer; 7 9 8 import org.openstreetmap.josm.data.coor.LatLon; 10 import org.openstreetmap.josm.Main; 11 import org.openstreetmap.josm.tools.Utils; 9 12 10 13 /** 11 * This class can be used to run consistency tests on dataset. Any errors found will be written to provided PrintWriter 14 * This class can be used to run consistency tests on dataset. Any errors found will be written to provided PrintWriter. 12 15 * <br> 13 * Texts here should not be translated because they're not intended for users but for josm developers 14 * 16 * Texts here should not be translated because they're not intended for users but for josm developers. 17 * @since 2500 15 18 */ 16 19 public class DatasetConsistencyTest { … … 21 24 private int errorCount; 22 25 26 /** 27 * Constructs a new {@code DatasetConsistencyTest}. 28 * @param dataSet The dataset to test 29 * @param writer The writer used to write results 30 */ 23 31 public DatasetConsistencyTest(DataSet dataSet, Writer writer) { 24 32 this.dataSet = dataSet; … … 33 41 } 34 42 43 /** 44 * Checks that parent primitive is referred from its child members 45 */ 35 46 public void checkReferrers() { 47 long startTime = System.currentTimeMillis(); 36 48 // It's also error when referred primitive's dataset is null but it's already covered by referredPrimitiveNotInDataset check 37 for (Way way :dataSet.getWays()) {49 for (Way way : dataSet.getWays()) { 38 50 if (!way.isDeleted()) { 39 for (Node n :way.getNodes()) {51 for (Node n : way.getNodes()) { 40 52 if (n.getDataSet() != null && !n.getReferrers().contains(way)) { 41 53 printError("WAY NOT IN REFERRERS", "%s is part of %s but is not in referrers", n, way); … … 45 57 } 46 58 47 for (Relation relation :dataSet.getRelations()) {59 for (Relation relation : dataSet.getRelations()) { 48 60 if (!relation.isDeleted()) { 49 for (RelationMember m :relation.getMembers()) {61 for (RelationMember m : relation.getMembers()) { 50 62 if (m.getMember().getDataSet() != null && !m.getMember().getReferrers().contains(relation)) { 51 63 printError("RELATION NOT IN REFERRERS", "%s is part of %s but is not in referrers", m.getMember(), relation); … … 54 66 } 55 67 } 56 } 57 68 printElapsedTime(startTime); 69 } 70 71 /** 72 * Checks for womplete ways with incomplete nodes. 73 */ 58 74 public void checkCompleteWaysWithIncompleteNodes() { 59 for (Way way:dataSet.getWays()) { 75 long startTime = System.currentTimeMillis(); 76 for (Way way : dataSet.getWays()) { 60 77 if (way.isUsable()) { 61 for (Node node :way.getNodes()) {78 for (Node node : way.getNodes()) { 62 79 if (node.isIncomplete()) { 63 80 printError("USABLE HAS INCOMPLETE", "%s is usable but contains incomplete node '%s'", way, node); … … 66 83 } 67 84 } 68 } 69 85 printElapsedTime(startTime); 86 } 87 88 /** 89 * Checks for complete nodes without coordinates. 90 */ 70 91 public void checkCompleteNodesWithoutCoordinates() { 71 for (Node node:dataSet.getNodes()) { 92 long startTime = System.currentTimeMillis(); 93 for (Node node : dataSet.getNodes()) { 72 94 if (!node.isIncomplete() && node.isVisible() && (node.getCoor() == null || node.getEastNorth() == null)) { 73 95 printError("COMPLETE WITHOUT COORDINATES", "%s is not incomplete but has null coordinates", node); 74 96 } 75 97 } 76 } 77 98 printElapsedTime(startTime); 99 } 100 101 /** 102 * Checks that nodes can be retrieved through their coordinates. 103 */ 78 104 public void searchNodes() { 79 for (Node n:dataSet.getNodes()) { 80 if (!n.isIncomplete() && !n.isDeleted()) { 81 LatLon c = n.getCoor(); 82 if (c != null) { 83 BBox box = c.toBBox(0.0001); 84 if (!dataSet.searchNodes(box).contains(n)) { 85 printError("SEARCH NODES", "%s not found using Dataset.searchNodes()", n); 86 } 87 } 88 } 89 } 90 } 91 105 long startTime = System.currentTimeMillis(); 106 dataSet.getReadLock().lock(); 107 try { 108 for (Node n : dataSet.getNodes()) { 109 // Call isDrawable() as an efficient replacement to previous checks (!deleted, !incomplete, getCoor() != null) 110 if (n.isDrawable() && !dataSet.containsNode(n)) { 111 printError("SEARCH NODES", "%s not found using Dataset.containsNode()", n); 112 } 113 } 114 } finally { 115 dataSet.getReadLock().unlock(); 116 } 117 printElapsedTime(startTime); 118 } 119 120 /** 121 * Checks that ways can be retrieved through their bounding box. 122 */ 92 123 public void searchWays() { 93 for (Way w:dataSet.getWays()) { 94 if (!w.isIncomplete() && !w.isDeleted() && w.getNodesCount() >= 2 && !dataSet.searchWays(w.getBBox()).contains(w)) { 95 printError("SEARCH WAYS", "%s not found using Dataset.searchWays()", w); 96 } 97 } 124 long startTime = System.currentTimeMillis(); 125 dataSet.getReadLock().lock(); 126 try { 127 for (Way w : dataSet.getWays()) { 128 if (!w.isIncomplete() && !w.isDeleted() && w.getNodesCount() >= 2 && !dataSet.containsWay(w)) { 129 printError("SEARCH WAYS", "%s not found using Dataset.containsWay()", w); 130 } 131 } 132 } finally { 133 dataSet.getReadLock().unlock(); 134 } 135 printElapsedTime(startTime); 98 136 } 99 137 … … 112 150 } 113 151 152 /** 153 * Checks that referred primitives are present in dataset. 154 */ 114 155 public void referredPrimitiveNotInDataset() { 115 for (Way way:dataSet.getWays()) { 116 for (Node node:way.getNodes()) { 156 long startTime = System.currentTimeMillis(); 157 for (Way way : dataSet.getWays()) { 158 for (Node node : way.getNodes()) { 117 159 checkReferredPrimitive(node, way); 118 160 } 119 161 } 120 162 121 for (Relation relation :dataSet.getRelations()) {122 for (RelationMember member :relation.getMembers()) {163 for (Relation relation : dataSet.getRelations()) { 164 for (RelationMember member : relation.getMembers()) { 123 165 checkReferredPrimitive(member.getMember(), relation); 124 166 } 125 167 } 126 } 127 128 168 printElapsedTime(startTime); 169 } 170 171 /** 172 * Checks for zero and one-node ways. 173 */ 129 174 public void checkZeroNodesWays() { 130 for (Way way:dataSet.getWays()) { 175 long startTime = System.currentTimeMillis(); 176 for (Way way : dataSet.getWays()) { 131 177 if (way.isUsable() && way.getNodesCount() == 0) { 132 178 printError("WARN - ZERO NODES", "Way %s has zero nodes", way); … … 135 181 } 136 182 } 137 } 138 183 printElapsedTime(startTime); 184 } 185 186 private void printElapsedTime(long startTime) { 187 if (Main.isDebugEnabled()) { 188 StackTraceElement item = Thread.currentThread().getStackTrace()[2]; 189 String operation = getClass().getSimpleName() + "." + item.getMethodName(); 190 long elapsedTime = System.currentTimeMillis() - startTime; 191 Main.debug(tr("Test ''{0}'' completed in {1}", 192 operation, Utils.getDurationString(elapsedTime))); 193 } 194 } 195 196 /** 197 * Runs test. 198 */ 139 199 public void runTest() { 140 200 try { 201 long startTime = System.currentTimeMillis(); 141 202 referredPrimitiveNotInDataset(); 142 203 checkReferrers(); … … 146 207 searchWays(); 147 208 checkZeroNodesWays(); 209 printElapsedTime(startTime); 148 210 if (errorCount > MAX_ERRORS) { 149 211 writer.println((errorCount - MAX_ERRORS) + " more..."); 150 212 } 213 151 214 } catch (Exception e) { 152 215 writer.println("Exception during dataset integrity test:"); … … 155 218 } 156 219 220 /** 221 * Runs test on the given dataset. 222 * @param dataSet the dataset to test 223 * @return the errors as string 224 */ 157 225 public static String runTests(DataSet dataSet) { 158 226 StringWriter writer = new StringWriter(); … … 160 228 return writer.toString(); 161 229 } 162 163 230 } -
/trunk/src/org/openstreetmap/josm/gui/tagging/TaggingPresetItems.java
r7499 r7505 592 592 private JComponent value; 593 593 594 @Override public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel, boolean presetInitiallyMatches) { 594 @Override 595 public boolean addToPanel(JPanel p, Collection<OsmPrimitive> sel, boolean presetInitiallyMatches) { 595 596 596 597 // find out if our key is already used in the selection. … … 602 603 initAutoCompletionField(textField, key); 603 604 } 605 textField.setHint(key); 604 606 if (length != null && !length.isEmpty()) { 605 607 textField.setMaxChars(Integer.valueOf(length)); … … 1219 1221 AutoCompletingTextField tf = new AutoCompletingTextField(); 1220 1222 initAutoCompletionField(tf, key); 1223 tf.setHint(key); 1221 1224 if (length != null && !length.isEmpty()) { 1222 1225 tf.setMaxChars(Integer.valueOf(length)); -
/trunk/src/org/openstreetmap/josm/gui/widgets/JosmTextField.java
r7499 r7505 1 1 // License: GPL. For details, see LICENSE file. 2 2 package org.openstreetmap.josm.gui.widgets; 3 4 import java.awt.Color; 5 import java.awt.FontMetrics; 6 import java.awt.Graphics; 7 import java.awt.Graphics2D; 8 import java.awt.Insets; 9 import java.awt.RenderingHints; 10 import java.awt.event.FocusEvent; 11 import java.awt.event.FocusListener; 3 12 4 13 import javax.swing.JTextField; … … 6 15 7 16 /** 8 * Subclass of {@link JTextField} that adds a "native" context menu (cut/copy/paste/select all). 17 * Subclass of {@link JTextField} that adds a "native" context menu (cut/copy/paste/select all) 18 * and an optional "hint" displayed when no text has been entered. 9 19 * @since 5886 10 20 */ 11 public class JosmTextField extends JTextField { 21 public class JosmTextField extends JTextField implements FocusListener { 22 23 private String hint; 12 24 13 25 /** … … 34 46 setMinimumSize(getPreferredSize()); 35 47 } 48 addFocusListener(this); 36 49 } 37 50 … … 84 97 this(null, null, 0); 85 98 } 99 100 /** 101 * Replies the hint displayed when no text has been entered. 102 * @return the hint 103 * @since 7505 104 */ 105 public final String getHint() { 106 return hint; 107 } 108 109 /** 110 * Sets the hint to display when no text has been entered. 111 * @param hint the hint to set 112 * @since 7505 113 */ 114 public final void setHint(String hint) { 115 this.hint = hint; 116 } 117 118 @Override 119 public void paint(Graphics g) { 120 super.paint(g); 121 if (hint != null && !hint.isEmpty() && getText().isEmpty() && !isFocusOwner()) { 122 // Taken from http://stackoverflow.com/a/24571681/2257172 123 int h = getHeight(); 124 ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 125 Insets ins = getInsets(); 126 FontMetrics fm = g.getFontMetrics(); 127 int c0 = getBackground().getRGB(); 128 int c1 = getForeground().getRGB(); 129 int m = 0xfefefefe; 130 int c2 = ((c0 & m) >>> 1) + ((c1 & m) >>> 1); 131 g.setColor(new Color(c2, true)); 132 g.drawString(hint, ins.left, h / 2 + fm.getAscent() / 2 - 2); 133 } 134 } 135 136 @Override 137 public void focusGained(FocusEvent e) { 138 repaint(); 139 } 140 141 @Override 142 public void focusLost(FocusEvent e) { 143 repaint(); 144 } 86 145 }
Note:
See TracChangeset
for help on using the changeset viewer.
