Changeset 24 in josm


Ignore:
Timestamp:
2005-10-28T17:06:06+02:00 (16 years ago)
Author:
imi
Message:
  • added new osm export to file
  • added key/value editing
Files:
4 added
12 edited
1 moved

Legend:

Unmodified
Added
Removed
  • src/org/openstreetmap/josm/Main.java

    r23 r24  
    1919import org.openstreetmap.josm.actions.OpenOsmServerAction;
    2020import org.openstreetmap.josm.actions.PreferencesAction;
     21import org.openstreetmap.josm.actions.SaveAction;
    2122import org.openstreetmap.josm.actions.SaveGpxAction;
    2223import org.openstreetmap.josm.data.Preferences;
     
    7677                OpenOsmServerAction openServerAction = new OpenOsmServerAction();
    7778                OpenGpxAction openGpxAction = new OpenGpxAction();
     79                SaveAction saveAction = new SaveAction();
    7880                SaveGpxAction saveGpxAction = new SaveGpxAction();
    7981                ExitAction exitAction = new ExitAction();
     
    8890                fileMenu.setMnemonic('F');
    8991                fileMenu.add(openGpxAction);
     92                fileMenu.add(saveAction);
    9093                fileMenu.add(saveGpxAction);
    9194                fileMenu.addSeparator();
     
    114117                toolBar.add(openServerAction);
    115118                toolBar.add(openGpxAction);
     119                toolBar.add(saveAction);
    116120                toolBar.add(saveGpxAction);
    117121                toolBar.addSeparator();
  • src/org/openstreetmap/josm/actions/AboutAction.java

    r21 r24  
    55import java.awt.GridBagLayout;
    66import java.awt.event.ActionEvent;
     7import java.awt.event.InputEvent;
    78import java.awt.event.KeyEvent;
    89import java.io.BufferedReader;
     
    2122import javax.swing.JTabbedPane;
    2223import javax.swing.JTextArea;
     24import javax.swing.KeyStroke;
    2325import javax.swing.event.HyperlinkEvent;
    2426import javax.swing.event.HyperlinkListener;
  • src/org/openstreetmap/josm/actions/OpenGpxAction.java

    r23 r24  
    33import java.awt.GridBagLayout;
    44import java.awt.event.ActionEvent;
     5import java.awt.event.InputEvent;
    56import java.awt.event.KeyEvent;
    67import java.io.File;
     
    1617import javax.swing.JOptionPane;
    1718import javax.swing.JPanel;
     19import javax.swing.KeyStroke;
    1820import javax.swing.filechooser.FileFilter;
    1921
     
    4547        public OpenGpxAction() {
    4648                super("Open GPX", ImageProvider.get("opengpx"));
     49                putValue(ACCELERATOR_KEY, KeyStroke.getAWTKeyStroke(KeyEvent.VK_O,
     50                                InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK));
    4751                putValue(MNEMONIC_KEY, KeyEvent.VK_O);
    4852                putValue(SHORT_DESCRIPTION, "Open a file in GPX format.");
  • src/org/openstreetmap/josm/actions/OpenOsmServerAction.java

    r23 r24  
    3535import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    3636import org.openstreetmap.josm.gui.layer.RawGpsDataLayer;
    37 import org.openstreetmap.josm.io.OsmReader;
     37import org.openstreetmap.josm.io.OsmServerReader;
    3838
    3939/**
     
    147147                        return;
    148148                }
    149                 OsmReader osmReader = new OsmReader(Main.pref.osmDataServer,
     149                OsmServerReader osmReader = new OsmServerReader(Main.pref.osmDataServer,
    150150                                b.latlon[0], b.latlon[1], b.latlon[2], b.latlon[3]);
    151151                try {
  • src/org/openstreetmap/josm/actions/PreferencesAction.java

    r17 r24  
    22
    33import java.awt.event.ActionEvent;
     4import java.awt.event.InputEvent;
    45import java.awt.event.KeyEvent;
    56
    67import javax.swing.AbstractAction;
     8import javax.swing.KeyStroke;
    79
    810import org.openstreetmap.josm.gui.ImageProvider;
     
    2123        public PreferencesAction() {
    2224                super("Preferences", ImageProvider.get("preference"));
     25                putValue(ACCELERATOR_KEY, KeyStroke.getAWTKeyStroke(KeyEvent.VK_P, InputEvent.CTRL_DOWN_MASK));
    2326                putValue(MNEMONIC_KEY, KeyEvent.VK_P);
    2427                putValue(SHORT_DESCRIPTION, "Open a preferences page for global settings.");
  • src/org/openstreetmap/josm/actions/SaveGpxAction.java

    r22 r24  
    22
    33import java.awt.event.ActionEvent;
     4import java.awt.event.InputEvent;
    45import java.awt.event.KeyEvent;
    56import java.io.File;
     
    1011import javax.swing.JFileChooser;
    1112import javax.swing.JOptionPane;
     13import javax.swing.KeyStroke;
    1214
    1315import org.openstreetmap.josm.Main;
     
    2931        public SaveGpxAction() {
    3032                super("Save GPX", ImageProvider.get("savegpx"));
     33                putValue(ACCELERATOR_KEY, KeyStroke.getAWTKeyStroke(KeyEvent.VK_S,
     34                                InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK));
    3135                putValue(MNEMONIC_KEY, KeyEvent.VK_S);
    32                 putValue(SHORT_DESCRIPTION, "Save the current active layer as GPX file.");
     36                putValue(SHORT_DESCRIPTION, "Export the current data as GPX file.");
    3337        }
    3438       
    35         @SuppressWarnings("unchecked")
    3639        public void actionPerformed(ActionEvent event) {
    3740                if (Main.main.getMapFrame() == null) {
  • src/org/openstreetmap/josm/actions/mapmode/AddLineSegmentAction.java

    r23 r24  
    5454         */
    5555        public AddLineSegmentAction(MapFrame mapFrame) {
    56                 super("Add Line Segment", "addlinesegment", "Add a line segment between two nodes.", KeyEvent.VK_L, mapFrame);
     56                super("Add Line Segment", "addlinesegment", "Add a line segment between two nodes.", KeyEvent.VK_G, mapFrame);
    5757        }
    5858
  • src/org/openstreetmap/josm/data/osm/Key.java

    r23 r24  
    2222         * All keys are stored here.
    2323         */
    24         private static Map<String, Key> allKeys = new HashMap<String, Key>();
     24        public static final Map<String, Key> allKeys = new HashMap<String, Key>();
    2525       
    2626        /**
     
    5151                visitor.visit(this);
    5252        }
     53
     54        @Override
     55        public String toString() {
     56                return name;
     57        }
    5358}
  • src/org/openstreetmap/josm/gui/MapView.java

    r23 r24  
    406406                                if (bounds == null)
    407407                                        bounds = l.getBoundsXY();
    408                                 else
    409                                         bounds = bounds.mergeXY(l.getBoundsXY());
     408                                else {
     409                                        Bounds lb = l.getBoundsXY();
     410                                        if (lb != null)
     411                                                bounds = bounds.mergeXY(lb);
     412                                }
    410413                        }
    411414
  • src/org/openstreetmap/josm/gui/dialogs/PropertiesDialog.java

    r21 r24  
    11package org.openstreetmap.josm.gui.dialogs;
    22
     3import java.awt.BorderLayout;
     4import java.awt.Component;
     5import java.awt.Font;
     6import java.awt.GridLayout;
     7import java.awt.event.ActionEvent;
     8import java.awt.event.ActionListener;
    39import java.awt.event.KeyEvent;
    4 
    5 import javax.swing.BorderFactory;
    6 import javax.swing.Box;
     10import java.awt.event.MouseAdapter;
     11import java.awt.event.MouseEvent;
     12import java.awt.event.WindowEvent;
     13import java.awt.event.WindowFocusListener;
     14import java.util.Collection;
     15import java.util.Iterator;
     16import java.util.TreeMap;
     17import java.util.TreeSet;
     18import java.util.Vector;
     19import java.util.Map.Entry;
     20
     21import javax.swing.JButton;
     22import javax.swing.JComboBox;
     23import javax.swing.JDialog;
    724import javax.swing.JLabel;
    8 import javax.swing.border.Border;
     25import javax.swing.JOptionPane;
     26import javax.swing.JPanel;
     27import javax.swing.JScrollPane;
     28import javax.swing.JTable;
     29import javax.swing.JTextField;
     30import javax.swing.ListSelectionModel;
     31import javax.swing.table.DefaultTableCellRenderer;
     32import javax.swing.table.DefaultTableModel;
    933
    1034import org.openstreetmap.josm.Main;
     35import org.openstreetmap.josm.command.ChangeKeyValueCommand;
     36import org.openstreetmap.josm.data.SelectionChangedListener;
     37import org.openstreetmap.josm.data.osm.Key;
     38import org.openstreetmap.josm.data.osm.OsmPrimitive;
     39import org.openstreetmap.josm.gui.ImageProvider;
    1140import org.openstreetmap.josm.gui.MapFrame;
     41import org.openstreetmap.josm.gui.MapView;
    1242
    1343/**
    14  * Open a Property dialog for the current visible map. When saving to own josm-
    15  * data format, the properties are saved along.
     44 * This dialog displays the properties of the current selected primitives.
     45 *
     46 * If no object is selected, the dialog list is empty.
     47 * If only one is selected, all properties of this object are selected.
     48 * If more than one object are selected, the sum of all properties are displayed. If the
     49 * different objects share the same property, the shared value is displayed. If they have
     50 * different values, all of them are put in a combo box and the string "&lt;different&gt;"
     51 * is displayed in italic.
     52 *
     53 * Below the list, the user can click on an add, modify and delete property button to
     54 * edit the table selection value.
     55 *
     56 * The command is applied to all selected entries.
    1657 *
    1758 * @author imi
    1859 */
    19 public class PropertiesDialog extends ToggleDialog {
    20 
     60public class PropertiesDialog extends ToggleDialog implements SelectionChangedListener {
     61
     62        /**
     63         * Watches for double clicks and start editing or new property, depending on the
     64         * location, the click was.
     65         * @author imi
     66         */
     67        public class DblClickWatch extends MouseAdapter {
     68                @Override
     69                public void mouseClicked(MouseEvent e) {
     70                        if (e.getClickCount() < 2)
     71                                return;
     72                        if (e.getSource() instanceof JScrollPane)
     73                                add();
     74                        else {
     75                                int row = propertyTable.rowAtPoint(e.getPoint());
     76                                edit(row);
     77                        }
     78                }
     79        }
     80       
     81        /**
     82         * Edit the value in the table row
     83         * @param row   The row of the table, from which the value is edited.
     84         */
     85        void edit(int row) {
     86                String key = data.getValueAt(row, 0).toString();
     87                Collection<OsmPrimitive> sel = Main.main.ds.getSelected();
     88                String msg = "<html>This will change "+sel.size()+" object"+(sel.size()==1?"":"s")+".<br><br>"+
     89                "Please select a new value for '"+key+"'.<br>(Empty string deletes the key.)";
     90                final JComboBox combo = (JComboBox)data.getValueAt(row, 1);
     91                JPanel p = new JPanel(new BorderLayout());
     92                p.add(new JLabel(msg+"</html>"), BorderLayout.NORTH);
     93                p.add(combo, BorderLayout.CENTER);
     94
     95                final JOptionPane optionPane = new JOptionPane(p, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
     96                final JDialog dlg = optionPane.createDialog(PropertiesDialog.this, "Change values?");
     97                dlg.addWindowFocusListener(new WindowFocusListener(){
     98                        public void windowGainedFocus(WindowEvent e) {
     99                                combo.requestFocusInWindow();
     100                        }
     101                        public void windowLostFocus(WindowEvent e) {
     102                        }
     103                });
     104                combo.getEditor().addActionListener(new ActionListener(){
     105                        public void actionPerformed(ActionEvent e) {
     106                                optionPane.setValue(JOptionPane.OK_OPTION);
     107                                dlg.setVisible(false);
     108                        }
     109                });
     110                dlg.setVisible(true);
     111
     112                Object answer = optionPane.getValue();
     113                if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE ||
     114                                (answer instanceof Integer && (Integer)answer != JOptionPane.OK_OPTION))
     115                        return;
     116
     117                String value = combo.getEditor().getItem().toString();
     118                if (value.equals("<different>"))
     119                        return;
     120                if (value.equals(""))
     121                        value = null; // delete the key
     122                mv.editLayer().add(new ChangeKeyValueCommand(sel, Key.get(key), value));
     123
     124                if (value == null)
     125                        selectionChanged(sel); // update whole table
     126                else
     127                        PropertiesDialog.this.repaint(); // repaint is enough
     128        }
     129       
     130        /**
     131         * Open the add selection dialog and add a new key/value to the table (and to the
     132         * dataset, of course).
     133         */
     134        void add() {
     135                Collection<OsmPrimitive> sel = Main.main.ds.getSelected();
     136               
     137                JPanel p = new JPanel(new BorderLayout());
     138                p.add(new JLabel("<html>This will change "+sel.size()+" object"+(sel.size()==1?"":"s")+".<br><br>"+
     139                "Please select a key"), BorderLayout.NORTH);
     140                Vector<String> allKeys = new Vector<String>(Key.allKeys.keySet());
     141                for (Iterator<String> it = allKeys.iterator(); it.hasNext();) {
     142                        String s = it.next();
     143                        for (int i = 0; i < data.getRowCount(); ++i) {
     144                                if (s.equals(data.getValueAt(i, 0))) {
     145                                        it.remove();
     146                                        break;
     147                                }
     148                        }
     149                }
     150                JComboBox keys = new JComboBox(allKeys);
     151                keys.setEditable(true);
     152                p.add(keys, BorderLayout.CENTER);
     153               
     154                JPanel p2 = new JPanel(new BorderLayout());
     155                p.add(p2, BorderLayout.SOUTH);
     156                p2.add(new JLabel("Please select a value"), BorderLayout.NORTH);
     157                JTextField values = new JTextField();
     158                p2.add(values, BorderLayout.CENTER);
     159                int answer = JOptionPane.showConfirmDialog(PropertiesDialog.this, p,
     160                                "Change values?", JOptionPane.OK_CANCEL_OPTION);
     161                if (answer != JOptionPane.OK_OPTION)
     162                        return;
     163                String key = keys.getEditor().getItem().toString();
     164                String value = values.getText();
     165                if (value.equals(""))
     166                        return;
     167                mv.editLayer().add(new ChangeKeyValueCommand(sel, Key.get(key), value));
     168                selectionChanged(sel); // update table
     169        }
     170
     171        /**
     172         * Delete the keys from the given row.
     173         * @param row   The row, which key gets deleted from the dataset.
     174         */
     175        private void delete(int row) {
     176                String key = data.getValueAt(row, 0).toString();
     177                Collection<OsmPrimitive> sel = Main.main.ds.getSelected();
     178                mv.editLayer().add(new ChangeKeyValueCommand(sel, Key.get(key), null));
     179                selectionChanged(sel); // update table
     180        }
     181       
     182        /**
     183         * The property data.
     184         */
     185        private final DefaultTableModel data = new DefaultTableModel(){
     186                @Override
     187                public boolean isCellEditable(int row, int column) {
     188                        return false;
     189                }
     190                @Override
     191                public Class<?> getColumnClass(int columnIndex) {
     192                        return columnIndex == 1 ? JComboBox.class : String.class;
     193                }
     194        };
     195        /**
     196         * The properties list.
     197         */
     198        private final JTable propertyTable = new JTable(data);
     199        /**
     200         * The map view this dialog operates on.
     201         */
     202        private final MapView mv;
     203       
    21204        /**
    22205         * Create a new PropertiesDialog
    23206         */
    24207        public PropertiesDialog(MapFrame mapFrame) {
    25                 super(mapFrame, "Properties of "+Main.main.getNameOfLoadedMapFrame(), "Properties Dialog", "properties", KeyEvent.VK_P, "Property page for this map.");
    26                 putValue(MNEMONIC_KEY, KeyEvent.VK_P);
    27 
    28                 final Border panelBorder = BorderFactory.createEmptyBorder(5,0,0,0);
    29                 Box panel = Box.createVerticalBox();
     208                super(mapFrame, "Properties", "Properties Dialog", "properties", KeyEvent.VK_P, "Property for selected objects.");
     209                mv = mapFrame.mapView;
     210
     211                setLayout(new BorderLayout());
     212                setSize(350,450);
    30213               
    31                 JLabel todo = new JLabel("Nothing implemented yet.");
    32                 todo.setBorder(panelBorder);
    33                 panel.add(todo);
     214                data.setColumnIdentifiers(new String[]{"Key", "Value"});
     215                propertyTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     216                propertyTable.setDefaultRenderer(JComboBox.class, new DefaultTableCellRenderer(){
     217                        @Override
     218                        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
     219                                Component c = super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
     220                                if (c instanceof JLabel) {
     221                                        String str = ((JComboBox)value).getEditor().getItem().toString();
     222                                        ((JLabel)c).setText(str);
     223                                        if (str.equals("<different>"))
     224                                                c.setFont(c.getFont().deriveFont(Font.ITALIC));
     225                                }
     226                                return c;
     227                        }
     228                });
     229                propertyTable.setDefaultRenderer(String.class, new DefaultTableCellRenderer(){
     230                        @Override
     231                        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
     232                                return super.getTableCellRendererComponent(table, value, isSelected, false, row, column);
     233                        }
     234                });
     235                propertyTable.addMouseListener(new DblClickWatch());
     236
     237                JScrollPane scrollPane = new JScrollPane(propertyTable);
     238                scrollPane.addMouseListener(new DblClickWatch());
     239                getContentPane().add(scrollPane, BorderLayout.CENTER);
    34240               
    35                 panel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
    36                 setContentPane(panel);
    37                 pack();
    38                 setResizable(false);
     241                JPanel buttonPanel = new JPanel(new GridLayout(1,3));
     242                ActionListener buttonAction = new ActionListener(){
     243                        public void actionPerformed(ActionEvent e) {
     244                                int sel = propertyTable.getSelectedRow();
     245                                if (e.getActionCommand().equals("Add"))
     246                                        add();
     247                                else if (e.getActionCommand().equals("Edit")) {
     248                                        if (sel == -1)
     249                                                JOptionPane.showMessageDialog(PropertiesDialog.this, "Please select the row to edit.");
     250                                        else
     251                                                edit(sel);
     252                                } else if (e.getActionCommand().equals("Delete")) {
     253                                        if (sel == -1)
     254                                                JOptionPane.showMessageDialog(PropertiesDialog.this, "Please select the row to delete.");
     255                                        else
     256                                                delete(sel);
     257                                }
     258                        }
     259                };
     260                buttonPanel.add(createButton("Add", "Add a new key/value pair to all objects", KeyEvent.VK_A, buttonAction));
     261                buttonPanel.add(createButton("Edit", "Edit the value of the selected key for all objects", KeyEvent.VK_E, buttonAction));
     262                buttonPanel.add(createButton("Delete", "Delete the selected key in all objects", KeyEvent.VK_DELETE, buttonAction));
     263                getContentPane().add(buttonPanel, BorderLayout.SOUTH);
     264        }
     265       
     266        private JButton createButton(String name, String tooltip, int mnemonic, ActionListener actionListener) {
     267                JButton b = new JButton(name, ImageProvider.get("dialogs", name.toLowerCase()));
     268                b.setActionCommand(name);
     269                b.addActionListener(actionListener);
     270                b.setToolTipText(tooltip);
     271                b.setMnemonic(mnemonic);
     272                return b;
     273        }
     274
     275        @Override
     276        public void setVisible(boolean b) {
     277                if (b) {
     278                        Main.main.ds.addSelectionChangedListener(this);
     279                        selectionChanged(Main.main.ds.getSelected());
     280                } else {
     281                        Main.main.ds.removeSelectionChangedListener(this);
     282                }
     283                super.setVisible(b);
     284        }
     285
     286        public void selectionChanged(Collection<OsmPrimitive> newSelection) {
     287                if (propertyTable.getCellEditor() != null)
     288                        propertyTable.getCellEditor().cancelCellEditing();
     289                data.setRowCount(0);
     290                TreeMap<String, Collection<String>> props = new TreeMap<String, Collection<String>>();
     291                for (OsmPrimitive osm : newSelection) {
     292                        if (osm.keys != null) {
     293                                for (Entry<Key, String> e : osm.keys.entrySet()) {
     294                                        Collection<String> value = props.get(e.getKey().name);
     295                                        if (value == null) {
     296                                                value = new TreeSet<String>();
     297                                                props.put(e.getKey().name, value);
     298                                        }
     299                                        value.add(e.getValue());
     300                                }
     301                        }
     302                }
     303                for (Entry<String, Collection<String>> e : props.entrySet()) {
     304                        JComboBox value = new JComboBox(e.getValue().toArray());
     305                        value.setEditable(true);
     306                        if (e.getValue().size() > 1)
     307                                value.getEditor().setItem("<different>");
     308                        data.addRow(new Object[]{e.getKey(), value});
     309                }
    39310        }
    40311}
  • src/org/openstreetmap/josm/io/GpxReader.java

    r23 r24  
    4040         */
    4141        public Reader source;
    42        
     42
    4343        /**
    4444         * Construct a parser from a specific data source.
     
    132132                                        }
    133133                                }
    134                         }
    135                        
    136                         if (child.getName().equals("extensions"))
     134                        } else if (child.getName().equals("extensions"))
    137135                                parseKeyValueExtensions(track, child);
    138136                        else if (child.getName().equals("link"))
     
    157155         * @return Either the parameter node or the old node found in the dataset.
    158156         */
    159         private Node addNode (DataSet data, Node node) {
     157        private Node addNode(DataSet data, Node node) {
    160158                if (Main.pref.mergeNodes)
    161159                        for (Node n : data.nodes)
  • src/org/openstreetmap/josm/io/OsmServerReader.java

    r23 r24  
    1818 * @author imi
    1919 */
    20 public class OsmReader extends OsmConnection {
     20public class OsmServerReader extends OsmConnection {
    2121
    2222        /**
     
    3232         * Construct the reader and store the information for attaching
    3333         */
    34         public OsmReader(String server,
     34        public OsmServerReader(String server,
    3535                        double lat1, double lon1, double lat2, double lon2) {
    3636                this.lon2 = lon2;
  • src/org/openstreetmap/josm/io/OsmWriter.java

    r22 r24  
    22
    33import java.io.IOException;
     4import java.io.Writer;
    45import java.util.Collection;
     6import java.util.HashSet;
    57import java.util.LinkedList;
     8import java.util.List;
     9import java.util.Set;
     10import java.util.Map.Entry;
    611
    7 import javax.swing.JOptionPane;
    8 
    9 import org.openstreetmap.josm.Main;
    10 import org.openstreetmap.josm.command.Command;
     12import org.jdom.Document;
     13import org.jdom.Element;
     14import org.jdom.output.Format;
     15import org.jdom.output.XMLOutputter;
     16import org.openstreetmap.josm.data.osm.DataSet;
     17import org.openstreetmap.josm.data.osm.Key;
     18import org.openstreetmap.josm.data.osm.LineSegment;
     19import org.openstreetmap.josm.data.osm.Node;
    1120import org.openstreetmap.josm.data.osm.OsmPrimitive;
     21import org.openstreetmap.josm.data.osm.Track;
    1222
    1323
    1424/**
    15  * Send back the modified data to the osm server.
     25 * Save the dataset into a stream as osm intern xml format.
    1626 * @author imi
    1727 */
     
    1929
    2030        /**
    21          * The server base url to handle the osm requests.
     31         * The output writer to write the xml stream to.
    2232         */
    23         private final String server;
     33        private final Writer out;
    2434        /**
    2535         * The commands that should be uploaded on the server.
    2636         */
    27         private final Collection<Command> commands;
     37        private DataSet ds;
     38        /**
     39         * ID generator start for all nodes with id==0
     40         */
     41        private long id = 0;
     42        /**
     43         * A collection of all ids used so far to look up and jump over used ids.
     44         */
     45        private Set<Long> ids;
     46       
     47        public OsmWriter(Writer out, DataSet dataSet) {
     48                this.out = out;
     49                ds = dataSet;
     50        }
    2851
    29         public OsmWriter(String server, Collection<Command> commands) {
    30                 this.server = server;
    31                 this.commands = commands;
     52        /**
     53         * Output the data to the stream
     54         * @throws IOException In case of stream IO errors.
     55         */
     56        @SuppressWarnings("unchecked")
     57        public void output() throws IOException {
     58                ids = allUsedIds();
     59                Element root = new Element("osm");
     60                List<Element> list = root.getChildren();
     61                Collection<Element> properties = new LinkedList<Element>();
     62                for (Node n : ds.nodes)
     63                        list.add(parseNode(n, properties));
     64                for (LineSegment ls : ds.pendingLineSegments)
     65                        list.add(parseLineSegment(ls, properties));
     66                // all other line segments
     67                Collection<LineSegment> lineSegments = new HashSet<LineSegment>();
     68                for (Track t : ds.tracks)
     69                        lineSegments.addAll(t.segments);
     70                for (LineSegment ls : lineSegments)
     71                        list.add(parseLineSegment(ls, properties));
     72                for (Track t : ds.tracks)
     73                        list.add(parseTrack(t, properties));
     74                list.addAll(properties);
     75
     76                Document d = new Document(root);
     77                XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());
     78                xmlOut.output(d, out);
     79        }
     80
     81        /**
     82         * Create an track element. Add all properties of the node to the properties-list.
     83         */
     84        @SuppressWarnings("unchecked")
     85        private Element parseTrack(Track t, Collection<Element> properties) {
     86                Element e = new Element("track");
     87                addProperties(e, t, properties);
     88                for (LineSegment ls : t.segments)
     89                        e.getChildren().add(new Element("segment").setAttribute("id", ""+ls.id));
     90                return e;
     91        }
     92
     93        /**
     94         * Create an node element. Add all properties of the node to the properties-list.
     95         */
     96        private Element parseNode(Node n, Collection<Element> properties) {
     97                Element e = new Element("node");
     98                addProperties(e, n, properties);
     99                e.setAttribute("lat", ""+n.coor.lat);
     100                e.setAttribute("lon", ""+n.coor.lon);
     101                return e;
     102        }
     103
     104       
     105
     106        /**
     107         * Create an line segment element. Add all properties of the node to the properties-list.
     108         */
     109        private Element parseLineSegment(LineSegment ls, Collection<Element> properties) {
     110                Element e = new Element("segment");
     111                addProperties(e, ls, properties);
     112                e.setAttribute("start", ""+ls.start.id);
     113                e.setAttribute("end", ""+ls.end.id);
     114                return e;
    32115        }
    33116       
    34117        /**
    35          * Upload the commands to the server.
    36          * @throws IOException
     118         * Create a properties element.
    37119         */
    38         public void output() throws IOException {
    39                 Collection<OsmPrimitive> added = new LinkedList<OsmPrimitive>();
    40                 Collection<OsmPrimitive> modified = new LinkedList<OsmPrimitive>();
    41                 Collection<OsmPrimitive> deleted = new LinkedList<OsmPrimitive>();
    42                 for (Command c : commands)
    43                         c.fillModifiedData(modified, deleted, added);
    44                 int answer = JOptionPane.showConfirmDialog(Main.main, "Send "+added.size()+" new, "
    45                                 +modified.size()+" modified and "+deleted.size()+" deleted objects to server?");
    46                 if (answer != JOptionPane.YES_OPTION)
    47                         return;
     120        private Element parseProperty(OsmPrimitive osm, Entry<Key, String> entry) {
     121                Element e = new Element("property");
     122                Key key = entry.getKey();
     123                if (key.id == 0)
     124                        key.id = generateId();
     125                e.setAttribute("id", ""+key.id);
     126                e.setAttribute("object", ""+osm.id);
     127                e.setAttribute("key", key.name);
     128                e.setAttribute("value", entry.getValue());
     129                return e;
     130        }
     131       
     132        /**
     133         * Add the id attribute to the element and the properties to the collection.
     134         */
     135        private void addProperties(Element e, OsmPrimitive osm, Collection<Element> properties) {
     136                if (osm.id == 0)
     137                        osm.id = generateId();
     138                e.setAttribute("id", ""+osm.id);
     139                if (osm.keys != null)
     140                        for (Entry<Key, String> entry : osm.keys.entrySet())
     141                                properties.add(parseProperty(osm, entry));
     142        }
     143
     144        /**
     145         * Generate an new unused id.
     146         */
     147        private long generateId() {
     148                while (ids.contains(Long.valueOf(id)))
     149                        id++;
     150                ids.add(id);
     151                return id;
     152        }
     153
     154        /**
     155         * Return all used ids in a set.
     156         */
     157        private Set<Long> allUsedIds() {
     158                HashSet<Long> ids = new HashSet<Long>();
     159                for (OsmPrimitive osm : ds.nodes)
     160                        addIdAndKeyIds(osm, ids);
     161                for (OsmPrimitive osm : ds.pendingLineSegments)
     162                        addIdAndKeyIds(osm, ids);
     163                for (Track t : ds.tracks) {
     164                        addIdAndKeyIds(t, ids);
     165                        for (LineSegment ls : t.segments) {
     166                                addIdAndKeyIds(ls, ids);
     167                                addIdAndKeyIds(ls.start, ids);
     168                                addIdAndKeyIds(ls.end, ids);
     169                        }
     170                }
     171                return ids;
     172        }
     173
     174        /**
     175         * Return all used ids in the given osm primitive.
     176         */
     177        private void addIdAndKeyIds(OsmPrimitive osm, Collection<Long> ids) {
     178                ids.add(osm.id);
     179                if (osm.keys != null)
     180                        for (Key key : osm.keys.keySet())
     181                                ids.add(key.id);
    48182        }
    49183}
     184
Note: See TracChangeset for help on using the changeset viewer.