Changeset 32066 in osm for applications/editors/josm
- Timestamp:
- 2016-02-11T23:17:32+01:00 (9 years ago)
- Location:
- applications/editors/josm/plugins/mapillary
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/MapillaryTrafficSignLayer.java
r31810 r32066 23 23 import org.openstreetmap.josm.gui.layer.Layer; 24 24 import org.openstreetmap.josm.plugins.mapillary.traffico.TrafficoSign; 25 import org.openstreetmap.josm.plugins.mapillary.traffico.TrafficoSignElement;26 25 import org.openstreetmap.josm.tools.I18n; 27 26 … … 38 37 throw new IOException(I18n.tr("Traffic sign font at ''{0}'' has wrong format.", TRAFFICO_PATH), e); 39 38 } catch (IOException e) { 40 throw new IOException(I18n.tr("Could not read font-file from ''{ {0}}''.", TRAFFICO_PATH), e);39 throw new IOException(I18n.tr("Could not read font-file from ''{0}''.", TRAFFICO_PATH), e); 41 40 } 42 41 } … … 81 80 points[2] = mv.getPoint(new LatLon(49.01038, 8.40636)); 82 81 83 TrafficoSign Element[][] signs = {82 TrafficoSign[] signs = { 84 83 TrafficoSign.getSign("europe", "mandatory_cycle_track"), 85 84 TrafficoSign.getSign("de", "information_bus_stop"), … … 87 86 88 87 for (int i = 0; i < signs.length && i < points.length; i++) { 89 for ( TrafficoSignElement layer : signs[i]) { // TODO: NPE90 g.setColor( layer.getColor());91 g.drawString(Character.toString( layer.getGlyph()), points[i].x - 25, points[i].y + 25);88 for (int j = 0; signs[i] != null && j < signs[i].getNumElements(); j++) { 89 g.setColor(signs[i].getElement(j).getColor()); 90 g.drawString(Character.toString(signs[i].getElement(j).getGlyph()), points[i].x - 25, points[i].y + 25); 92 91 } 93 92 } … … 100 99 if (!((MapillaryImage) img).getSigns().isEmpty()) { 101 100 Point imgLoc = mv.getPoint(img.getLatLon()); 102 for (TrafficoSignElement e : TrafficoSign.getSign("de", ((MapillaryImage) img).getSigns().get(0))) { 103 g.setColor(e.getColor()); 104 g.drawString(Character.toString(e.getGlyph()), imgLoc.x, imgLoc.y); 105 } 101 // TODO: Paint a sign from the image 106 102 } 107 103 } -
applications/editors/josm/plugins/mapillary/src/org/openstreetmap/josm/plugins/mapillary/traffico/TrafficoSign.java
r31988 r32066 6 6 import java.io.InputStream; 7 7 import java.util.ArrayList; 8 import java.util.HashMap;9 8 import java.util.List; 10 9 import java.util.Map; 11 10 import java.util.Set; 11 import java.util.TreeMap; 12 12 13 13 import javax.json.Json; … … 17 17 import org.openstreetmap.josm.Main; 18 18 19 /** 20 * <p> 21 * Representation of a traffico sign, which consists of a country code, a unique name and the individual 22 * layers of the sign. 23 * </p><p> 24 * You can obtain a {@link TrafficoSign} via {@link #getSign(String, String)}. The first call to that method reads 25 * all sign definition for the queried country from disk and holds them in memory for future access. 26 * </p><p> 27 * You can rely on the fact, that two instances of {@link TrafficoSign} with same {@link #getName()} and same 28 * {@link #getCountry()} that were obtained via {@link #getSign(String, String)} will return <code>true</code> when 29 * compared with <code>==</code> 30 * </p> 31 */ 19 32 public final class TrafficoSign { 20 private static Map<String, Map<String, TrafficoSignElement[]>> signs = new HashMap<>(); 33 private static final String SIGN_DEFINITION_PATH = "/data/fonts/traffico/signs/%s.json"; 34 /** 35 * The signs that are already created from the JSON source file 36 */ 37 private static final Map<String, Map<String, TrafficoSign>> signs = new TreeMap<>(); 21 38 22 private TrafficoSign() { 23 // private constructor to avoid instantiation 39 private final String country; 40 private final String name; 41 private final TrafficoSignElement[] elements; 42 43 private TrafficoSign(TrafficoSignElement[] elements, String country, String name) { 44 this.country = country; 45 this.name = name; 46 if (elements == null) { 47 this.elements = new TrafficoSignElement[0]; 48 } else { 49 this.elements = elements.clone(); 50 } 24 51 } 25 52 26 public static TrafficoSignElement[] getSign(String country, String signName) { 27 if (signs.get(country) == null) { 28 Main.info("Reading signs for country ''{0}''.", country); 29 try ( 30 InputStream countryStream = TrafficoSign.class 31 .getResourceAsStream("/data/fonts/traffico/signs/" + country + ".json")) { 32 if (countryStream == null) { 33 return null; 34 } 35 JsonObject countrySigns = Json.createReader(countryStream).readObject(); 36 Set<String> countrySignNames = countrySigns.keySet(); 37 Main.info( 38 countrySignNames.size() + " different signs are supported for ''{0}'' by the Mapillary-plugin .", 39 country 53 /** 54 * @return the country of this sign 55 */ 56 public String getCountry() { 57 return country; 58 } 59 60 /** 61 * @return the name of the sign 62 */ 63 public String getName() { 64 return name; 65 } 66 67 /** 68 * @return the number of sign elements (=layers) of which this sign consists 69 */ 70 public int getNumElements() { 71 return elements.length; 72 } 73 74 /** 75 * 76 * @param index the index which is assigned to the sign element in question 77 * @return the sign element (=layer) with the given index 78 * @throws ArrayIndexOutOfBoundsException if index >= {@link #getNumElements()} or index < 0 79 */ 80 public TrafficoSignElement getElement(int index) { 81 return elements[index]; 82 } 83 84 /** 85 * <p> 86 * Returns the sign associated with the given country and name or <code>null</code> if no such sign is available. 87 * </p><p> 88 * If you obtain two instances of {@link TrafficoSign} with this method that have the same country and name, you can 89 * safely assume that a comparison of both objects with <code>==</code> will result in <code>true</code>. 90 * </p> 91 * @param country the country to which the sign belongs 92 * @param signName the name of the sign (unique in a country) 93 * @return the requested sign or <code>null</code> if this sign is unavailable 94 */ 95 public static TrafficoSign getSign(String country, String signName) { 96 synchronized (signs) { 97 if (!signs.containsKey(country)) { 98 buildSignsFromJsonDefinition(country); 99 } 100 if (signs.containsKey(country) && signs.get(country).containsKey(signName)) { 101 return signs.get(country).get(signName); 102 } 103 return null; 104 } 105 } 106 107 private static void addSign(TrafficoSign sign) { 108 synchronized (signs) { 109 // Create Map for country if not already exists 110 if (!signs.containsKey(sign.getCountry())) { 111 signs.put(sign.getCountry(), new TreeMap<String, TrafficoSign>()); 112 } 113 // Don't overwrite existing sign with same country-name-combination 114 if (signs.get(sign.getCountry()).containsKey(sign.getName())) { 115 Main.warn( 116 "The sign {0}--{1} was found multiple times in the traffico sign-definitions.", 117 sign.getName(), sign.getCountry() 40 118 ); 41 Map<String, TrafficoSignElement[]> countryMap = new HashMap<>(); 42 for (String name : countrySignNames) { 43 JsonArray elements = countrySigns.getJsonObject(name).getJsonArray("elements"); 44 45 // TODO: Replace by an array when all types of sign elements (text!) are 46 // supported 47 List<TrafficoSignElement> layers = new ArrayList<>(); 48 49 for (int i = 0; i < elements.size(); i++) { 50 Character glyph = TrafficoGlyph.getGlyph(elements.getJsonObject(i) 51 .getString("type")); 52 if (glyph != null) { 53 Color c; 54 switch (elements.getJsonObject(i).getString("color").toLowerCase()) { 55 case "black": 56 c = Color.BLACK; 57 break; 58 case "red": 59 c = Color.RED; 60 break; 61 case "blue": 62 c = Color.BLUE; 63 break; 64 case "white": 65 c = Color.WHITE; 66 break; 67 case "green": 68 c = Color.GREEN; 69 break; 70 case "yellow": 71 c = Color.YELLOW; 72 break; 73 default: 74 c = Color.MAGENTA; 75 } 76 layers.add(new TrafficoSignElement(glyph, c)); 77 } 78 } 79 countryMap.put(name, layers.toArray(new TrafficoSignElement[layers.size()])); 80 } 81 signs.put(country, countryMap); 82 } catch (IOException e) { 83 Main.error(e); 119 } else { 120 signs.get(sign.getCountry()).put(sign.getName(), sign); 84 121 } 85 122 } 86 if (signs.get(country).get(signName) != null) { 87 return signs.get(country).get(signName); 123 } 124 125 private static void buildSignsFromJsonDefinition(String country) { 126 Main.info("Reading signs for country ''{0}''.", country); 127 try ( 128 InputStream countryStream = TrafficoSign.class.getResourceAsStream(String.format(SIGN_DEFINITION_PATH, country)) 129 ) { 130 if (countryStream == null) { 131 return; 132 } 133 JsonObject countrySigns = Json.createReader(countryStream).readObject(); 134 Set<String> countrySignNames = countrySigns.keySet(); 135 Main.info( 136 countrySignNames.size() + " different signs are supported for ''{0}'' by the Mapillary-plugin .", 137 country 138 ); 139 140 // TODO: Replace by an array when all types of sign elements (text!) are supported 141 List<TrafficoSignElement> signLayers = new ArrayList<>(); 142 for (String name : countrySignNames) { 143 signLayers.clear(); 144 JsonArray elements = countrySigns.getJsonObject(name).getJsonArray("elements"); 145 146 for (int i = 0; i < elements.size(); i++) { 147 Character glyph = TrafficoGlyph.getGlyph(elements.getJsonObject(i).getString("type")); 148 if (glyph != null) { 149 Color c; 150 switch (elements.getJsonObject(i).getString("color").toLowerCase()) { 151 case "black": 152 c = Color.BLACK; 153 break; 154 case "red": 155 c = new Color(0xc1121c); 156 break; 157 case "blue": 158 c = new Color(0x154889); 159 break; 160 case "white": 161 c = Color.WHITE; 162 break; 163 case "green": 164 c = new Color(0x008754); 165 break; 166 case "yellow": 167 c = new Color(0xfecf33); 168 break; 169 default: 170 c = Color.MAGENTA; 171 break; 172 } 173 signLayers.add(new TrafficoSignElement(glyph, c)); 174 } 175 } 176 addSign(new TrafficoSign(signLayers.toArray(new TrafficoSignElement[signLayers.size()]), country, name)); 177 } 178 } catch (IOException e) { 179 Main.error(e); 88 180 } 89 return null;90 181 } 91 182 } -
applications/editors/josm/plugins/mapillary/test/unit/org/openstreetmap/josm/plugins/mapillary/traffico/TrafficoSignTest.java
r31795 r32066 1 1 package org.openstreetmap.josm.plugins.mapillary.traffico; 2 2 3 import static org.junit.Assert.assertArrayEquals;4 3 import static org.junit.Assert.assertEquals; 5 4 import static org.junit.Assert.assertNotEquals; 6 5 7 6 import org.junit.Test; 8 import org.openstreetmap.josm.plugins.mapillary.utils.TestUtil;9 7 10 8 public class TrafficoSignTest { 11 12 9 @Test 13 10 public void test() { 14 assert ArrayEquals(null, TrafficoSign.getSign("de", ""));15 TrafficoSign Element[]trafficSignals = TrafficoSign.getSign("de", "traffic-signals-ahead");11 assertEquals(null, TrafficoSign.getSign("de", "")); 12 TrafficoSign trafficSignals = TrafficoSign.getSign("de", "traffic-signals-ahead"); 16 13 assertNotEquals(null, trafficSignals); 17 assertEquals(5, trafficSignals. length);18 assert ArrayEquals(null, TrafficoSign.getSign("us", ""));19 assert ArrayEquals(null, TrafficoSign.getSign("xyz", ""));14 assertEquals(5, trafficSignals.getNumElements()); 15 assertEquals(null, TrafficoSign.getSign("us", "")); 16 assertEquals(null, TrafficoSign.getSign("xyz", "")); 20 17 } 21 22 @Test23 public void testUtilityClass() {24 TestUtil.testUtilityClass(TrafficoSign.class);25 }26 27 18 }
Note:
See TracChangeset
for help on using the changeset viewer.