Changeset 444 in josm for trunk/src/org


Ignore:
Timestamp:
2007-11-01T01:50:51+01:00 (16 years ago)
Author:
framm
Message:
  • patch for better GPX file support by Raphael Mack <ramack@…>
  • dropped support for CSV files
Location:
trunk/src/org/openstreetmap/josm
Files:
9 added
3 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/GpxExportAction.java

    r298 r444  
    2929import org.openstreetmap.josm.Main;
    3030import org.openstreetmap.josm.gui.layer.Layer;
    31 import org.openstreetmap.josm.gui.layer.RawGpsLayer;
     31import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     32import org.openstreetmap.josm.gui.layer.GpxLayer;
    3233import org.openstreetmap.josm.io.GpxWriter;
    3334import org.openstreetmap.josm.io.XmlWriter;
    3435import org.openstreetmap.josm.tools.GBC;
     36import org.openstreetmap.josm.data.gpx.GpxData;
    3537
    3638/**
     
    118120                if (copyright.getText().length() != 0)
    119121                        Main.pref.put("lastCopyright", copyright.getText());
    120                
    121                 XmlWriter.OsmWriterInterface w;
    122                 if (layer instanceof RawGpsLayer)
    123                         w = new GpxWriter.Trk(((RawGpsLayer)layer).data);
     122
     123                GpxData gpxData;
     124                if (layer instanceof OsmDataLayer)
     125                        gpxData = ((OsmDataLayer)layer).toGpxData();
     126                else if (layer instanceof GpxLayer)
     127                        gpxData = ((GpxLayer)layer).data;
    124128                else
    125                         w = new GpxWriter.All(Main.ds, layer.name, desc.getText(),
    126                                         authorName.getText(), email.getText(), copyright.getText(),
    127                                         copyrightYear.getText(), keywords.getText());
     129                        gpxData = OsmDataLayer.toGpxData(Main.ds);
     130                // TODO: add copyright, etc.
    128131                try {
    129                         XmlWriter.output(new FileOutputStream(file), w);
     132                        new GpxWriter(new FileOutputStream(file)).write(gpxData);
    130133                } catch (IOException x) {
    131134                        x.printStackTrace();
  • trunk/src/org/openstreetmap/josm/actions/OpenAction.java

    r298 r444  
    2222import org.openstreetmap.josm.data.osm.DataSet;
    2323import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    24 import org.openstreetmap.josm.gui.layer.RawGpsLayer;
    25 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
     24import org.openstreetmap.josm.gui.layer.GpxLayer;
    2625import org.openstreetmap.josm.gui.layer.markerlayer.Marker;
    2726import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
    2827import org.openstreetmap.josm.io.OsmReader;
    29 import org.openstreetmap.josm.io.RawCsvReader;
    30 import org.openstreetmap.josm.io.RawGpsReader;
     28import org.openstreetmap.josm.io.GpxReader;
    3129import org.xml.sax.SAXException;
    3230
     
    6058        public void openFile(File file) {
    6159                try {
    62                         if (asRawData(file.getName()))
    63                                 openFileAsRawGps(file);
     60                        if (asGpxData(file.getName()))
     61                                openFileAsGpx(file);
    6462                        else
    6563                                openAsData(file);
     
    8583    }
    8684
    87         private void openFileAsRawGps(File file) throws SAXException, IOException, FileNotFoundException {
    88             String fn = file.getName();
    89             Collection<Collection<GpsPoint>> gpsData = null;
    90             Collection<Marker> markerData = null;
    91             if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn)) {
    92                 RawGpsReader r = null;
    93                 if (file.getName().endsWith(".gpx.gz"))
    94                         r = new RawGpsReader(new GZIPInputStream(new FileInputStream(file)), file.getAbsoluteFile().getParentFile());
    95                 else
    96                         r = new RawGpsReader(new FileInputStream(file), file.getAbsoluteFile().getParentFile());
    97                 gpsData = r.trackData;
    98                 markerData = r.markerData;
    99             } else if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(fn)) {
    100                 gpsData = new LinkedList<Collection<GpsPoint>>();
    101                 gpsData.add(new RawCsvReader(new FileReader(file)).parse());
    102             } else
    103                 throw new IllegalStateException();
    104             if (gpsData != null && !gpsData.isEmpty())
    105                 Main.main.addLayer(new RawGpsLayer(false, gpsData, tr("Tracks from {0}", file.getName()), file));
    106             if (markerData != null && !markerData.isEmpty())
    107                 Main.main.addLayer(new MarkerLayer(markerData, tr ("Markers from {0}", file.getName()), file));
     85        private void openFileAsGpx(File file) throws SAXException, IOException, FileNotFoundException {
     86                String fn = file.getName();
     87                if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn)) {
     88                        GpxReader r = null;
     89                        if (file.getName().endsWith(".gpx.gz")) {
     90                                r = new GpxReader(new GZIPInputStream(new FileInputStream(file)), file.getAbsoluteFile().getParentFile());
     91                        } else{
     92                                r = new GpxReader(new FileInputStream(file), file.getAbsoluteFile().getParentFile());
     93                        }
     94                        r.data.storageFile = file;
     95                        Main.main.addLayer(new GpxLayer(r.data, fn));
     96            Main.main.addLayer(new MarkerLayer(r.data, tr("Markers from {0}", fn), file));
     97
     98                } else {
     99                        throw new IllegalStateException();
     100                }
    108101    }
    109102
    110         /**
    111          * @return Return whether the file should be opened as raw gps data. May ask the
    112          * user, if unsure.
    113          */
    114         private boolean asRawData(String fn) {
    115                 if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(fn))
    116                         return true;
    117                 if (!ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn))
    118                         return false;
    119                 return true;
     103
     104        private boolean asGpxData(String fn) {
     105                return ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn);
    120106        }
     107
     108
    121109}
  • trunk/src/org/openstreetmap/josm/actions/SaveAction.java

    r298 r444  
    88import java.io.File;
    99
     10import org.openstreetmap.josm.gui.layer.Layer;
     11import org.openstreetmap.josm.gui.layer.GpxLayer;
    1012import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    1113
     
    2123         * @param layer Save this layer.
    2224         */
    23         public SaveAction(OsmDataLayer layer) {
     25        public SaveAction(Layer layer) {
    2426                super(tr("Save"), "save", tr("Save the current data."), KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK, layer);
    2527        }
    2628       
    27         @Override public File getFile(OsmDataLayer layer) {
    28                 if (layer.associatedFile != null)
    29                         return layer.associatedFile;
     29        @Override public File getFile(Layer layer) {
     30                if (layer instanceof OsmDataLayer) {
     31                        File f = ((OsmDataLayer)layer).associatedFile;
     32                        if (f != null) {
     33                                return f;
     34                        }
     35                }
     36                if (layer instanceof GpxLayer) {
     37                        File f = ((GpxLayer)layer).data.storageFile;
     38                        if (f != null) {
     39                                return f;
     40                        }
     41                }
    3042                return openFileDialog();
    3143        }
  • trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java

    r343 r444  
    1818import org.openstreetmap.josm.data.osm.OsmPrimitive;
    1919import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     20import org.openstreetmap.josm.gui.layer.Layer;
     21import org.openstreetmap.josm.gui.layer.GpxLayer;
    2022import org.openstreetmap.josm.io.OsmWriter;
     23import org.openstreetmap.josm.io.GpxWriter;
    2124
    2225public abstract class SaveActionBase extends DiskAccessAction {
    2326
    24         private OsmDataLayer layer;
    25 
    26         public SaveActionBase(String name, String iconName, String tooltip, int shortCut, int modifiers, OsmDataLayer layer) {
     27        private Layer layer;
     28
     29        public SaveActionBase(String name, String iconName, String tooltip, int shortCut, int modifiers, Layer layer) {
    2730                super(name, iconName, tooltip, shortCut, modifiers);
    2831                this.layer = layer;
     
    3033
    3134        public void actionPerformed(ActionEvent e) {
    32                 OsmDataLayer layer = this.layer;
    33                 if (layer == null && Main.map != null && Main.map.mapView.getActiveLayer() instanceof OsmDataLayer)
    34                         layer = (OsmDataLayer)Main.map.mapView.getActiveLayer();
     35                Layer layer = this.layer;
     36                if (layer == null && Main.map != null && (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
     37                                || Main.map.mapView.getActiveLayer() instanceof GpxLayer))
     38                        layer = Main.map.mapView.getActiveLayer();
    3539                if (layer == null)
    3640                        layer = Main.main.editLayer();
     
    5155        }
    5256
    53         protected abstract File getFile(OsmDataLayer layer);
     57        protected abstract File getFile(Layer layer);
    5458
    5559        /**
     
    5862         * @return <code>true</code>, if it is save to save.
    5963         */
    60         public boolean checkSaveConditions(OsmDataLayer layer) {
     64        public boolean checkSaveConditions(Layer layer) {
     65                if (layer == null) {
     66                        JOptionPane.showMessageDialog(Main.parent, tr("Internal Error: cannot check conditions for no layer. Please report this as a bug."));
     67                        return false;
     68                }
    6169                if (Main.map == null) {
    6270                        JOptionPane.showMessageDialog(Main.parent, tr("No document open so nothing to save."));
    6371                        return false;
    6472                }
    65                 if (isDataSetEmpty(layer) && JOptionPane.NO_OPTION == JOptionPane.showConfirmDialog(Main.parent,tr("The document contains no data. Save anyway?"), tr("Empty document"), JOptionPane.YES_NO_OPTION))
    66                         return false;
     73
     74                if (layer instanceof OsmDataLayer && isDataSetEmpty((OsmDataLayer)layer) && JOptionPane.NO_OPTION == JOptionPane.showConfirmDialog(Main.parent,tr("The document contains no data. Save anyway?"), tr("Empty document"), JOptionPane.YES_NO_OPTION)) {
     75                        return false;
     76                }
     77                if (layer instanceof GpxLayer && ((GpxLayer)layer).data == null) {
     78                        return false;
     79                }
    6780                if (!Main.map.conflictDialog.conflicts.isEmpty()) {
    6881                        int answer = JOptionPane.showConfirmDialog(Main.parent,
     
    110123                srcStream.close();
    111124                dstStream.close();
     125        }
     126
     127        public static void save(File file, Layer layer) {
     128                if (layer instanceof GpxLayer) {
     129                        save(file, (GpxLayer)layer);
     130                        ((GpxLayer)layer).data.storageFile = file;
     131                } else if (layer instanceof OsmDataLayer) {
     132                        save(file, (OsmDataLayer)layer);
     133                }
    112134        }
    113135
     
    152174        }
    153175
     176        public static void save(File file, GpxLayer layer) {
     177                File tmpFile = null;
     178                try {
     179                        if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(file.getPath())) {
     180
     181                                // use a tmp file because if something errors out in the
     182                                // process of writing the file, we might just end up with
     183                                // a truncated file.  That can destroy lots of work.
     184                                if (file.exists()) {
     185                                        tmpFile = new File(file.getPath() + "~");
     186                                        copy(file, tmpFile);
     187                                }
     188
     189                                new GpxWriter(new FileOutputStream(file)).write(layer.data);
     190                                if (!Main.pref.getBoolean("save.keepbackup") && (tmpFile != null)) {
     191                                        tmpFile.delete();
     192                                }
     193                        } else if (ExtensionFileFilter.filters[ExtensionFileFilter.CSV].acceptName(file.getPath())) {
     194                                JOptionPane.showMessageDialog(Main.parent, tr("CSV output not supported yet."));
     195                                return;
     196                        } else {
     197                                JOptionPane.showMessageDialog(Main.parent, tr("Unknown file extension."));
     198                                return;
     199                        }
     200                } catch (IOException e) {
     201                        e.printStackTrace();
     202                        JOptionPane.showMessageDialog(Main.parent, tr("An error occurred while saving.")+"\n"+e.getMessage());
     203                }
     204                try {
     205                        // if the file save failed, then the tempfile will not
     206                        // be deleted.  So, restore the backup if we made one.
     207                        if (tmpFile != null && tmpFile.exists()) {
     208                                copy(tmpFile, file);
     209                        }
     210                } catch (IOException e) {
     211                        e.printStackTrace();
     212                        JOptionPane.showMessageDialog(Main.parent, tr("An error occurred while restoring backup file.")+"\n"+e.getMessage());
     213                }
     214        }
     215
    154216        /**
    155217         * Check the data set if it would be empty on save. It is empty, if it contains
  • trunk/src/org/openstreetmap/josm/actions/SaveAsAction.java

    r298 r444  
    88import java.io.File;
    99
    10 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     10import org.openstreetmap.josm.gui.layer.Layer;
    1111
    1212/**
    13  * Export the data  as OSM intern xml file.
     13 * Export the data.
    1414 *
    1515 * @author imi
     
    2121         * @param layer Save this layer.
    2222         */
    23         public SaveAsAction(OsmDataLayer layer) {
     23        public SaveAsAction(Layer layer) {
    2424                super(tr("Save as"), "save_as", tr("Save the current data to a new file."), KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK, layer);
    2525        }
    2626       
    27         @Override protected File getFile(OsmDataLayer layer) {
     27        @Override protected File getFile(Layer layer) {
    2828                return openFileDialog();
    2929        }
  • trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java

    r298 r444  
    1414import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask;
    1515import org.openstreetmap.josm.gui.layer.Layer;
    16 import org.openstreetmap.josm.gui.layer.RawGpsLayer;
    17 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
     16import org.openstreetmap.josm.gui.layer.GpxLayer;
     17import org.openstreetmap.josm.data.gpx.GpxData;
     18import org.openstreetmap.josm.data.Bounds;
    1819import org.openstreetmap.josm.io.BoundingBoxDownloader;
    1920import org.xml.sax.SAXException;
     
    2425                private BoundingBoxDownloader reader;
    2526                private DownloadAction action;
    26                 private Collection<Collection<GpsPoint>> rawData;
     27                private GpxData rawData;
    2728                private final boolean newLayer;
    2829
     
    4142                        if (rawData == null)
    4243                                return;
    43                         String name = action.dialog.minlat + " " + action.dialog.minlon + " x " + action.dialog.maxlat + " " + action.dialog.maxlon;
    44                         RawGpsLayer layer = new RawGpsLayer(true, rawData, name, null);
     44                        rawData.recalculateBounds();
     45                        Bounds b = rawData.bounds;
     46                                                String name = b.min.lat() + " " + b.min.lon() + " x " + b.max.lat() + " " + b.max.lon();
     47                                                GpxLayer layer = new GpxLayer(rawData, name);
    4548                        if (newLayer || findMergeLayer() == null)
    4649                    Main.main.addLayer(layer);
     
    5356                                return null;
    5457                Layer active = Main.map.mapView.getActiveLayer();
    55                 if (active != null && active instanceof RawGpsLayer)
     58                if (active != null && active instanceof GpxLayer)
    5659                        return active;
    5760                for (Layer l : Main.map.mapView.getAllLayers())
    58                         if (l instanceof RawGpsLayer && ((RawGpsLayer)l).fromServer)
     61                                if (l instanceof GpxLayer)
    5962                                return l;
    6063                return null;
  • trunk/src/org/openstreetmap/josm/gui/layer/GeoImageLayer.java

    r323 r444  
    5858import org.openstreetmap.josm.data.coor.LatLon;
    5959import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
     60import org.openstreetmap.josm.data.gpx.GpxData;
     61import org.openstreetmap.josm.data.gpx.GpxTrack;
     62import org.openstreetmap.josm.data.gpx.WayPoint;
    6063import org.openstreetmap.josm.gui.MapView;
    6164import org.openstreetmap.josm.gui.PleaseWaitRunnable;
    6265import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
    6366import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
    64 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
    6567import org.openstreetmap.josm.tools.DateParser;
    6668import org.openstreetmap.josm.tools.ExifReader;
     
    9092                private GeoImageLayer layer;
    9193                private final Collection<File> files;
    92                 private final RawGpsLayer gpsLayer;
    93                 public Loader(Collection<File> files, RawGpsLayer gpsLayer) {
    94                         super(tr("Images for {0}", gpsLayer.name));
     94                private final GpxLayer gpxLayer;
     95                public Loader(Collection<File> files, GpxLayer gpxLayer) {
     96                        super(tr("Images for {0}", gpxLayer.name));
    9597                        this.files = files;
    96                         this.gpsLayer = gpsLayer;
     98                        this.gpxLayer = gpxLayer;
    9799                }
    98100                @Override protected void realRun() throws IOException {
    99                         Main.pleaseWaitDlg.currentAction.setText(tr("Read GPS..."));
     101                        Main.pleaseWaitDlg.currentAction.setText(tr("Read GPX..."));
    100102                        LinkedList<TimedPoint> gps = new LinkedList<TimedPoint>();
    101103
    102                         // Extract dates and locations from GPS input
    103                         for (Collection<GpsPoint> c : gpsLayer.data) {
    104                                 for (GpsPoint p : c) {
    105                                         if (p.time == null)
     104                        // Extract dates and locations from GPX input
     105
     106                        for (GpxTrack trk : gpxLayer.data.tracks) {
     107                                for (Collection<WayPoint> segment : trk.trackSegs) {
     108                                        for (WayPoint p : segment) {
     109                                        if (!p.attr.containsKey("time"))
    106110                                                throw new IOException(tr("No time for point {0} x {1}",p.latlon.lat(),p.latlon.lon()));
    107111                                        Date d = null;
    108112                                        try {
    109                                                 d = DateParser.parse(p.time);
     113                                                d = DateParser.parse((String) p.attr.get("time"));
    110114                                        } catch (ParseException e) {
    111                                                 throw new IOException(tr("Cannot read time \"{0}\" from point {1} x {2}",p.time,p.latlon.lat(),p.latlon.lon()));
     115                                                throw new IOException(tr("Cannot read time \"{0}\" from point {1} x {2}",p.attr.get("time"),p.latlon.lat(),p.latlon.lon()));
    112116                                        }
    113117                                        gps.add(new TimedPoint(d, p.eastNorth));
    114118                                }
     119                        }
    115120                        }
    116121
     
    188193        }
    189194
    190         public static void create(Collection<File> files, RawGpsLayer gpsLayer) {
    191                 Loader loader = new Loader(files, gpsLayer);
     195        public static void create(Collection<File> files, GpxLayer gpxLayer) {
     196                Loader loader = new Loader(files, gpxLayer);
    192197                Main.worker.execute(loader);
    193198        }
  • trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

    r407 r444  
    1717import java.util.LinkedList;
    1818import java.util.Set;
    19 
     19import java.util.ArrayList;
     20
     21import javax.swing.AbstractAction;
    2022import javax.swing.Icon;
    2123import javax.swing.JLabel;
     
    4244import org.openstreetmap.josm.data.osm.visitor.SimplePaintVisitor;
    4345import org.openstreetmap.josm.data.osm.visitor.Visitor;
     46import org.openstreetmap.josm.data.gpx.GpxData;
     47import org.openstreetmap.josm.data.gpx.GpxTrack;
     48import org.openstreetmap.josm.data.gpx.WayPoint;
    4449import org.openstreetmap.josm.gui.MapView;
    4550import org.openstreetmap.josm.gui.dialogs.ConflictDialog;
     
    309314                                new JMenuItem(new SaveAsAction(this)),
    310315                                new JMenuItem(new GpxExportAction(this)),
     316                                new JMenuItem(new ConvertToGpxLayerAction()),
    311317                                new JSeparator(),
    312318                                new JMenuItem(new RenameLayerAction(associatedFile, this)),
     
    325331                }
    326332        }
     333
     334        public static GpxData toGpxData(DataSet data) {
     335                GpxData gpxData = new GpxData();
     336                HashSet<Node> doneNodes = new HashSet<Node>();
     337                for (Way w : data.ways) {
     338                        if (w.incomplete || w.deleted) continue;
     339                        GpxTrack trk = new GpxTrack();
     340                        gpxData.tracks.add(trk);
     341                        ArrayList<WayPoint> trkseg = null;
     342                        for (Node n : w.nodes) {
     343                                if (n.incomplete || n.deleted) {
     344                                        trkseg = null;
     345                                        continue;
     346                                }
     347                                if (trkseg == null) {
     348                                        trkseg = new ArrayList<WayPoint>();
     349                                        trk.trackSegs.add(trkseg);
     350                                }
     351                                if (!n.tagged) {
     352                                        doneNodes.add(n);
     353                                }
     354                                trkseg.add(new WayPoint(n.coor));
     355                        }
     356                }
     357                for (Node n : data.nodes) {
     358                        if (n.incomplete || n.deleted || doneNodes.contains(n)) continue;
     359                        WayPoint wpt = new WayPoint(n.coor);
     360                        if (n.keys.containsKey("name")) {
     361                                wpt.attr.put("name", n.keys.get("name"));
     362                        }
     363                }
     364                return gpxData;
     365        }
     366
     367        public GpxData toGpxData() {
     368                return toGpxData(data);
     369        }
     370
     371        public class ConvertToGpxLayerAction extends AbstractAction {
     372                public ConvertToGpxLayerAction() {
     373                        super(tr("Convert to GPX layer"), ImageProvider.get("converttogpx"));
     374                }
     375                public void actionPerformed(ActionEvent e) {
     376                        Main.main.addLayer(new GpxLayer(toGpxData(), tr("Converted from: {0}", name)));
     377                        Main.main.removeLayer(OsmDataLayer.this);
     378                }
     379        }
    327380}
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java

    r298 r444  
    99import java.net.MalformedURLException;
    1010import java.net.URL;
     11import java.util.Collection;
    1112import java.util.HashMap;
    1213import java.util.LinkedList;
     
    1819import org.openstreetmap.josm.data.coor.EastNorth;
    1920import org.openstreetmap.josm.data.coor.LatLon;
     21import org.openstreetmap.josm.data.gpx.GpxLink;
     22import org.openstreetmap.josm.data.gpx.WayPoint;
    2023import org.openstreetmap.josm.gui.MapView;
    2124import org.openstreetmap.josm.tools.ImageProvider;
     
    7275        static {
    7376                Marker.markerProducers.add(new MarkerProducers() {
    74                         public Marker createMarker(LatLon ll, Map<String,String> data, File relativePath) {
    75                                 String link = data.get("link");
     77                        public Marker createMarker(WayPoint wpt, File relativePath) {
     78                                String uri = null;
     79                                // cheapest way to check whether "link" object exists and is a non-empty
     80                                // collection of GpxLink objects...
     81                                try {
     82                                        for (GpxLink oneLink : (Collection<GpxLink>) wpt.attr.get("link")) {
     83                                                uri = oneLink.uri;
     84                                                break;
     85                                        }
     86                                } catch (Exception ex) {};
    7687
    7788                                // Try a relative file:// url, if the link is not in an URL-compatible form
    78                                 if (relativePath != null && link != null && !isWellFormedAddress(link))
    79                                         link = new File(relativePath, link).toURI().toString();
     89                                if (relativePath != null && uri != null && !isWellFormedAddress(uri))
     90                                        uri = new File(relativePath, uri).toURI().toString();
    8091
    81                                 if (link == null)
    82                                         return new Marker(ll, data.get("name"), data.get("symbol"));
    83                                 if (link.endsWith(".wav"))
    84                                         return AudioMarker.create(ll, link);
    85                                 else if (link.endsWith(".png") || link.endsWith(".jpg") || link.endsWith(".jpeg") || link.endsWith(".gif"))
    86                                         return ImageMarker.create(ll, link);
     92                                if (uri == null)
     93                                        return new Marker(wpt.latlon, wpt.getString("name"), wpt.getString("symbol"));
     94                                if (uri.endsWith(".wav"))
     95                                        return AudioMarker.create(wpt.latlon, uri);
     96                                else if (uri.endsWith(".png") || uri.endsWith(".jpg") || uri.endsWith(".jpeg") || uri.endsWith(".gif"))
     97                                        return ImageMarker.create(wpt.latlon, uri);
    8798                                else
    88                                         return WebMarker.create(ll, link);
     99                                        return WebMarker.create(wpt.latlon, uri);
    89100                        }
    90101
     
    160171         * @return a new Marker object
    161172         */
    162         public static Marker createMarker(LatLon ll, HashMap<String,String> data, File relativePath) {
     173        public static Marker createMarker(WayPoint wpt, File relativePath) {
    163174                for (MarkerProducers maker : Marker.markerProducers) {
    164                         Marker marker = maker.createMarker(ll, data, relativePath);
     175                        Marker marker = maker.createMarker(wpt, relativePath);
    165176                        if (marker != null)
    166177                                return marker;
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java

    r304 r444  
    1414import java.awt.event.MouseEvent;
    1515import java.io.File;
     16import java.util.ArrayList;
    1617import java.util.Collection;
    1718
     
    2526import org.openstreetmap.josm.Main;
    2627import org.openstreetmap.josm.actions.RenameLayerAction;
     28import org.openstreetmap.josm.data.gpx.GpxData;
     29import org.openstreetmap.josm.data.gpx.WayPoint;
    2730import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
    2831import org.openstreetmap.josm.gui.MapView;
     
    5255        private boolean mousePressed = false;
    5356       
    54         public MarkerLayer(Collection<Marker> indata, String name, File associatedFile) {
     57        public MarkerLayer(GpxData indata, String name, File associatedFile) {
     58               
    5559                super(name);
    5660                this.associatedFile = associatedFile;
    57                 this.data = indata;
     61                this.data = new ArrayList<Marker>();
     62               
     63                for (WayPoint wpt : indata.waypoints) {
     64            Marker m = Marker.createMarker(wpt, indata.storageFile);
     65            if (m != null)
     66                data.add(m);
     67                }
    5868               
    5969                SwingUtilities.invokeLater(new Runnable(){
  • trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerProducers.java

    r298 r444  
    66
    77import org.openstreetmap.josm.data.coor.LatLon;
     8import org.openstreetmap.josm.data.gpx.WayPoint;
    89
    910/**
     
    2627         * @return A Marker object, or <code>null</code>.
    2728         */
    28         public Marker createMarker(LatLon ll, Map<String,String> data, File relativePath);
     29        public Marker createMarker(WayPoint wp, File relativePath);
    2930}
  • trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java

    r343 r444  
    66import java.io.IOException;
    77import java.io.InputStream;
    8 import java.util.Collection;
    9 import java.util.LinkedList;
    108
    119import org.openstreetmap.josm.Main;
     
    1412import org.openstreetmap.josm.data.osm.DataSet;
    1513import org.openstreetmap.josm.data.osm.DataSource;
    16 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
     14import org.openstreetmap.josm.data.gpx.GpxData;
    1715import org.xml.sax.SAXException;
    1816
     
    4139     *          ways.
    4240     */
    43     public Collection<Collection<GpsPoint>> parseRawGps() throws IOException, SAXException {
     41        public GpxData parseRawGps() throws IOException, SAXException {
    4442                Main.pleaseWaitDlg.currentAction.setText(tr("Contacting OSM Server..."));
    4543        try {
    4644                String url = "trackpoints?bbox="+lon1+","+lat1+","+lon2+","+lat2+"&page=";
    47                 Collection<Collection<GpsPoint>> data = new LinkedList<Collection<GpsPoint>>();
    48                 Collection<GpsPoint> list = new LinkedList<GpsPoint>();
    4945
    50                 for (int i = 0;;++i) {
     46                        boolean done = false;
     47                        GpxData result = null;
     48                        for (int i = 0;!done;++i) {
    5149                        Main.pleaseWaitDlg.currentAction.setText(tr("Downloading points {0} to {1}...", i * 5000, ((i + 1) * 5000)));
    5250                        InputStream in = getInputStream(url+i, Main.pleaseWaitDlg);
    5351                        if (in == null)
    5452                                break;
    55                         // Use only track points, since the server mix everything together
    56                         Collection<Collection<GpsPoint>> allWays = new RawGpsReader(in, null).trackData;
    57 
    58                         boolean foundSomething = false;
    59                         for (Collection<GpsPoint> t : allWays) {
    60                                 if (!t.isEmpty()) {
    61                                         foundSomething = true;
    62                                         list.addAll(t);
    63                                 }
     53                                GpxData currentGpx = new GpxReader(in, null).data;
     54                                if (result == null) {
     55                                        result = currentGpx;
     56                                } else if (currentGpx.hasTrackPoints()) {
     57                                        result.mergeFrom(currentGpx);
     58                                } else{
     59                                        done = true;
    6460                        }
    65                         if (!foundSomething)
    66                                 break;
    6761                        in.close();
    6862                        activeConnection = null;
    6963                }
    70                 if (!list.isEmpty())
    71                         data.add(list);
    72                 return data;
     64                        result.fromServer = true;
     65                        return result;
    7366        } catch (IllegalArgumentException e) {
    7467                // caused by HttpUrlConnection in case of illegal stuff in the response
  • trunk/src/org/openstreetmap/josm/io/GpxWriter.java

    r343 r444  
    33
    44import java.io.PrintWriter;
     5import java.io.OutputStream;
    56import java.util.Collection;
    6 import java.util.LinkedList;
     7import java.util.Map;
    78
    89import org.openstreetmap.josm.data.Bounds;
    9 import org.openstreetmap.josm.data.coor.LatLon;
    10 import org.openstreetmap.josm.data.osm.DataSet;
    11 import org.openstreetmap.josm.data.osm.Node;
    12 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    13 import org.openstreetmap.josm.data.osm.Way;
    14 import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
     10
     11import org.openstreetmap.josm.data.gpx.GpxData;
     12import org.openstreetmap.josm.data.gpx.GpxTrack;
     13import org.openstreetmap.josm.data.gpx.GpxRoute;
     14import org.openstreetmap.josm.data.gpx.GpxLink;
     15import org.openstreetmap.josm.data.gpx.WayPoint;
    1516
    1617/**
     
    2223 * or less than 2 &lt;trkpt&gt; are exported.
    2324 *
     25 * TODO: to export OSM data as gpx do a transformation into a GpxData instance first
     26 *
    2427 * @author imi
    2528 */
     
    3033        }
    3134
    32         /**
    33          * Export the dataset to gpx.  The ways are converted to trksegs, each in
    34          * a seperate trk.  Finally, all remaining nodes are added as wpt.
     35        public GpxWriter(OutputStream out) {
     36                super(new PrintWriter(out));
     37        }
     38
     39        public GpxWriter() {
     40                super(null);
     41                //sorry for this one here, this will be cleaned up once the new scheme works
     42        }
     43
     44        private GpxData data;
     45        private String indent = "";
     46
     47        private final static int WAY_POINT = 0;
     48        private final static int ROUTE_POINT = 1;
     49        private final static int TRACK_POINT = 2;
     50
     51        public void write(GpxData data) {
     52                this.data = data;
     53                out.println("<?xml version='1.0' encoding='UTF-8'?>");
     54                out.println("<gpx version=\"1.1\" creator=\"JOSM GPX export\" xmlns=\"http://www.topografix.com/GPX/1/1\">");
     55                indent = "  ";
     56                writeMetaData();
     57                writeWayPoints();
     58                writeRoutes();
     59                writeTracks();
     60                out.print("</gpx>");
     61                out.flush();
     62                out.close();
     63        }
     64
     65        private void writeAttr(Map<String, Object> attr) {
     66                boolean hasAuthor = false;
     67                for (Map.Entry<String, Object> ent : attr.entrySet()) {
     68                        String k = ent.getKey();
     69                        if (k.indexOf("author") == 0) {
     70                                hasAuthor = true;
     71                        } else if (k.equals("link")) {
     72                                for (GpxLink link : (Collection<GpxLink>) ent.getValue()) {
     73                                        gpxLink(link);
     74                                }
     75                        } else {
     76                                simpleTag(k, (String) ent.getValue());
     77                        }
     78                }
     79
     80                if (hasAuthor) {
     81                        open("author");
     82                        simpleTag("name", (String) attr.get("authorname"));
     83                        simpleTag("email", (String) attr.get("authoremail"));
     84                        gpxLink((GpxLink) attr.get("authorlink"));
     85                        closeln("author");
     86                }
     87
     88                // TODO: copyright
     89        }
     90
     91        private void writeMetaData() {
     92                openln("metadata");
     93                writeAttr(data.attr);
     94
     95                data.recalculateBounds();
     96                Bounds bounds = data.bounds;
     97                String b = "minlat=\"" + bounds.min.lat() + "\" minlon=\"" + bounds.min.lon() +
     98                        "\" maxlat=\"" + bounds.max.lat() + "\" maxlon=\"" + bounds.max.lon() + "\"" ;
     99                inline("bounds", b);
     100
     101                closeln("metadata");
     102        }
     103
     104        private void writeWayPoints() {
     105                for (WayPoint pnt : data.waypoints) {
     106                        wayPoint(pnt, WAY_POINT);
     107                }       
     108        }
     109       
     110        private void writeRoutes() {
     111                for (GpxRoute rte : data.routes) {
     112                        openln("rte");
     113                        writeAttr(rte.attr);
     114                        for (WayPoint pnt : rte.routePoints) {
     115                                wayPoint(pnt, ROUTE_POINT);
     116                        }
     117                        closeln("rte");
     118                }
     119        }
     120       
     121        private void writeTracks() {
     122                for (GpxTrack trk : data.tracks) {
     123                        open("trk");
     124                        writeAttr(trk.attr);
     125                        for (Collection<WayPoint> seg : trk.trackSegs) {
     126                                openln("trkseg");
     127                                for (WayPoint pnt : seg) {
     128                                        wayPoint(pnt, TRACK_POINT);
     129                                }
     130                                closeln("trkseg");
     131                        }
     132                        closeln("trk");
     133                }
     134        }
     135
     136        private void openln(String tag) {
     137                open(tag);
     138                out.print("\n");
     139        }
     140
     141        private void open(String tag) {
     142                out.print(indent + "<" + tag + ">");
     143                indent += "  ";
     144        }
     145
     146        private void openAtt(String tag, String attributes) {
     147                out.println(indent + "<" + tag + " " + attributes + ">");
     148                indent += "  ";
     149        }
     150       
     151        private void inline(String tag, String attributes) {
     152                out.println(indent + "<" + tag + " " + attributes + " />");
     153        }
     154
     155        private void close(String tag) {
     156                indent = indent.substring(2);
     157                out.print(indent + "</" + tag + ">");
     158        }
     159
     160        private void closeln(String tag) {
     161                close(tag);
     162                out.print("\n");
     163        }
     164
     165        /**       
     166         * if content not null, open tag, write encoded content, and close tag
     167         * else do nothing.
    35168         */
    36         public static final class All implements XmlWriter.OsmWriterInterface {
    37                 private final DataSet data;
    38                 private final String name;
    39                 private final String desc;
    40                 private final String author;
    41                 private final String email;
    42                 private final String copyright;
    43                 private final String year;
    44                 private final String keywords;
    45                 private boolean metadataClosed = false;
    46 
    47                 public All(DataSet data, String name, String desc, String author, String email, String copyright, String year, String keywords) {
    48                         this.data = data;
    49                         this.name = name;
    50                         this.desc = desc;
    51                         this.author = author;
    52                         this.email = email;
    53                         this.copyright = copyright;
    54                         this.year = year;
    55                         this.keywords = keywords;
    56                 }
    57 
    58                 public void header(PrintWriter out) {
    59                         out.println("<gpx version='1.1' creator='JOSM' xmlns='http://www.topografix.com/GPX/1/1'>");
    60                         out.println("  <metadata>");
    61                         if (!name.equals(""))
    62                                 out.println("    <name>"+XmlWriter.encode(name)+"</name>");
    63                         if (!desc.equals(""))
    64                                 out.println("    <desc>"+XmlWriter.encode(desc)+"</desc>");
    65                         if (!author.equals("")) {
    66                                 out.println("    <author>");
    67                                 out.println("      <name>"+XmlWriter.encode(author)+"</name>");
    68                                 if (!email.equals(""))
    69                                         out.println("      <email>"+XmlWriter.encode(email)+"</email>");
    70                                 out.println("    </author>");
    71                                 if (!copyright.equals("")) {
    72                                         out.println("    <copyright author='"+XmlWriter.encode(author)+"'>");
    73                                         if (!year.equals(""))
    74                                                 out.println("      <year>"+XmlWriter.encode(year)+"</year>");
    75                                         out.println("      <license>"+XmlWriter.encode(copyright)+"</license>");
    76                                         out.println("    </copyright>");
    77                                 }
    78                         }
    79                         if (!keywords.equals("")) {
    80                                 out.println("    <keywords>"+XmlWriter.encode(keywords)+"</keywords>");
    81                         }
    82                         // don't finish here, to give output functions the chance to add <bounds>
    83                 }
    84 
    85                 public void write(PrintWriter out) {
    86                         Collection<OsmPrimitive> all = data.allNonDeletedPrimitives();
    87                         if (all.isEmpty())
    88                                 return;
    89                         GpxWriter writer = new GpxWriter(out);
    90                         // calculate bounds
    91                         Bounds b = new Bounds(new LatLon(Double.MAX_VALUE, Double.MAX_VALUE), new LatLon(-Double.MAX_VALUE, -Double.MAX_VALUE));
    92                         for (Node n : data.nodes)
    93                                 if (!n.deleted)
    94                                         b.extend(n.coor);
    95                         out.println("    <bounds minlat='"+b.min.lat()+"' minlon='"+b.min.lon()+"' maxlat='"+b.max.lat()+"' maxlon='"+b.max.lon()+"' />");
    96                         out.println("  </metadata>");
    97                         metadataClosed = true;
    98 
    99                         // add ways
    100                         for (Way w : data.ways) {
    101                                 if (w.deleted)
    102                                         continue;
    103                                 out.println("  <trk>");
    104                                                 out.println("    <trkseg>");
    105                                 for (Node n : w.nodes) {
    106                                         writer.outputNode(n, false);
    107                                         all.remove(n);
    108                         }
    109                                         out.println("    </trkseg>");
    110                                 out.println("  </trk>");
    111                                 all.remove(w);
    112                         }
    113 
    114                         // finally add the remaining nodes
    115                         for (OsmPrimitive osm : all)
    116                                 if (osm instanceof Node)
    117                                         writer.outputNode((Node)osm, true);
    118                 }
    119 
    120                 public void footer(PrintWriter out) {
    121                         if (!metadataClosed)
    122                                 out.println("  </metadata>");
    123                         out.println("</gpx>");
    124                 }
    125         }
    126 
    127 
    128         /**
    129          * Export the collection structure to gpx. The gpx will consists of only one
    130          * trk with as many trkseg as there are collections in the outer collection.
     169        private void simpleTag(String tag, String content) {
     170                if (content != null && content.length() > 0) {
     171                        open(tag);
     172                        out.print(encode(content));
     173                        out.println("</" + tag + ">");
     174                        indent = indent.substring(2);
     175                }
     176        }
     177
     178        /**       
     179         * output link
    131180         */
    132         public static final class Trk implements XmlWriter.OsmWriterInterface {
    133                 private final Collection<Collection<GpsPoint>> data;
    134                 public Trk(Collection<Collection<GpsPoint>> data) {
    135                         this.data = data;
    136                 }
    137 
    138                 public void header(PrintWriter out) {
    139                         out.println("<gpx version='1.1' creator='JOSM' xmlns='http://www.topografix.com/GPX/1/1'>");
    140                 }
    141 
    142                 public void write(PrintWriter out) {
    143                         if (data.size() == 0)
    144                                 return;
    145                         // calculate bounds
    146                         Bounds b = new Bounds(new LatLon(Double.MAX_VALUE, Double.MAX_VALUE), new LatLon(Double.MIN_VALUE, Double.MIN_VALUE));
    147                         for (Collection<GpsPoint> c : data)
    148                                 for (GpsPoint p : c)
    149                                         b.extend(p.latlon);
    150                         out.println("  <metadata>");
    151                         out.println("    <bounds minlat='"+b.min.lat()+"' minlon='"+b.min.lon()+"' maxlat='"+b.max.lat()+"' maxlon='"+b.max.lon()+"' />");
    152                         out.println("  </metadata>");
    153 
    154                         out.println("  <trk>");
    155                         for (Collection<GpsPoint> c : data) {
    156                                 out.println("    <trkseg>");
    157                                 LatLon last = null;
    158                                 for (GpsPoint p : c) {
    159                                         // skip double entries
    160                                         if (p.latlon.equals(last))
    161                                                 continue;
    162                                         last =  p.latlon;
    163                                         LatLon ll = p.latlon;
    164                                         out.print("      <trkpt lat='"+ll.lat()+"' lon='"+ll.lon()+"'");
    165                                         if (p.time != null && p.time.length()!=0) {
    166                                                 out.println(">");
    167                                                 out.println("        <time>"+p.time+"</time>");
    168                                                 out.println("      </trkpt>");
    169                                         } else
    170                                                 out.println(" />");
    171                                 }
    172                                 out.println("    </trkseg>");
    173                         }
    174                         out.println("  </trk>");
    175                 }
    176 
    177                 public void footer(PrintWriter out) {
    178                         out.println("</gpx>");
    179         }
    180         }
    181 
    182         private void outputNode(Node n, boolean wpt) {
    183                 out.print((wpt?"  <wpt":"      <trkpt")+" lat='"+n.coor.lat()+"' lon='"+n.coor.lon()+"'");
    184                 if (n.keys == null) {
    185                         out.println(" />");
    186                         return;
    187                 }
    188                 boolean found = false;
    189                 String[] possibleKeys = {"ele", "time", "magvar", "geoidheight", "name",
    190                                 "cmt", "desc", "src", "link", "sym", "type", "fix", "sat",
    191                                 "hdop", "vdop", "pdop", "ageofgpsdata", "dgpsid"};
    192                 Collection<String> keys = n.keySet();
    193                 for (String k : possibleKeys) {
    194                         if (keys.contains(k)) {
    195                                 if (!found) {
    196                                         found = true;
    197                                         out.println(">");
    198                                 }
    199                                 if (k.equals("link")) {
    200                                         out.println("        <link>");
    201                                         out.println("          <text>"+XmlWriter.encode(n.get(k))+"</text>");
    202                                         out.println("        </link>");
    203                                 } else
    204                                         out.println("        <"+k+">"+XmlWriter.encode(n.get(k))+"</"+k+">");
    205                         }
    206                 }
    207                 if (found)
    208                         out.println(wpt?"  </wpt>":"      </trkpt>");
    209                 else
    210                         out.println(" />");
     181        private void gpxLink(GpxLink link) {
     182                if (link != null) {
     183                        openAtt("link", "href=\"" + link.uri + "\"");
     184                        simpleTag("text", link.text);
     185                        simpleTag("type", link.type);
     186                        closeln("link");
     187                }
     188        }
     189
     190        /**       
     191         * output a point
     192         */
     193        private void wayPoint(WayPoint pnt, int mode) {
     194                String type;
     195                switch(mode) {
     196                case WAY_POINT:
     197                        type = "wpt";
     198                        break;
     199                case ROUTE_POINT:
     200                        type = "rtept";
     201                        break;
     202                case TRACK_POINT:
     203                        type = "trkpt";
     204                        break;
     205                default:
     206                        throw new RuntimeException("Bug detected. Please report this!");
     207                }
     208                if (pnt != null) {
     209                        openAtt(type, "lat=\"" + pnt.latlon.lat() + "\" lon=\"" + pnt.latlon.lon() + "\"");
     210                        writeAttr(pnt.attr);
     211                        closeln(type);
     212                }
    211213        }
    212214}
Note: See TracChangeset for help on using the changeset viewer.