Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryTrafficSignLayer.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryTrafficSignLayer.java	(revision 31383)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryTrafficSignLayer.java	(revision 31383)
@@ -0,0 +1,170 @@
+/**
+ *
+ */
+package org.openstreetmap.josm.plugins.mapillary;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontFormatException;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.io.File;
+import java.io.IOException;
+
+import javax.swing.Action;
+import javax.swing.Icon;
+
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.layer.AbstractModifiableLayer;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.plugins.mapillary.traffico.TrafficoSign;
+import org.openstreetmap.josm.plugins.mapillary.traffico.TrafficoSignElement;
+
+/**
+ *
+ */
+public class MapillaryTrafficSignLayer extends AbstractModifiableLayer {
+  private static MapillaryTrafficSignLayer instance;
+
+  /**
+   * Returns and when needed instantiates the Mapillary traffic sign layer.
+   * @return the only instance of the traffic sign layer
+   */
+  public static MapillaryTrafficSignLayer getInstance() {
+    return instance == null ? (instance = new MapillaryTrafficSignLayer()) : instance;
+  }
+
+  /**
+   * @param name
+   */
+  private MapillaryTrafficSignLayer() {
+    super("Mapillary traffic signs");
+  }
+
+  /*
+   * (non-Javadoc)
+   * @see org.openstreetmap.josm.gui.layer.AbstractModifiableLayer#isModified()
+   */
+  @Override
+  public boolean isModified() {
+    return false;
+  }
+
+  /*
+   * (non-Javadoc)
+   * @see org.openstreetmap.josm.gui.layer.Layer#paint(java.awt.Graphics2D, org.openstreetmap.josm.gui.MapView,
+   * org.openstreetmap.josm.data.Bounds)
+   */
+  @Override
+  public void paint(Graphics2D g, MapView mv, Bounds box) {
+    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+    try {
+      g.setFont(Font.createFont(Font.TRUETYPE_FONT, new File("data/fonts/traffico/traffico.ttf")).deriveFont(50.0f));
+    } catch (FontFormatException e) {
+      e.printStackTrace();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+
+    Point[] points = new Point[3];
+    points[0] = mv.getPoint(new LatLon(49.01058, 8.40743));
+    points[1] = mv.getPoint(new LatLon(49.01116, 8.40679));
+    points[2] = mv.getPoint(new LatLon(49.01038, 8.40636));
+
+    TrafficoSignElement[][] signs = { TrafficoSign.getSign("europe", "mandatory_cycle_track"), TrafficoSign.getSign("de", "information_bus_stop"), TrafficoSign.getSign("europe", "information_pedestrian_crossing") };
+
+    for (int i = 0; i < signs.length && i < points.length; i++) {
+      for (TrafficoSignElement layer : signs[i]) { // TODO: NPE
+        g.setColor(layer.getColor());
+        g.drawString("" + layer.getGlyph(), points[i].x - 25, points[i].y + 25);
+      }
+    }
+
+    // Start iterating the images
+    g.setColor(Color.MAGENTA);
+    for (MapillaryAbstractImage img : MapillaryLayer.getInstance().data.getImages()) {
+      if (img instanceof MapillaryImage) {
+        g.fillOval(mv.getPoint(img.getLatLon()).x-3, mv.getPoint(img.getLatLon()).y-3, 6, 6);
+        if (((MapillaryImage) img).getSigns().size() >= 1) {
+          Point imgLoc = mv.getPoint(img.getLatLon());
+          for (TrafficoSignElement e : TrafficoSign.getSign("de", ((MapillaryImage) img).getSigns().get(0))) {
+            g.setColor(e.getColor());
+            g.drawString("" + e.getGlyph(), imgLoc.x, imgLoc.y);
+          }
+        }
+      }
+    }
+  }
+
+  /*
+   * (non-Javadoc)
+   * @see org.openstreetmap.josm.gui.layer.Layer#getIcon()
+   */
+  @Override
+  public Icon getIcon() {
+    return MapillaryPlugin.ICON16;
+  }
+
+  /*
+   * (non-Javadoc)
+   * @see org.openstreetmap.josm.gui.layer.Layer#getToolTipText()
+   */
+  @Override
+  public String getToolTipText() {
+    return null;
+  }
+
+  /*
+   * (non-Javadoc)
+   * @see org.openstreetmap.josm.gui.layer.Layer#mergeFrom(org.openstreetmap.josm.gui.layer.Layer)
+   */
+  @Override
+  public void mergeFrom(Layer from) {
+    // Does nothing as this layer is not mergeable (see method isMergable(Layer))
+  }
+
+  /*
+   * (non-Javadoc)
+   * @see org.openstreetmap.josm.gui.layer.Layer#isMergable(org.openstreetmap.josm.gui.layer.Layer)
+   */
+  @Override
+  public boolean isMergable(Layer other) {
+    return false;
+  }
+
+  /*
+   * (non-Javadoc)
+   * @see
+   * org.openstreetmap.josm.gui.layer.Layer#visitBoundingBox(org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor)
+   */
+  @Override
+  public void visitBoundingBox(BoundingXYVisitor v) {
+    // TODO Auto-generated method stub
+
+  }
+
+  /*
+   * (non-Javadoc)
+   * @see org.openstreetmap.josm.gui.layer.Layer#getInfoComponent()
+   */
+  @Override
+  public Object getInfoComponent() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  /*
+   * (non-Javadoc)
+   * @see org.openstreetmap.josm.gui.layer.Layer#getMenuEntries()
+   */
+  @Override
+  public Action[] getMenuEntries() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+}
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/traffico/TrafficoGlyph.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/traffico/TrafficoGlyph.java	(revision 31383)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/traffico/TrafficoGlyph.java	(revision 31383)
@@ -0,0 +1,33 @@
+package org.openstreetmap.josm.plugins.mapillary.traffico;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.json.Json;
+import javax.json.JsonObject;
+import javax.json.JsonReader;
+
+public class TrafficoGlyph {
+  private static Map<String, Character> glyphs;
+  private static Map<String, Character> readGlyphsFromResources() {
+    JsonReader reader = Json.createReader(TrafficoSignElement.class.getResourceAsStream("/data/fonts/traffico/glyphs.json"));
+    JsonObject glyphObject = reader.readObject().getJsonObject("glyphs");
+    Set<String> glyphNames = glyphObject.keySet();
+    glyphs = new HashMap<>();
+    for (String name : glyphNames) {
+      glyphs.put(name, glyphObject.getString(name).charAt(0));
+    }
+    return glyphs;
+  }
+  public static Character getGlyph(String key) {
+    if (glyphs == null) {
+      glyphs = readGlyphsFromResources();
+    }
+    return glyphs.get(key);
+  }
+  public static void main(String[] args) {
+    System.out.println(TrafficoGlyph.getGlyph("h"));
+    System.out.println(TrafficoGlyph.getGlyph("DE-arrow-up"));
+  }
+}
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/traffico/TrafficoSign.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/traffico/TrafficoSign.java	(revision 31383)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/traffico/TrafficoSign.java	(revision 31383)
@@ -0,0 +1,82 @@
+package org.openstreetmap.josm.plugins.mapillary.traffico;
+
+import java.awt.Color;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+
+public class TrafficoSign {
+  private static final Map<String, String> isIn = new TreeMap<>();
+
+  static {
+    isIn.put("be", "europe");
+    isIn.put("de", "europe");
+    isIn.put("dk", "europe");
+    isIn.put("es", "europe");
+  }
+
+  private static Map<String, Map<String, TrafficoSignElement[]>> signs = new HashMap<>();
+
+  public static TrafficoSignElement[] getSign(String country, String signName) {
+    if (signs.get(country) == null) {
+      System.out.println("Read signs for " + country);
+      InputStream countryStream = TrafficoSign.class
+          .getResourceAsStream("/data/fonts/traffico/signs/" + country + ".json");
+      if (countryStream == null) { return null; }
+      JsonObject countrySigns = Json.createReader(countryStream).readObject();
+      Set<String> countrySignNames = countrySigns.keySet();
+      System.out.println(countrySignNames.size() + " signs found");
+      Map<String, TrafficoSignElement[]> countryMap = new HashMap<>();
+      for (String name : countrySignNames) {
+        System.out.println(" * sign " + name);
+        JsonArray elements = countrySigns.getJsonObject(name).getJsonArray("elements");
+        List<TrafficoSignElement> layers = new ArrayList<>(); // TODO: Replace by an array when all types of sign
+                                                              // elements (text!) are supported
+        for (int i = 0; i < elements.size(); i++) {
+          System.out.println("   - " + elements.getJsonObject(i).getString("color") + " layer "
+              + elements.getJsonObject(i).getString("type"));
+          Character glyph = TrafficoGlyph.getGlyph(elements.getJsonObject(i).getString("type"));
+          if (glyph != null) {
+            Color c;
+            switch (elements.getJsonObject(i).getString("color").toLowerCase()) {
+            case "black":
+              c = Color.BLACK;
+              break;
+            case "red":
+              c = Color.RED;
+              break;
+            case "blue":
+              c = Color.BLUE;
+              break;
+            case "white":
+              c = Color.WHITE;
+              break;
+            case "green":
+              c = Color.GREEN;
+              break;
+            case "yellow":
+              c = Color.YELLOW;
+              break;
+            default:
+              c = Color.MAGENTA;
+            }
+            layers.add(new TrafficoSignElement(glyph, c));
+          }
+        }
+        countryMap.put(name, layers.toArray(new TrafficoSignElement[0]));
+      }
+      signs.put(country, countryMap);
+    }
+    if (signs.get(country).get(signName) != null) { return signs.get(country).get(signName); }
+    if (isIn.containsKey(country)) { return TrafficoSign.getSign(isIn.get(country), signName); }
+    return null;
+  }
+}
Index: applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/traffico/TrafficoSignElement.java
===================================================================
--- applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/traffico/TrafficoSignElement.java	(revision 31383)
+++ applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/traffico/TrafficoSignElement.java	(revision 31383)
@@ -0,0 +1,31 @@
+package org.openstreetmap.josm.plugins.mapillary.traffico;
+
+import java.awt.Color;
+
+public class TrafficoSignElement {
+
+  private Color color;
+  private char glyph;
+
+  public TrafficoSignElement(char glyph, Color c) {
+     if (c == null) {
+       throw new IllegalArgumentException();
+     }
+     this.color = c;
+     this.glyph = glyph;
+  }
+
+  /**
+   * @return the color
+   */
+  public Color getColor() {
+    return color;
+  }
+
+  /**
+   * @return the glyph
+   */
+  public char getGlyph() {
+    return glyph;
+  }
+}
