1 package nl.tudelft.simulation.dsol.animation.gis.osm;
2
3 import java.awt.Color;
4 import java.io.IOException;
5 import java.io.InputStreamReader;
6 import java.io.Reader;
7 import java.net.URL;
8 import java.util.ArrayList;
9 import java.util.Iterator;
10 import java.util.LinkedHashMap;
11 import java.util.List;
12 import java.util.Map;
13 import java.util.Set;
14
15 import org.djutils.exceptions.Throw;
16
17 import de.siegmar.fastcsv.reader.NamedCsvReader;
18 import de.siegmar.fastcsv.reader.NamedCsvRow;
19 import nl.tudelft.simulation.dsol.animation.gis.FeatureInterface;
20 import nl.tudelft.simulation.dsol.animation.gis.GisMapInterface;
21 import nl.tudelft.simulation.dsol.animation.gis.LayerInterface;
22 import nl.tudelft.simulation.dsol.animation.gis.Style;
23 import nl.tudelft.simulation.dsol.animation.gis.map.Feature;
24 import nl.tudelft.simulation.dsol.animation.gis.map.GisMap;
25 import nl.tudelft.simulation.dsol.animation.gis.map.Layer;
26 import nl.tudelft.simulation.dsol.animation.gis.parser.ColorParser;
27 import nl.tudelft.simulation.dsol.animation.gis.transform.CoordinateTransform;
28
29
30
31
32
33
34
35
36
37
38
39 public final class OsmFileCsvParser
40 {
41
42 private OsmFileCsvParser()
43 {
44
45 }
46
47
48
49
50
51
52
53
54
55 public static GisMapInterface parseMapFile(final URL csvUrl, final URL osmUrl, final String mapName) throws IOException
56 {
57 return parseMapFile(csvUrl, osmUrl, mapName, new CoordinateTransform.NoTransform());
58 }
59
60
61
62
63
64
65
66
67
68
69 public static GisMapInterface parseMapFile(final URL csvUrl, final URL osmUrl, final String mapName,
70 final CoordinateTransform coordinateTransform) throws IOException
71 {
72 return parseMapFile(csvUrl, osmUrl, mapName, coordinateTransform, ',', '"');
73 }
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 public static GisMapInterface parseMapFile(final URL csvUrl, final URL osmUrl, final String mapName,
90 final CoordinateTransform coordinateTransform, final char fieldSeparator, final char quoteCharacter)
91 throws IOException
92 {
93 GisMapInterface map = new GisMap();
94 map.setName(mapName);
95 List<String> layerNames = new ArrayList<>();
96 List<LayerInterface> layerList = new ArrayList<>();
97 List<FeatureInterface> featuresToRead = new ArrayList<>();
98
99 Reader reader = new InputStreamReader(csvUrl.openStream());
100 Throw.when(reader == null, IOException.class, "Cannot find CSV file with OSM shape file information at " + csvUrl);
101 NamedCsvReader csvReader =
102 NamedCsvReader.builder().fieldSeparator(fieldSeparator).quoteCharacter(quoteCharacter).build(reader);
103 Set<String> header = csvReader.getHeader();
104 if (!header.contains("layer") || !header.contains("key") || !header.contains("value")
105 || !header.contains("outlineColor") || !header.contains("fillColor") || !header.contains("display")
106 || !header.contains("transform") || !header.contains("zIndex") || !header.contains("scale"))
107 {
108 throw new IOException("OSM GIS map csv-file header row did not contain all column headers\n" + header.toString());
109 }
110
111 Iterator<NamedCsvRow> it = csvReader.iterator();
112 while (it.hasNext())
113 {
114 NamedCsvRow row = it.next();
115
116 String layerName = row.getField("layer");
117 String key = row.getField("key");
118 String value = row.getField("value");
119 Color outlineColor = ColorParser.parse(row.getField("outlineColor"));
120 Color fillColor = ColorParser.parse(row.getField("fillColor"));
121 boolean display = row.getField("display").toLowerCase().startsWith("t");
122 boolean transform = row.getField("transform").toLowerCase().startsWith("t");
123 double zIndex = Double.parseDouble(row.getField("zIndex"));
124 double scaleThresholdMetersPerPx = Double.parseDouble(row.getField("scale"));
125
126 if (header.contains("filter"))
127 {
128 String filter = row.getField("filter");
129 }
130
131 Map<String, Number> styleMap = new LinkedHashMap<>();
132 if (header.contains("style"))
133 {
134 String styleStr = row.getField("style");
135 String[] styles = styleStr.split(";");
136 for(var style : styles)
137 {
138 String[] kv = style.strip().split("=");
139 String k = kv[0].strip();
140 String v = kv.length > 1 ? kv[1].strip() : "1";
141 Number n = Double.valueOf(v);
142 styleMap.put(k, n);
143 }
144 }
145
146 LayerInterface layer = null;
147 if (layerNames.contains(layerName))
148 {
149 layer = layerList.get(layerNames.indexOf(layerName));
150 }
151 else
152 {
153 layer = new Layer();
154 layerList.add(layer);
155 layer.setName(layerName);
156 layerNames.add(layerName);
157 }
158
159 Feature feature = new Feature(layer);
160 feature.setKey(key);
161 feature.setValue(value);
162 Style shapeStyle = new Style();
163 feature.setShapeStyle(shapeStyle);
164 shapeStyle.setOutlineColor(outlineColor);
165 shapeStyle.setFillColor(fillColor);
166 feature.setZIndex(zIndex);
167 shapeStyle.setScaleThresholdMetersPerPx(scaleThresholdMetersPerPx);
168 if (styleMap.containsKey("lineWidthPx"))
169 shapeStyle.setLineWidthPx(styleMap.get("lineWidthPx").intValue());
170 if (styleMap.containsKey("lineWidthM"))
171 shapeStyle.setLineWidthM(styleMap.get("lineWidthM").doubleValue());
172 layer.addFeature(feature);
173 featuresToRead.add(feature);
174 layer.setDisplay(display);
175 layer.setTransform(transform);
176 }
177 reader.close();
178 csvReader.close();
179
180 map.setLayers(layerList);
181 OsmFileReader osmReader = new OsmFileReader(osmUrl, coordinateTransform, featuresToRead);
182 osmReader.populateShapes();
183 return map;
184 }
185
186 }