/************************************************************************************
* 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;
}
}
}