package org.opentrafficsim.demo.ntm.IO; import java.awt.Color; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.Serializable; import java.rmi.RemoteException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Locale; import java.util.Map; import javax.naming.NamingException; import org.djunits.unit.DurationUnit; import org.djunits.value.vdouble.scalar.Duration; import org.locationtech.jts.geom.Geometry; import org.opentrafficsim.core.dsol.AbstractOTSModel; import org.opentrafficsim.core.dsol.OTSSimulatorInterface; import org.opentrafficsim.core.network.OTSNetwork; import org.opentrafficsim.demo.ntm.animation.RoadAnimation; import org.opentrafficsim.demo.ntm.shapeobjects.ShapeObject; import org.opentrafficsim.demo.ntm.shapeobjects.ShapeStore; import nl.tudelft.simulation.dsol.SimRuntimeException; import nl.tudelft.simulation.dsol.simulators.AnimatorInterface; /** *

* Copyright (c) 2013-2017 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
* BSD-style license. See OpenTrafficSim License. *

* $LastChangedDate$, @version $Revision$, by $Author$, * initial version 3 Nov 2014
* @author Alexander Verbraeck * @author Hans van Lint * @author Peter Knoppers * @author Guus Tamminga * @author Yufei Yuan */ public class DataViewer extends AbstractOTSModel { /** */ private static final long serialVersionUID = 1L; /** *

* Copyright (c) 2013-2017 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. *
* BSD-style license. See OpenTrafficSim License. *

* $LastChangedDate$, @version $Revision$, by $Author$, * initial version 14 Nov 2014
* @author Alexander Verbraeck * @author Hans van Lint * @author Peter Knoppers * @author Guus Tamminga * @author Yufei Yuan */ public enum days { Sat, Sun, Mon, Tue, Wed, Thu, Fri }; /** */ LinkedHashMap mapRoadCounts; /** * Constructor to make the graphs with the right type. * @param simulator OTSSimulatorInterface; the simulator */ public DataViewer(final OTSSimulatorInterface simulator) { super(simulator); } /** * {@inheritDoc} */ @Override public final void constructModel() throws SimRuntimeException { String startMap = "D:/gtamminga/My Documents/03 Case The Hague NTM/TNO data"; String fileArea = FileDialog.showFileDialog(true, "shp", "Shapefile with Areas", startMap); // File file = new File(fileName); String fileRoads = FileDialog.showFileDialog(true, "shp", "Shapefile with Roads", startMap); // "D:/gtamminga/My Documents/03 Case The Hague NTM/TNO data/TheHagueNetwork_Unidirectional_v2.shp"; String filePathData = "D:/gtamminga/My Documents/03 Case The Hague NTM/TNO data/20141016 Oplevering/Oplevering o.b.v. VLOG data/di-do-2014/"; String fileNameStarts = "I_"; boolean fileNameDay = false; try { this.mapRoadCounts = addArea(fileArea, fileRoads, filePathData, fileNameStarts, fileNameDay); } catch (IOException exception) { exception.printStackTrace(); } /* * filePathData = * "D:/gtamminga/My Documents/03 Case The Hague NTM/TNO data/20141016 Oplevering/Oplevering o.b.v. NDW data_v2/" ; * fileNameStarts = "I_"; fileNameDay = true; try { addArea(fileArea, fileRoads, filePathData, fileNameStarts, * fileNameDay); } catch (IOException exception) { exception.printStackTrace(); } fileNameStarts = "VL_"; fileNameDay = * true; try { addArea(fileArea, fileRoads, filePathData, fileNameStarts, fileNameDay); } catch (IOException exception) * { exception.printStackTrace(); } */ this.simulator.scheduleEventRel(new Duration(0.0, DurationUnit.SECOND), this, this, "ntmFlowTimestep", null); } /** * */ @SuppressWarnings("unchecked") protected final void ntmFlowTimestep() { this.mapRoadCounts.values(); Duration timeStep = new Duration(2.0, DurationUnit.SECOND); // in case we run on an animator and not on a simulator, we create the animation if (this.simulator instanceof AnimatorInterface) { createDynamicAreaAnimation(); } try { // start this method again this.simulator.scheduleEventRel(timeStep, this, this, "ntmFlowTimestep", null); } catch (Exception e) { e.printStackTrace(); } } /** * @param fileArea String; * @param fileRoads String; * @param pathData String; * @param fileNameStarts String; * @param fileNameDay boolean; * @return * @throws IOException */ public static LinkedHashMap addArea(String fileArea, String fileRoads, String pathData, String fileNameStarts, boolean fileNameDay) throws IOException { ShapeStore roads = null; // Map areas = new LinkedHashMap(); ShapeStore areas = null; File file = new File(fileArea); areas = ShapeStore.openGISFile(file); // the specific ID we want to use, and the geometry (the_geom) of the road file = new File(fileRoads); roads = ShapeStore.openGISFile(file); // we are looking for a specific day! String year = "2014"; String day = null; String month = null; LinkedHashMap mapRoads = new LinkedHashMap(); // for (int i = 1; i <= 12; i++) for (int i = 5; i <= 5; i++) { // for (int j = 1; j <= 31; j++) for (int j = 29; j <= 29; j++) { if (i <= 10) { month = "0" + i; } else { month = Integer.toString(i); } if (j <= 10) { day = "0" + j; } else { day = Integer.toString(j); } if (fileNameDay) { for (days dayName : days.values()) { String inputFile = pathData + fileNameStarts + year + month + day + "_" + dayName + "_GV[none].csv"; Map> countMap = readData(inputFile, ";", pathData, year, 5); if (countMap.size() > 0) { String outputFile = pathData + "new/" + fileNameStarts + year + month + day + "_" + dayName + "_area_GV[none].csv"; String outputShapeFile = pathData + "new/" + fileNameStarts + year + month + day + "_" + dayName + ".shp"; mapRoads = detectLocationOfObject(outputShapeFile, outputFile, countMap, roads, areas, "LINK_ID", "Name"); } } } else { String inputFile = pathData + fileNameStarts + year + month + day + ".csv"; Map> countMap = readData(inputFile, ",", pathData, year, 5); if (countMap.size() > 0) { String outputShapeFile = pathData + "new/" + fileNameStarts + year + month + day + ".shp"; String outputFile = pathData + "new/" + fileNameStarts + year + month + day + "_area.csv"; mapRoads = detectLocationOfObject(outputShapeFile, outputFile, countMap, roads, areas, "LINK_ID", "Name"); } } } } return mapRoads; } /** * @param inputFile String; * @param csvSplitBy String; * @param path String; * @param year String; * @return values * @throws FileNotFoundException */ public static Map> readData(String inputFile, String csvSplitBy, String path, String year, Integer aggregateBy) throws FileNotFoundException { Map> countMap = new LinkedHashMap>(); BufferedReader in = null; String line = ""; if (new File(inputFile).canRead()) { File file = new File(inputFile); in = new BufferedReader(new FileReader(file)); // read all lines: first column contains the name of the origin // this can be either a link or a centroid (starts with "C") boolean header = true; ArrayList segment = new ArrayList(); try { while ((line = in.readLine()) != null) { String[] completeLine = line.split(csvSplitBy); // first line contains the column identifiers if (header) { int columnNumber = 0; for (String lineSegment : completeLine) { lineSegment = lineSegment.trim(); if (columnNumber > 0) { SimpleDateFormat sdf = new SimpleDateFormat("mm:ss", Locale.ENGLISH); String time = lineSegment; segment.add(time); } columnNumber++; } header = false; } else { int columnNumber = 0; ArrayList counts = new ArrayList(); String id = null; for (String lineSegment : completeLine) { lineSegment = lineSegment.trim(); if (columnNumber > 0) { String counted = lineSegment; counts.add(java.lang.Double.parseDouble(counted)); } else if (columnNumber == 0) { id = lineSegment; } columnNumber++; } ArrayList aggregatedCounts = new ArrayList(); if (aggregateBy > 1) { int i = 1; double aggregatedCount = 0.0; for (java.lang.Double count : counts) { aggregatedCount += count; i++; if (i == aggregateBy) { aggregatedCounts.add(aggregatedCount); i = 1; aggregatedCount = 0.0; } } } else { aggregatedCounts = counts; } countMap.put(id, aggregatedCounts); } } in.close(); } catch (NumberFormatException exception) { exception.printStackTrace(); } catch (IOException exception) { exception.printStackTrace(); } } return countMap; } /** * @param outputFile * @param outputFile * @param countMap * @param objectsToDetect * @param searchLocations * @param fieldNameToDetect * @param fieldNameSearchAreas * @return * @throws IOException */ public static LinkedHashMap detectLocationOfObject(String outputShapeFile, String outputFile, Map> countMap, ShapeStore objectsToDetect, ShapeStore searchLocations, String fieldNameToDetect, String fieldNameSearchAreas) throws IOException { File fileNew = new File(outputFile); BufferedWriter out = null; // if file doesn't exists, then create it... if (fileNew.exists()) { fileNew.createNewFile(); } out = new BufferedWriter(new FileWriter(fileNew)); // add data to the point/line (road) file of attributes within a polygon objectsToDetect.addAttribute("Count", "Double"); int indexAttributeAdded0 = objectsToDetect.getVariableNames().size() - 1; // add data to the area (polygon) file searchLocations.addAttribute("Counted", "Integer"); int indexAttributeAdded1 = searchLocations.getVariableNames().size() - 1; searchLocations.addAttribute("CountedIDs", "String"); int indexAttributeAdded2 = indexAttributeAdded1 + 1; // we are looking for roads with a specific ID that is included in the data from TNO // step 1: create a LinkedHashMap to find the geometry of a road with a specific ID // step 2: find the corresponding Area LinkedHashMap mapRoads = new LinkedHashMap(); int indexFieldNameToDetect = -1; for (String name : objectsToDetect.getVariableNames()) { if (name.equals(fieldNameToDetect)) { indexFieldNameToDetect = objectsToDetect.getVariableNames().indexOf(name); break; } } for (ShapeObject road : objectsToDetect.getGeoObjects()) { mapRoads.put(road.getValues().get(indexFieldNameToDetect), road); } // write the data with the corresponding area ID to a new file Iterator it = countMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry countIdValue = (Map.Entry) it.next(); Geometry geomToDetect = null; if (mapRoads.get(countIdValue.getKey()) != null) { geomToDetect = mapRoads.get(countIdValue.getKey()).getDesignLine(); } ShapeObject area = null; if (geomToDetect != null) { area = findObjectInPolygon(geomToDetect, searchLocations); } String text = ""; String id = (String) countIdValue.getKey(); if (area != null) { Integer counted; if (area.getValues().get(indexAttributeAdded1).equals("NaN")) { counted = -999; } else if (area.getValues().get(indexAttributeAdded1).equals(" ")) { counted = -999; } else { counted = Integer.parseInt(area.getValues().get(indexAttributeAdded1)); } area.getValues().set(indexAttributeAdded1, Integer.toString(counted + 1)); // String ids = area.getValues().get(indexAttributeAdded2); // area.getValues().set(indexAttributeAdded2, ids + id); text = id + ", " + area.getValues().get(0); } else { text = id + " no area found"; } ArrayList counts = (ArrayList) countIdValue.getValue(); for (java.lang.Double count : counts) { text += ", " + count; } text += " \n"; out.write(text); // extend the shape of roads with count data if (mapRoads.get(countIdValue.getKey()) != null) { mapRoads.get(countIdValue.getKey()).getValues().set(indexAttributeAdded0, text); } it.remove(); // avoids a ConcurrentModificationException } /* * if (new File(outputShapeFile).isAbsolute()) { File file = new File(outputShapeFile); * ShapeStore.createShapeFile(searchLocations, file); } if (new File(outputShapeFile).isAbsolute()) { File file = new * File(outputShapeFile); ShapeStore.createShapeFile(objectsToDetect, file); } */ out.close(); return mapRoads; } /** * Make the animation for each of the components that we want to see on the screen. */ private void createDynamicAreaAnimation() { try { // let's make several layers with the different types of information boolean showLinks = true; if (showLinks) { for (ShapeObject road : this.mapRoadCounts.values()) { new RoadAnimation(road, this.simulator, 2.0F, Color.GRAY); } } } catch (NamingException | RemoteException exception) { exception.printStackTrace(); } } /** * @param p the point to search. * @return the area that contains point p, or null if not found. */ private static ShapeObject findObjectInPolygon(final Geometry geom, ShapeStore areas) { ShapeObject area = null; for (ShapeObject a : areas.getGeoObjects()) { // could also be contains.... if (a.getDesignLine().intersects(geom)) { area = a; break; } } return area; } /** {@inheritDoc} */ @Override public OTSNetwork getNetwork() { return null; } /** {@inheritDoc} */ @Override public Serializable getSourceId() { return "DataViewer"; } }