source: tmcsimulator/trunk/webapps/GTEC/js/vdsLayer.js @ 570

Revision 570, 14.2 KB checked in by jdalbey, 6 years ago (diff)

GTEC vdsLayer.js Add time autoincrement.

Line 
1var postmileList = [];  // the list of postmiles saved from the json file.
2var chosenColor = "yellow"; // stores color that user picks, initial default yellow
3
4// function to find differences between two arrays
5Array.prototype.diff = function(a) {
6    return this.filter(function(i) {return a.indexOf(i) < 0;});
7};
8
9    // Build a solid colored icon to use instead of the classic pin
10    function dotSymbol(color) 
11    {
12        var iconPath = iconVDSwhite;
13        if (color == 'red')
14        {
15           iconPath = iconVDSred;
16        }
17        else if (color == 'yellow')
18        {
19            iconPath = iconVDSyellow;
20        }
21        else if (color == 'lime')
22        {
23            iconPath = iconVDSgreen;
24        }
25        return {
26            url: iconPath, 
27            anchor: new google.maps.Point(6, 6)
28        };
29    }
30
31    // Load the map data from a json file and style all the points
32    function loadVDSlayer()
33    {
34        // Load the static map data and call saveCoords when done
35        map.data.loadGeoJson(kMapStartupFile, null, saveCoords)
36        // Style the map data by applying the desired properties to each feature (marker)
37        // The function will be called every time a feature's properties are updated.
38        map.data.setStyle(function(feature)
39        {
40            // Get the postmile id
41            var name = feature.getId();
42            // Get the desired color value
43            var ptColor = feature.getProperty("color");
44            var street = feature.getProperty("street");
45            // Build the marker
46            var iconSymbol = dotSymbol(ptColor);
47            // return the StyleOptions
48            return {
49                icon: iconSymbol,
50                title: name + " @" + street, // set rollover text
51                // set zIndex for slowed traffic to a higher value so they overlap
52                zIndex: colorZvalues[ptColor]
53            };
54        });
55        var clicked = false; 
56        var first = []; // stores first dot
57        var asc = false; //ascending
58        //var color_arr = [];
59        var white_arr = []; //stores all white dots
60        // Initialize the current time to zero
61        var currentTime = new Date(0);
62        currentTime.setHours(0);
63        currentTime.setMinutes(0);
64        currentTime.setSeconds(0);
65
66        map.data.addListener('click', function(event) 
67        {
68            var event_arr = event.feature.getId().split(/[ ,]+/);
69            // if user has already made the first click and the second click is
70            // on the same highway and same direction
71            if (clicked && event_arr[0] === first[0] && event_arr[1] === first[1])
72            {
73                // compute range between the two clicked dots
74                var range = Math.abs(parseFloat(event_arr[2]) - parseFloat(first[2]));
75                var clicked_dots = [];
76                // checks highway direction to determine if postmiles are ascending or descending
77                if (parseFloat(event_arr[2]) < parseFloat(first[2]))
78                {
79                    asc = false;
80                }
81                else 
82                {
83                    asc = true;
84                }
85                // searches map for all dots between the two clicked dots and adds it to list "clicked_dots"
86                map.data.forEach(function (marker) 
87                {
88                    var marker_arr = marker.getId().split(/[ ,]+/);
89                    // if the dot in the map matches the highway and direction of the clicked dot
90                    if (marker_arr[0] === event_arr[0] && marker_arr[1] === event_arr[1])
91                    {
92                        // compute distance based on direction of highway
93                        if (asc)
94                        {
95                            var dist = parseFloat(marker_arr[2]) - parseFloat(first[2]);
96                        }
97                        else 
98                        {
99                            var dist = parseFloat(parseFloat(first[2]) - (marker_arr[2]));
100                        }
101                        // if dist within range of the two clicked dots, add to list "clicked_dots"
102                        if (dist <= range && dist >= 0)
103                        {
104                            clicked_dots.push(marker);
105                        }
106                    }
107                });
108                //color_arr.push(clicked_dots);
109                //console.log(clicked_dots);
110                //console.log(range);
111                // extracts ids for all the white dots
112                var white_arr_ids = white_arr.map(function (marker) {
113                    return marker.id;
114                });
115                // extracts ids for all the clicked dots
116                var clicked_dots_ids = clicked_dots.map(function (marker) {
117                    return marker.getId();
118                });
119                // computes difference between the white dots and clicked dots to find the unused dots
120                var unused_ids = white_arr_ids.diff(clicked_dots_ids);
121                //console.log("Unused: ",unused_ids, "White: ",white_arr_ids);
122                // change the dot color of all the unused white dots back to their previous color
123                unused_ids.forEach(function (id){
124                    var marker = white_arr.filter(function (dot) {
125                        return dot.id === id;
126                    })[0];
127                    var feature = map.data.getFeatureById(marker.id); 
128                    feature.setProperty("color", marker.color);
129                });
130                white_arr = [];
131                // change the color of all the dots between the two clicked dots to the user picked color
132                if (chosenColor)
133                {
134                    clicked_dots.forEach(function (dot) {
135                        dot.setProperty("color", chosenColor);
136                    });
137                }
138                // Increment the time by one-half minute (30 seconds)
139                var millisecs = currentTime.getTime();
140                millisecs += 30000; 
141                currentTime = new Date(millisecs);
142
143                // Create a printable string for the time (HH:MM:SS)
144                var printableTime = currentTime.toLocaleTimeString('it-IT');
145
146                // Assemble the line to be written to the events file
147                var lineOut = "101   " + printableTime + "\t" + first[0] + "\t" + 
148                first[1] + "\t" + first[2] + "\t" + range.toFixed(3) + "\t" 
149                + getColorAbbr(chosenColor);
150                console.log(lineOut);
151
152                // Using Ajax POST to send the data
153                var xhr = new XMLHttpRequest();
154                xhr.open("POST", "../../cgi-bin/saveTrafficEvent.py", true);
155                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
156                // send the collected data
157                xhr.send("msg="+lineOut + "\n")
158            }
159            // if user has not yet clicked on a dot
160            else if (!clicked)
161            {
162                first = event_arr;
163
164                // turns relevant dots white
165                selectedID = event.feature.getId();  // get the id of the clicked dot
166                curr = postmileList.indexOf(selectedID); // find the id in the postmile list
167                var firstBlank = postmileList[curr].indexOf(" ", 0);  // find direction substring
168                var secondBlank = firstBlank+2; 
169                var direction = postmileList[curr].charAt(firstBlank+1); // extract direction
170                target = event.feature.getId().substring(0,secondBlank); // extract target string
171                //console.log("making white dots from " + selectedID + " in direction "+direction)
172                // Decide whether to increment or decrement based on direction of hwy;
173                //  N and E increment,  S and W decrement
174                if (direction == 'N' || direction == 'E')
175                {
176                    // Process all dots with same hwy and direction
177                    while  (postmileList[curr].startsWith(target) && curr < postmileList.length)
178                    {
179                        // turn the dot white
180                        currFeat = map.data.getFeatureById(postmileList[curr]);
181                        white_arr.push({id : currFeat.getId(), color : currFeat.getProperty("color")});         
182                        currFeat.setProperty("color", "white"); 
183                        curr++;
184               
185                    } 
186                }
187                else
188                {
189                    // Process all dots with same hwy and direction
190                    while  (postmileList[curr].startsWith(target) && curr > 0)
191                    {
192                        currFeat = map.data.getFeatureById(postmileList[curr]);
193                        white_arr.push({id : currFeat.getId(), color : currFeat.getProperty("color")});
194                        // turn the dot white
195                        currFeat.setProperty("color", "white"); 
196                        curr--;
197                    }                 
198                }
199            }
200            // if the user's second click is made on a dot not on the first dot's highway
201            else 
202            {
203                console.log('wrong choice');
204                clicked = !clicked;
205            }
206            clicked = !clicked;
207        });
208    }
209    // callback when load GeoJson completes
210    // save each feature's Point as the original coordinates for later reference
211    function saveCoords(features)
212    {
213        // Iterate over all the features in the map
214        features.forEach(function(feature)
215        {
216            var pt = feature.getGeometry().get();
217            vds_coords[feature.getId()] = pt; // save the Point in a dictionary
218            postmileList.push(feature.getId()); // save the postmile in a list
219        });
220        // update the dot colors from the dynamic json data
221        updateVDSlayer();
222        // go adjust the marker coordinates so dots don't overlap
223        adjustCoords(calcDistanceFactor());
224    } 
225
226    // magic formula controls distance between dots proportionate to zoom factor
227    function calcDistanceFactor()
228    {
229        // 15 is maximum zoom, the point at which no adjustment is needed
230        return (.0005 * (15 - map.getZoom()));
231    }
232
233    // Adjust the coordinates of dots so they appear side-by-side
234    // The perpendicular vector for each dot has been provided,
235    // so we just need to multiply by a scaling factor (adjAmount)
236    // @param adjAmount amount by which to adjust coordinate
237    function adjustCoords(adjAmount)
238    {
239        // Adjust the NB points a slight amount
240        map.data.forEach(function(feature)
241        {
242            // get the name of the current feature
243            var name = feature.getId();
244            // lookup the original coordinates for this feature
245            var coords = vds_coords[name];
246
247            //retrieve the perpendicular vector (precomputed)
248            var perpx = feature.getProperty("perpx")
249            var perpy = feature.getProperty("perpy")
250                // Make adjustment and save it
251            var myLat = coords.lat() + perpy * adjAmount
252            var myLong = coords.lng() + perpx * adjAmount
253            feature.setGeometry(
254            {
255                lat: myLat,
256                lng: myLong
257            });
258        });
259    }
260
261    // update the color (as needed) for a given marker
262    function updateMarker(marker)
263    {
264        target = marker.id;
265        newColor = marker.properties.color;
266        // see if new color is different than current color
267        currentFeature = map.data.getFeatureById(target);
268        if (currentFeature) {
269            currentColor = currentFeature.getProperty("color");
270            // if a new color is desired then assign it to the feature's color property
271            if (currentColor != newColor)
272            {
273                currentFeature.setProperty("color", newColor);
274                // set zIndex for slowed traffic to a higher value so they overlap
275                currentFeature.setProperty("zIndex", colorZvalues[newColor]);
276            }
277        }
278    }
279
280    // Load the highways dynamic json file and update the map
281    function updateVDSlayer()
282    {
283        eventIndex = -1;
284        var parsed_JSON;
285        loadJSON(kVDSstatusFile, function(response)
286        {
287            // Parse JSON string into object
288            parsed_JSON = JSON.parse(response);
289            // Process each new marker - lookup in current map
290            parsed_JSON.features.forEach(updateMarker);
291        });
292    }
293
294    function getColorName(str){
295        if (str === "R\r" || str === "R")
296            return "red";
297        else if (str === "Y\r" || str === "Y")
298            return "yellow";
299        else if (str === "G\r" || str === "G")
300            return "lime";
301    }
302
303    // gets the starting letter of a given color
304    function getColorAbbr(str){
305        if (str === "red")
306            return "R";
307        else if (str === "yellow")
308            return "Y";
309        else if (str === "lime")
310            return "G";
311    }
312
313function initColorButtons()
314{
315    // add the respective color buttons onto the map
316    var redColor = document.getElementById('redButton');
317    var greenColor = document.getElementById('greenButton');
318    var yellowColor = document.getElementById('yellowButton');
319    map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(redColor);
320    map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(greenColor);
321    map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(yellowColor);
322    // store the user picked color in "chosenColor"
323   
324    redColor.addEventListener('click', function() {
325        chosenColor = "red";
326        redColor.style.background = "red";
327        greenColor.style.background = "gray";
328        yellowColor.style.background = "gray";
329       
330    });
331    greenColor.addEventListener('click', function() {
332        chosenColor = "lime";
333        greenColor.style.background = "green";
334        redColor.style.background = "gray";
335        yellowColor.style.background = "gray";       
336    });
337    yellowColor.addEventListener('click', function(){
338        chosenColor = "yellow";
339        yellowColor.style.background = "yellow";
340        redColor.style.background = "gray";
341        greenColor.style.background = "gray";     
342    });
343        // set default button on
344    yellowColor.style.background = "yellow";   
345}
Note: See TracBrowser for help on using the repository browser.