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

Last change on this file since 298 was 298, checked in by imi, 17 years ago
  • added license description to head of each source file
File size: 10.7 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.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.awt.Color;
8import java.awt.Component;
9import java.awt.Graphics;
10import java.awt.GridBagLayout;
11import java.awt.Point;
12import java.awt.event.ActionEvent;
13import java.awt.event.ActionListener;
14import java.io.File;
15import java.util.Collection;
16import java.util.LinkedList;
17
18import javax.swing.AbstractAction;
19import javax.swing.Box;
20import javax.swing.ButtonGroup;
21import javax.swing.Icon;
22import javax.swing.JColorChooser;
23import javax.swing.JFileChooser;
24import javax.swing.JLabel;
25import javax.swing.JMenuItem;
26import javax.swing.JOptionPane;
27import javax.swing.JPanel;
28import javax.swing.JRadioButton;
29import javax.swing.JSeparator;
30import javax.swing.filechooser.FileFilter;
31
32import org.openstreetmap.josm.Main;
33import org.openstreetmap.josm.actions.GpxExportAction;
34import org.openstreetmap.josm.actions.RenameLayerAction;
35import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
36import org.openstreetmap.josm.data.coor.EastNorth;
37import org.openstreetmap.josm.data.coor.LatLon;
38import org.openstreetmap.josm.data.osm.DataSet;
39import org.openstreetmap.josm.data.osm.Node;
40import org.openstreetmap.josm.data.osm.Segment;
41import org.openstreetmap.josm.data.osm.Way;
42import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
43import org.openstreetmap.josm.gui.MapView;
44import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
45import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
46import org.openstreetmap.josm.tools.ColorHelper;
47import org.openstreetmap.josm.tools.DontShowAgainInfo;
48import org.openstreetmap.josm.tools.GBC;
49import org.openstreetmap.josm.tools.ImageProvider;
50import org.openstreetmap.josm.tools.UrlLabel;
51
52/**
53 * A layer holding data from a gps source.
54 * The data is read only.
55 *
56 * @author imi
57 */
58public class RawGpsLayer extends Layer implements PreferenceChangedListener {
59
60 public class ConvertToDataLayerAction extends AbstractAction {
61 public ConvertToDataLayerAction() {
62 super(tr("Convert to data layer"), ImageProvider.get("converttoosm"));
63 }
64 public void actionPerformed(ActionEvent e) {
65 JPanel msg = new JPanel(new GridBagLayout());
66 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());
67 msg.add(new UrlLabel(tr("http://www.openstreetmap.org/traces")), GBC.eop());
68 if (!DontShowAgainInfo.show("convert_to_data", msg))
69 return;
70 DataSet ds = new DataSet();
71 for (Collection<GpsPoint> c : data) {
72 Way w = new Way();
73 Node start = null;
74 for (GpsPoint p : c) {
75 Node end = new Node(p.latlon);
76 ds.nodes.add(end);
77 if (start != null) {
78 Segment segment = new Segment(start,end);
79 w.segments.add(segment);
80 ds.segments.add(segment);
81 }
82 start = end;
83 }
84 ds.ways.add(w);
85 }
86 Main.main.addLayer(new OsmDataLayer(ds, tr("Converted from: {0}", RawGpsLayer.this.name), null));
87 Main.main.removeLayer(RawGpsLayer.this);
88 }
89 }
90
91 public static class GpsPoint {
92 public final LatLon latlon;
93 public final EastNorth eastNorth;
94 public final String time;
95 public GpsPoint(LatLon ll, String t) {
96 latlon = ll;
97 eastNorth = Main.proj.latlon2eastNorth(ll);
98 time = t;
99 }
100 }
101
102 /**
103 * A list of ways which containing a list of points.
104 */
105 public final Collection<Collection<GpsPoint>> data;
106 public final boolean fromServer;
107
108 public RawGpsLayer(boolean fromServer, Collection<Collection<GpsPoint>> data, String name, File associatedFile) {
109 super(name);
110 this.fromServer = fromServer;
111 this.associatedFile = associatedFile;
112 this.data = data;
113 Main.pref.listener.add(this);
114 }
115
116 /**
117 * Return a static icon.
118 */
119 @Override public Icon getIcon() {
120 return ImageProvider.get("layer", "rawgps_small");
121 }
122
123 @Override public void paint(Graphics g, MapView mv) {
124 String gpsCol = Main.pref.get("color.gps point");
125 String gpsColSpecial = Main.pref.get("color.layer "+name);
126 if (!gpsColSpecial.equals(""))
127 g.setColor(ColorHelper.html2color(gpsColSpecial));
128 else if (!gpsCol.equals(""))
129 g.setColor(ColorHelper.html2color(gpsCol));
130 else
131 g.setColor(Color.GRAY);
132 Point old = null;
133
134 boolean force = Main.pref.getBoolean("draw.rawgps.lines.force");
135 boolean lines = Main.pref.getBoolean("draw.rawgps.lines");
136 String linesKey = "draw.rawgps.lines.layer "+name;
137 if (Main.pref.hasKey(linesKey))
138 lines = Main.pref.getBoolean(linesKey);
139 boolean large = Main.pref.getBoolean("draw.rawgps.large");
140 for (Collection<GpsPoint> c : data) {
141 if (!force)
142 old = null;
143 for (GpsPoint p : c) {
144 Point screen = mv.getPoint(p.eastNorth);
145 if (lines && old != null)
146 g.drawLine(old.x, old.y, screen.x, screen.y);
147 else if (!large)
148 g.drawRect(screen.x, screen.y, 0, 0);
149 if (large)
150 g.fillRect(screen.x-1, screen.y-1, 3, 3);
151 old = screen;
152 }
153 }
154 }
155
156 @Override public String getToolTipText() {
157 int points = 0;
158 for (Collection<GpsPoint> c : data)
159 points += c.size();
160 String tool = data.size()+" "+trn("track", "tracks", data.size())
161 +" "+points+" "+trn("point", "points", points);
162 if (associatedFile != null)
163 tool = "<html>"+tool+"<br>"+associatedFile.getPath()+"</html>";
164 return tool;
165 }
166
167 @Override public void mergeFrom(Layer from) {
168 RawGpsLayer layer = (RawGpsLayer)from;
169 data.addAll(layer.data);
170 }
171
172 @Override public boolean isMergable(Layer other) {
173 return other instanceof RawGpsLayer;
174 }
175
176 @Override public void visitBoundingBox(BoundingXYVisitor v) {
177 for (Collection<GpsPoint> c : data)
178 for (GpsPoint p : c)
179 v.visit(p.eastNorth);
180 }
181
182 @Override public Object getInfoComponent() {
183 StringBuilder b = new StringBuilder();
184 int points = 0;
185 for (Collection<GpsPoint> c : data) {
186 b.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"+trn("a track with {0} point","a track with {0} points", c.size(), c.size())+"<br>");
187 points += c.size();
188 }
189 b.append("</html>");
190 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();
191 }
192
193 @Override public Component[] getMenuEntries() {
194 JMenuItem line = new JMenuItem(tr("Customize line drawing"), ImageProvider.get("mapmode/addsegment"));
195 line.addActionListener(new ActionListener(){
196 public void actionPerformed(ActionEvent e) {
197 JRadioButton[] r = new JRadioButton[3];
198 r[0] = new JRadioButton(tr("Use global settings."));
199 r[1] = new JRadioButton(tr("Draw lines between points for this layer."));
200 r[2] = new JRadioButton(tr("Do not draw lines between points for this layer."));
201 ButtonGroup group = new ButtonGroup();
202 Box panel = Box.createVerticalBox();
203 for (JRadioButton b : r) {
204 group.add(b);
205 panel.add(b);
206 }
207 String propName = "draw.rawgps.lines.layer "+name;
208 if (Main.pref.hasKey(propName))
209 group.setSelected(r[Main.pref.getBoolean(propName) ? 1:2].getModel(), true);
210 else
211 group.setSelected(r[0].getModel(), true);
212 int answer = JOptionPane.showConfirmDialog(Main.parent, panel, tr("Select line drawing options"), JOptionPane.OK_CANCEL_OPTION);
213 if (answer == JOptionPane.CANCEL_OPTION)
214 return;
215 if (group.getSelection() == r[0].getModel())
216 Main.pref.put(propName, null);
217 else
218 Main.pref.put(propName, group.getSelection() == r[1].getModel());
219 Main.map.repaint();
220 }
221 });
222
223 JMenuItem color = new JMenuItem(tr("Customize Color"), ImageProvider.get("colorchooser"));
224 color.addActionListener(new ActionListener(){
225 public void actionPerformed(ActionEvent e) {
226 String col = Main.pref.get("color.layer "+name, Main.pref.get("color.gps point", ColorHelper.color2html(Color.gray)));
227 JColorChooser c = new JColorChooser(ColorHelper.html2color(col));
228 Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")};
229 int answer = JOptionPane.showOptionDialog(Main.parent, c, tr("Choose a color"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
230 switch (answer) {
231 case 0:
232 Main.pref.put("color.layer "+name, ColorHelper.color2html(c.getColor()));
233 break;
234 case 1:
235 return;
236 case 2:
237 Main.pref.put("color.layer "+name, null);
238 break;
239 }
240 Main.map.repaint();
241 }
242 });
243
244 JMenuItem tagimage = new JMenuItem(tr("Import images"), ImageProvider.get("tagimages"));
245 tagimage.addActionListener(new ActionListener(){
246 public void actionPerformed(ActionEvent e) {
247 JFileChooser fc = new JFileChooser(Main.pref.get("tagimages.lastdirectory"));
248 fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
249 fc.setMultiSelectionEnabled(true);
250 fc.setAcceptAllFileFilterUsed(false);
251 fc.setFileFilter(new FileFilter(){
252 @Override public boolean accept(File f) {
253 return f.isDirectory() || f.getName().toLowerCase().endsWith(".jpg");
254 }
255 @Override public String getDescription() {
256 return tr("JPEG images (*.jpg)");
257 }
258 });
259 fc.showOpenDialog(Main.parent);
260 File[] sel = fc.getSelectedFiles();
261 if (sel == null || sel.length == 0)
262 return;
263 LinkedList<File> files = new LinkedList<File>();
264 addRecursiveFiles(files, sel);
265 Main.pref.put("tagimages.lastdirectory", fc.getCurrentDirectory().getPath());
266 GeoImageLayer.create(files, RawGpsLayer.this);
267 }
268
269 private void addRecursiveFiles(LinkedList<File> files, File[] sel) {
270 for (File f : sel) {
271 if (f.isDirectory())
272 addRecursiveFiles(files, f.listFiles());
273 else if (f.getName().toLowerCase().endsWith(".jpg"))
274 files.add(f);
275 }
276 }
277 });
278
279 if (Main.applet)
280 return new Component[]{
281 new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
282 new JMenuItem(new LayerListDialog.DeleteLayerAction(this)),
283 new JSeparator(),
284 color,
285 line,
286 new JMenuItem(new ConvertToDataLayerAction()),
287 new JSeparator(),
288 new JMenuItem(new RenameLayerAction(associatedFile, this)),
289 new JSeparator(),
290 new JMenuItem(new LayerListPopup.InfoAction(this))};
291 return new Component[]{
292 new JMenuItem(new LayerListDialog.ShowHideLayerAction(this)),
293 new JMenuItem(new LayerListDialog.DeleteLayerAction(this)),
294 new JSeparator(),
295 new JMenuItem(new GpxExportAction(this)),
296 color,
297 line,
298 tagimage,
299 new JMenuItem(new ConvertToDataLayerAction()),
300 new JSeparator(),
301 new JMenuItem(new RenameLayerAction(associatedFile, this)),
302 new JSeparator(),
303 new JMenuItem(new LayerListPopup.InfoAction(this))};
304 }
305
306 public void preferenceChanged(String key, String newValue) {
307 if (Main.map != null && (key.equals("draw.rawgps.lines") || key.equals("draw.rawgps.lines.force")))
308 Main.map.repaint();
309 }
310
311 @Override public void destroy() {
312 Main.pref.listener.remove(RawGpsLayer.this);
313 }
314}
Note: See TracBrowser for help on using the repository browser.