source: josm/trunk/src/org/openstreetmap/josm/io/OsmChangeReader.java@ 14145

Last change on this file since 14145 was 14101, checked in by Don-vip, 6 years ago

see #8765, fix #11086 - Support notes in osmChange (.osc) files created by OsmAnd

  • Property svn:eol-style set to native
File size: 6.0 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.InputStream;
7import java.util.Arrays;
8
9import javax.xml.stream.XMLStreamConstants;
10import javax.xml.stream.XMLStreamException;
11
12import org.openstreetmap.josm.data.coor.LatLon;
13import org.openstreetmap.josm.data.osm.DataSet;
14import org.openstreetmap.josm.data.osm.NoteData;
15import org.openstreetmap.josm.data.osm.OsmPrimitive;
16import org.openstreetmap.josm.gui.progress.ProgressMonitor;
17import org.openstreetmap.josm.tools.Pair;
18
19/**
20 * Reader for <a href="http://wiki.openstreetmap.org/wiki/OsmChange">OsmChange</a> file format.
21 */
22public class OsmChangeReader extends OsmReader {
23
24 /**
25 * List of possible actions.
26 */
27 private static final String[] ACTIONS = {"create", "modify", "delete"};
28
29 protected final NoteData noteData = new NoteData();
30
31 /**
32 * constructor (for private and subclasses use only)
33 *
34 * @see #parseDataSet(InputStream, ProgressMonitor)
35 */
36 protected OsmChangeReader() {
37 // Restricts visibility
38 }
39
40 @Override
41 protected void parseRoot() throws XMLStreamException {
42 if ("osmChange".equals(parser.getLocalName())) {
43 parseOsmChange();
44 } else {
45 parseUnknown();
46 }
47 }
48
49 private void parseOsmChange() throws XMLStreamException {
50 String v = parser.getAttributeValue(null, "version");
51 if (v == null) {
52 throwException(tr("Missing mandatory attribute ''{0}''.", "version"));
53 }
54 if (!"0.6".equals(v)) {
55 throwException(tr("Unsupported version: {0}", v));
56 }
57 ds.setVersion(v);
58 while (parser.hasNext()) {
59 int event = parser.next();
60 if (event == XMLStreamConstants.START_ELEMENT) {
61 if (Arrays.asList(ACTIONS).contains(parser.getLocalName())) {
62 parseCommon(parser.getLocalName());
63 } else {
64 parseUnknown();
65 }
66 } else if (event == XMLStreamConstants.END_ELEMENT) {
67 return;
68 }
69 }
70 }
71
72 private void parseCommon(String action) throws XMLStreamException {
73 while (parser.hasNext()) {
74 int event = parser.next();
75 if (event == XMLStreamConstants.START_ELEMENT) {
76 OsmPrimitive p = null;
77 switch (parser.getLocalName()) {
78 case "node":
79 p = parseNode();
80 break;
81 case "way":
82 p = parseWay();
83 break;
84 case "relation":
85 p = parseRelation();
86 break;
87 case "note":
88 parseNote();
89 break;
90 default:
91 parseUnknown();
92 }
93 if (p != null && action != null) {
94 if ("modify".equals(action)) {
95 p.setModified(true);
96 } else if ("delete".equals(action)) {
97 p.setDeleted(true);
98 }
99 }
100 } else if (event == XMLStreamConstants.END_ELEMENT) {
101 return;
102 }
103 }
104 }
105
106 private void parseNote() throws XMLStreamException {
107 LatLon location = NoteReader.parseLatLon(s -> parser.getAttributeValue(null, s));
108 String text = null;
109 while (parser.hasNext()) {
110 int event = parser.next();
111 if (event == XMLStreamConstants.START_ELEMENT) {
112 switch (parser.getLocalName()) {
113 case "comment":
114 text = parser.getAttributeValue(null, "text");
115 break;
116 default:
117 parseUnknown();
118 }
119 } else if (event == XMLStreamConstants.END_ELEMENT) {
120 break;
121 }
122 }
123 if (location != null && text != null) {
124 noteData.createNote(location, text);
125 }
126 }
127
128 /**
129 * Replies the parsed notes data.
130 * @return the parsed notes data
131 * @since 14101
132 */
133 public final NoteData getNoteData() {
134 return noteData;
135 }
136
137 /**
138 * Parse the given input source and return the dataset.
139 *
140 * @param source the source input stream. Must not be <code>null</code>.
141 * @param progressMonitor the progress monitor. If <code>null</code>,
142 * {@link org.openstreetmap.josm.gui.progress.NullProgressMonitor#INSTANCE} is assumed
143 *
144 * @return the dataset with the parsed data
145 * @throws IllegalDataException if the an error was found while parsing the data from the source
146 * @throws IllegalArgumentException if source is <code>null</code>
147 */
148 public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException {
149 return new OsmChangeReader().doParseDataSet(source, progressMonitor);
150 }
151
152 /**
153 * Parse the given input source and return the dataset and notes, if any (OsmAnd extends the osmChange format by adding notes).
154 *
155 * @param source the source input stream. Must not be <code>null</code>.
156 * @param progressMonitor the progress monitor. If <code>null</code>,
157 * {@link org.openstreetmap.josm.gui.progress.NullProgressMonitor#INSTANCE} is assumed
158 *
159 * @return the dataset with the parsed data
160 * @throws IllegalDataException if the an error was found while parsing the data from the source
161 * @throws IllegalArgumentException if source is <code>null</code>
162 * @since 14101
163 */
164 public static Pair<DataSet, NoteData> parseDataSetAndNotes(InputStream source, ProgressMonitor progressMonitor)
165 throws IllegalDataException {
166 OsmChangeReader osmChangeReader = new OsmChangeReader();
167 osmChangeReader.doParseDataSet(source, progressMonitor);
168 return new Pair<>(osmChangeReader.getDataSet(), osmChangeReader.getNoteData());
169 }
170}
Note: See TracBrowser for help on using the repository browser.