// License: GPL. Copyright 2007 by Immanuel Scholz and others
package org.openstreetmap.josm.gui.layer;
import static org.openstreetmap.josm.tools.I18n.marktr;
import static org.openstreetmap.josm.tools.I18n.tr;
import static org.openstreetmap.josm.tools.I18n.trn;
import static org.openstreetmap.josm.tools.I18n.trnc;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSeparator;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.actions.RenameLayerAction;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
import org.openstreetmap.josm.data.coor.EastNorth;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.osm.DataSet;
import org.openstreetmap.josm.data.osm.Node;
import org.openstreetmap.josm.data.osm.Way;
import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
import org.openstreetmap.josm.gui.ConditionalOptionPaneUtil;
import org.openstreetmap.josm.gui.MapView;
import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
import org.openstreetmap.josm.tools.GBC;
import org.openstreetmap.josm.tools.ImageProvider;
import org.openstreetmap.josm.tools.UrlLabel;
/**
* A layer holding data from a gps source.
* The data is read only.
*
* @author imi
*/
public class RawGpsLayer extends Layer implements PreferenceChangedListener {
public class ConvertToDataLayerAction extends AbstractAction {
public ConvertToDataLayerAction() {
super(tr("Convert to data layer"), ImageProvider.get("converttoosm"));
}
public void actionPerformed(ActionEvent e) {
JPanel msg = new JPanel(new GridBagLayout());
msg.add(new JLabel(tr("Upload of unprocessed GPS data as map data is considered harmful.
If you want to upload traces, look here:")), GBC.eol());
msg.add(new UrlLabel(tr("http://www.openstreetmap.org/traces")), GBC.eop());
if (!ConditionalOptionPaneUtil.showConfirmationDialog(
"convert_to_data",
Main.parent,
msg,
tr("Warning"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE,
JOptionPane.OK_OPTION))
return;
DataSet ds = new DataSet();
for (Collection c : data) {
List nodes = new ArrayList();
for (GpsPoint p : c) {
Node n = new Node(p.latlon);
ds.addPrimitive(n);
nodes.add(n);
}
Way w = new Way();
w.setNodes(nodes);
ds.addPrimitive(w);
}
Main.main.addLayer(new OsmDataLayer(ds, tr("Converted from: {0}", RawGpsLayer.this.getName()), null));
Main.main.removeLayer(RawGpsLayer.this);
}
}
public static class GpsPoint {
public final LatLon latlon;
public final EastNorth eastNorth;
public final String time;
public GpsPoint(LatLon ll, String t) {
latlon = ll;
eastNorth = Main.proj.latlon2eastNorth(ll);
time = t;
}
}
/**
* A list of ways which containing a list of points.
*/
public final Collection> data;
public final boolean fromServer;
public RawGpsLayer(boolean fromServer, Collection> data, String name, File associatedFile) {
super(name);
this.fromServer = fromServer;
setAssociatedFile(associatedFile);
this.data = data;
Main.pref.listener.add(this);
}
/**
* Return a static icon.
*/
@Override public Icon getIcon() {
return ImageProvider.get("layer", "rawgps_small");
}
@Override public void paint(Graphics2D g, MapView mv, Bounds box) {
g.setColor(Main.pref.getColor(marktr("gps point"), "layer "+getName(), Color.gray));
Point old = null;
boolean force = Main.pref.getBoolean("draw.rawgps.lines.force");
boolean lines = Main.pref.getBoolean("draw.rawgps.lines", true);
String linesKey = "draw.rawgps.lines.layer "+getName();
if (Main.pref.hasKey(linesKey)) {
lines = Main.pref.getBoolean(linesKey);
}
boolean large = Main.pref.getBoolean("draw.rawgps.large");
for (Collection c : data) {
if (!force) {
old = null;
}
for (GpsPoint p : c) {
Point screen = mv.getPoint(p.eastNorth);
if (lines && old != null) {
g.drawLine(old.x, old.y, screen.x, screen.y);
} else if (!large) {
g.drawRect(screen.x, screen.y, 0, 0);
}
if (large) {
g.fillRect(screen.x-1, screen.y-1, 3, 3);
}
old = screen;
}
}
}
@Override public String getToolTipText() {
int points = 0;
for (Collection c : data) {
points += c.size();
}
String tool = data.size()+" "+trnc("gps", "track", "tracks", data.size())
+" "+points+" "+trn("point", "points", points);
File f = getAssociatedFile();
if (f != null) {
tool = ""+tool+"
"+f.getPath()+"";
}
return tool;
}
@Override public void mergeFrom(Layer from) {
RawGpsLayer layer = (RawGpsLayer)from;
data.addAll(layer.data);
}
@Override public boolean isMergable(Layer other) {
return other instanceof RawGpsLayer;
}
@Override public void visitBoundingBox(BoundingXYVisitor v) {
for (Collection c : data) {
for (GpsPoint p : c) {
v.visit(p.eastNorth);
}
}
}
@Override public Object getInfoComponent() {
StringBuilder b = new StringBuilder();
int points = 0;
for (Collection c : data) {
b.append(" "+trn("a track with {0} point","a track with {0} points", c.size(), c.size())+"
");
points += c.size();
}
b.append("