Changeset 15419 in josm for trunk/src/org
- Timestamp:
- 2019-10-05T15:59:56+02:00 (5 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/actions/SimplifyWayAction.java
r15152 r15419 6 6 import static org.openstreetmap.josm.tools.I18n.trn; 7 7 8 import java.awt.GridBagLayout; 8 9 import java.awt.event.ActionEvent; 9 10 import java.awt.event.KeyEvent; … … 18 19 import java.util.stream.Collectors; 19 20 21 import javax.swing.BorderFactory; 22 import javax.swing.JCheckBox; 23 import javax.swing.JLabel; 20 24 import javax.swing.JOptionPane; 25 import javax.swing.JPanel; 26 import javax.swing.JSpinner; 27 import javax.swing.SpinnerNumberModel; 21 28 import javax.swing.SwingUtilities; 22 29 … … 25 32 import org.openstreetmap.josm.command.DeleteCommand; 26 33 import org.openstreetmap.josm.command.SequenceCommand; 34 import org.openstreetmap.josm.data.SystemOfMeasurement; 27 35 import org.openstreetmap.josm.data.UndoRedoHandler; 28 36 import org.openstreetmap.josm.data.osm.DataSet; … … 31 39 import org.openstreetmap.josm.data.osm.Way; 32 40 import org.openstreetmap.josm.data.projection.Ellipsoid; 41 import org.openstreetmap.josm.gui.ExtendedDialog; 33 42 import org.openstreetmap.josm.gui.HelpAwareOptionPane; 34 43 import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec; … … 36 45 import org.openstreetmap.josm.gui.Notification; 37 46 import org.openstreetmap.josm.spi.preferences.Config; 47 import org.openstreetmap.josm.spi.preferences.IPreferences; 48 import org.openstreetmap.josm.tools.GBC; 38 49 import org.openstreetmap.josm.tools.ImageProvider; 39 50 import org.openstreetmap.josm.tools.Shortcut; … … 94 105 } 95 106 107 /** 108 * Asks the user for max-err value used to simplify ways, if not remembered before 109 * @param text the text being shown 110 * @param auto whether it's called automatically (conversion) or by the user 111 * @return the max-err value or -1 if canceled 112 * @since 15419 113 */ 114 public static double askSimplifyWays(String text, boolean auto) { 115 IPreferences s = Config.getPref(); 116 String key = "simplify-way." + (auto ? "auto." : ""); 117 String keyRemember = key + "remember"; 118 String keyError = key + "max-error"; 119 120 String r = s.get(keyRemember, "ask"); 121 if (auto && "no".equals(r)) { 122 return -1; 123 } else if ("yes".equals(r)) { 124 return s.getDouble(keyError, 3.0); 125 } 126 127 JPanel p = new JPanel(new GridBagLayout()); 128 p.add(new JLabel("<html><body style=\"width: 375px;\">" + text + "<br><br>" + 129 tr("This reduces unnecessary nodes along the way and is especially recommended if GPS tracks were recorded by time " 130 + "(e.g. one point per second) or when the accuracy was low (reduces \"zigzag\" tracks).") 131 + "</body></html>"), GBC.eol()); 132 p.setBorder(BorderFactory.createEmptyBorder(5, 10, 10, 5)); 133 JPanel q = new JPanel(new GridBagLayout()); 134 q.add(new JLabel(tr("Maximum error (meters): "))); 135 JSpinner n = new JSpinner(new SpinnerNumberModel( 136 s.getDouble(keyError, 3.0), 0.01, 100, 0.5)); 137 q.add(n); 138 q.setBorder(BorderFactory.createEmptyBorder(14, 0, 10, 0)); 139 p.add(q, GBC.eol()); 140 JCheckBox c = new JCheckBox(tr("Do not ask again")); 141 p.add(c, GBC.eol()); 142 143 ExtendedDialog ed = new ExtendedDialog(MainApplication.getMainFrame(), 144 tr("Simplify way"), tr("Simplify"), 145 auto ? tr("Proceed without simplifying") : tr("Cancel")) 146 .setContent(p) 147 .configureContextsensitiveHelp(("Action/SimplifyWay"), true); 148 if (auto) { 149 ed.setButtonIcons("simplify", "ok"); 150 } else { 151 ed.setButtonIcons("ok", "cancel"); 152 } 153 154 int ret = ed.showDialog().getValue(); 155 double val = (double) n.getValue(); 156 if (ret == 1) { 157 s.putDouble(keyError, val); 158 if (c.isSelected()) { 159 s.put(keyRemember, "yes"); 160 } 161 return val; 162 } else { 163 if (auto && c.isSelected()) { //do not remember cancel for manual simplify, otherwise nothing would happen 164 s.put(keyRemember, "no"); 165 } 166 return -1; 167 } 168 } 169 96 170 @Override 97 171 public void actionPerformed(ActionEvent e) { … … 109 183 } 110 184 111 Collection<Command> allCommands = new LinkedList<>();112 for (Way way: ways) {113 SequenceCommand simplifyCommand = simplifyWay(way);114 if (simplifyCommand == null) {115 continue;116 } 117 allCommands.add(simplifyCommand);118 }119 if (allCommands.isEmpty()) return;120 SequenceCommand rootCommand = new SequenceCommand(121 trn("Simplify {0} way", "Simplify {0} ways", allCommands.size(), allCommands.size()), 122 allCommands123 124 UndoRedoHandler.getInstance().add(rootCommand);185 String lengthstr = SystemOfMeasurement.getSystemOfMeasurement().getDistText( 186 ways.stream().collect( 187 Collectors.summingDouble(w -> { 188 return w.getLength(); 189 }))); 190 191 double err = askSimplifyWays(trn( 192 "You are about to simplify {0} way with a total length of {1}.", 193 "You are about to simplify {0} ways with a total length of {1}.", 194 ways.size(), ways.size(), lengthstr), false); 195 196 if (err > 0) { 197 simplifyWays(ways, err); 198 } 125 199 } finally { 126 200 ds.endUpdate(); … … 157 231 158 232 /** 159 * Simplifies a way with default threshold (read from preferences).160 *161 * @param w the way to simplify162 * @return The sequence of commands to run163 * @since 6411164 */165 public final SequenceCommand simplifyWay(Way w) {166 return simplifyWay(w, Config.getPref().getDouble("simplify-way.max-error", 3.0));167 }168 169 /**170 233 * Calculate a set of nodes which occurs more than once in the way 171 234 * @param w the way … … 183 246 184 247 /** 185 * Simplifies a way with a given threshold. 248 * Runs the commands to simplify the ways with the given threshold 249 * 250 * @param ways the ways to simplify 251 * @param threshold the max error threshold 252 * @since 15419 253 */ 254 public static void simplifyWays(List<Way> ways, double threshold) { 255 Collection<Command> allCommands = new LinkedList<>(); 256 for (Way way : ways) { 257 SequenceCommand simplifyCommand = createSimplifyCommand(way, threshold); 258 if (simplifyCommand == null) { 259 continue; 260 } 261 allCommands.add(simplifyCommand); 262 } 263 if (allCommands.isEmpty()) 264 return; 265 SequenceCommand rootCommand = new SequenceCommand( 266 trn("Simplify {0} way", "Simplify {0} ways", allCommands.size(), allCommands.size()), 267 allCommands); 268 UndoRedoHandler.getInstance().add(rootCommand); 269 } 270 271 /** 272 * Creates the SequenceCommand to simplify a way with default threshold. 273 * 274 * @param w the way to simplify 275 * @return The sequence of commands to run 276 * @since 6411 277 * @deprecated Replaced by {@link #createSimplifyCommand(Way)}. You can also use {@link #simplifyWays(List, double)} directly. 278 */ 279 @Deprecated 280 public final SequenceCommand simplifyWay(Way w) { 281 return createSimplifyCommand(w); 282 } 283 284 /** 285 * Creates the SequenceCommand to simplify a way with a given threshold. 186 286 * 187 287 * @param w the way to simplify … … 189 289 * @return The sequence of commands to run 190 290 * @since 6411 191 */ 291 * @deprecated Replaced by {@link #createSimplifyCommand(Way, double)}. You can also use {@link #simplifyWays(List, double)} directly. 292 */ 293 @Deprecated 192 294 public static SequenceCommand simplifyWay(Way w, double threshold) { 295 return createSimplifyCommand(w, threshold); 296 } 297 298 /** 299 * Creates the SequenceCommand to simplify a way with default threshold. 300 * 301 * @param w the way to simplify 302 * @return The sequence of commands to run 303 * @since 15419 304 */ 305 public final SequenceCommand createSimplifyCommand(Way w) { 306 return createSimplifyCommand(w, Config.getPref().getDouble("simplify-way.max-error", 3.0)); 307 } 308 309 /** 310 * Creates the SequenceCommand to simplify a way with a given threshold. 311 * 312 * @param w the way to simplify 313 * @param threshold the max error threshold 314 * @return The sequence of commands to run 315 * @since 15419 316 */ 317 public static SequenceCommand createSimplifyCommand(Way w, double threshold) { 193 318 int lower = 0; 194 319 int i = 0; -
trunk/src/org/openstreetmap/josm/data/gpx/GpxConstants.java
r15249 r15419 14 14 */ 15 15 public interface GpxConstants { 16 17 /** Prefix used for attributes when converting to OSM data */ 18 String GPX_PREFIX = "gpx:"; 16 19 17 20 /** GPS name of the element. This field will be transferred to and from the GPS. -
trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java
r15014 r15419 21 21 import java.util.function.BiPredicate; 22 22 23 import org.openstreetmap.josm.data.gpx.GpxConstants; 23 24 import org.openstreetmap.josm.spi.preferences.Config; 24 25 import org.openstreetmap.josm.tools.Utils; … … 741 742 List<String> l = new LinkedList<>(Arrays.asList( 742 743 "source", "source_ref", "source:", "comment", 743 "watch", "watch:", "description", "attribution" ));744 "watch", "watch:", "description", "attribution", GpxConstants.GPX_PREFIX)); 744 745 l.addAll(getDiscardableKeys()); 745 746 l.addAll(getWorkInProgressKeys()); -
trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
r15280 r15419 32 32 import java.util.List; 33 33 import java.util.Map; 34 import java.util.Optional; 34 35 import java.util.Set; 35 36 import java.util.concurrent.CopyOnWriteArrayList; … … 780 781 Map<String, Object> trkAttr = new HashMap<>(); 781 782 782 String name = w.get("name");783 String name = gpxVal(w, "name"); 783 784 if (name != null) { 784 785 trkAttr.put("name", name); … … 807 808 private static boolean containsOnlyGpxTags(Tagged t) { 808 809 for (String key : t.getKeys().keySet()) { 809 if (!GpxConstants.WPT_KEYS.contains(key) ) {810 if (!GpxConstants.WPT_KEYS.contains(key) && !key.startsWith(GpxConstants.GPX_PREFIX)) { 810 811 return false; 811 812 } 812 813 } 813 814 return true; 815 } 816 817 /** 818 * Reads the Gpx key from the given {@link OsmPrimitive}, with or without "gpx:" prefix 819 * @param node 820 * @param key 821 * @return the value or <code>null</code> if not present 822 * @since 15419 823 */ 824 public static String gpxVal(OsmPrimitive node, String key) { 825 return Optional.ofNullable(node.get(GpxConstants.GPX_PREFIX + key)).orElse(node.get(key)); 814 826 } 815 827 … … 837 849 838 850 try { 851 String v; 839 852 if (time > Long.MIN_VALUE) { 840 853 wpt.setTimeInMillis(time); 841 } else if ( n.hasKey(GpxConstants.PT_TIME)) {842 wpt.setTimeInMillis(DateUtils.tsFromString( n.get(GpxConstants.PT_TIME)));854 } else if ((v = gpxVal(n, GpxConstants.PT_TIME)) != null) { 855 wpt.setTimeInMillis(DateUtils.tsFromString(v)); 843 856 } else if (!n.isTimestampEmpty()) { 844 857 wpt.setTime(Integer.toUnsignedLong(n.getRawTimestamp())); … … 860 873 Collection<GpxLink> links = new ArrayList<>(); 861 874 for (String key : new String[]{"link", "url", "website", "contact:website"}) { 862 String value = n.get(key);875 String value = gpxVal(n, key); 863 876 if (value != null) { 864 877 links.add(new GpxLink(value)); … … 898 911 possibleKeys.add(0, gpxKey); 899 912 for (String key : possibleKeys) { 900 String value = p.get(key);913 String value = gpxVal(p, key); 901 914 if (value != null) { 902 915 try { … … 919 932 possibleKeys.add(0, gpxKey); 920 933 for (String key : possibleKeys) { 921 String value = p.get(key);934 String value = gpxVal(p, key); 922 935 if (value != null) { 923 936 try { … … 939 952 possibleKeys.add(0, gpxKey); 940 953 for (String key : possibleKeys) { 941 String value = p.get(key);954 String value = gpxVal(p, key); 942 955 // Sanity checks 943 956 if (value != null && (!GpxConstants.PT_FIX.equals(gpxKey) || GpxConstants.FIX_VALUES.contains(value))) { -
trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertFromGpxLayerAction.java
r15249 r15419 55 55 final DataSet ds = new DataSet(); 56 56 57 List<String> keys = new ArrayList<>(); 57 List<String> keys = new ArrayList<>(); // note that items in this list don't have the GPX_PREFIX 58 58 String convertTags = Config.getPref().get(GPX_SETTING, "ask"); 59 59 boolean check = "list".equals(convertTags) || "ask".equals(convertTags); … … 73 73 if (!none && (obj instanceof String || obj instanceof Number)) { 74 74 // only convert when required 75 n.put( key, obj.toString());75 n.put(GpxConstants.GPX_PREFIX + key, obj.toString()); 76 76 } else if (obj instanceof Date && GpxConstants.PT_TIME.equals(key)) { 77 77 // timestamps should always be converted 78 78 Date date = (Date) obj; 79 79 if (!none) { //... but the tag will only be set when required 80 n.put( key, DateUtils.fromDate(date));80 n.put(GpxConstants.GPX_PREFIX + key, DateUtils.fromDate(date)); 81 81 } 82 82 n.setTimestamp(date); … … 126 126 * Filters the tags of the given {@link DataSet} 127 127 * @param ds The {@link DataSet} 128 * @param listPos A {@code List<String>} containing the tags to be kept, can be {@code null} if all tags are to be removed128 * @param listPos A {@code List<String>} containing the tags (without prefix) to be kept, can be {@code null} if all tags are to be removed 129 129 * @return The {@link DataSet} 130 130 * @since 14103 … … 134 134 for (Node n : nodes) { 135 135 for (String key : n.keySet()) { 136 if (listPos == null || !listPos.contains(key )) {136 if (listPos == null || !listPos.contains(key.substring(GpxConstants.GPX_PREFIX.length()))) { 137 137 n.put(key, null); 138 138 } -
trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertToDataLayerAction.java
r14153 r15419 8 8 import java.awt.event.ActionEvent; 9 9 import java.io.File; 10 import java.util.ArrayList; 10 11 11 12 import javax.swing.AbstractAction; … … 14 15 import javax.swing.JPanel; 15 16 17 import org.openstreetmap.josm.actions.SimplifyWayAction; 16 18 import org.openstreetmap.josm.data.osm.DataSet; 17 19 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; … … 63 65 final DataSet ds = convert(); 64 66 if (ds != null) { 67 double err = SimplifyWayAction.askSimplifyWays(tr("Would you like to simplify the ways in the converted layer?"), true); 68 if (err > 0) { 69 SimplifyWayAction.simplifyWays(new ArrayList<>(ds.getWays()), err); 70 } 65 71 final OsmDataLayer osmLayer = new OsmDataLayer(ds, tr("Converted from: {0}", layer.getName()), null); 66 72 if (layer.getAssociatedFile() != null) {
Note:
See TracChangeset
for help on using the changeset viewer.