Changeset 14101 in josm


Ignore:
Timestamp:
2018-08-07T00:24:36+02:00 (7 weeks ago)
Author:
Don-vip
Message:

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

Location:
trunk
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/osm/NoteData.java

    r13437 r14101  
    4949
    5050    private final ListenerList<NoteDataUpdateListener> listeners = ListenerList.create();
     51
     52    /**
     53     * Construct a new note container with a given list of notes
     54     * @since 14101
     55     */
     56    public NoteData() {
     57        this(null);
     58    }
    5159
    5260    /**
  • trunk/src/org/openstreetmap/josm/gui/io/importexport/OsmChangeImporter.java

    r12671 r14101  
    1414import org.openstreetmap.josm.actions.ExtensionFileFilter;
    1515import org.openstreetmap.josm.data.osm.DataSet;
     16import org.openstreetmap.josm.data.osm.NoteData;
    1617import org.openstreetmap.josm.gui.MainApplication;
     18import org.openstreetmap.josm.gui.layer.Layer;
     19import org.openstreetmap.josm.gui.layer.NoteLayer;
    1720import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    1821import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     
    2225import org.openstreetmap.josm.io.OsmChangeReader;
    2326import org.openstreetmap.josm.tools.Logging;
     27import org.openstreetmap.josm.tools.Pair;
    2428
    2529/**
     
    2933public class OsmChangeImporter extends FileImporter {
    3034
     35    /**
     36     * File filter for OsmChange files.
     37     */
    3138    public static final ExtensionFileFilter FILE_FILTER = ExtensionFileFilter.newFilterWithArchiveExtensions(
    3239            "osc", "osc", tr("OsmChange File"), true);
    3340
    3441    /**
    35      * Constructs a new {@code OsmChangeImporter}.
     42     * Constructs a new {@code OsmChangeImporter} with default file filter.
    3643     */
    3744    public OsmChangeImporter() {
     
    3946    }
    4047
     48    /**
     49     * Constructs a new {@code OsmChangeImporter} with custom file filter.
     50     * @param filter file filter
     51     */
    4152    public OsmChangeImporter(ExtensionFileFilter filter) {
    4253        super(filter);
     
    5465
    5566    protected void importData(InputStream in, final File associatedFile, ProgressMonitor progressMonitor) throws IllegalDataException {
    56         final DataSet dataSet = OsmChangeReader.parseDataSet(in, progressMonitor);
    57         final OsmDataLayer layer = new OsmDataLayer(dataSet, associatedFile.getName(), associatedFile);
    58         addDataLayer(dataSet, layer, associatedFile.getPath());
     67        final Pair<DataSet, NoteData> p = OsmChangeReader.parseDataSetAndNotes(in, progressMonitor);
     68        final boolean hasOsmData = p.a != null && !p.a.allPrimitives().isEmpty();
     69        final boolean hasNotes = p.b != null && !p.b.getNotes().isEmpty();
     70        if (hasOsmData) {
     71            addLayer(new OsmDataLayer(p.a, associatedFile.getName(), associatedFile));
     72        }
     73        if (hasNotes) {
     74            addLayer(new NoteLayer(p.b, associatedFile.getName()));
     75        }
     76        if (!hasOsmData && !hasNotes) {
     77            // FIXME: remove UI stuff from IO subsystem
     78            GuiHelper.runInEDT(() -> {
     79                JOptionPane.showMessageDialog(
     80                        Main.parent,
     81                        tr("No data found in file {0}.", associatedFile.getPath()),
     82                        tr("Open OsmChange file"),
     83                        JOptionPane.INFORMATION_MESSAGE);
     84            });
     85        }
    5986    }
    6087
    61     protected void addDataLayer(final DataSet dataSet, final OsmDataLayer layer, final String filePath) {
     88    protected void addLayer(final Layer layer) {
    6289        // FIXME: remove UI stuff from IO subsystem
    63         //
    6490        GuiHelper.runInEDT(() -> {
    65             if (dataSet.allPrimitives().isEmpty()) {
    66                 JOptionPane.showMessageDialog(
    67                         Main.parent,
    68                         tr("No data found in file {0}.", filePath),
    69                         tr("Open OsmChange file"),
    70                         JOptionPane.INFORMATION_MESSAGE);
    71             }
    7291            MainApplication.getLayerManager().addLayer(layer);
    7392            layer.onPostLoadFromFile();
  • trunk/src/org/openstreetmap/josm/gui/layer/NoteLayer.java

    r13852 r14101  
    102102    }
    103103
     104    /**
     105     * Create a new note layer with a notes data
     106     * @param noteData Notes data
     107     * @param name The name of the layer. Typically "Notes"
     108     * @since 14101
     109     */
     110    public NoteLayer(NoteData noteData, String name) {
     111        super(name);
     112        this.noteData = noteData;
     113        this.noteData.addNoteDataUpdateListener(this);
     114    }
     115
    104116    /** Convenience constructor that creates a layer with an empty note list */
    105117    public NoteLayer() {
  • trunk/src/org/openstreetmap/josm/io/NoteReader.java

    r13901 r14101  
    1111import java.util.Locale;
    1212import java.util.Optional;
     13import java.util.function.Function;
    1314
    1415import javax.xml.parsers.ParserConfigurationException;
     
    8586            if (parseMode == NoteParseMode.API) {
    8687                if ("note".equals(qName)) {
    87                     double lat = Double.parseDouble(attrs.getValue("lat"));
    88                     double lon = Double.parseDouble(attrs.getValue("lon"));
    89                     LatLon noteLatLon = new LatLon(lat, lon);
    90                     thisNote = new Note(noteLatLon);
     88                    thisNote = parseNoteBasic(attrs);
    9189                }
    9290                return;
     
    9694            switch(qName) {
    9795            case "note":
    98                 double lat = Double.parseDouble(attrs.getValue("lat"));
    99                 double lon = Double.parseDouble(attrs.getValue("lon"));
    100                 LatLon noteLatLon = new LatLon(lat, lon);
    101                 thisNote = new Note(noteLatLon);
    102                 thisNote.setId(Long.parseLong(attrs.getValue("id")));
    103                 String closedTimeStr = attrs.getValue("closed_at");
    104                 if (closedTimeStr == null) { //no closed_at means the note is still open
    105                     thisNote.setState(Note.State.OPEN);
    106                 } else {
    107                     thisNote.setState(Note.State.CLOSED);
    108                     thisNote.setClosedAt(DateUtils.fromString(closedTimeStr));
    109                 }
    110                 thisNote.setCreatedAt(DateUtils.fromString(attrs.getValue("created_at")));
     96                thisNote = parseNoteFull(attrs);
    11197                break;
    11298            case "comment":
     
    188174            parsedNotes = notes;
    189175        }
     176    }
     177
     178    static LatLon parseLatLon(Function<String, String> attrs) {
     179        double lat = Double.parseDouble(attrs.apply("lat"));
     180        double lon = Double.parseDouble(attrs.apply("lon"));
     181        return new LatLon(lat, lon);
     182    }
     183
     184    static Note parseNoteBasic(Attributes attrs) {
     185        return parseNoteBasic(attrs::getValue);
     186    }
     187
     188    static Note parseNoteBasic(Function<String, String> attrs) {
     189        return new Note(parseLatLon(attrs));
     190    }
     191
     192    static Note parseNoteFull(Attributes attrs) {
     193        return parseNoteFull(attrs::getValue);
     194    }
     195
     196    static Note parseNoteFull(Function<String, String> attrs) {
     197        Note note = parseNoteBasic(attrs);
     198        String id = attrs.apply("id");
     199        if (id != null) {
     200            note.setId(Long.parseLong(id));
     201        }
     202        String closedTimeStr = attrs.apply("closed_at");
     203        if (closedTimeStr == null) { //no closed_at means the note is still open
     204            note.setState(Note.State.OPEN);
     205        } else {
     206            note.setState(Note.State.CLOSED);
     207            note.setClosedAt(DateUtils.fromString(closedTimeStr));
     208        }
     209        String createdAt = attrs.apply("created_at");
     210        if (createdAt != null) {
     211            note.setCreatedAt(DateUtils.fromString(createdAt));
     212        }
     213        return note;
    190214    }
    191215
  • trunk/src/org/openstreetmap/josm/io/OsmChangeReader.java

    r8415 r14101  
    1010import javax.xml.stream.XMLStreamException;
    1111
     12import org.openstreetmap.josm.data.coor.LatLon;
    1213import org.openstreetmap.josm.data.osm.DataSet;
     14import org.openstreetmap.josm.data.osm.NoteData;
    1315import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1416import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     17import org.openstreetmap.josm.tools.Pair;
    1518
    1619/**
     
    2326     */
    2427    private static final String[] ACTIONS = {"create", "modify", "delete"};
     28
     29    protected final NoteData noteData = new NoteData();
    2530
    2631    /**
     
    8085                    p = parseRelation();
    8186                    break;
     87                case "note":
     88                    parseNote();
     89                    break;
    8290                default:
    8391                    parseUnknown();
     
    96104    }
    97105
     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
    98137    /**
    99138     * Parse the given input source and return the dataset.
     
    110149        return new OsmChangeReader().doParseDataSet(source, progressMonitor);
    111150    }
     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    }
    112170}
  • trunk/test/unit/org/openstreetmap/josm/actions/mapmode/AddNoteActionTest.java

    r12636 r14101  
    55import static org.junit.Assert.assertTrue;
    66
    7 import java.util.Collections;
    8 
    97import org.junit.Rule;
    108import org.junit.Test;
    11 import org.openstreetmap.josm.data.notes.Note;
    129import org.openstreetmap.josm.data.osm.DataSet;
    1310import org.openstreetmap.josm.data.osm.NoteData;
     
    3936        try {
    4037            MainApplication.getLayerManager().addLayer(layer);
    41             AddNoteAction mapMode = new AddNoteAction(new NoteData(Collections.<Note>emptyList()));
     38            AddNoteAction mapMode = new AddNoteAction(new NoteData());
    4239            MapFrame map = MainApplication.getMap();
    4340            MapMode oldMapMode = map.mapMode;
  • trunk/test/unit/org/openstreetmap/josm/data/osm/NoteDataTest.java

    r9666 r14101  
    2020    @Test
    2121    public void testNoteData() {
    22         NoteData empty = new NoteData(null);
     22        NoteData empty = new NoteData();
    2323        assertEquals(0, empty.getNotes().size());
    2424        NoteData notEmpty = new NoteData(Arrays.asList(new Note(LatLon.ZERO)));
Note: See TracChangeset for help on using the changeset viewer.