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

Revision 568, 13.6 KB checked in by jdalbey, 6 years ago (diff)

GTEC vdsLayer.js Add colors to buttons. Improve button selection so a second click is rquired on a white dot.

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