/************************************************************************************ * Copyright (C) 2008 by Politehnica University of Bucharest and Rutgers University * All rights reserved. * Refer to LICENSE for terms and conditions of use. ***********************************************************************************/ package vnsim.map.object; import java.util.Comparator; import java.util.Random; import java.util.Collections; import java.util.ArrayList; import java.util.logging.*; import java.io.*; import vnsim.applications.adaptiveTL.*; import vnsim.applications.emissions.EmissionsTrafficLight; import vnsim.map.utils.*; import vnsim.vehicular.routePlan.selfRouted.RoadAreaUtils; import vnsim.vehicular.simulator.intersections.*; import vnsim.gui.*; /** * @author Victor-Radu */ public class Map implements Serializable { /** serialVersionUID */ private static final long serialVersionUID = -5883719321862303634L; /** Logger used by this class */ private static final transient Logger logger = Logger.getLogger("vnsim.map.object.Map"); public ArrayList roads = new ArrayList(); public ArrayList peanoKeys = new ArrayList(); public Point minPoint, maxPoint; public RoadAreaUtils mapSpliter; //all intersections public ArrayList allIntersections=new ArrayList (); //the indices of the intersections with traffic lights //(kept here for optimization) public ArrayList lightsIndices=new ArrayList (); //intersections with traffic lights // public ArrayList intersectionsWithLights=new ArrayList (); public Map(){ } public Map(String rt1file, String rt2file){ double kmNo=0; int j = 0; Point p1; Point p2; logger.info("File name is "+rt1file); /* load the roads vector and sort streets on id */ loadRoadsFromRT1File(rt1file); logger.info("Done loading roads"); /* load intermediate points for each road segment */ loadPointsFromRT2File(rt2file); logger.info("Done loading points"); /* add more points on each street using interpolation, in order to have * a higher resolution and be able to map a car more accurately on the * road (Globals.MAXSEGLEN - meters - dictates this resolution) */ for (int i = 0; i Globals.MAXSEGLEN){ Point p = new Point( (p1.getLongitude() + p2.getLongitude())/ 2.0, (p1.getLatitude() + p2.getLatitude()) / 2.0); r.points.add(j+1, p); p1 = (Point)r.points.get(j); p2 = (Point)r.points.get(j+1); } j++; } } logger.info("Done interpolating"); /* merge small segments with the same road name (a segment is between 2 * consecutive intersections) into big roads with refferences to the * intersections - it's easier to apply graph algorithms*/ mergeRoadSegments(rt1file); logger.info("Done merging segments - " + roads.size()); /* compute distances along the road, between each point and * the start point on the segment * We also compute here the PeanoKey for each point */ for (int i = 0; i ids = new ArrayList(); if (MODIFYMAP){ BufferedReader br = null; try{ br = new BufferedReader(new InputStreamReader(Utils.getInstance().openStream("roadids.txt"))); String s; while ((s = br.readLine())!=null){ ids.add(Integer.parseInt(s)); } br.close(); }catch(Exception e){ logger.log(Level.INFO, "File roadids.txt not found", e); } try{ g = new PrintWriter(new BufferedWriter(new FileWriter(System.getProperty("user.home")+File.separatorChar+"downtown2.RT1"))); }catch(IOException e){ logger.info("File downtown2.RT1 could not be open!"); g = null; } } try{ while ((len = f.read(buffer,0,Globals.RT1_length)) != -1){ if (len != Globals.RT1_length){ logger.info("File " + rt1file + " invalid RT1 format!"); System.exit(0); } Road r = ParsingUtil.parseRoad(buffer); if (r!=null){ roads.add(r); if (MODIFYMAP){ if (ids.indexOf((int)r.getId()) == -1 && !r.getName().trim().equals("Lexington") && !r.getName().trim().equals("7th") && !r.getName().trim().equals("22nd") && !r.getName().trim().equals("35th") ){ g.print(new String(buffer)); } int last = r.points.size() - 1; /*if ( (((Point)r.points.get(0)).getLatitude() < 40.751221 && ((Point)r.points.get(0)).getLatitude() > 40.737553 && ((Point)r.points.get(0)).getLongitude() < -73.978051 && ((Point)r.points.get(0)).getLongitude() > -73.993238) || (((Point)r.points.get(last)).getLatitude() < 40.751221 && ((Point)r.points.get(last)).getLatitude() > 40.737553 && ((Point)r.points.get(last)).getLongitude() < -73.978051 && ((Point)r.points.get(last)).getLongitude() > -73.993238)){ // g.print(new String(buffer)); }*/ } /* //I used this section to find out the min/max latitude/longitude of the map if (((Point)r.points.get(0)).getLatitude() < minl) minl = ((Point)r.points.get(0)).getLatitude(); if (((Point)r.points.get(0)).getLatitude() > maxl) maxl = ((Point)r.points.get(0)).getLatitude(); if (((Point)r.points.get(1)).getLatitude() < minl) minl = ((Point)r.points.get(1)).getLatitude(); if (((Point)r.points.get(1)).getLatitude() > maxl) maxl = ((Point)r.points.get(1)).getLatitude(); if (((Point)r.points.get(0)).getLongitude() > minL) minL = ((Point)r.points.get(0)).getLongitude(); if (((Point)r.points.get(0)).getLongitude() < maxL) maxL = ((Point)r.points.get(0)).getLongitude(); if (((Point)r.points.get(1)).getLongitude() > minL) minL = ((Point)r.points.get(1)).getLongitude(); if (((Point)r.points.get(1)).getLongitude() < maxL) maxL = ((Point)r.points.get(1)).getLongitude(); */ }else{ //System.out.println("-> null"); } } /* System.out.println("minl " + minl); System.out.println("maxl " + maxl); System.out.println("minL " + minL); System.out.println("maxL " + maxL); */ f.close(); if (MODIFYMAP){ g.close(); } Collections.sort(roads); }catch (IOException e){ logger.log(Level.SEVERE, "File "+rt1file+"not found", e); System.exit(0); } } // public void loadRoadsFromRT1File(String rt1file){ // /* loads segments from the RT1 file in the roads vector*/ // DataInputStream f; // PrintWriter g; //I used g when I wanted to create smaller TIGER files // //from the original TIGER files. So, to create these small // //smaller files I comment everything in the map constructor // //but the calls to // // loadRoadsFromRT1File // // loadPointsFromRT2File // // int len; // byte[] buffer = new byte[Globals.RT1_length]; // //rt1file = "file://" + System.getProperty("user.dir") + rt1file; // //System.out.println("New path is "+rt1file); // try{ // f = new DataInputStream(Utils.getInstance().openStream(rt1file)); // }catch(Exception e){ // logger.log(Level.SEVERE, "File "+rt1file+" not found!", e); // System.exit(0); // return; // } // // ArrayList ids = new ArrayList(); // if (MODIFYMAP){ // BufferedReader br = null; // try{ // br = new BufferedReader(new InputStreamReader(Utils.getInstance().openStream("roadids.txt"))); // String s; // while ((s = br.readLine())!=null){ // ids.add(Integer.parseInt(s)); // } // br.close(); // }catch(Exception e){ // logger.log(Level.INFO, "File roadids.txt not found", e); // } // try{ // g = new PrintWriter(new BufferedWriter(new FileWriter(System.getProperty("user.home")+File.separatorChar+"downtown2.RT1"))); // }catch(IOException e){ // logger.info("File downtown2.RT1 could not be open!"); // g = null; // } // } // // try{ // while ((len = f.read(buffer,0,Globals.RT1_length)) != -1){ // if (len != Globals.RT1_length){ // logger.info("File " + rt1file + " invalid RT1 format!"); // System.exit(0); // } // // Road r = ParsingUtil.parseRoad(buffer); // if (r!=null){ // roads.add(r); // if (MODIFYMAP){ // if (ids.indexOf((int)r.getId()) == -1 // && !r.getName().trim().equals("Lexington") // && !r.getName().trim().equals("7th") // && !r.getName().trim().equals("22nd") // && !r.getName().trim().equals("35th") // ){ // g.print(new String(buffer)); // } // int last = r.points.size() - 1; // /*if ( // (((Point)r.points.get(0)).getLatitude() < 40.751221 // && ((Point)r.points.get(0)).getLatitude() > 40.737553 // && ((Point)r.points.get(0)).getLongitude() < -73.978051 // && ((Point)r.points.get(0)).getLongitude() > -73.993238) // || (((Point)r.points.get(last)).getLatitude() < 40.751221 // && ((Point)r.points.get(last)).getLatitude() > 40.737553 // && ((Point)r.points.get(last)).getLongitude() < -73.978051 // && ((Point)r.points.get(last)).getLongitude() > -73.993238)){ // //// g.print(new String(buffer)); // }*/ // } // // ///* //I used this section to find out the min/max latitude/longitude of the map // if (((Point)r.points.get(0)).getLatitude() < minl) // minl = ((Point)r.points.get(0)).getLatitude(); // if (((Point)r.points.get(0)).getLatitude() > maxl) // maxl = ((Point)r.points.get(0)).getLatitude(); // if (((Point)r.points.get(1)).getLatitude() < minl) // minl = ((Point)r.points.get(1)).getLatitude(); // if (((Point)r.points.get(1)).getLatitude() > maxl) // maxl = ((Point)r.points.get(1)).getLatitude(); // if (((Point)r.points.get(0)).getLongitude() > minL) // minL = ((Point)r.points.get(0)).getLongitude(); // if (((Point)r.points.get(0)).getLongitude() < maxL) // maxL = ((Point)r.points.get(0)).getLongitude(); // if (((Point)r.points.get(1)).getLongitude() > minL) // minL = ((Point)r.points.get(1)).getLongitude(); // if (((Point)r.points.get(1)).getLongitude() < maxL) // maxL = ((Point)r.points.get(1)).getLongitude(); //*/ }else{ // //System.out.println("-> null"); // } // } ///* System.out.println("minl " + minl); // System.out.println("maxl " + maxl); // System.out.println("minL " + minL); // System.out.println("maxL " + maxL); //*/ // f.close(); // if (MODIFYMAP){ // g.close(); // } // Collections.sort(roads); // }catch (IOException e){ // logger.log(Level.SEVERE, "File "+rt1file+"not found", e); // System.exit(0); // } // } public void loadPointsFromRT2File(String rt2file){ /* parse RT2 file and load additional points for the segments * already read from the RT1 file*/ DataInputStream f; PrintWriter g; int len; byte[] buffer = new byte[Globals.RT2_length]; try{ f = new DataInputStream(Utils.getInstance().openStream(rt2file)); }catch(Exception e){ logger.log(Level.SEVERE, "File "+rt2file+" not found", e); System.exit(0); return; } /*try{ f = new RandomAccessFile(rt2file,"r"); }catch(FileNotFoundException e){ System.out.println("File " + rt2file + " not found!"); System.exit(0); return; }*/ ArrayList ids = new ArrayList(); if (MODIFYMAP){ try{ g = new PrintWriter(new BufferedWriter(new FileWriter(System.getProperty("user.home")+File.separatorChar+"downtown2.RT2"))); //g = new PrintWriter( // new BufferedWriter(new FileWriter("downtown2.RT2"))); }catch(IOException e){ logger.info("File downtown2.RT2 could not be open"); //System.out.println("File NJTurnpike2.RT2 could not be open!"); System.exit(0); return; } BufferedReader br = null; try{ br = new BufferedReader(new FileReader(new File("roadids.txt"))); String s; while ((s = br.readLine())!=null){ ids.add(Integer.parseInt(s)); } br.close(); }catch(IOException e){ e.printStackTrace(); } } try{ while ((len = f.read(buffer,0,Globals.RT2_length)) != -1){ if (len != Globals.RT2_length){ System.out.println("File " + rt2file + " invalid RT2 format!"); System.exit(0); } Road r = new Road(); r.setId( Long.parseLong(new String(buffer, 5, 10).trim()) ); int idx = Collections.binarySearch(roads,r); if (idx >= 0){ r = (Road)roads.get(idx); if (MODIFYMAP){ // if (ids.indexOf((int)r.getId()) == -1){ // g.print(new String(buffer)); // } int last = r.points.size() - 1; if ( (((Point)r.points.get(0)).getLatitude() < 40.751221 && ((Point)r.points.get(0)).getLatitude() > 40.737553 && ((Point)r.points.get(0)).getLongitude() < -73.978051 && ((Point)r.points.get(0)).getLongitude() > -73.993238) || (((Point)r.points.get(last)).getLatitude() < 40.751221 && ((Point)r.points.get(last)).getLatitude() > 40.737553 && ((Point)r.points.get(last)).getLongitude() < -73.978051 && ((Point)r.points.get(last)).getLongitude() > -73.993238)){ // g.print(new String(buffer)); } } for (int i=0;i<10;i++){ Point p = ParsingUtil.parsePoint(new String(buffer, 18 + i*19, 19).getBytes()); if (p.getLatitude() != 0.0 && p.getLongitude() != 0.0){ /* for multiple RT2 records, assume the points * are all ordered nicely */ r.points.add(r.points.size()-1,p); } } } } f.close(); if (MODIFYMAP){ g.close(); } Collections.sort(roads); }catch (IOException e){ System.out.println("File " + rt2file + " invalid format!"); System.exit(0); } } private final void createMapsDir() { // create local path... final String dir = System.getProperty("user.home")+File.separatorChar+"maps"; File f = new File(dir); if (!f.exists()) f.mkdirs(); } public void mergeRoadSegments(String rt1file){ /* the goal of this function is to eliminate prev and next information in road structure * by merging road segments with the same name*/ ArrayList roads_aux = new ArrayList(); int[] v = new int[roads.size()]; int next,prev; BufferedReader f=null; boolean needAdjacencyFile = false; /* As an optimization, a file with adjacency information is created in the current * directory, and any following execution of this program will avoid O(n^2) complexity * of completing next and previous fields for each segment. The file will have the name * of the RT1 file written on the first line, in order to know wich map it is associated with * On each line there will be */ try{ f = new BufferedReader(new InputStreamReader(Utils.getInstance().openStream("/maps/adjacency.txt"))); }catch(Exception e){ needAdjacencyFile = true; } if (f!=null){ try{ String s = f.readLine(); if (!rt1file.equals(s)){ logger.info("Inconsistent adjacency file, recreating..."); f.close(); // create local path... createMapsDir(); // delete previous existing file... (new File(System.getProperty("user.home")+File.separatorChar+"maps"+File.separatorChar+"adjacency.txt")).delete(); needAdjacencyFile = true; } }catch(IOException e){ logger.warning("Error reading file adjacency.txt"); try { f.close(); // create local path... createMapsDir(); // delete previous existing file... (new File(System.getProperty("user.home")+File.separatorChar+"maps"+File.separatorChar+"adjacency.txt")).delete(); needAdjacencyFile = true; } catch (Exception ex) { logger.log(Level.SEVERE, "Error creating file adjacency... ", ex); System.exit(0); } } } if (needAdjacencyFile){ System.out.println("Adjacency file does not exist - wait while it is being built..."); buildAdjacencyFile(rt1file); try{ createMapsDir(); f = new BufferedReader(new InputStreamReader(new FileInputStream(System.getProperty("user.home")+File.separatorChar+"maps"+File.separatorChar+"adjacency.txt"))); }catch(Exception e){ logger.log(Level.SEVERE, "Adjacency file was not built...", e); System.exit(0); } try{ String s = f.readLine(); String rt1filename=new File(rt1file).getName(); if (!rt1filename.equals(s)){ f.close(); logger.severe("Error: Adjacency file was built wrong"); System.exit(0); } }catch(IOException e){ logger.log(Level.SEVERE, "Error reading locally built file adjacency.txt", e); System.exit(0); } } //complete next an prev fields for each segment try{ String line; while ((line = f.readLine())!=null){ //System.out.println("**" + line); int i = Integer.parseInt(line.substring(0, line.indexOf(" "))); int j = Integer.parseInt(line.substring(line.indexOf(" ")+1, line.length())); v[i] = 0; v[j] = 0; Road r1 = (Road)roads.get(i); Road r2 = (Road)roads.get(j); r1.setNextRdIdx(j); r2.setPrevRdIdx(i); } f.close(); }catch(IOException e){ logger.severe("Error reading adjacency file "); System.exit(0); return; } // for (int i = 0; i= 0) return ((PeanoKey)peanoKeys.get(idx)); int insertIdx = -(idx + 1); // System.out.println("Key " + new String(searchpk.getValue())+ " - insert at " + insertIdx); double mindist = Globals.CLOSEST_PEANOKEY_MAXDIST; int pkIdx = -1; int j = 1; while (j <= Globals.PEANOKEY_SEARCH_RANGE && insertIdx - j >= 0){ PeanoKey pk = (PeanoKey)peanoKeys.get(insertIdx-j); Point p = (Point)((Road)roads.get(pk.getRoadIndex())).points.get(pk.getPointIndex()); double dist = gpsPoint.distanceTo(p); // System.out.println("\t"+new String(pk.getValue())+" "+((Road)roads.get(pk.getRoadIndex())).getName().trim() + " - " + // ((Road)roads.get(pk.getRoadIndex())).getId() + " - point " + // pk.getPointIndex() + " / " + ((Road)roads.get(pk.getRoadIndex())).points.size() // + " distance: " + dist); if (dist < mindist) { mindist = dist; pkIdx = insertIdx-j; } j++; } j = 0; while (j < Globals.PEANOKEY_SEARCH_RANGE && insertIdx + j < peanoKeys.size()){ PeanoKey pk = (PeanoKey)peanoKeys.get(insertIdx+j); Point p = (Point)((Road)roads.get(pk.getRoadIndex())).points.get(pk.getPointIndex()); double dist = gpsPoint.distanceTo(p); // System.out.println("\t"+new String(pk.getValue())+" "+((Road)roads.get(pk.getRoadIndex())).getName().trim() + " - " + // ((Road)roads.get(pk.getRoadIndex())).getId() + " - point " + // pk.getPointIndex() + " / " + ((Road)roads.get(pk.getRoadIndex())).points.size() // + " distance: " + dist); if (dist < mindist){ mindist = dist; pkIdx = insertIdx+j; } j++; } if (pkIdx == -1) return null; return (PeanoKey)peanoKeys.get(pkIdx); } /** * After loading the crossroad this method is called in order to add all auxiliary intersections. */ public void addIntersections() { for(int i=0;i() { public int compare(Cross c1, Cross c2) { if(c1.pointIndexc2.pointIndex) return 1; if(c1.pointIndex==c2.pointIndex) { //compare crossRoadIndices if(c1.crossRoadIndex0) inters.addCrossingSegment(new DirectedRoadSegment(i, c.pointIndex, false)); if(c.pointIndex0) inters.addCrossingSegment(new DirectedRoadSegment(c.crossRoadIndex, c.crossPointIndex, false)); if(c.crossPointIndex0) inters.addCrossingSegment(new DirectedRoadSegment(i, c2.pointIndex, false)); if(c2.pointIndex0) inters.addCrossingSegment(new DirectedRoadSegment(c2.crossRoadIndex, c2.crossPointIndex, false)); if(c2.crossPointIndex1) { //change it into a traffic lights intersection WirelessTrafficLight newInters=new WirelessTrafficLight(); // IntersectionWithTrafficLights newInters=new IntersectionWithTrafficLights(); IntersectionWithoutTrafficLights oldInters=(IntersectionWithoutTrafficLights) allIntersections.get(i); for(int j=0;j 170) seg1.front = seg2; if (angle >= 190) seg1.right = seg2; if (angle <= 170) seg1.left = seg2; } } } // newInters.lightInfos=new ArrayList (); //green duration for priority roads // int green=(int)(20.0+30.0*generator.nextDouble()); int green=37; if (!roads.get(0).getName().startsWith("Iuliu")){ //!apaca green = 30; } int time=0; int j = 2; if (roads.get(0).getName().startsWith("Dr ") && i == 1){ green = 30; } newInters.segments.get(0).setLightInfo(new TrafficLightInfo(0, green)); if (roads.get(0).getName().startsWith("Dr ") && i == 1){ green = 45; } newInters.segments.get(1).setLightInfo(new TrafficLightInfo(0, green)); time=time + green + Globals.DEFAULT_YELLOW_TIME + Globals.DEFAULT_ALL_RED; if (roads.get(0).getName().startsWith("Iuliu") && i == 1){ newInters.segments.get(2).setLightInfo(new TrafficLightInfo(time, time + green)); time=time + green + Globals.DEFAULT_YELLOW_TIME + Globals.DEFAULT_ALL_RED; newInters.segments.get(3).setLightInfo(new TrafficLightInfo(time, time + green)); time=time + green + Globals.DEFAULT_YELLOW_TIME + Globals.DEFAULT_ALL_RED; j = 4; } for(;j maxPoint.getLatitude()) { maxPoint.setLatitude(tmpPoint.getLatitude()); } if (tmpPoint.getLongitude() > maxPoint.getLongitude()) { maxPoint.setLongitude(tmpPoint.getLongitude()); } j++; } i++; } this.minPoint = minPoint; this.maxPoint = maxPoint; } public void setLaneNoExtra() { //Intersection if (roads.get(0).getName().startsWith("Calculatoare")){ roads.get(0).laneNo=3; roads.get(1).laneNo=2; } if (roads.get(0).getName().startsWith("Iuliu")){ // Apaca roads.get(0).laneNo=3; roads.get(1).laneNo=4; roads.get(2).laneNo=3; } } }