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

Last change on this file since 2617 was 2450, checked in by jttt, 14 years ago

Added parameter Bounds to MapView, draw only currently visible primitives in MapPaintVisititor

  • Property svn:eol-style set to native
File size: 11.5 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;
7import static org.openstreetmap.josm.tools.I18n.trnc;
8
9import java.awt.Color;
10import java.awt.Component;
11import java.awt.Graphics2D;
12import java.awt.GridBagLayout;
13import java.awt.Point;
14import java.awt.event.ActionEvent;
15import java.awt.event.ActionListener;
16import java.io.File;
17import java.util.ArrayList;
18import java.util.Collection;
19import java.util.List;
20
21import javax.swing.AbstractAction;
22import javax.swing.Box;
23import javax.swing.ButtonGroup;
24import javax.swing.Icon;
25import javax.swing.JColorChooser;
26import javax.swing.JLabel;
27import javax.swing.JMenuItem;
28import javax.swing.JOptionPane;
29import javax.swing.JPanel;
30import javax.swing.JRadioButton;
31import javax.swing.JSeparator;
32
33import org.openstreetmap.josm.Main;
34import org.openstreetmap.josm.actions.RenameLayerAction;
35import org.openstreetmap.josm.data.Bounds;
36import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
37import org.openstreetmap.josm.data.coor.EastNorth;
38import org.openstreetmap.josm.data.coor.LatLon;
39import org.openstreetmap.josm.data.osm.DataSet;
40import org.openstreetmap.josm.data.osm.Node;
41import org.openstreetmap.josm.data.osm.Way;
42import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
43import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
44import org.openstreetmap.josm.gui.MapView;
45import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
46import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
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:</html>")), GBC.eol());
66 msg.add(new UrlLabel(tr("http://www.openstreetmap.org/traces")), GBC.eop());
67 if (!ConditionalOptionPaneUtil.showConfirmationDialog(
68 "convert_to_data",
69 Main.parent,
70 msg,
71 tr("Warning"),
72 JOptionPane.OK_CANCEL_OPTION,
73 JOptionPane.WARNING_MESSAGE,
74 JOptionPane.OK_OPTION))
75 return;
76 DataSet ds = new DataSet();
77 for (Collection<GpsPoint> c : data) {
78 List<Node> nodes = new ArrayList<Node>();
79 for (GpsPoint p : c) {
80 Node n = new Node(p.latlon);
81 ds.addPrimitive(n);
82 nodes.add(n);
83 }
84 Way w = new Way();
85 w.setNodes(nodes);
86 ds.addPrimitive(w);
87 }
88 Main.main.addLayer(new OsmDataLayer(ds, tr("Converted from: {0}", RawGpsLayer.this.getName()), null));
89 Main.main.removeLayer(RawGpsLayer.this);
90 }
91 }
92
93 public static class GpsPoint {
94 public final LatLon latlon;
95 public final EastNorth eastNorth;
96 public final String time;
97 public GpsPoint(LatLon ll, String t) {
98 latlon = ll;
99 eastNorth = Main.proj.latlon2eastNorth(ll);
100 time = t;
101 }
102 }
103
104 /**
105 * A list of ways which containing a list of points.
106 */
107 public final Collection<Collection<GpsPoint>> data;
108 public final boolean fromServer;
109
110 public RawGpsLayer(boolean fromServer, Collection<Collection<GpsPoint>> data, String name, File associatedFile) {
111 super(name);
112 this.fromServer = fromServer;
113 setAssociatedFile(associatedFile);
114 this.data = data;
115 Main.pref.listener.add(this);
116 }
117
118 /**
119 * Return a static icon.
120 */
121 @Override public Icon getIcon() {
122 return ImageProvider.get("layer", "rawgps_small");
123 }
124
125 @Override public void paint(Graphics2D g, MapView mv, Bounds box) {
126 g.setColor(Main.pref.getColor(marktr("gps point"), "layer "+getName(), Color.gray));
127 Point old = null;
128
129 boolean force = Main.pref.getBoolean("draw.rawgps.lines.force");
130 boolean lines = Main.pref.getBoolean("draw.rawgps.lines", true);
131 String linesKey = "draw.rawgps.lines.layer "+getName();
132 if (Main.pref.hasKey(linesKey)) {
133 lines = Main.pref.getBoolean(linesKey);
134 }
135 boolean large = Main.pref.getBoolean("draw.rawgps.large");
136 for (Collection<GpsPoint> c : data) {
137 if (!force) {
138 old = null;
139 }
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 }
147 if (large) {
148 g.fillRect(screen.x-1, screen.y-1, 3, 3);
149 }
150 old = screen;
151 }
152 }
153 }
154
155 @Override public String getToolTipText() {
156 int points = 0;
157 for (Collection<GpsPoint> c : data) {
158 points += c.size();
159 }
160 String tool = data.size()+" "+trnc("gps", "track", "tracks", data.size())
161 +" "+points+" "+trn("point", "points", points);
162 File f = getAssociatedFile();
163 if (f != null) {
164 tool = "<html>"+tool+"<br>"+f.getPath()+"</html>";
165 }
166 return tool;
167 }
168
169 @Override public void mergeFrom(Layer from) {
170 RawGpsLayer layer = (RawGpsLayer)from;
171 data.addAll(layer.data);
172 }
173
174 @Override public boolean isMergable(Layer other) {
175 return other instanceof RawGpsLayer;
176 }
177
178 @Override public void visitBoundingBox(BoundingXYVisitor v) {
179 for (Collection<GpsPoint> c : data) {
180 for (GpsPoint p : c) {
181 v.visit(p.eastNorth);
182 }
183 }
184 }
185
186 @Override public Object getInfoComponent() {
187 StringBuilder b = new StringBuilder();
188 int points = 0;
189 for (Collection<GpsPoint> c : data) {
190 b.append("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"+trn("a track with {0} point","a track with {0} points", c.size(), c.size())+"<br>");
191 points += c.size();
192 }
193 b.append("</html>");
194 return "<html>"+trn("{0} consists of {1} track", "{0} consists of {1} tracks", data.size(), getName(), data.size())+" ("+trn("{0} point", "{0} points", points, points)+")<br>"+b.toString();
195 }
196
197 @Override public Component[] getMenuEntries() {
198 JMenuItem line = new JMenuItem(tr("Customize line drawing"), ImageProvider.get("mapmode/addsegment"));
199 line.addActionListener(new ActionListener(){
200 public void actionPerformed(ActionEvent e) {
201 JRadioButton[] r = new JRadioButton[3];
202 r[0] = new JRadioButton(tr("Use global settings."));
203 r[1] = new JRadioButton(tr("Draw lines between points for this layer."));
204 r[2] = new JRadioButton(tr("Do not draw lines between points for this layer."));
205 ButtonGroup group = new ButtonGroup();
206 Box panel = Box.createVerticalBox();
207 for (JRadioButton b : r) {
208 group.add(b);
209 panel.add(b);
210 }
211 String propName = "draw.rawgps.lines.layer "+getName();
212 if (Main.pref.hasKey(propName)) {
213 group.setSelected(r[Main.pref.getBoolean(propName) ? 1:2].getModel(), true);
214 } else {
215 group.setSelected(r[0].getModel(), true);
216 }
217 int answer = JOptionPane.showConfirmDialog(
218 Main.parent,
219 panel,
220 tr("Select line drawing options"),
221 JOptionPane.OK_CANCEL_OPTION,
222 JOptionPane.PLAIN_MESSAGE
223 );
224 if (answer == JOptionPane.CANCEL_OPTION)
225 return;
226 if (group.getSelection() == r[0].getModel()) {
227 Main.pref.put(propName, null);
228 } else {
229 Main.pref.put(propName, group.getSelection() == r[1].getModel());
230 }
231 Main.map.repaint();
232 }
233 });
234
235 JMenuItem color = new JMenuItem(tr("Customize Color"), ImageProvider.get("colorchooser"));
236 color.addActionListener(new ActionListener(){
237 public void actionPerformed(ActionEvent e) {
238 JColorChooser c = new JColorChooser(Main.pref.getColor(marktr("gps point"), "layer "+getName(), Color.gray));
239 Object[] options = new Object[]{tr("OK"), tr("Cancel"), tr("Default")};
240 int answer = JOptionPane.showOptionDialog(
241 Main.parent,
242 c,
243 tr("Choose a color"),
244 JOptionPane.OK_CANCEL_OPTION,
245 JOptionPane.PLAIN_MESSAGE, null,options, options[0]);
246 switch (answer) {
247 case 0:
248 Main.pref.putColor("layer "+getName(), c.getColor());
249 break;
250 case 1:
251 return;
252 case 2:
253 Main.pref.putColor("layer "+getName(), null);
254 break;
255 }
256 Main.map.repaint();
257 }
258 });
259
260 if (Main.applet)
261 return new Component[]{
262 new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
263 new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
264 new JSeparator(),
265 color,
266 line,
267 new JMenuItem(new ConvertToDataLayerAction()),
268 new JSeparator(),
269 new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)),
270 new JSeparator(),
271 new JMenuItem(new LayerListPopup.InfoAction(this))};
272 return new Component[]{
273 new JMenuItem(LayerListDialog.getInstance().createShowHideLayerAction(this)),
274 new JMenuItem(LayerListDialog.getInstance().createDeleteLayerAction(this)),
275 new JSeparator(),
276 new JMenuItem(new LayerGpxExportAction(this)),
277 color,
278 line,
279 new JMenuItem(new ConvertToDataLayerAction()),
280 new JSeparator(),
281 new JMenuItem(new RenameLayerAction(getAssociatedFile(), this)),
282 new JSeparator(),
283 new JMenuItem(new LayerListPopup.InfoAction(this))};
284 }
285
286 public void preferenceChanged(String key, String newValue) {
287 if (Main.map != null && (key.equals("draw.rawgps.lines") || key.equals("draw.rawgps.lines.force"))) {
288 Main.map.repaint();
289 }
290 }
291
292 @Override public void destroy() {
293 Main.pref.listener.remove(RawGpsLayer.this);
294 }
295}
Note: See TracBrowser for help on using the repository browser.