diff --git a/data/gpx-extensions.xsd b/data/gpx-extensions.xsd
index bc5452e..875be90 100644
a
|
b
|
|
5 | 5 | <!-- true, if gpx data has been downloaded from the osm server --> |
6 | 6 | <!-- it this case, JOSM improves the rendering of clouds of anonymous TrackPoints --> |
7 | 7 | <element name="from-server" type="boolean"/> |
8 | | |
| 8 | |
| 9 | <!-- custom colors set to this layer --> |
| 10 | <element name="color" type="string"/> |
| 11 | <element name="marker-color" type="string"/> |
| 12 | |
9 | 13 | <!-- the following properties are only set for marker layer export --> |
10 | 14 | <element name="offset" type="decimal"/> |
11 | 15 | <element name="sync-offset" type="decimal"/> |
diff --git a/src/org/openstreetmap/josm/data/gpx/GpxData.java b/src/org/openstreetmap/josm/data/gpx/GpxData.java
index 88ac490..63ad205 100644
a
|
b
|
|
1 | 1 | // License: GPL. For details, see LICENSE file. |
2 | 2 | package org.openstreetmap.josm.data.gpx; |
3 | 3 | |
| 4 | import java.awt.Color; |
4 | 5 | import java.awt.geom.Area; |
5 | 6 | import java.io.File; |
6 | 7 | import java.util.Collection; |
… |
… |
public class GpxData extends WithAttributes implements Data {
|
31 | 32 | public File storageFile; |
32 | 33 | public boolean fromServer; |
33 | 34 | |
| 35 | public Color color; |
| 36 | public Color markerColor; |
| 37 | |
34 | 38 | public String creator; |
35 | 39 | |
36 | 40 | public final Collection<GpxTrack> tracks = new LinkedList<>(); |
diff --git a/src/org/openstreetmap/josm/gui/MapView.java b/src/org/openstreetmap/josm/gui/MapView.java
index 530856e..2c0cc6a 100644
a
|
b
|
implements PropertyChangeListener, PreferenceChangedListener, OsmDataLayer.Layer
|
1072 | 1072 | if (evt.getPropertyName().equals(Layer.VISIBLE_PROP)) { |
1073 | 1073 | repaint(); |
1074 | 1074 | } else if (evt.getPropertyName().equals(Layer.OPACITY_PROP) || |
1075 | | evt.getPropertyName().equals(Layer.FILTER_STATE_PROP)) { |
| 1075 | evt.getPropertyName().equals(Layer.FILTER_STATE_PROP) || |
| 1076 | evt.getPropertyName().equals(Layer.COLOR_PROP)) { |
1076 | 1077 | Layer l = (Layer) evt.getSource(); |
1077 | 1078 | if (l.isVisible()) { |
1078 | 1079 | changedLayer = l; |
diff --git a/src/org/openstreetmap/josm/gui/layer/CustomizeColor.java b/src/org/openstreetmap/josm/gui/layer/CustomizeColor.java
index 2fa5bc3..b562fb8 100644
a
|
b
|
import javax.swing.JMenuItem;
|
17 | 17 | import javax.swing.JOptionPane; |
18 | 18 | |
19 | 19 | import org.openstreetmap.josm.Main; |
| 20 | import org.openstreetmap.josm.data.preferences.BooleanProperty; |
20 | 21 | import org.openstreetmap.josm.gui.layer.Layer.LayerAction; |
21 | 22 | import org.openstreetmap.josm.gui.layer.Layer.MultiLayerAction; |
22 | 23 | import org.openstreetmap.josm.tools.ImageProvider; |
23 | 24 | |
24 | 25 | public class CustomizeColor extends AbstractAction implements LayerAction, MultiLayerAction { |
25 | 26 | private transient List<Layer> layers; |
| 27 | /** |
| 28 | * Use preferences to save and load customized settings for each layer |
| 29 | * where preferences key contains layer name |
| 30 | */ |
| 31 | public static final BooleanProperty USE_PREF_LAYER_NAME = new BooleanProperty("dialog.layer.use-pref-layer-name", false); |
26 | 32 | |
27 | 33 | public CustomizeColor(List<Layer> l) { |
28 | 34 | this(); |
… |
… |
public class CustomizeColor extends AbstractAction implements LayerAction, Multi
|
78 | 84 | switch (answer) { |
79 | 85 | case 0: |
80 | 86 | for (Layer layer : layers) { |
81 | | Main.pref.putColor("layer "+layer.getName(), c.getColor()); |
| 87 | if (USE_PREF_LAYER_NAME.get()) { |
| 88 | Main.pref.putColor("layer "+layer.getName(), c.getColor()); |
| 89 | } |
| 90 | layer.setColor(c.getColor()); |
82 | 91 | } |
83 | 92 | break; |
84 | 93 | case 1: |
85 | 94 | return; |
86 | 95 | case 2: |
87 | 96 | for (Layer layer : layers) { |
88 | | Main.pref.putColor("layer "+layer.getName(), null); |
| 97 | if (USE_PREF_LAYER_NAME.get()) { |
| 98 | Main.pref.putColor("layer "+layer.getName(), null); |
| 99 | } |
| 100 | layer.setColor(null); |
89 | 101 | } |
90 | 102 | break; |
91 | 103 | } |
92 | | Main.map.repaint(); |
93 | 104 | } |
94 | 105 | } |
diff --git a/src/org/openstreetmap/josm/gui/layer/GpxLayer.java b/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
index 6c54410..e5ee02a 100644
a
|
b
|
public class GpxLayer extends Layer {
|
84 | 84 | return drawHelper.getColor(getName(), ignoreCustom); |
85 | 85 | } |
86 | 86 | |
| 87 | @Override |
| 88 | public void setColor(Color color) { |
| 89 | Color oldValue = data.color; |
| 90 | data.color = color; |
| 91 | if (oldValue == null ? color != null : !oldValue.equals(color)) { |
| 92 | propertyChangeSupport.firePropertyChange(COLOR_PROP, oldValue, color); |
| 93 | } |
| 94 | } |
| 95 | |
87 | 96 | /** |
88 | 97 | * Returns a human readable string that shows the timespan of the given track |
89 | 98 | * @param trk The GPX track for which timespan is displayed |
diff --git a/src/org/openstreetmap/josm/gui/layer/Layer.java b/src/org/openstreetmap/josm/gui/layer/Layer.java
index ed33791..2935922 100644
a
|
b
|
public abstract class Layer implements Destroyable, MapViewPaintable, Projection
|
85 | 85 | public static final String OPACITY_PROP = Layer.class.getName() + ".opacity"; |
86 | 86 | public static final String NAME_PROP = Layer.class.getName() + ".name"; |
87 | 87 | public static final String FILTER_STATE_PROP = Layer.class.getName() + ".filterstate"; |
| 88 | public static final String COLOR_PROP = Layer.class.getName() + ".color"; |
88 | 89 | |
89 | 90 | public static final int ICON_SIZE = 16; |
90 | 91 | |
… |
… |
public abstract class Layer implements Destroyable, MapViewPaintable, Projection
|
191 | 192 | } |
192 | 193 | |
193 | 194 | /** |
| 195 | * Set a Color for this layer. |
| 196 | */ |
| 197 | public void setColor(Color color) { |
| 198 | } |
| 199 | |
| 200 | /** |
194 | 201 | * @return A small tooltip hint about some statistics for this layer. |
195 | 202 | */ |
196 | 203 | public abstract String getToolTipText(); |
diff --git a/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java b/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java
index ed925af..eeefe55 100644
a
|
b
|
import org.openstreetmap.josm.data.gpx.GpxConstants;
|
23 | 23 | import org.openstreetmap.josm.data.gpx.GpxData; |
24 | 24 | import org.openstreetmap.josm.data.gpx.WayPoint; |
25 | 25 | import org.openstreetmap.josm.gui.MapView; |
| 26 | import org.openstreetmap.josm.gui.layer.CustomizeColor; |
26 | 27 | import org.openstreetmap.josm.tools.ColorScale; |
27 | 28 | |
28 | 29 | /** |
… |
… |
public class GpxDrawHelper {
|
137 | 138 | * @return the color or null if the color is not constant |
138 | 139 | */ |
139 | 140 | public Color getColor(String layerName, boolean ignoreCustom) { |
140 | | Color c = Main.pref.getColor(marktr("gps point"), specName(layerName), DEFAULT_COLOR); |
141 | | return ignoreCustom || getColorMode(layerName) == ColorMode.NONE ? c : null; |
| 141 | Color color = data.color; |
| 142 | if (color == null) { |
| 143 | color = Main.pref.getColor(marktr("gps point"), CustomizeColor.USE_PREF_LAYER_NAME.get() ? specName(layerName) : null, DEFAULT_COLOR); |
| 144 | } |
| 145 | return ignoreCustom || getColorMode(layerName) == ColorMode.NONE ? color : null; |
142 | 146 | } |
143 | 147 | |
144 | 148 | /** |
145 | 149 | * Read coloring mode for specified layer from preferences |
146 | 150 | * @param layerName name of the GpxLayer |
147 | | * @return coloting mode |
| 151 | * @return coloring mode |
148 | 152 | */ |
149 | 153 | public ColorMode getColorMode(String layerName) { |
150 | 154 | try { |
diff --git a/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java b/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
index e62d62b..9c73ae0 100644
a
|
b
|
public class MarkerLayer extends Layer implements JumpToMarkerLayer {
|
190 | 190 | |
191 | 191 | @Override |
192 | 192 | public Color getColor(boolean ignoreCustom) { |
193 | | String name = getName(); |
194 | | return Main.pref.getColor(marktr("gps marker"), name != null ? "layer "+name : null, DEFAULT_COLOR); |
| 193 | Color color = fromLayer.data.markerColor; |
| 194 | if (color == null) { |
| 195 | color = Main.pref.getColor(marktr("gps marker"), CustomizeColor.USE_PREF_LAYER_NAME.get() ? specName(getName()) : null, DEFAULT_COLOR); |
| 196 | } |
| 197 | return color; |
| 198 | } |
| 199 | |
| 200 | @Override |
| 201 | public void setColor(Color color) { |
| 202 | fromLayer.data.markerColor = color; |
| 203 | } |
| 204 | |
| 205 | private static String specName(String layerName) { |
| 206 | return "layer " + layerName; |
195 | 207 | } |
196 | 208 | |
197 | 209 | /* for preferences */ |
diff --git a/src/org/openstreetmap/josm/io/GpxReader.java b/src/org/openstreetmap/josm/io/GpxReader.java
index 73372e2..4abd8cd 100644
a
|
b
|
import org.openstreetmap.josm.data.gpx.GpxLink;
|
26 | 26 | import org.openstreetmap.josm.data.gpx.GpxRoute; |
27 | 27 | import org.openstreetmap.josm.data.gpx.ImmutableGpxTrack; |
28 | 28 | import org.openstreetmap.josm.data.gpx.WayPoint; |
| 29 | import org.openstreetmap.josm.tools.ColorHelper; |
29 | 30 | import org.openstreetmap.josm.tools.Utils; |
30 | 31 | import org.xml.sax.Attributes; |
31 | 32 | import org.xml.sax.InputSource; |
… |
… |
public class GpxReader implements GpxConstants {
|
332 | 333 | case "bounds": |
333 | 334 | // do nothing, has been parsed on startElement |
334 | 335 | break; |
335 | | default: |
336 | | //TODO: parse extensions |
337 | 336 | } |
338 | 337 | break; |
339 | 338 | case author: |
… |
… |
public class GpxReader implements GpxConstants {
|
468 | 467 | currentState = states.pop(); |
469 | 468 | } else if (JOSM_EXTENSIONS_NAMESPACE_URI.equals(namespaceURI)) { |
470 | 469 | // only interested in extensions written by JOSM |
471 | | currentExtensions.put(localName, accumulator.toString()); |
| 470 | switch (localName) { |
| 471 | case "extensions": |
| 472 | currentState = states.pop(); |
| 473 | break; |
| 474 | case "from-server": |
| 475 | data.fromServer = "true".equals(accumulator.toString()); |
| 476 | break; |
| 477 | case "color": |
| 478 | data.color = ColorHelper.html2color(accumulator.toString()); |
| 479 | break; |
| 480 | case "marker-color": |
| 481 | data.markerColor = ColorHelper.html2color(accumulator.toString()); |
| 482 | break; |
| 483 | default: |
| 484 | currentExtensions.put(localName, accumulator.toString()); |
| 485 | } |
472 | 486 | } |
473 | 487 | break; |
474 | 488 | default: |
… |
… |
public class GpxReader implements GpxConstants {
|
489 | 503 | public void endDocument() throws SAXException { |
490 | 504 | if (!states.empty()) |
491 | 505 | throw new SAXException(tr("Parse error: invalid document structure for GPX document.")); |
492 | | Extensions metaExt = (Extensions) data.get(META_EXTENSIONS); |
493 | | if (metaExt != null && "true".equals(metaExt.get("from-server"))) { |
494 | | data.fromServer = true; |
495 | | } |
496 | 506 | gpxData = data; |
497 | 507 | } |
498 | 508 | |
diff --git a/src/org/openstreetmap/josm/io/GpxWriter.java b/src/org/openstreetmap/josm/io/GpxWriter.java
index 9a04d09..25fb2d4 100644
a
|
b
|
import org.openstreetmap.josm.data.gpx.GpxTrack;
|
26 | 26 | import org.openstreetmap.josm.data.gpx.GpxTrackSegment; |
27 | 27 | import org.openstreetmap.josm.data.gpx.IWithAttributes; |
28 | 28 | import org.openstreetmap.josm.data.gpx.WayPoint; |
| 29 | import org.openstreetmap.josm.tools.ColorHelper; |
29 | 30 | |
30 | 31 | /** |
31 | 32 | * Writes GPX files from GPX data or OSM data. |
… |
… |
public class GpxWriter extends XmlWriter implements GpxConstants {
|
50 | 51 | |
51 | 52 | private GpxData data; |
52 | 53 | private String indent = ""; |
| 54 | private boolean hasExtensions; |
53 | 55 | |
54 | 56 | private static final int WAY_POINT = 0; |
55 | 57 | private static final int ROUTE_POINT = 1; |
… |
… |
public class GpxWriter extends XmlWriter implements GpxConstants {
|
67 | 69 | // and some extra synchronization info for export of AudioMarkers. |
68 | 70 | // It is checked in advance, if any extensions are used, so we know whether |
69 | 71 | // a namespace declaration is necessary. |
70 | | boolean hasExtensions = data.fromServer; |
| 72 | hasExtensions = data.fromServer || |
| 73 | data.color != null || |
| 74 | data.markerColor != null; |
| 75 | |
71 | 76 | if (!hasExtensions) { |
72 | 77 | for (WayPoint wpt : data.waypoints) { |
73 | 78 | Extensions extensions = (Extensions) wpt.get(META_EXTENSIONS); |
… |
… |
public class GpxWriter extends XmlWriter implements GpxConstants {
|
174 | 179 | inline("bounds", b); |
175 | 180 | } |
176 | 181 | |
177 | | if (data.fromServer) { |
| 182 | if (hasExtensions) { |
178 | 183 | openln("extensions"); |
179 | | simpleTag("josm:from-server", "true"); |
| 184 | if (data.fromServer) { |
| 185 | simpleTag("josm:from-server", "true"); |
| 186 | } |
| 187 | if (data.color != null) { |
| 188 | simpleTag("josm:color", ColorHelper.color2html(data.color, true)); |
| 189 | } |
| 190 | if (data.markerColor != null) { |
| 191 | simpleTag("josm:marker-color", ColorHelper.color2html(data.markerColor, true)); |
| 192 | } |
180 | 193 | closeln("extensions"); |
181 | 194 | } |
182 | 195 | |