source: proiecte/ptvs/src/vnsim/map/object/Map.java @ 31

Last change on this file since 31 was 31, checked in by (none), 14 years ago
File size: 38.6 KB
Line 
1/************************************************************************************
2 * Copyright (C) 2008 by Politehnica University of Bucharest and Rutgers University
3 * All rights reserved.
4 * Refer to LICENSE for terms and conditions of use.
5 ***********************************************************************************/
6package vnsim.map.object;
7
8
9import java.util.Comparator;
10import java.util.Random;
11import java.util.Collections;
12import java.util.ArrayList;
13import java.util.logging.*;
14import java.io.*;
15
16import vnsim.applications.adaptiveTL.*;
17import vnsim.applications.emissions.EmissionsTrafficLight;
18import vnsim.map.utils.*;
19import vnsim.vehicular.routePlan.selfRouted.RoadAreaUtils;
20import vnsim.vehicular.simulator.intersections.*;
21import vnsim.gui.*;
22
23
24
25
26/**
27 * @author Victor-Radu
28 */
29public class Map implements Serializable {
30       
31        /** <code>serialVersionUID</code> */
32        private static final long serialVersionUID = -5883719321862303634L;
33       
34        /** Logger used by this class */
35        private static final transient Logger logger = Logger.getLogger("vnsim.map.object.Map");
36       
37        public ArrayList<Road> roads = new ArrayList<Road>();
38
39        public ArrayList<PeanoKey> peanoKeys = new ArrayList<PeanoKey>();
40
41        public Point minPoint, maxPoint;
42
43        public RoadAreaUtils mapSpliter;
44
45        //all intersections
46        public ArrayList<Intersection> allIntersections=new ArrayList<Intersection> ();
47       
48        //the indices of the intersections with traffic lights
49        //(kept here for optimization)
50        public ArrayList<Integer> lightsIndices=new ArrayList<Integer> ();
51
52        //intersections with traffic lights
53        //      public ArrayList<IntersectionWithTrafficLights> intersectionsWithLights=new ArrayList<IntersectionWithTrafficLights> ();
54
55        public Map(){
56        }
57       
58        public Map(String rt1file, String rt2file){
59                double kmNo=0;
60                int j = 0;
61                Point p1;
62                Point p2;
63                logger.info("File name is "+rt1file);
64                /* load the roads vector and sort streets on id */ 
65                loadRoadsFromRT1File(rt1file);
66                logger.info("Done loading roads");
67                /* load intermediate points for each road segment */ 
68                loadPointsFromRT2File(rt2file);
69                logger.info("Done loading points");
70               
71                /* add more points on each street using interpolation, in order to have
72                 * a higher resolution and be able to map a car more accurately on the
73                 * road (Globals.MAXSEGLEN - meters - dictates this resolution) */
74                for (int i = 0; i<roads.size(); i++){
75                        Road r = (Road)roads.get(i);
76                        j=0;
77                        while (j < r.points.size()-1){
78                                p1 = (Point)r.points.get(j);
79                                p2 = (Point)r.points.get(j+1);
80                                while (GPSutil.distance(p1, p2) > Globals.MAXSEGLEN){
81                                        Point p = new Point( (p1.getLongitude() + p2.getLongitude())/ 2.0,
82                                                                        (p1.getLatitude() + p2.getLatitude()) / 2.0);
83                                        r.points.add(j+1, p);
84                                        p1 = (Point)r.points.get(j);
85                                        p2 = (Point)r.points.get(j+1);
86                                }
87                                j++;
88                        }
89                }
90                logger.info("Done interpolating");
91                       
92                /* merge small segments with the same road name (a segment is between 2
93                 * consecutive intersections) into big roads with refferences to the
94                 * intersections - it's easier to apply graph algorithms*/
95                mergeRoadSegments(rt1file);
96                logger.info("Done merging segments - " + roads.size());
97               
98                /* compute distances along the road, between each point and
99                 * the start point on the segment
100                 * We also compute here the PeanoKey for each point
101                 */
102                for (int i = 0; i<roads.size(); i++){
103                        Road r = (Road)roads.get(i);
104                        j=0;
105                        p1 = (Point)r.points.get(0);
106                        p1.setDistance(0.0);
107                        peanoKeys.add(new PeanoKey(p1, i, j));
108                        for (j = 1; j < r.points.size();j++){
109                                p2 = (Point)r.points.get(j);
110                                p2.setDistance(p1.getDistance() + GPSutil.distance(p1, p2));
111                                p1 = p2;
112                               
113                                peanoKeys.add(new PeanoKey(p1, i, j));
114                        }
115                        kmNo += ((Point)r.points.get(r.points.size()-1)).getDistance();
116                        //System.out.println("Done computing distances and Peano Keys");
117                       
118                }
119                logger.info("Done adding points, computing distances and Peano Keys");
120                logger.info("Roads " + roads.size());
121                logger.info("Points " + peanoKeys.size());
122                logger.info("Total number of kilometers " + kmNo);
123                logger.info("Average segment size " + kmNo/roads.size());
124               
125                /* sort the PeanoKey vector */
126                Collections.sort(peanoKeys);
127               
128                // complete inverse reference from point to peano key
129                for (int i = 0; i < peanoKeys.size();i++){
130                        Road r = roads.get(peanoKeys.get(i).getRoadIndex());
131                        Point p = r.points.get(peanoKeys.get(i).getPointIndex());
132                        p.setPeanoKeyIdx(i);
133                } 
134               
135                logger.info("Done sorting");
136               
137                /* add crosses
138                 * for each road
139                 *              find other roads that intersect and add them to the Crosses vector
140                 * Complexity: O(n) n - number of points
141                 *                      - because we just need to find equal values in the sorted PeanoKey
142                 *                      vector in order to find the two equal points, that are each on a
143                 *                      different street.
144                 *                      These are intersection points that come from
145                 *                      the TIGER files, not from interpolation because. For a bridge over
146                 *                      another street you wouldn't have TIGER segments that end in that point
147                 *                      so you can't have false intersections*/
148               
149                Random generator = new Random(System.currentTimeMillis());
150                setLaneNoRandom(generator);
151                setLaneNoExtra();
152               
153                addCrossroads();
154                logger.info("Done adding crossroads");
155               
156                Globals.map=this;
157                addIntersections();
158               
159                checkIntersections();
160               
161                logger.info("Done creating intersections!");
162                Globals.map=this;
163                for(int ll=0;ll<allIntersections.size();ll++){
164                        if(!allIntersections.get(ll).hasTrafficLights()){       
165                                ((IntersectionWithoutTrafficLights)(allIntersections.get(ll))).sort(generator);
166                        }
167                }
168//              createTrafficLights(generator);
169
170//              System.out.println("INTERSECTIONS:"+allIntersections);
171                logger.info("INTERSECTIONS :"+allIntersections.size());
172                //System.out.println("INTERSECTIONS WITH LIOGHTS:"+intersectionsWithLights.size());
173                getMinAndMaxPoint();
174        }
175       
176        public int connectionPoint(int rdIdx1, int rdIdx2){
177        //checks to see if the road which contains rdIdx1 has an intersection with rdIdx2
178        //If it has, the function returns the cross index in the
179        //array of crosses of road rdIdx1       
180                        if (rdIdx1 == rdIdx2)
181                                return -1;
182                        Road r1 = (Road)roads.get(rdIdx1);
183                       
184                        for (int i=0; i<r1.crosses.size();i++){
185                                Cross c = (Cross)r1.crosses.get(i);
186                                if (c.getCrossRoadIndex() == rdIdx2)
187                                        return i;
188                        }
189                        return -1;
190                }
191       
192//http://maps.google.com/?ll=40.741209,-73.983092&spn=0.015315,0.029268
193        public static final boolean MODIFYMAP = false;
194       
195        public void loadRoadsFromRT1File(String rt1file){
196                /* loads segments from the RT1 file in the roads vector*/       
197                        DataInputStream f;
198                        PrintWriter g;                  //I used g when I wanted to create smaller TIGER files
199                        //from the original TIGER files. So, to create these small
200                        //smaller files I comment everything in the map constructor
201                        //but the calls to
202                        //                      loadRoadsFromRT1File
203                        //                      loadPointsFromRT2File
204
205                        int len;
206                        byte[] buffer = new byte[Globals.RT1_length];
207                        //rt1file = "file://" + System.getProperty("user.dir") + rt1file;
208                        //System.out.println("New path is "+rt1file);
209                        try{
210                                f = new DataInputStream(Utils.getInstance().openStream(rt1file));
211                        }catch(Exception e){
212                                logger.log(Level.SEVERE, "File "+rt1file+" not found!", e);
213                                System.exit(0);
214                                return;
215                        }
216
217                        ArrayList<Integer> ids = new ArrayList<Integer>();
218                        if (MODIFYMAP){
219                                BufferedReader br = null;
220                                try{
221                                        br = new BufferedReader(new InputStreamReader(Utils.getInstance().openStream("roadids.txt"))); 
222                                        String s;
223                                        while ((s = br.readLine())!=null){
224                                                ids.add(Integer.parseInt(s));
225                                        }
226                                        br.close();
227                                }catch(Exception e){
228                                        logger.log(Level.INFO, "File roadids.txt not found", e); 
229                                }
230                                try{
231                                        g = new PrintWriter(new BufferedWriter(new FileWriter(System.getProperty("user.home")+File.separatorChar+"downtown2.RT1")));
232                                }catch(IOException e){
233                                        logger.info("File downtown2.RT1 could not be open!");
234                                        g = null;
235                                }
236                        }
237
238                        try{
239                                while ((len = f.read(buffer,0,Globals.RT1_length)) != -1){
240                                        if (len != Globals.RT1_length){
241                                                logger.info("File " + rt1file + " invalid RT1 format!");
242                                                System.exit(0);
243                                        }
244                       
245                                        Road r = ParsingUtil.parseRoad(buffer);
246                                        if (r!=null){
247                                                roads.add(r);
248                                                if (MODIFYMAP){
249                                                        if (ids.indexOf((int)r.getId()) == -1 
250                                                                        && !r.getName().trim().equals("Lexington") 
251                                                                        && !r.getName().trim().equals("7th") 
252                                                                        && !r.getName().trim().equals("22nd") 
253                                                                        && !r.getName().trim().equals("35th") 
254                                                                        ){
255                                                                g.print(new String(buffer));
256                                                        }
257                                                        int last = r.points.size() - 1;
258                                                        /*if (
259                                                                        (((Point)r.points.get(0)).getLatitude() < 40.751221
260                                                                                        && ((Point)r.points.get(0)).getLatitude() > 40.737553
261                                                                                        && ((Point)r.points.get(0)).getLongitude() < -73.978051
262                                                                                        && ((Point)r.points.get(0)).getLongitude() > -73.993238)
263                                                                                        || (((Point)r.points.get(last)).getLatitude() < 40.751221
264                                                                                                        && ((Point)r.points.get(last)).getLatitude() > 40.737553
265                                                                                                        && ((Point)r.points.get(last)).getLongitude() < -73.978051
266                                                                                                        && ((Point)r.points.get(last)).getLongitude() > -73.993238)){
267                                                               
268//                                                              g.print(new String(buffer));
269                                                        }*/
270                                                }
271                                                         
272                                                                       
273        /*                                      //I used this section to find out the min/max latitude/longitude of the map                                     
274                                                if (((Point)r.points.get(0)).getLatitude() < minl)
275                                                        minl = ((Point)r.points.get(0)).getLatitude();
276                                                if (((Point)r.points.get(0)).getLatitude() > maxl)
277                                                        maxl = ((Point)r.points.get(0)).getLatitude();
278                                                if (((Point)r.points.get(1)).getLatitude() < minl)
279                                                        minl = ((Point)r.points.get(1)).getLatitude();
280                                                if (((Point)r.points.get(1)).getLatitude() > maxl)
281                                                        maxl = ((Point)r.points.get(1)).getLatitude();
282                                                if (((Point)r.points.get(0)).getLongitude() > minL)
283                                                        minL = ((Point)r.points.get(0)).getLongitude();
284                                                if (((Point)r.points.get(0)).getLongitude() < maxL)
285                                                        maxL = ((Point)r.points.get(0)).getLongitude();
286                                                if (((Point)r.points.get(1)).getLongitude() > minL)
287                                                        minL = ((Point)r.points.get(1)).getLongitude();
288                                                if (((Point)r.points.get(1)).getLongitude() < maxL)
289                                                        maxL = ((Point)r.points.get(1)).getLongitude();
290        */                              }else{
291                                                //System.out.println("-> null");
292                                        }
293                                }
294        /*                      System.out.println("minl " + minl);
295                                System.out.println("maxl " + maxl);
296                                System.out.println("minL " + minL);
297                                System.out.println("maxL " + maxL);
298        */                     
299                                f.close();
300                                if (MODIFYMAP){
301                                        g.close();
302                                }
303                                Collections.sort(roads);
304                        }catch (IOException e){
305                                logger.log(Level.SEVERE, "File "+rt1file+"not found", e);
306                                System.exit(0);
307                        }
308                }
309
310       
311       
312//      public void loadRoadsFromRT1File(String rt1file){
313//      /* loads segments from the RT1 file in the roads vector*/       
314//              DataInputStream f;
315//              PrintWriter g;                  //I used g when I wanted to create smaller TIGER files
316//              //from the original TIGER files. So, to create these small
317//              //smaller files I comment everything in the map constructor
318//              //but the calls to
319//              //                      loadRoadsFromRT1File
320//              //                      loadPointsFromRT2File
321//
322//              int len;
323//              byte[] buffer = new byte[Globals.RT1_length];
324//              //rt1file = "file://" + System.getProperty("user.dir") + rt1file;
325//              //System.out.println("New path is "+rt1file);
326//              try{
327//                      f = new DataInputStream(Utils.getInstance().openStream(rt1file));
328//              }catch(Exception e){
329//                      logger.log(Level.SEVERE, "File "+rt1file+" not found!", e);
330//                      System.exit(0);
331//                      return;
332//              }
333//
334//              ArrayList<Integer> ids = new ArrayList<Integer>();
335//              if (MODIFYMAP){
336//                      BufferedReader br = null;
337//                      try{
338//                              br = new BufferedReader(new InputStreamReader(Utils.getInstance().openStream("roadids.txt")));
339//                              String s;
340//                              while ((s = br.readLine())!=null){
341//                                      ids.add(Integer.parseInt(s));
342//                              }
343//                              br.close();
344//                      }catch(Exception e){
345//                              logger.log(Level.INFO, "File roadids.txt not found", e);
346//                      }
347//                      try{
348//                              g = new PrintWriter(new BufferedWriter(new FileWriter(System.getProperty("user.home")+File.separatorChar+"downtown2.RT1")));
349//                      }catch(IOException e){
350//                              logger.info("File downtown2.RT1 could not be open!");
351//                              g = null;
352//                      }
353//              }
354//
355//              try{
356//                      while ((len = f.read(buffer,0,Globals.RT1_length)) != -1){
357//                              if (len != Globals.RT1_length){
358//                                      logger.info("File " + rt1file + " invalid RT1 format!");
359//                                      System.exit(0);
360//                              }
361//             
362//                              Road r = ParsingUtil.parseRoad(buffer);
363//                              if (r!=null){
364//                                      roads.add(r);
365//                                      if (MODIFYMAP){
366//                                              if (ids.indexOf((int)r.getId()) == -1
367//                                                              && !r.getName().trim().equals("Lexington")
368//                                                              && !r.getName().trim().equals("7th")
369//                                                              && !r.getName().trim().equals("22nd")
370//                                                              && !r.getName().trim().equals("35th")
371//                                                              ){
372//                                                      g.print(new String(buffer));
373//                                              }
374//                                              int last = r.points.size() - 1;
375//                                              /*if (
376//                                                              (((Point)r.points.get(0)).getLatitude() < 40.751221
377//                                                                              && ((Point)r.points.get(0)).getLatitude() > 40.737553
378//                                                                              && ((Point)r.points.get(0)).getLongitude() < -73.978051
379//                                                                              && ((Point)r.points.get(0)).getLongitude() > -73.993238)
380//                                                                              || (((Point)r.points.get(last)).getLatitude() < 40.751221
381//                                                                                              && ((Point)r.points.get(last)).getLatitude() > 40.737553
382//                                                                                              && ((Point)r.points.get(last)).getLongitude() < -73.978051
383//                                                                                              && ((Point)r.points.get(last)).getLongitude() > -73.993238)){
384//                                                     
385////                                                    g.print(new String(buffer));
386//                                              }*/
387//                                      }
388//                                               
389//                                                             
390///*                                    //I used this section to find out the min/max latitude/longitude of the map                                     
391//                                      if (((Point)r.points.get(0)).getLatitude() < minl)
392//                                              minl = ((Point)r.points.get(0)).getLatitude();
393//                                      if (((Point)r.points.get(0)).getLatitude() > maxl)
394//                                              maxl = ((Point)r.points.get(0)).getLatitude();
395//                                      if (((Point)r.points.get(1)).getLatitude() < minl)
396//                                              minl = ((Point)r.points.get(1)).getLatitude();
397//                                      if (((Point)r.points.get(1)).getLatitude() > maxl)
398//                                              maxl = ((Point)r.points.get(1)).getLatitude();
399//                                      if (((Point)r.points.get(0)).getLongitude() > minL)
400//                                              minL = ((Point)r.points.get(0)).getLongitude();
401//                                      if (((Point)r.points.get(0)).getLongitude() < maxL)
402//                                              maxL = ((Point)r.points.get(0)).getLongitude();
403//                                      if (((Point)r.points.get(1)).getLongitude() > minL)
404//                                              minL = ((Point)r.points.get(1)).getLongitude();
405//                                      if (((Point)r.points.get(1)).getLongitude() < maxL)
406//                                              maxL = ((Point)r.points.get(1)).getLongitude();
407//*/                            }else{
408//                                      //System.out.println("-> null");
409//                              }
410//                      }
411///*                    System.out.println("minl " + minl);
412//                      System.out.println("maxl " + maxl);
413//                      System.out.println("minL " + minL);
414//                      System.out.println("maxL " + maxL);
415//*/                   
416//                      f.close();
417//                      if (MODIFYMAP){
418//                              g.close();
419//                      }
420//                      Collections.sort(roads);
421//              }catch (IOException e){
422//                      logger.log(Level.SEVERE, "File "+rt1file+"not found", e);
423//                      System.exit(0);
424//              }
425//      }
426       
427
428       
429        public void loadPointsFromRT2File(String rt2file){
430        /* parse RT2 file and load additional points for the segments
431         * already read from the RT1 file*/     
432               
433                DataInputStream f;
434                PrintWriter g;
435                int len;
436                byte[] buffer = new byte[Globals.RT2_length];
437               
438                try{
439                        f = new DataInputStream(Utils.getInstance().openStream(rt2file));
440                }catch(Exception e){
441                        logger.log(Level.SEVERE, "File "+rt2file+" not found", e);
442                        System.exit(0);
443                        return;
444                }
445                /*try{
446                        f = new RandomAccessFile(rt2file,"r");
447                }catch(FileNotFoundException e){
448                        System.out.println("File " + rt2file + " not found!");
449                        System.exit(0);
450                        return;
451                }*/
452                ArrayList<Integer> ids = new ArrayList<Integer>();
453                if (MODIFYMAP){
454                        try{
455                                g = new PrintWriter(new BufferedWriter(new FileWriter(System.getProperty("user.home")+File.separatorChar+"downtown2.RT2")));
456                                //g = new PrintWriter(
457                                //              new BufferedWriter(new FileWriter("downtown2.RT2")));
458                        }catch(IOException e){
459                                logger.info("File downtown2.RT2 could not be open");
460                                //System.out.println("File NJTurnpike2.RT2 could not be open!");
461                                System.exit(0);
462                                return;
463                        }
464                        BufferedReader br = null;
465                        try{
466                                br = new BufferedReader(new FileReader(new File("roadids.txt")));
467                                String s;
468                                while ((s = br.readLine())!=null){
469                                        ids.add(Integer.parseInt(s));
470                                }
471                                br.close();
472                        }catch(IOException e){
473                                e.printStackTrace();
474                        }
475                }
476                try{
477                        while ((len = f.read(buffer,0,Globals.RT2_length)) != -1){
478                                if (len != Globals.RT2_length){
479                                        System.out.println("File " + rt2file + " invalid RT2 format!");
480                                        System.exit(0);
481                                }
482                               
483                                Road r = new Road();
484                                r.setId( Long.parseLong(new String(buffer, 5, 10).trim()) );
485                                int idx = Collections.binarySearch(roads,r);
486                                if (idx >= 0){
487                                        r = (Road)roads.get(idx);
488                                       
489                                        if (MODIFYMAP){
490//                                              if (ids.indexOf((int)r.getId()) == -1){
491//                                              g.print(new String(buffer));
492//                                              }
493                                                int last = r.points.size() - 1;
494                                                if (
495                                                                (((Point)r.points.get(0)).getLatitude() < 40.751221
496                                                                                && ((Point)r.points.get(0)).getLatitude() > 40.737553
497                                                                                && ((Point)r.points.get(0)).getLongitude() < -73.978051
498                                                                                && ((Point)r.points.get(0)).getLongitude() > -73.993238)
499                                                                                || (((Point)r.points.get(last)).getLatitude() < 40.751221
500                                                                                                && ((Point)r.points.get(last)).getLatitude() > 40.737553
501                                                                                                && ((Point)r.points.get(last)).getLongitude() < -73.978051
502                                                                                                && ((Point)r.points.get(last)).getLongitude() > -73.993238)){
503//                                                      g.print(new String(buffer));
504                                                }
505                                        }
506                                       
507                                       
508                                        for (int i=0;i<10;i++){
509                                                Point p = ParsingUtil.parsePoint(new String(buffer, 18 + i*19, 19).getBytes());
510                                                if (p.getLatitude() != 0.0 && p.getLongitude() != 0.0){
511                                                        /* for multiple RT2 records, assume the points
512                                                         * are all ordered nicely
513                                                         */
514                                                        r.points.add(r.points.size()-1,p);
515                                                }
516                                        }
517                                }
518                        }
519                        f.close();
520                        if (MODIFYMAP){
521                                g.close();
522                        }
523                        Collections.sort(roads);
524                }catch (IOException e){
525                        System.out.println("File " + rt2file + " invalid format!");
526                        System.exit(0);
527                }
528        }
529       
530        private final void createMapsDir() {
531                // create local path...
532                final String dir = System.getProperty("user.home")+File.separatorChar+"maps";
533                File f = new File(dir);
534                if (!f.exists())
535                        f.mkdirs();
536        }
537       
538        public void mergeRoadSegments(String rt1file){
539        /* the goal of this function is to eliminate prev and next information in road structure
540         * by merging road segments with the same name*/
541                ArrayList<Road> roads_aux = new ArrayList<Road>(); 
542                int[] v = new int[roads.size()]; 
543                int next,prev;
544                BufferedReader f=null;
545                boolean needAdjacencyFile = false;
546/*      As an optimization, a file with adjacency information is created in the current
547 *      directory, and any following execution of this program will avoid O(n^2) complexity
548 *      of completing next and previous fields for each segment. The file will have the name
549 *      of the RT1 file written on the first line, in order to know wich map it is associated with
550 *      On each line there will be <currentRoadIndex> <NextRoadIndex>
551 */             
552                try{
553                        f = new BufferedReader(new InputStreamReader(Utils.getInstance().openStream("/maps/adjacency.txt")));
554                }catch(Exception e){
555                        needAdjacencyFile = true;
556                }
557
558                if (f!=null){
559                       
560                        try{
561                                String s = f.readLine();
562                                if (!rt1file.equals(s)){
563                                        logger.info("Inconsistent adjacency file, recreating...");
564                                        f.close();
565                                        // create local path...
566                                        createMapsDir();
567                                        // delete previous existing file...
568                                        (new File(System.getProperty("user.home")+File.separatorChar+"maps"+File.separatorChar+"adjacency.txt")).delete();
569                                        needAdjacencyFile = true;
570                                }
571                        }catch(IOException e){
572                                logger.warning("Error reading file adjacency.txt");
573                                try {
574                                        f.close();
575                                        // create local path...
576                                        createMapsDir();
577                                        // delete previous existing file...
578                                        (new File(System.getProperty("user.home")+File.separatorChar+"maps"+File.separatorChar+"adjacency.txt")).delete();
579                                        needAdjacencyFile = true;
580                                } catch (Exception ex) {
581                                        logger.log(Level.SEVERE, "Error creating file adjacency... ", ex);
582                                        System.exit(0);
583                                }
584                        }
585                }
586                       
587                if (needAdjacencyFile){
588                        System.out.println("Adjacency file does not exist - wait while it is being built...");
589                        buildAdjacencyFile(rt1file);
590                       
591                        try{
592                                createMapsDir();
593                                f = new BufferedReader(new InputStreamReader(new FileInputStream(System.getProperty("user.home")+File.separatorChar+"maps"+File.separatorChar+"adjacency.txt")));
594                        }catch(Exception e){
595                                logger.log(Level.SEVERE, "Adjacency file was not built...", e);
596                                System.exit(0);
597                        }
598                        try{
599                                String s = f.readLine();
600                                String rt1filename=new File(rt1file).getName();
601                                if (!rt1filename.equals(s)){
602                                        f.close();
603                                        logger.severe("Error: Adjacency file was built wrong");
604                                        System.exit(0);
605                                }
606                        }catch(IOException e){
607                                logger.log(Level.SEVERE, "Error reading locally built file adjacency.txt", e);
608                                System.exit(0);
609                        }
610                }
611               
612                //complete next an prev fields for each segment
613                try{
614                        String line;
615                        while ((line = f.readLine())!=null){
616                                //System.out.println("**" + line);
617                               
618                                int i = Integer.parseInt(line.substring(0, line.indexOf(" ")));
619                                int j = Integer.parseInt(line.substring(line.indexOf(" ")+1, line.length()));
620                                v[i] = 0;
621                                v[j] = 0;
622                                Road r1 = (Road)roads.get(i);
623                                Road r2 = (Road)roads.get(j);
624                                r1.setNextRdIdx(j);
625                                r2.setPrevRdIdx(i);
626                        }
627                        f.close();
628                }catch(IOException e){
629                        logger.severe("Error reading adjacency file ");
630                        System.exit(0);
631                        return;
632                }
633               
634//              for (int i = 0; i<roads.size(); i++)
635//                      v[i] = 0;
636//             
637                //merge segments using next & prev connections between segments
638                int loops = 0;
639                for (int i = 0; i<roads.size(); i++){
640                        if (v[i] != 0)
641                                continue;
642                        Road r = (Road)roads.get(i);
643                        prev = i;
644                        while (r.getPrevRdIdx() != i && r.getPrevRdIdx() != -1){
645                                prev = r.getPrevRdIdx();
646                                r = (Road)roads.get(prev);
647                        }
648                        roads_aux.add(r);
649                        if (r.getPrevRdIdx() != -1){
650                                v[i] = 1;
651                                loops++;
652                                continue;       //if the road has loops we will consider each road segment
653                        }                               // a different road as if it had a different name
654                        v[prev] = 1;
655                        while ((next = r.getNextRdIdx()) != -1){
656                                Road r2 = (Road)roads.get(next);
657                                if (v[next] == 1){
658                                        System.out.println("Error: bad road segments adjacency");
659                                        System.exit(0);
660                                }
661                                v[next] = 1;
662                               
663                                r.setNextRdIdx(r2.getNextRdIdx());
664                               
665                                r2.points.remove(0);
666                                r.points.addAll(r2.points);
667                               
668                        }
669                }
670                roads = roads_aux;
671                logger.info("Loops " + loops);
672        }
673       
674        public void buildAdjacencyFile(String rt1file){
675                /* for every two segments that have a common end and the same name
676                 * compute next and prev fields
677                 */
678                RandomAccessFile f;
679                try{
680                        createMapsDir();
681                        // delete previous existing file...
682                        (new File(System.getProperty("user.home")+File.separatorChar+"maps"+File.separatorChar+"adjacency.txt")).delete();
683                        f = new RandomAccessFile(System.getProperty("user.home")+File.separatorChar+"maps"+File.separatorChar+"adjacency.txt","rw");   
684                }catch(FileNotFoundException e){
685                        System.out.println("Error creating file");
686                        System.exit(0);
687                        return;
688                }
689               
690                try{
691                        File ftest=new File(rt1file);
692
693                        StringBuffer sb = new StringBuffer(ftest.getName());
694                        sb.append("\n");
695                        f.writeBytes(sb.toString());
696                       
697                        for (int i = 0; i<roads.size(); i++){
698                                Road r1 = (Road)roads.get(i);
699                                Point p0 = (Point)r1.points.get(0);
700                                Point p1 = (Point)r1.points.get(r1.points.size()-1);
701                                for (int j = i+1; j<roads.size(); j++){
702                                        Road r2 = (Road)roads.get(j);
703                                        Point p10 = (Point)r2.points.get(0);
704                                        Point p11 = (Point)r2.points.get(r2.points.size()-1);
705                                       
706                                        if (r1.getName().equals(r2.getName())){
707                                                if (p0.equals(p11)){
708                                                        if (r1.getPrevRdIdx() == -1 && r2.getNextRdIdx() == -1){
709                                                                StringBuffer s = new StringBuffer();
710                                                                s.append(j).append(" ").append(i).append("\n");
711                                                                //System.out.println(s.toString());
712                                                                f.writeBytes(s.toString());
713                                                                r2.setNextRdIdx(i);
714                                                                r1.setPrevRdIdx(j);
715                                                        }
716                                                }
717                                                if (p1.equals(p10)){
718                                                        if (r1.getNextRdIdx() == -1 && r2.getPrevRdIdx() == -1){
719                                                                StringBuffer s = new StringBuffer();
720                                                                s.append(i).append(" ").append(j).append("\n");
721                                                                //System.out.println(s.toString());
722                                                                f.writeBytes(s.toString());
723                                                                r2.setPrevRdIdx(i);
724                                                                r1.setNextRdIdx(j);
725                                                        }
726                                                }
727                                                if (p0.equals(p10)){
728                                                }
729                                                if (p1.equals(p11)){
730                                                }
731                                        }
732                                }
733                       
734                        }
735                        f.close();
736
737                }catch(IOException e){
738                        System.out.println("Error writing adjacency file!");
739                        System.exit(0);
740                }
741
742        }
743       
744        /**
745         * add crosses for each road by traversing the sorted PeanoKey vector and
746         * detecting equal values corresponding to points on different roads
747         **/ 
748        public void addCrossroads(){
749                int cno=0;
750                for (int i = 0; i < peanoKeys.size(); i++){
751                        PeanoKey pk1 = (PeanoKey)peanoKeys.get(i);
752                        Road r1 = (Road)roads.get(pk1.getRoadIndex());
753                        int j = i+1;
754                        while (j<peanoKeys.size()){ 
755                                PeanoKey pk2 = (PeanoKey)peanoKeys.get(j);
756                                if (pk1.compareTo(pk2) == 0){//they have the same value
757                                        cno ++;
758                                        Road r2 = (Road)roads.get(pk2.getRoadIndex());
759                                        r1.crosses.add(new Cross(pk1.getRoadIndex(), pk1.getPointIndex(), pk2.getRoadIndex(), pk2.getPointIndex()));
760                                        r2.crosses.add(new Cross(pk2.getRoadIndex(), pk2.getPointIndex(), pk1.getRoadIndex(), pk1.getPointIndex()));
761                                }
762                                else 
763                                        break;
764                                j++;   
765                        }
766                }
767                logger.info("Done building the map " + cno + " crosses");
768        }
769       
770        public PeanoKey findClosestPeanoKey(Point gpsPoint){
771                //given a gps point with latitude end longitude, the function tries to find
772                //the closest point on a road on the map, by using the PeanoKey mechanism
773                        PeanoKey searchpk = new PeanoKey(gpsPoint);
774                       
775                       
776                        int idx = Collections.binarySearch(peanoKeys, searchpk);
777                        if (idx >= 0)
778                                return ((PeanoKey)peanoKeys.get(idx));
779                        int insertIdx = -(idx + 1);
780//                      System.out.println("Key " + new String(searchpk.getValue())+ " - insert at " + insertIdx);
781                       
782                        double mindist = Globals.CLOSEST_PEANOKEY_MAXDIST;
783                        int pkIdx = -1;
784                        int j = 1;
785                        while (j <= Globals.PEANOKEY_SEARCH_RANGE && insertIdx - j >= 0){
786                                PeanoKey pk = (PeanoKey)peanoKeys.get(insertIdx-j);
787                                Point p = (Point)((Road)roads.get(pk.getRoadIndex())).points.get(pk.getPointIndex());
788                                double dist = gpsPoint.distanceTo(p);
789//                              System.out.println("\t"+new String(pk.getValue())+" "+((Road)roads.get(pk.getRoadIndex())).getName().trim() + " - " +
790//                                              ((Road)roads.get(pk.getRoadIndex())).getId() + " - point " +
791//                                              pk.getPointIndex() + " / " + ((Road)roads.get(pk.getRoadIndex())).points.size()
792//                                              + " distance: " + dist);
793                                if (dist < mindist) {
794                                        mindist = dist;
795                                        pkIdx = insertIdx-j;
796                                }
797                                j++;
798                        }
799                       
800                        j = 0;
801                        while (j < Globals.PEANOKEY_SEARCH_RANGE && insertIdx + j < peanoKeys.size()){
802                                PeanoKey pk = (PeanoKey)peanoKeys.get(insertIdx+j);
803                                Point p = (Point)((Road)roads.get(pk.getRoadIndex())).points.get(pk.getPointIndex());
804                                double dist = gpsPoint.distanceTo(p);
805//                              System.out.println("\t"+new String(pk.getValue())+" "+((Road)roads.get(pk.getRoadIndex())).getName().trim() + " - " +
806//                                              ((Road)roads.get(pk.getRoadIndex())).getId() + " - point " +
807//                                              pk.getPointIndex() + " / " + ((Road)roads.get(pk.getRoadIndex())).points.size()
808//                                              + " distance: " + dist);
809                                if (dist < mindist){
810                                        mindist = dist;
811                                        pkIdx = insertIdx+j;
812                                }
813                                j++;
814                        }
815                        if (pkIdx == -1)
816                                return null;
817                        return (PeanoKey)peanoKeys.get(pkIdx);
818        }
819
820        /**
821         * After loading the crossroad this method is called in order to add all auxiliary intersections.
822         */
823        public void addIntersections() {
824                for(int i=0;i<roads.size();i++) {
825                        Collections.sort(roads.get(i).crosses, new Comparator<Cross>() {
826                                public int compare(Cross c1, Cross c2) {
827                                        if(c1.pointIndex<c2.pointIndex)
828                                                return -1;
829                                        if(c1.pointIndex>c2.pointIndex)
830                                                return 1;
831                                        if(c1.pointIndex==c2.pointIndex) {
832                                                //compare crossRoadIndices
833                                                if(c1.crossRoadIndex<c2.crossRoadIndex) {
834                                                        return -1;
835                                                } else
836                                                        return 1;
837                                        }
838                                        return 0;
839                                }
840                        });
841                }
842               
843                //init indices with -1
844//              for(int i=0;i<roads.size();i++) {
845//                      for(int j=0;j<Globals.map.roads.get(i).crosses.size();j++) {
846//                              Globals.map.roads.get(i).crosses.get(j).intersectionIndex=-1;
847//                      }
848//              }
849
850                for(int i=0;i<roads.size();i++) {
851                        Road r=roads.get(i);
852                        for(int j=0;j<r.crosses.size();j++) {
853                                Cross c=r.crosses.get(j);
854                                if(c.intersectionIndex==-1) {
855                                        //try to find all concurrent roads (in this intersection)
856                                        //create a new Intersection object
857                                        c.intersectionIndex=allIntersections.size();
858                                        IntersectionWithoutTrafficLights inters=new IntersectionWithoutTrafficLights();
859                                        if(c.pointIndex>0) 
860                                                inters.addCrossingSegment(new DirectedRoadSegment(i, c.pointIndex, false));
861                                        if(c.pointIndex<r.points.size()-1)
862                                                inters.addCrossingSegment(new DirectedRoadSegment(i, c.pointIndex, true));
863                                                                               
864                                        Road otherRoad=roads.get(c.crossRoadIndex);
865                                       
866                                        for(int k=0;k<otherRoad.crosses.size();k++) {
867                                                Cross otherCross=otherRoad.crosses.get(k);
868                                                if(otherCross.crossRoadIndex==i && otherCross.crossPointIndex==c.pointIndex) {
869                                                        //that's the one
870                                                        otherCross.intersectionIndex=allIntersections.size();
871                                                        break;
872                                                }
873                                        }
874                                        if(c.crossPointIndex>0)
875                                                inters.addCrossingSegment(new DirectedRoadSegment(c.crossRoadIndex, c.crossPointIndex, false));
876                                        if(c.crossPointIndex<otherRoad.points.size()-1)
877                                                inters.addCrossingSegment(new DirectedRoadSegment(c.crossRoadIndex, c.crossPointIndex, true));
878
879                                        //also check if there are other crosses in the same point
880                                        while(j+1 < r.crosses.size()) {
881                                                Cross c2=r.crosses.get(j+1);
882                                                if(c2.pointIndex==c.pointIndex) {
883                                                        //also add these segments
884                                                        c2.intersectionIndex=allIntersections.size();
885                                                        if(c2.pointIndex>0) 
886                                                                inters.addCrossingSegment(new DirectedRoadSegment(i, c2.pointIndex, false));
887                                                        if(c2.pointIndex<r.points.size()-1)
888                                                                inters.addCrossingSegment(new DirectedRoadSegment(i, c2.pointIndex, true));
889                                                       
890                                                        Road otherRoad2=roads.get(c2.crossRoadIndex);
891                                                       
892                                                        for(int k=0;k<otherRoad2.crosses.size();k++) {
893                                                                Cross otherCross2=otherRoad2.crosses.get(k);
894                                                                if(otherCross2.crossRoadIndex==i && otherCross2.crossPointIndex==c2.pointIndex) {
895                                                                        //that's the one
896                                                                        otherCross2.intersectionIndex=allIntersections.size();
897                                                                        break;
898                                                                }
899                                                        }
900                                                        if(c2.crossPointIndex>0)
901                                                                inters.addCrossingSegment(new DirectedRoadSegment(c2.crossRoadIndex, c2.crossPointIndex, false));
902                                                        if(c2.crossPointIndex<otherRoad2.points.size()-1)
903                                                                inters.addCrossingSegment(new DirectedRoadSegment(c2.crossRoadIndex, c2.crossPointIndex, true));
904                                                        j++;
905                                                } else
906                                                        break;
907                                        }
908                                        //finally add the object
909                                        allIntersections.add(inters);
910                                        System.out.println("### Intersection no " + Globals.map.allIntersections.size()
911                                                        + " " + Globals.map.allIntersections.toString());
912                                } else {
913                                        while(j+1 < r.crosses.size()) {
914                                                Cross c2=r.crosses.get(j+1);
915                                                if(c2.pointIndex==c.pointIndex) {
916                                                        c2.intersectionIndex=c.intersectionIndex;
917                                                        j++;
918                                                } else 
919                                                        break;
920                                        }
921                                }
922                        }
923                }
924               
925        }
926
927        public void checkIntersections() {
928                try {
929                        for(int i=0;i<Globals.map.roads.size();i++) {
930                                Road r=Globals.map.roads.get(i);
931                                for(int j=0;j<r.crosses.size();j++) {
932                                        Cross c=r.crosses.get(j);
933                                        Road crossRoad=Globals.map.roads.get(c.crossRoadIndex);
934                                        for(int k=0;k<crossRoad.crosses.size();k++) {
935                                                Cross otherCross=crossRoad.crosses.get(k);
936                                                if(otherCross.pointIndex==c.crossPointIndex) {
937                                                        //that's the one;
938                                                        if(c.intersectionIndex!=otherCross.intersectionIndex) {
939                                                                logger.severe("ERROR! INTERSECTIONS WRONG!!! ");
940                                                                logger.severe("Road:"+i+";Pt="+c.pointIndex+"; INDEX="+c.intersectionIndex);
941                                                                logger.severe("Road:"+c.crossRoadIndex+";Pt="+otherCross.pointIndex+"; INDEX="+otherCross.intersectionIndex);
942                                                        }
943                                                        break;
944                                                }
945                                        }
946                                }
947                        }
948                } catch (Exception ex) {
949                        logger.severe("ERROR! INTERSECTIONS WRONG!!! : "+ex.toString());
950                        ex.printStackTrace();
951                        return;
952                }
953                logger.info("ALL INTERSECTIONS="+allIntersections.size());
954        }
955
956       
957        /* Szekeres A. START_MODIFY */
958        /* Change from WirelessTrafficLights to EmissionsTrafficLights*/
959        public void changeToEmissionsTrafficLights()
960        {
961                for(int i=0;i<allIntersections.size();i++) {
962                        if (allIntersections.get(i) instanceof WirelessTrafficLight)
963                        {
964                                WirelessTrafficLight in = (WirelessTrafficLight)allIntersections.get(i);
965                                allIntersections.set(i, 
966                                                new EmissionsTrafficLight(in));
967                        }
968                }
969        }
970        /* Szekeres A. STOP_MODIFY*/
971       
972        public void createTrafficLights(Random generator) {
973                //ArrayList<IntersectionWithoutTrafficLights> without=new ArrayList<IntersectionWithoutTrafficLights> ();
974                for(int i=0;i<allIntersections.size();i++) {
975                        if(allIntersections.get(i).segments.size()<=2) {
976                                continue;
977                        }
978//                      if(generator.nextBoolean()) {
979                       
980                        //if(true && roads.size() > 5 && !roads.get(5).getName().startsWith("New Jersey")) {
981                        // changed the if condition for cityPlan scenario to work
982                        if(roads.size()>1) {
983                                //change it into a traffic lights intersection
984                                WirelessTrafficLight newInters=new WirelessTrafficLight();
985//                              IntersectionWithTrafficLights newInters=new IntersectionWithTrafficLights();
986                                IntersectionWithoutTrafficLights oldInters=(IntersectionWithoutTrafficLights) allIntersections.get(i);
987                                for(int j=0;j<oldInters.segments.size();j++) {
988                                        newInters.addCrossingSegment(oldInters.segments.get(j));
989                                }
990                                for(int j=0;j<oldInters.segments.size();j++) {
991                                        DirectedRoadSegment seg1 = (DirectedRoadSegment)oldInters.segments.get(j);
992                                        for (int k = 0; k < oldInters.segments.size(); k++){
993                                                DirectedRoadSegment seg2 = (DirectedRoadSegment)oldInters.segments.get(k);
994                                                if (k!= j){
995                                                        double angle = seg1.angle - seg2.angle;
996                                                        if (angle < 0)
997                                                                angle = 360 + angle;
998                                                        if (angle < 190 && angle > 170)
999                                                                seg1.front = seg2;
1000                                                        if (angle >= 190)
1001                                                                seg1.right = seg2;
1002                                                        if (angle <= 170)
1003                                                                seg1.left = seg2;
1004                                                }
1005                                        }
1006                                }
1007//                              newInters.lightInfos=new ArrayList<TrafficLightInfo> ();
1008                                //green duration for priority roads
1009        //                      int green=(int)(20.0+30.0*generator.nextDouble());
1010                                int green=37;
1011                                if (!roads.get(0).getName().startsWith("Iuliu")){
1012                                        //!apaca
1013                                        green = 30;
1014                                }
1015                                int time=0;
1016                                int j = 2;
1017                                if (roads.get(0).getName().startsWith("Dr ") && i == 1){
1018                                        green = 30;
1019                                }
1020                                newInters.segments.get(0).setLightInfo(new TrafficLightInfo(0, green));
1021                                if (roads.get(0).getName().startsWith("Dr ") && i == 1){
1022                                        green = 45;
1023                                }
1024                                newInters.segments.get(1).setLightInfo(new TrafficLightInfo(0, green));
1025                                time=time + green + Globals.DEFAULT_YELLOW_TIME + Globals.DEFAULT_ALL_RED;
1026                               
1027                                if (roads.get(0).getName().startsWith("Iuliu") && i == 1){
1028                                        newInters.segments.get(2).setLightInfo(new TrafficLightInfo(time, time + green));
1029                                        time=time + green + Globals.DEFAULT_YELLOW_TIME + Globals.DEFAULT_ALL_RED;
1030                                        newInters.segments.get(3).setLightInfo(new TrafficLightInfo(time, time + green));
1031                                        time=time + green + Globals.DEFAULT_YELLOW_TIME + Globals.DEFAULT_ALL_RED;
1032                                        j = 4;
1033                                }                               
1034                                for(;j<oldInters.segments.size();j++) {
1035                                        if(oldInters.segments.get(j).isExitOnly()) {
1036                                                newInters.segments.get(j).setLightInfo(new TrafficLightInfo(time, time));
1037                                                if (j % 2 == 1){
1038                                                        if (!oldInters.segments.get(j-1).isExitOnly());
1039                                                                time=time+green+Globals.DEFAULT_YELLOW_TIME + Globals.DEFAULT_ALL_RED;
1040                                                }
1041                                                continue;
1042                                        }
1043//                                      green=(int)(10.0+10.0*generator.nextDouble());
1044                                        green = 30;
1045                                        newInters.segments.get(j).setLightInfo(new TrafficLightInfo(time, time+green));
1046                                        if (j % 2 == 0) 
1047                                                time=time+green+Globals.DEFAULT_YELLOW_TIME + Globals.DEFAULT_ALL_RED;
1048                                }
1049                                newInters.cycleLength=time;
1050                                allIntersections.set(i, newInters);
1051                                lightsIndices.add(new Integer(i));
1052                        } 
1053                }
1054        }
1055
1056        private void setLaneNoRandom(Random generator) {
1057                for(int i=0;i<roads.size();i++) {
1058                        Road r=roads.get(i);
1059                        double d;
1060                        switch(r.roadinfo[1]) {
1061                                case 49:
1062                                        d=generator.nextDouble();
1063                                        if(d<0.33) 
1064                                                r.laneNo=5;
1065                                        else if(d<0.66)
1066                                                r.laneNo=4;
1067                                        else r.laneNo=3;
1068                                        break;
1069                                case 50:
1070                                        d=generator.nextDouble();
1071                                        if(d<0.33) 
1072                                                r.laneNo=4;
1073                                        else if(d<0.66)
1074                                                r.laneNo=3;
1075                                        else r.laneNo=2;
1076                                        break;
1077                                case 51:
1078                                        d=generator.nextDouble();
1079                                        if(d<0.50) 
1080                                                r.laneNo=3;
1081                                        else r.laneNo=2;
1082                                        break;
1083                                case 52:
1084                                        d=generator.nextDouble();
1085                                        if(d<0.33) 
1086                                                r.laneNo=2;
1087                                        else r.laneNo=1;
1088                                        break;
1089                                default:
1090                        }
1091                }
1092        }
1093
1094        /**
1095         * Sets the lower and lowest points on the map, given the earth coordinates.
1096         */
1097        public void getMinAndMaxPoint() {
1098                // sets the Globals.minPoint and Globals.maxPoint
1099                // with the determined values
1100                Map currentMap;
1101                Point tmpPoint, minPoint, maxPoint;
1102                Road tmpRoad;
1103                int i, j;
1104                i = 0;
1105                currentMap = Globals.map;
1106
1107                minPoint = new Point((double) 180, (double) 90);
1108                maxPoint = new Point((double) -180, (double) -90);
1109                while (i < currentMap.roads.size()) {
1110                        tmpRoad = (Road) currentMap.roads.get(i);
1111                        j = 0;
1112                        while (j < tmpRoad.points.size()) {
1113                                tmpPoint = (Point) tmpRoad.points.get(j);
1114                                if (tmpPoint.getLatitude() < minPoint.getLatitude()) {
1115                                        minPoint.setLatitude(tmpPoint.getLatitude());
1116                                }
1117                                if (tmpPoint.getLongitude() < minPoint.getLongitude()) {
1118                                        minPoint.setLongitude(tmpPoint.getLongitude());
1119                                }
1120
1121                                if (tmpPoint.getLatitude() > maxPoint.getLatitude()) {
1122                                        maxPoint.setLatitude(tmpPoint.getLatitude());
1123                                }
1124                                if (tmpPoint.getLongitude() > maxPoint.getLongitude()) {
1125                                        maxPoint.setLongitude(tmpPoint.getLongitude());
1126                                }
1127
1128                                j++;
1129                        }
1130                        i++;
1131                }
1132                this.minPoint = minPoint;
1133                this.maxPoint = maxPoint;
1134        }
1135       
1136        public void setLaneNoExtra() {
1137//Intersection
1138                if (roads.get(0).getName().startsWith("Calculatoare")){
1139                        roads.get(0).laneNo=3;
1140                        roads.get(1).laneNo=2;
1141                }
1142               
1143                if (roads.get(0).getName().startsWith("Iuliu")){
1144//                              Apaca
1145                        roads.get(0).laneNo=3;
1146                        roads.get(1).laneNo=4;
1147                        roads.get(2).laneNo=3;
1148                }
1149        }
1150}
Note: See TracBrowser for help on using the repository browser.