source: josm/trunk/src/org/openstreetmap/josm/gui/layer/RawGpsLayer.java@ 1210

Last change on this file since 1210 was 1169, checked in by stoecker, 15 years ago

removed usage of tab stops

  • Property svn:eol-style set to native
File size: 16.1 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui.layer;
3
4import static org.openstreetmap.josm.tools.I18n.marktr;
5import static org.openstreetmap.josm.tools.I18n.tr;
6import static org.openstreetmap.josm.tools.I18n.trn;
7
8import java.awt.Color;
9import java.awt.Component;
10import java.awt.Graphics;
11import java.awt.GridBagLayout;
12import java.awt.Point;
13import java.awt.event.ActionEvent;
14import java.awt.event.ActionListener;
15import java.io.BufferedReader;
16import java.io.File;
17import java.io.InputStreamReader;
18import java.net.URL;
19import java.net.URLConnection;
20import java.net.UnknownHostException;
21import java.util.Collection;
22
23import javax.swing.AbstractAction;
24import javax.swing.Box;
25import javax.swing.ButtonGroup;
26import javax.swing.Icon;
27import javax.swing.JCheckBox;
28import javax.swing.JColorChooser;
29import javax.swing.JLabel;
30import javax.swing.JMenuItem;
31import javax.swing.JOptionPane;
32import javax.swing.JPanel;
33import javax.swing.JRadioButton;
34import javax.swing.JSeparator;
35import javax.swing.JTextField;
36
37import org.openstreetmap.josm.Main;
38import org.openstreetmap.josm.actions.GpxExportAction;
39import org.openstreetmap.josm.actions.RenameLayerAction;
40import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
41import org.openstreetmap.josm.data.coor.EastNorth;
42import org.openstreetmap.josm.data.coor.LatLon;
43import org.openstreetmap.josm.data.osm.DataSet;
44import org.openstreetmap.josm.data.osm.Node;
45import org.openstreetmap.josm.data.osm.Way;
46import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
47import org.openstreetmap.josm.gui.MapView;
48import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
49import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
50import org.openstreetmap.josm.io.MultiPartFormOutputStream;
51import org.openstreetmap.josm.tools.DontShowAgainInfo;
52import org.openstreetmap.josm.tools.GBC;
53import org.openstreetmap.josm.tools.ImageProvider;
54import org.openstreetmap.josm.tools.UrlLabel;
55
56/**
57 * A layer holding data from a gps source.
58 * The data is read only.
59 *
60 * @author imi
61 */
62public class RawGpsLayer extends Layer implements PreferenceChangedListener {
63
64 public class ConvertToDataLayerAction extends AbstractAction {
65 public ConvertToDataLayerAction() {
66 super(tr("Convert to data layer"), ImageProvider.get("converttoosm"));
67 }
68 public void actionPerformed(ActionEvent e) {
69 JPanel msg = new JPanel(new GridBagLayout());
70 msg.add(new JLabel(tr("<html>Upload of unprocessed GPS data as map data is considered harmful.<br>If you want to upload traces, look here:")), GBC.eol());
71 msg.add(new UrlLabel(tr("http://www.openstreetmap.org/traces")), GBC.eop());
72 if (!DontShowAgainInfo.show("convert_to_data", msg))
73 return;
74 DataSet ds = new DataSet();
75 for (Collection<GpsPoint> c : data) {
76 Way w = new Way();
77 for (GpsPoint p : c) {
78 Node n = new Node(p.latlon);
79 ds.nodes.add(n);
80 w.nodes.add(n);
81 }
82 ds.ways.add(w);
83 }
84 Main.main.addLayer(new OsmDataLayer(ds, tr("Converted from: {0}", RawGpsLayer.this.name), null));
85 Main.main.removeLayer(RawGpsLayer.this);
86 }
87 }
88
89 public class UploadTraceAction extends AbstractAction {
90 public UploadTraceAction() {
91 super(tr("Upload this trace..."), ImageProvider.get("uploadtrace"));
92 }
93 public void actionPerformed(ActionEvent e) {
94 JPanel msg = new JPanel(new GridBagLayout());
95 msg.add(new JLabel(tr("<html>This functionality has been added only recently. Please<br>"+
96 "use with care and check if it works as expected.</html>")), GBC.eop());
97 ButtonGroup bg = new ButtonGroup();
98 JRadioButton c1 = null;
99 JRadioButton c2 = null;
100
101 if (associatedFile != null) {
102 c1 = new JRadioButton(tr("Upload track filtered by JOSM"), false);
103 c2 = new JRadioButton(tr("Upload raw file: {0}", associatedFile.getName()), true);
104 }
105 else
106 {
107 c1 = new JRadioButton(tr("Upload track filtered by JOSM"), true);
108 c2 = new JRadioButton(tr("Upload raw file: "), false);
109 c2.setEnabled(false);
110 }
111 c1.setEnabled(false);
112 bg.add(c1);
113 bg.add(c2);
114
115 msg.add(c1, GBC.eol());
116 msg.add(c2, GBC.eop());
117
118
119 JTextField description = new JTextField();
120 JTextField tags = new JTextField();
121 msg.add(new JLabel(tr("Description:")), GBC.std());
122 msg.add(description, GBC.eol().fill(GBC.HORIZONTAL));
123 msg.add(new JLabel(tr("Tags:")), GBC.std());
124 msg.add(tags, GBC.eol().fill(GBC.HORIZONTAL));
125 JCheckBox c3 = new JCheckBox("public");
126 msg.add(c3, GBC.eop());
127 msg.add(new JLabel("Please ensure that you don't upload your traces twice."), GBC.eop());
128
129 int answer = JOptionPane.showConfirmDialog(Main.parent, msg, tr("GPX-Upload"), JOptionPane.OK_CANCEL_OPTION);
130 if (answer == JOptionPane.OK_OPTION)
131 {
132 try {
133 String version = Main.pref.get("osm-server.version", "0.5");
134 URL url = new URL(Main.pref.get("osm-server.url") +
135 "/" + version + "/gpx/create");
136
137 // create a boundary string
138 String boundary = MultiPartFormOutputStream.createBoundary();
139 URLConnection urlConn = MultiPartFormOutputStream.createConnection(url);
140 urlConn.setRequestProperty("Accept", "*/*");
141 urlConn.setRequestProperty("Content-Type",
142 MultiPartFormOutputStream.getContentType(boundary));
143 // set some other request headers...
144 urlConn.setRequestProperty("Connection", "Keep-Alive");
145 urlConn.setRequestProperty("Cache-Control", "no-cache");
146 // no need to connect cuz getOutputStream() does it
147 MultiPartFormOutputStream out =
148 new MultiPartFormOutputStream(urlConn.getOutputStream(), boundary);
149 out.writeField("description", description.getText());
150 out.writeField("tags", tags.getText());
151 out.writeField("public", (c3.getSelectedObjects() != null) ? "1" : "0");
152 // upload a file
153 out.writeFile("gpx_file", "text/xml", associatedFile);
154 // can also write bytes directly
155 // out.writeFile("myFile", "text/plain", "C:\\test.txt",
156 // "This is some file text.".getBytes("ASCII"));
157 out.close();
158 // read response from server
159 BufferedReader in = new BufferedReader(
160 new InputStreamReader(urlConn.getInputStream()));
161 String line = "";
162 while((line = in.readLine()) != null) {
163 System.out.println(line);
164 }
165 in.close();
166
167 /*
168 int retCode = activeConnection.getResponseCode();
169 System.out.println("got return: "+retCode);
170 String retMsg = activeConnection.getResponseMessage();
171 activeConnection.disconnect();
172 if (retCode != 200) {
173 // Look for a detailed error message from the server
174 if (activeConnection.getHeaderField("Error") != null)
175 retMsg += "\n" + activeConnection.getHeaderField("Error");
176
177 // Report our error
178 ByteArrayOutputStream o = new ByteArrayOutputStream();
179 System.out.println(new String(o.toByteArray(), "UTF-8").toString());
180 throw new RuntimeException(retCode+" "+retMsg);
181 }
182 */
183 } catch (UnknownHostException ex) {
184 throw new RuntimeException(tr("Unknown host")+": "+ex.getMessage(), ex);
185 } catch (Exception ex) {
186 //if (cancel)
187 // return; // assume cancel
188 if (ex instanceof RuntimeException)
189 throw (RuntimeException)ex;
190 throw new RuntimeException(ex.getMessage(), ex);
191 }
192 }
193 }
194 }
195
196 public static class GpsPoint {
197 public final LatLon latlon;
198 public final EastNorth eastNorth;
199 public final String time;
200 public GpsPoint(LatLon ll, String t) {
201 latlon = ll;
202 eastNorth = Main.proj.latlon2eastNorth(ll);
203 time = t;
204 }
205 }
206
207 /**
208 * A list of ways which containing a list of points.
209 */
210 public final Collection<Collection<GpsPoint>> data;
211 public final boolean fromServer;
212
213 public RawGpsLayer(boolean fromServer, Collection<Collection<GpsPoint>> data, String name, File associatedFile) {
214 super(name);
215 this.fromServer = fromServer;
216 this.associatedFile = associatedFile;
217 this.data = data;
218 Main.pref.listener.add(this);
219 }
220
221 /**
222 * Return a static icon.
223 */
224 @Override public Icon getIcon() {
225 return ImageProvider.get("layer", "rawgps_small");
226 }
227
228 @Override public void paint(Graphics g, MapView mv) {
229 g.setColor(Main.pref.getColor(marktr("gps point"), "layer "+name, Color.gray));
230 Point old = null;
231
232 boolean force = Main.pref.getBoolean("draw.rawgps.lines.force");
233 boolean lines = Main.pref.getBoolean("draw.rawgps.lines");
234 String linesKey = "draw.rawgps.lines.layer "+name;
235 if (Main.pref.hasKey(linesKey))
236 lines = Main.pref.getBoolean(linesKey);
237 boolean large = Main.pref.getBoolean("draw.rawgps.large");
238 for (Collection<GpsPoint> c : data) {
239 if (!force)
240 old = null;
241 for (GpsPoint p : c) {
242 Point screen = mv.getPoint(p.eastNorth);
243 if (lines && old != null)
244 g.drawLine(old.x, old.y, screen.x, screen.y);
245 else if (!large)
246 g.drawRect(screen.x, screen.y, 0, 0);
247 if (large)
248 g.fillRect(screen.x-1, screen.y-1, 3, 3);
249 old = screen;
250 }
251 }
252 }
253
254 @Override public String getToolTipText() {
255 int points = 0;
256 for (Collection<GpsPoint> c : data)
257 points += c.size();
258 String tool = data.size()+" "+trn("track", "tracks", data.size())
259 +" "+points+" "+trn("point", "points", points);
260 if (associatedFile != null)
261 tool = "<html>"+tool+"<br>"+associatedFile.getPath()+"</html>";
262 return tool;
263 }
264
265 @Override public void mergeFrom(Layer from) {
266 RawGpsLayer layer = (RawGpsLayer)from;
267 data.addAll(layer.data);
268 }
269
270 @Override public boolean isMergable(Layer other) {
271 return other instanceof RawGpsLayer;
272 }
273
274 @Override public void visitBoundingBox(BoundingXYVisitor v) {
275 for (Collection<GpsPoint> c : data)
276 for (GpsPoint p : c)
277 v.visit(p.eastNorth);
278 }
279
280 @Override public Object getInfoComponent() {
281 StringBuilder b = new StringBuilder();
282 int points = 0;
283 for (Collection<GpsPoint> c : data) {
284 b.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"+trn("a track with {0} point","a track with {0} points", c.size(), c.size())+"<br>");
285 points += c.size();
286 }
287 b.append("</html>");
288 return "<html>"+trn("{0} consists of {1} track", "{0} consists of {1} tracks", data.size(), name, data.size())+" ("+trn("{0} point", "{0} points", points, points)+")<br>"+b.toString();
289 }
290
291 @Override public Component[] getMenuEntries() {
292 JMenuItem line = new JMenuItem(tr("Customize line drawing"), ImageProvider.get("mapmode/addsegment"));
293 line.addActionListener(new ActionListener(){
294 public void actionPerformed(ActionEvent e) {
295 JRadioButton[] r = new JRadioButton[3];
296 r[0] = new JRadioButton(tr("Use global settings."));
297 r[1] = new JRadioButton(tr("Draw lines between points for this layer."));
298 r[2] = new JRadioButton(tr("Do not draw lines between points for this layer."));
299 ButtonGroup group = new ButtonGroup();
300 Box panel = Box.createVerticalBox();
301 for (JRadioButton b : r) {
302 group.add(b);
303 panel.add(b);
304 }
305 String propName = "draw.rawgps.lines.layer "+name;
306 if (Main.pref.hasKey(propName))
307 group.setSelected(r[Main.pref.getBoolean(propName) ? 1:2].getModel(), true);
308 else
309 group.setSelected(r[0].getModel(), true);
310 int answer = JOptionPane.showConfirmDialog(Main.parent, panel, tr("Select line drawing options"), JOptionPane.OK_CANCEL_OPTION);
311 if (answer == JOptionPane.CANCEL_OPTION)
312 return;
313 if (group.getSelection() == r[0].getModel())
314 Main.pref.put(propName, null);
315 else
316 Main.pref.put(propName, group.getSelection() == r[1].getModel());
317 Main.map.repaint();
318 }
319 });
320
321 JMenuItem color = new JMenuItem(tr("Customize Color"), ImageProvider.get("colorchooser"));
322 color.addActionListener(new ActionListener(){
323 public void actionPerformed(ActionEvent e) {
324 JColorChooser c = new JColorChooser(Main.pref.getColor(marktr("gps point"), "layer "+name, Color.gray));
325 Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")};
326 int answer = JOptionPane.showOptionDialog(Main.parent, c, tr("Choose a color"), JOptionPane.OK_CANCEL_OPTION,
327 JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
328 switch (answer) {
329 case 0:
330 Main.pref.putColor("layer "+name, c.getColor());
331 break;
332 case 1:
333 return;
334 case 2:
335 Main.pref.putColor("layer "+name, null);
336 break;
337 }
338 Main.map.repaint();
339 }
340 });
341
342 if (Main.applet)
343 return new Component[]{
344 new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
345 new JMenuItem(new LayerListDialog.DeleteLayerAction(this)),
346 new JSeparator(),
347 color,
348 line,
349 new JMenuItem(new ConvertToDataLayerAction()),
350 //new JMenuItem(new UploadTraceAction()),
351 new JSeparator(),
352 new JMenuItem(new RenameLayerAction(associatedFile, this)),
353 new JSeparator(),
354 new JMenuItem(new LayerListPopup.InfoAction(this))};
355 return new Component[]{
356 new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
357 new JMenuItem(new LayerListDialog.DeleteLayerAction(this)),
358 new JSeparator(),
359 new JMenuItem(new GpxExportAction(this)),
360 color,
361 line,
362 new JMenuItem(new ConvertToDataLayerAction()),
363 //new JMenuItem(new UploadTraceAction()),
364 new JSeparator(),
365 new JMenuItem(new RenameLayerAction(associatedFile, this)),
366 new JSeparator(),
367 new JMenuItem(new LayerListPopup.InfoAction(this))};
368 }
369
370 public void preferenceChanged(String key, String newValue) {
371 if (Main.map != null && (key.equals("draw.rawgps.lines") || key.equals("draw.rawgps.lines.force")))
372 Main.map.repaint();
373 }
374
375 @Override public void destroy() {
376 Main.pref.listener.remove(RawGpsLayer.this);
377 }
378}
Note: See TracBrowser for help on using the repository browser.