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

Revision 567, 13.1 KB checked in by jdalbey, 6 years ago (diff)

GTEC vdsLayer.js Add color buttons.

Line 
1var postmileList = [];  // the list of postmiles saved from the json file.
2var chosenColor = null; // stores color that user picks
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
138                // Using Ajax POST to send the data
139                var xhr = new XMLHttpRequest();
140                xhr.open("POST", "../../cgi-bin/saveTrafficEvent.py", true);
141                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
142                // send the collected data
143                xhr.send("msg="+lineOut + "\n")
144            }
145            // if user has not yet clicked on a dot
146            else if (!clicked)
147            {
148                first = event_arr;
149
150                // turns relevant dots white
151                selectedID = event.feature.getId();  // get the id of the clicked dot
152                curr = postmileList.indexOf(selectedID); // find the id in the postmile list
153                var firstBlank = postmileList[curr].indexOf(" ", 0);  // find direction substring
154                var secondBlank = firstBlank+2; 
155                var direction = postmileList[curr].charAt(firstBlank+1); // extract direction
156                target = event.feature.getId().substring(0,secondBlank); // extract target string
157                console.log("making white dots from " + selectedID + " in direction "+direction)
158                // Decide whether to increment or decrement based on direction of hwy;
159                //  N and E increment,  S and W decrement
160                if (direction == 'N' || direction == 'E')
161                {
162                    // Process all dots with same hwy and direction
163                    while  (postmileList[curr].startsWith(target) && curr < postmileList.length)
164                    {
165                        // turn the dot white
166                        currFeat = map.data.getFeatureById(postmileList[curr]);
167                        white_arr.push({id : currFeat.getId(), color : currFeat.getProperty("color")});         
168                        currFeat.setProperty("color", "white"); 
169                        curr++;
170               
171                    } 
172                }
173                else
174                {
175                    // Process all dots with same hwy and direction
176                    while  (postmileList[curr].startsWith(target) && curr > 0)
177                    {
178                        currFeat = map.data.getFeatureById(postmileList[curr]);
179                        white_arr.push({id : currFeat.getId(), color : currFeat.getProperty("color")});
180                        // turn the dot white
181                        currFeat.setProperty("color", "white"); 
182                        curr--;
183                    }                 
184                }
185            }
186            // if the user's second click is made on a dot not on the first dot's highway
187            else 
188            {
189                console.log('wrong choice');
190            }
191            clicked = !clicked;
192        });
193    }
194    // callback when load GeoJson completes
195    // save each feature's Point as the original coordinates for later reference
196    function saveCoords(features)
197    {
198        // Iterate over all the features in the map
199        features.forEach(function(feature)
200        {
201            var pt = feature.getGeometry().get();
202            vds_coords[feature.getId()] = pt; // save the Point in a dictionary
203            postmileList.push(feature.getId()); // save the postmile in a list
204        });
205        // update the dot colors from the dynamic json data
206        updateVDSlayer();
207        // go adjust the marker coordinates so dots don't overlap
208        adjustCoords(calcDistanceFactor());
209    } 
210
211    // magic formula controls distance between dots proportionate to zoom factor
212    function calcDistanceFactor()
213    {
214        // 15 is maximum zoom, the point at which no adjustment is needed
215        return (.0005 * (15 - map.getZoom()));
216    }
217
218    // Adjust the coordinates of dots so they appear side-by-side
219    // The perpendicular vector for each dot has been provided,
220    // so we just need to multiply by a scaling factor (adjAmount)
221    // @param adjAmount amount by which to adjust coordinate
222    function adjustCoords(adjAmount)
223    {
224        // Adjust the NB points a slight amount
225        map.data.forEach(function(feature)
226        {
227            // get the name of the current feature
228            var name = feature.getId();
229            // lookup the original coordinates for this feature
230            var coords = vds_coords[name];
231
232            //retrieve the perpendicular vector (precomputed)
233            var perpx = feature.getProperty("perpx")
234            var perpy = feature.getProperty("perpy")
235                // Make adjustment and save it
236            var myLat = coords.lat() + perpy * adjAmount
237            var myLong = coords.lng() + perpx * adjAmount
238            feature.setGeometry(
239            {
240                lat: myLat,
241                lng: myLong
242            });
243        });
244    }
245
246    // update the color (as needed) for a given marker
247    function updateMarker(marker)
248    {
249        target = marker.id;
250        newColor = marker.properties.color;
251        // see if new color is different than current color
252        currentFeature = map.data.getFeatureById(target);
253        if (currentFeature) {
254            currentColor = currentFeature.getProperty("color");
255            // if a new color is desired then assign it to the feature's color property
256            if (currentColor != newColor)
257            {
258                currentFeature.setProperty("color", newColor);
259                // set zIndex for slowed traffic to a higher value so they overlap
260                currentFeature.setProperty("zIndex", colorZvalues[newColor]);
261            }
262        }
263    }
264
265    // Load the highways dynamic json file and update the map
266    function updateVDSlayer()
267    {
268        eventIndex = -1;
269        var parsed_JSON;
270        loadJSON(kVDSstatusFile, function(response)
271        {
272            // Parse JSON string into object
273            parsed_JSON = JSON.parse(response);
274            // Process each new marker - lookup in current map
275            parsed_JSON.features.forEach(updateMarker);
276        });
277    }
278
279    function getColorName(str){
280        if (str === "R\r" || str === "R")
281            return "red";
282        else if (str === "Y\r" || str === "Y")
283            return "yellow";
284        else if (str === "G\r" || str === "G")
285            return "lime";
286    }
287
288    // gets the starting letter of a given color
289    function getColorAbbr(str){
290        if (str === "red")
291            return "R";
292        else if (str === "yellow")
293            return "Y";
294        else if (str === "lime")
295            return "G";
296    }
297
298function initColorButtons()
299{
300    // add the respective color buttons onto the map
301    var redColor = document.getElementById('redButton');
302    var greenColor = document.getElementById('greenButton');
303    var yellowColor = document.getElementById('yellowButton');
304    map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(redColor);
305    map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(greenColor);
306    map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(yellowColor);
307    // store the user picked color in "chosenColor"
308    redColor.addEventListener('click', function() {
309        chosenColor = "red";
310    });
311    greenColor.addEventListener('click', function() {
312        chosenColor = "lime";
313    });
314    yellowColor.addEventListener('click', function(){
315        chosenColor = "yellow";
316    });
317}
Note: See TracBrowser for help on using the repository browser.