source: tmcsimulator/trunk/webapps/visualizer/js/vdsLayer.js @ 516

Revision 516, 8.7 KB checked in by jdalbey, 6 years ago (diff)

Add new web app: Traffic Events Visualizer

Line 
1    // Build a solid colored icon to use instead of the classic pin
2    function dotSymbol(color) 
3    {
4        var iconPath = iconVDSwhite;
5        if (color == 'red')
6        {
7           iconPath = iconVDSred;
8        }
9        else if (color == 'yellow')
10        {
11            iconPath = iconVDSyellow;
12        }
13        else if (color == 'lime')
14        {
15            iconPath = iconVDSgreen;
16        }
17        return {
18            url: iconPath, 
19            anchor: new google.maps.Point(6, 6)
20        };
21    }
22
23    // Load the map data from a json file and style all the points
24    function loadVDSlayer()
25    {
26        // Load the static map data and call saveCoords when done
27        map.data.loadGeoJson(kMapStartupFile, null, saveCoords)
28        // Style the map data by applying the desired properties to each feature (marker)
29        // The function will be called every time a feature's properties are updated.
30        map.data.setStyle(function(feature)
31        {
32            // Get the postmile id
33            var name = feature.getId();
34            // Get the desired color value
35            var ptColor = feature.getProperty("color");
36            var street = feature.getProperty("street");
37            // Build the marker
38            var iconSymbol = dotSymbol(ptColor);
39            // return the StyleOptions
40            return {
41                icon: iconSymbol,
42                title: name + " @" + street, // set rollover text
43                // set zIndex for slowed traffic to a higher value so they overlap
44                zIndex: colorZvalues[ptColor]
45            };
46        });
47    }
48    // callback when load GeoJson completes
49    // save each feature's Point as the original coordinates for later reference
50    function saveCoords(features)
51    {
52        // Iterate over all the features in the map
53        features.forEach(function(feature)
54        {
55            var pt = feature.getGeometry().get();
56            vds_coords[feature.getId()] = pt; // save the Point in a dictionary
57        });
58        // update the dot colors from the dynamic json data
59        updateVDSlayer();
60        // go adjust the marker coordinates so dots don't overlap
61        adjustCoords(calcDistanceFactor());
62    }
63
64    // magic formula controls distance between dots proportionate to zoom factor
65    function calcDistanceFactor()
66    {
67        // 15 is maximum zoom, the point at which no adjustment is needed
68        return (.0005 * (15 - map.getZoom()));
69    }
70
71    // Adjust the coordinates of dots so they appear side-by-side
72    // The perpendicular vector for each dot has been provided,
73    // so we just need to multiply by a scaling factor (adjAmount)
74    // @param adjAmount amount by which to adjust coordinate
75    function adjustCoords(adjAmount)
76    {
77        // Adjust the NB points a slight amount
78        map.data.forEach(function(feature)
79        {
80            // get the name of the current feature
81            var name = feature.getId();
82            // lookup the original coordinates for this feature
83            var coords = vds_coords[name];
84
85            //retrieve the perpendicular vector (precomputed)
86            var perpx = feature.getProperty("perpx")
87            var perpy = feature.getProperty("perpy")
88                // Make adjustment and save it
89            var myLat = coords.lat() + perpy * adjAmount
90            var myLong = coords.lng() + perpx * adjAmount
91            feature.setGeometry(
92            {
93                lat: myLat,
94                lng: myLong
95            });
96        });
97    }
98
99    // update the color (as needed) for a given marker
100    function updateMarker(marker)
101    {
102        target = marker.id;
103        newColor = marker.properties.color;
104        // see if new color is different than current color
105        currentFeature = map.data.getFeatureById(target);
106        currentColor = currentFeature.getProperty("color");
107        // if a new color is desired then assign it to the feature's color property
108        if (currentColor != newColor)
109        {
110            currentFeature.setProperty("color", newColor);
111            // set zIndex for slowed traffic to a higher value so they overlap
112            currentFeature.setProperty("zIndex", colorZvalues[newColor]);
113        }
114    }
115
116
117    // Load the highways dynamic json file and update the map
118    function updateVDSlayer()
119    {
120        index = -1;
121        var parsed_JSON;
122        loadJSON(kVDSstatusFile, function(response)
123        {
124            // Parse JSON string into object
125            parsed_JSON = JSON.parse(response);
126            // Process each new marker - lookup in current map
127            parsed_JSON.features.forEach(updateMarker);
128        });
129    }
130
131    function getColorName(str){
132        if (str === "R\r" || str === "R")
133            return "red";
134        else if (str === "Y\r" || str === "Y")
135            return "yellow";
136        else if (str === "G\r" || str === "G")
137            return "lime";
138    }
139
140    function processVDS() {
141        var parsed_JSON;
142        loadJSON(kVDSstatusFile, function(response)
143        { 
144            // Parse JSON string into object
145            parsed_JSON = JSON.parse(response);
146            // Process each new marker - lookup in current map
147            var array =  parsed_JSON.features;
148            var txt = '';
149            var xmlhttp = new XMLHttpRequest();
150            xmlhttp.onreadystatechange = function(){
151                if(xmlhttp.status == 200 && xmlhttp.readyState == 4){
152                    txt = xmlhttp.responseText;
153                    var lines = txt.toString().split("\n");
154                    for (var line = 1; line < lines.length; line++) {
155                        filters[line-1] = [];
156                        var event = lines[line].split(/[ ,]+/);
157                        var start = parseFloat(event[4]); // 7.73
158                        var range = parseFloat(event[5]); // 0.5
159                        var newColor = getColorName(event[6]); // "R"
160                        times.push(event[1]);
161                        array.forEach(function (marker) {
162                            var id_arr = marker.id.split(" ");
163                            if (id_arr[0] === event[2] && id_arr[1] === event[3]){
164                                var dist = parseFloat(id_arr[2]) - start; //difference of postmiles
165                                if (dist <= range && dist >= 0){
166                                    filters[line-1].push({"marker": marker, "color": newColor});
167                                }
168                            }
169                        });
170                    }
171                }
172            };
173            xmlhttp.open("GET",trafficEventsFile,true); //read traffic events text file
174            xmlhttp.send();
175        });
176    }
177     
178    // updates color for each marker based on color in filters array
179    function updateVDS(forwards) { 
180        index++;
181        if  (filters[index] !== undefined){
182            filters[index].forEach(function(item){
183                item.marker.properties.color = item.color;
184                updateMarker(item.marker);
185            });
186        }
187    }
188
189function initVDSbutton()
190{
191
192    var vdsBtnDiv = document.getElementById('vdsButton');
193    map.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(vdsBtnDiv)
194    vdsBtnDiv.title = 'Click to toggle vds view';
195
196    // Setup the click event listeners to toggle icon display
197    vdsBtnDiv.addEventListener('click', function()
198    {
199        vds_showing = !vds_showing;
200        // reveal or hide all the dots
201        map.data.forEach(function(feature)
202        {
203            map.data.overrideStyle(feature,
204            {
205                visible: vds_showing
206            });
207        });
208        // Determine which button image to show
209        if (vds_showing)
210        {
211            pic = "images/btnDepressed_VDS.png"
212        }
213        else
214        {
215            pic = "images/btnReady_VDS.png"
216        }
217        document.getElementById('vdsBtnImg').src = pic;
218    });
219}
220
221// init beginning and next buttons as well as time display on map
222function initForwardbutton()
223{
224    var i = 0;
225    var time = document.getElementById('time');
226    map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(time)
227    var start = document.getElementById('start');
228    map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(start)
229    start.title = 'Click to see the first event';
230    var forward = document.getElementById('forward');
231    map.controls[google.maps.ControlPosition.BOTTOM_CENTER].push(forward)
232    forward.title = 'Click to see the next event';
233    console.log(times);
234    forward.addEventListener('click', function() {
235        updateVDS(1);
236        if (i < times.length)
237            time.innerHTML = times[i++];
238    });
239    start.addEventListener('click', function() {
240        updateVDSlayer();
241        i = 0;
242        time.innerHTML = "Time"
243    });
244}
245
Note: See TracBrowser for help on using the repository browser.