- Timestamp:
- 2018-08-11T19:37:49+02:00 (6 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/osm/search/SearchCompiler.java
r14120 r14129 300 300 return match((Tagged) osm); 301 301 } 302 303 protected static Pattern compilePattern(String regex, int flags) throws SearchParseError { 304 try { 305 return Pattern.compile(regex, flags); 306 } catch (PatternSyntaxException e) { 307 throw new SearchParseError(tr(rxErrorMsg, e.getPattern(), e.getIndex(), e.getMessage()), e); 308 } catch (IllegalArgumentException | StringIndexOutOfBoundsException e) { 309 // StringIndexOutOfBoundsException catched because of https://bugs.openjdk.java.net/browse/JI-9044959 310 // See #13870: To remove after we switch to a version of Java which resolves this bug 311 throw new SearchParseError(tr(rxErrorMsgNoPos, regex, e.getMessage()), e); 312 } 313 } 302 314 } 303 315 … … 686 698 if (regexSearch) { 687 699 int searchFlags = regexFlags(caseSensitive); 688 689 try { 690 this.keyPattern = Pattern.compile(key, searchFlags); 691 } catch (PatternSyntaxException e) { 692 throw new SearchParseError(tr(rxErrorMsg, e.getPattern(), e.getIndex(), e.getMessage()), e); 693 } catch (IllegalArgumentException e) { 694 throw new SearchParseError(tr(rxErrorMsgNoPos, key, e.getMessage()), e); 695 } 696 try { 697 this.valuePattern = Pattern.compile(value, searchFlags); 698 } catch (PatternSyntaxException e) { 699 throw new SearchParseError(tr(rxErrorMsg, e.getPattern(), e.getIndex(), e.getMessage()), e); 700 } catch (IllegalArgumentException | StringIndexOutOfBoundsException e) { 701 throw new SearchParseError(tr(rxErrorMsgNoPos, value, e.getMessage()), e); 702 } 700 this.keyPattern = compilePattern(key, searchFlags); 701 this.valuePattern = compilePattern(value, searchFlags); 703 702 this.key = key; 704 703 this.value = value; 705 706 704 } else { 707 705 this.key = key; … … 966 964 967 965 if (regexp && !key.isEmpty() && !"*".equals(key)) { 968 try { 969 keyPattern = Pattern.compile(key, regexFlags(false)); 970 } catch (PatternSyntaxException e) { 971 throw new SearchParseError(tr(rxErrorMsg, e.getPattern(), e.getIndex(), e.getMessage()), e); 972 } catch (IllegalArgumentException e) { 973 throw new SearchParseError(tr(rxErrorMsgNoPos, key, e.getMessage()), e); 974 } 966 keyPattern = compilePattern(key, regexFlags(false)); 975 967 } else { 976 968 keyPattern = null; 977 969 } 978 970 if (regexp && !this.value.isEmpty() && !"*".equals(this.value)) { 979 try { 980 valuePattern = Pattern.compile(this.value, regexFlags(false)); 981 } catch (PatternSyntaxException e) { 982 throw new SearchParseError(tr(rxErrorMsg, e.getPattern(), e.getIndex(), e.getMessage()), e); 983 } catch (IllegalArgumentException e) { 984 throw new SearchParseError(tr(rxErrorMsgNoPos, value, e.getMessage()), e); 985 } 971 valuePattern = compilePattern(this.value, regexFlags(false)); 986 972 } else { 987 973 valuePattern = null; … … 1098 1084 this.caseSensitive = caseSensitive; 1099 1085 if (regexSearch) { 1100 try { 1101 this.searchRegex = Pattern.compile(s, regexFlags(caseSensitive)); 1102 } catch (PatternSyntaxException e) { 1103 throw new SearchParseError(tr(rxErrorMsg, e.getPattern(), e.getIndex(), e.getMessage()), e); 1104 } catch (IllegalArgumentException | StringIndexOutOfBoundsException e) { 1105 // StringIndexOutOfBoundsException catched because of https://bugs.openjdk.java.net/browse/JI-9044959 1106 // See #13870: To remove after we switch to a version of Java which resolves this bug 1107 throw new SearchParseError(tr(rxErrorMsgNoPos, s, e.getMessage()), e); 1108 } 1086 this.searchRegex = compilePattern(s, regexFlags(caseSensitive)); 1109 1087 this.search = s; 1110 1088 } else if (caseSensitive) { -
trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
r13849 r14129 39 39 import org.openstreetmap.josm.gui.io.importexport.GpxImporter; 40 40 import org.openstreetmap.josm.gui.layer.gpx.ChooseTrackVisibilityAction; 41 import org.openstreetmap.josm.gui.layer.gpx.ConvertToDataLayerAction;42 41 import org.openstreetmap.josm.gui.layer.gpx.CustomizeDrawingAction; 43 42 import org.openstreetmap.josm.gui.layer.gpx.DownloadAlongTrackAction; 44 43 import org.openstreetmap.josm.gui.layer.gpx.DownloadWmsAlongTrackAction; 44 import org.openstreetmap.josm.gui.layer.gpx.ConvertFromGpxLayerAction; 45 45 import org.openstreetmap.josm.gui.layer.gpx.GpxDrawHelper; 46 46 import org.openstreetmap.josm.gui.layer.gpx.ImportAudioAction; … … 225 225 new ImportAudioAction(this), 226 226 new MarkersFromNamedPointsAction(this), 227 new Convert ToDataLayerAction.FromGpxLayer(this),227 new ConvertFromGpxLayerAction(this), 228 228 new DownloadAlongTrackAction(data), 229 229 new DownloadWmsAlongTrackAction(data), -
trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertToDataLayerAction.java
r14119 r14129 7 7 import java.awt.GridBagLayout; 8 8 import java.awt.event.ActionEvent; 9 import java.awt.event.ActionListener;10 9 import java.io.File; 11 import java.text.DateFormat;12 import java.util.ArrayList;13 import java.util.Arrays;14 import java.util.Collection;15 import java.util.Date;16 import java.util.Iterator;17 import java.util.List;18 import java.util.Map.Entry;19 import java.util.Optional;20 10 21 11 import javax.swing.AbstractAction; 22 import javax.swing.BorderFactory;23 import javax.swing.ButtonGroup;24 import javax.swing.JCheckBox;25 12 import javax.swing.JLabel; 26 13 import javax.swing.JOptionPane; 27 14 import javax.swing.JPanel; 28 import javax.swing.JRadioButton;29 15 30 16 import org.openstreetmap.josm.Main; 31 import org.openstreetmap.josm.data.gpx.GpxConstants;32 import org.openstreetmap.josm.data.gpx.GpxTrack;33 import org.openstreetmap.josm.data.gpx.GpxTrackSegment;34 import org.openstreetmap.josm.data.gpx.WayPoint;35 17 import org.openstreetmap.josm.data.osm.DataSet; 36 import org.openstreetmap.josm.data.osm.Node;37 import org.openstreetmap.josm.data.osm.Way;38 18 import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil; 39 import org.openstreetmap.josm.gui.ExtendedDialog;40 19 import org.openstreetmap.josm.gui.MainApplication; 41 import org.openstreetmap.josm.gui.layer.GpxLayer;42 20 import org.openstreetmap.josm.gui.layer.Layer; 43 21 import org.openstreetmap.josm.gui.layer.OsmDataLayer; 44 import org.openstreetmap.josm.gui.layer.markerlayer.Marker;45 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;46 22 import org.openstreetmap.josm.gui.widgets.UrlLabel; 47 23 import org.openstreetmap.josm.spi.preferences.Config; 48 24 import org.openstreetmap.josm.tools.GBC; 49 25 import org.openstreetmap.josm.tools.ImageProvider; 50 import org.openstreetmap.josm.tools.Logging;51 import org.openstreetmap.josm.tools.UncheckedParseException;52 import org.openstreetmap.josm.tools.date.DateUtils;53 26 54 27 /** … … 69 42 this.layer = layer; 70 43 putValue("help", ht("/Action/ConvertToDataLayer")); 71 }72 73 /**74 * Converts a {@link GpxLayer} to a {@link OsmDataLayer}.75 */76 public static class FromGpxLayer extends ConvertToDataLayerAction<GpxLayer> {77 78 private static final String GPX_SETTING = "gpx.convert-tags";79 private final DateFormat timeFormatter = DateUtils.getGpxFormat();80 81 /**82 * Creates a new {@code FromGpxLayer}.83 * @param layer the source layer84 */85 public FromGpxLayer(GpxLayer layer) {86 super(layer);87 }88 89 @Override90 public DataSet convert() {91 final DataSet ds = new DataSet();92 93 List<String> keys = new ArrayList<>();94 String convertTags = Config.getPref().get(GPX_SETTING, "ask");95 boolean check = "list".equals(convertTags) || "ask".equals(convertTags);96 boolean none = "no".equals(convertTags); // no need to convert tags when no dialog will be shown anyways97 98 for (GpxTrack trk : layer.data.getTracks()) {99 for (GpxTrackSegment segment : trk.getSegments()) {100 List<Node> nodes = new ArrayList<>();101 for (WayPoint p : segment.getWayPoints()) {102 Node n = new Node(p.getCoor());103 for (Entry<String, Object> entry : p.attr.entrySet()) {104 String key = entry.getKey();105 Object obj = p.get(key);106 if (check && !keys.contains(key) && (obj instanceof String || obj instanceof Date)) {107 keys.add(key);108 }109 if (obj instanceof String) {110 String str = (String) obj;111 if (!none) {112 // only convert when required113 n.put(key, str);114 }115 if (GpxConstants.PT_TIME.equals(key)) {116 // timestamps should always be converted117 try {118 n.setTimestamp(DateUtils.fromString(str));119 } catch (UncheckedParseException e) {120 Logging.log(Logging.LEVEL_WARN, e);121 }122 }123 } else if (obj instanceof Date && GpxConstants.PT_TIME.equals(key)) {124 // timestamps should always be converted125 Date date = (Date) obj;126 if (!none) { //... but the tag will only be set when required127 n.put(key, timeFormatter.format(date));128 }129 n.setTimestamp(date);130 }131 }132 ds.addPrimitive(n);133 nodes.add(n);134 }135 Way w = new Way();136 w.setNodes(nodes);137 ds.addPrimitive(w);138 }139 }140 //gpx.convert-tags: all, list, *ask, no141 //gpx.convert-tags.last: *all, list, no142 //gpx.convert-tags.list.yes143 //gpx.convert-tags.list.no144 List<String> listPos = Config.getPref().getList(GPX_SETTING + ".list.yes");145 List<String> listNeg = Config.getPref().getList(GPX_SETTING + ".list.no");146 if (check && !keys.isEmpty()) {147 // Either "list" or "ask" was stored in the settings, so the Nodes have to be filtered after all tags have been processed148 List<String> allTags = new ArrayList<>(listPos);149 allTags.addAll(listNeg);150 if (!allTags.containsAll(keys) || "ask".equals(convertTags)) {151 // not all keys are in positive/negative list, so we have to ask the user152 TagConversionDialogResponse res = showTagConversionDialog(keys, listPos, listNeg);153 if (res.sel == null) {154 return null;155 }156 listPos = res.listPos;157 158 if ("no".equals(res.sel)) {159 // User just chose not to convert any tags, but that was unknown before the initial conversion160 return filterDataSet(ds, null);161 } else if ("all".equals(res.sel)) {162 return ds;163 }164 }165 if (!listPos.containsAll(keys)) {166 return filterDataSet(ds, listPos);167 }168 }169 return ds;170 }171 172 /**173 * Filters the tags of the given {@link DataSet}174 * @param ds The {@link DataSet}175 * @param listPos A {@code List<String>} containing the tags to be kept, can be {@code null} if all tags are to be removed176 * @return The {@link DataSet}177 * @since 14103178 */179 public DataSet filterDataSet(DataSet ds, List<String> listPos) {180 Collection<Node> nodes = ds.getNodes();181 for (Node n : nodes) {182 for (String key : n.keySet()) {183 if (listPos == null || !listPos.contains(key)) {184 n.put(key, null);185 }186 }187 }188 return ds;189 }190 191 /**192 * Shows the TagConversionDialog asking the user whether to keep all, some or no tags193 * @param keys The keys present during the current conversion194 * @param listPos The keys that were previously selected195 * @param listNeg The keys that were previously unselected196 * @return {@link TagConversionDialogResponse} containing the selection197 */198 private static TagConversionDialogResponse showTagConversionDialog(List<String> keys, List<String> listPos, List<String> listNeg) {199 TagConversionDialogResponse res = new TagConversionDialogResponse(listPos, listNeg);200 String lSel = Config.getPref().get(GPX_SETTING + ".last", "all");201 202 JPanel p = new JPanel(new GridBagLayout());203 ButtonGroup r = new ButtonGroup();204 205 p.add(new JLabel(206 tr("The GPX layer contains fields that can be converted to OSM tags. How would you like to proceed?")),207 GBC.eol());208 JRadioButton rAll = new JRadioButton(tr("Convert all fields"), "all".equals(lSel));209 r.add(rAll);210 p.add(rAll, GBC.eol());211 212 JRadioButton rList = new JRadioButton(tr("Only convert the following fields:"), "list".equals(lSel));213 r.add(rList);214 p.add(rList, GBC.eol());215 216 JPanel q = new JPanel();217 218 List<JCheckBox> checkList = new ArrayList<>();219 for (String key : keys) {220 JCheckBox cTmp = new JCheckBox(key, !listNeg.contains(key));221 checkList.add(cTmp);222 q.add(cTmp);223 }224 225 q.setBorder(BorderFactory.createEmptyBorder(0, 20, 5, 0));226 p.add(q, GBC.eol());227 228 JRadioButton rNone = new JRadioButton(tr("Do not convert any fields"), "no".equals(lSel));229 r.add(rNone);230 p.add(rNone, GBC.eol());231 232 ActionListener enabler = new TagConversionDialogRadioButtonActionListener(checkList, true);233 ActionListener disabler = new TagConversionDialogRadioButtonActionListener(checkList, false);234 235 if (!"list".equals(lSel)) {236 disabler.actionPerformed(null);237 }238 239 rAll.addActionListener(disabler);240 rList.addActionListener(enabler);241 rNone.addActionListener(disabler);242 243 ExtendedDialog ed = new ExtendedDialog(Main.parent, tr("Options"),244 tr("Convert"), tr("Convert and remember selection"), tr("Cancel"))245 .setButtonIcons("exportgpx", "exportgpx", "cancel").setContent(p);246 int ret = ed.showDialog().getValue();247 248 if (ret == 1 || ret == 2) {249 for (JCheckBox cItem : checkList) {250 String key = cItem.getText();251 if (cItem.isSelected()) {252 if (!res.listPos.contains(key)) {253 res.listPos.add(key);254 }255 res.listNeg.remove(key);256 } else {257 if (!res.listNeg.contains(key)) {258 res.listNeg.add(key);259 }260 res.listPos.remove(key);261 }262 }263 if (rAll.isSelected()) {264 res.sel = "all";265 } else if (rNone.isSelected()) {266 res.sel = "no";267 }268 Config.getPref().put(GPX_SETTING + ".last", res.sel);269 if (ret == 2) {270 Config.getPref().put(GPX_SETTING, res.sel);271 } else {272 Config.getPref().put(GPX_SETTING, "ask");273 }274 Config.getPref().putList(GPX_SETTING + ".list.yes", res.listPos);275 Config.getPref().putList(GPX_SETTING + ".list.no", res.listNeg);276 } else {277 res.sel = null;278 }279 return res;280 }281 282 private static class TagConversionDialogResponse {283 284 final List<String> listPos;285 final List<String> listNeg;286 String sel = "list";287 288 TagConversionDialogResponse(List<String> p, List<String> n) {289 listPos = new ArrayList<>(p);290 listNeg = new ArrayList<>(n);291 }292 }293 294 private static class TagConversionDialogRadioButtonActionListener implements ActionListener {295 296 private final boolean enable;297 private final List<JCheckBox> checkList;298 299 TagConversionDialogRadioButtonActionListener(List<JCheckBox> chks, boolean en) {300 enable = en;301 checkList = chks;302 }303 304 @Override305 public void actionPerformed(ActionEvent arg0) {306 for (JCheckBox ch : checkList) {307 ch.setEnabled(enable);308 }309 }310 }311 }312 313 /**314 * Converts a {@link MarkerLayer} to a {@link OsmDataLayer}.315 */316 public static class FromMarkerLayer extends ConvertToDataLayerAction<MarkerLayer> {317 318 /**319 * Converts a {@link MarkerLayer} to a {@link OsmDataLayer}.320 * @param layer marker layer321 */322 public FromMarkerLayer(MarkerLayer layer) {323 super(layer);324 }325 326 @Override327 public DataSet convert() {328 final DataSet ds = new DataSet();329 for (Marker marker : layer.data) {330 final Node node = new Node(marker.getCoor());331 final Collection<String> mapping = Config.getPref().getList("gpx.to-osm-mapping", Arrays.asList(332 GpxConstants.GPX_NAME, "name",333 GpxConstants.GPX_DESC, "description",334 GpxConstants.GPX_CMT, "note",335 GpxConstants.GPX_SRC, "source",336 GpxConstants.PT_SYM, "gpxicon"));337 if (mapping.size() % 2 == 0) {338 final Iterator<String> it = mapping.iterator();339 while (it.hasNext()) {340 final String gpxKey = it.next();341 final String osmKey = it.next();342 Optional.ofNullable(marker.getTemplateValue(gpxKey, false))343 .map(String::valueOf)344 .ifPresent(s -> node.put(osmKey, s));345 }346 } else {347 Logging.warn("Invalid gpx.to-osm-mapping Einstein setting: expecting even number of entries");348 }349 ds.addPrimitive(node);350 }351 return ds;352 }353 44 } 354 45 -
trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
r13419 r14129 49 49 import org.openstreetmap.josm.gui.layer.JumpToMarkerActions.JumpToPreviousMarker; 50 50 import org.openstreetmap.josm.gui.layer.Layer; 51 import org.openstreetmap.josm.gui.layer.gpx.Convert ToDataLayerAction;51 import org.openstreetmap.josm.gui.layer.gpx.ConvertFromMarkerLayerAction; 52 52 import org.openstreetmap.josm.io.audio.AudioPlayer; 53 53 import org.openstreetmap.josm.spi.preferences.Config; … … 248 248 components.add(new JumpToNextMarker(this)); 249 249 components.add(new JumpToPreviousMarker(this)); 250 components.add(new Convert ToDataLayerAction.FromMarkerLayer(this));250 components.add(new ConvertFromMarkerLayerAction(this)); 251 251 components.add(new RenameLayerAction(getAssociatedFile(), this)); 252 252 components.add(SeparatorLayerAction.INSTANCE); -
trunk/test/unit/org/openstreetmap/josm/gui/layer/gpx/ConvertToDataLayerActionTest.java
r12564 r14129 40 40 final GpxData data = GpxReaderTest.parseGpxData(TestUtils.getTestDataRoot() + "minimal.gpx"); 41 41 final MarkerLayer markers = new MarkerLayer(data, "Markers", data.storageFile, null); 42 final DataSet osm = new Convert ToDataLayerAction.FromMarkerLayer(markers).convert();42 final DataSet osm = new ConvertFromMarkerLayerAction(markers).convert(); 43 43 assertEquals(1, osm.getNodes().size()); 44 44 assertEquals(new TagMap("name", "Schranke", "description", "Pfad", "note", "Pfad", "gpxicon", "Toll Booth"),
Note:
See TracChangeset
for help on using the changeset viewer.