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

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