source: tmcsimulator/trunk/webapps/cptms/CameraDisplay.html @ 628

Revision 628, 8.3 KB checked in by jdalbey, 5 years ago (diff)

CameraDisplay?.html minor improvements to user interface

Line 
1<html>
2<head>
3<meta charset="UTF-8">
4<title>CPTMS Camera Display Controller V1</title>
5<style>
6.toprow {
7  text-align: center
8}
9td {
10  border: 1px solid black;
11}
12img {  /* confine the image to the cell dimensions */
13    max-width: 100%;
14    max-height: 100%;
15}
16.caption {
17    font-family: sans-serif;
18    text-align: center
19}
20</style>
21<script  src="../common/js/fileutils.js"></script>
22<script>
23/* Camera Controller for CPTMS
24 * @author jdalbey   Apr 2020
25 */
26var kVDSstatusFile = "../dynamicdata/highway_status.json"; // dynamic json data file
27var kCCTVfile = "data_layers/cctv_locations_D12.gjson"; // CCTV locations
28var vdsList;
29var cctvList;
30var routeCameras = {};  // for each route, a list of cameras on that route
31var cameraDict = {};    // for each cameraid, the associated nearVDS and locationName properties
32
33// Extracts VDS and CCTV data and builds a lookup dictionary that maps route to camera id's and adds routes to drop down list
34function init()
35{
36    loadJSON(kVDSstatusFile, function(response)
37    {
38        // Parse JSON string into list of VDS's
39        vdsList = JSON.parse(response);
40
41    });
42    loadJSON(kCCTVfile, function(response)
43    {
44        // Parse JSON string into list of cctv's
45        cctvList = JSON.parse(response);
46        cctvList.features.forEach(buildDict);
47        // Build the route dropdowns using routeCameras keys
48        for (var quadrant = 1; quadrant <= 4; quadrant++)
49        {
50            routecombo = document.getElementById("R"+quadrant)
51            removeOptions(routecombo);
52            routecombo.add(document.createElement('option')); // an empty entry
53            // Get all the routes and sort them
54            var routeList =  Object.keys(routeCameras);
55            routeList.sort()
56            // Add all the routes to the route dropdown box
57            for (var route of routeList)
58            {
59                opt1 = document.createElement('option')
60                opt1.text = opt1.value = route
61                routecombo.add(opt1);
62            }
63        }
64    });
65
66    // Start a timer to refresh the traffic colors every 30 seconds
67    var myTimer = setInterval(updateVDSlist, 30000);
68}
69
70// Takes in a CCTV location and builds a lookup dictionary that maps route to camera id's
71function buildDict(cctvItem)
72{
73    id = cctvItem.id
74    route = id.substring(3,6); // extract 3 character route number
75    if (route in routeCameras)
76    {
77        routeCameras[route].push(id); // add the camera id to the list for the route
78    }
79    else
80    {
81        routeCameras[route] = [id]; // special case for first occurrence of route
82    }
83    // Add a camera's info to the cameraDict
84    cameraDict[id] = {'nearVDS':cctvItem.properties["nearVDS"],
85                      'locationName':cctvItem.properties["locationName"]}
86}
87
88/* When a route is selected from the combobox, filter the
89   list of cameras for just those on that route. */
90function routechanged(routechoice, cameraselect) 
91{
92  // get the selected route
93  var e = document.getElementById(routechoice);
94  var currentRoute = e.options[e.selectedIndex].text;
95  // update the list of cameras
96  removeOptions(document.getElementById(cameraselect)); 
97  fillOptions(currentRoute, cameraselect);
98  showView(cameraselect); //show default first image from camera dropdown for the selected route
99}
100
101// Helper: Remove all the options from a combo box
102function removeOptions(selectbox)
103{
104    var idx;
105    for(idx = selectbox.options.length - 1 ; idx >= 0 ; idx--)
106    {
107       selectbox.remove(idx);
108    }
109}
110
111// Fill the selectbox with items from the lookup table that match route
112// route param may be empty if the first item in the combo box was chosen
113function fillOptions(route,cameraselect)
114{
115  // IF the route is not empty
116  if (route.length > 0)
117  {
118      var cameracombo = document.getElementById(cameraselect)
119      // grab cameras from lookup table
120      cameranames = routeCameras[route];
121      //console.log(cameranames.length + " cameras for route " + route);
122      // Create a new select OPTION for each camera
123      for (var idx = 0; idx < cameranames.length; idx++)
124      {
125        var opt1 = document.createElement('option')
126        opt1.value = cameranames[idx]
127        opt1.text = cameraDict[cameranames[idx]].locationName
128        cameracombo.add(opt1);
129      }
130   } 
131}
132
133// Display the image requested from a camera dropdown box
134function showView(cameraselect)
135{
136    var quadrant = "";
137    // if route dropdown box is selected, then view image
138    if (typeof cameraselect === 'string')
139    {
140      quadrant = cameraselect.charAt(1)  // extract numeric part of camera identifier
141      var chosenRoute = document.getElementById('R' + quadrant);
142      var imgElement = document.getElementById("img"+quadrant)   
143      var e = document.getElementById(cameraselect);
144      // if no camera was selected
145      if (e.selectedIndex == -1)
146      {
147          imgElement.src="" // remove the image
148      }
149      else
150      {
151          var chosenCamera = e.options[e.selectedIndex].value;
152          nearvds = cameraDict[chosenCamera].nearVDS
153          // Search for the vds that is nearest
154          var idx = 0; 
155          while (idx < vdsList.features.length && vdsList.features[idx].id != nearvds)
156          {
157              idx++;
158          }
159          // If we found the nearVDS
160          if (idx < vdsList.features.length)
161          {
162              // Obtain color and convert to speed
163              var foundVDS = vdsList.features[idx]
164              var color =  foundVDS.properties['color']
165              var speed = "freeflow"
166              if (color == "yellow")
167              {
168                  speed = "slow"
169              }
170              if (color == "red")
171              {
172                  speed = "stopped"
173              }
174              // construct filename
175              var filename =  chosenCamera + "-day-"+speed+".jpg"
176              //console.log("Found " + foundVDS.id + " " + foundVDS.properties['color'] + " " + filename)
177              // Load the desired image
178              var preload = new Image();
179              preload.onload = function() {
180                  if (imgElement) 
181                  { 
182                      imgElement.src = preload.src; // image
183                      imgElement.title=chosenCamera // tooltip
184                  }
185              };
186              // if couldn't load show as unavailable
187              preload.onerror = function() {
188                  if (imgElement) { imgElement.src = "images/CCTV/video_unavailable.jpg" } 
189              };
190              // attempt to load the image
191              preload.src = "images/CCTV/"+filename; 
192      //Reference: https://www.daniweb.com/programming/web-development/threads/272293/javascript-test-for-file-existence
193          }
194      }
195    }
196   //console.log("empty");
197}
198// Execute periodically to reload the vds list with current data
199function updateVDSlist()
200{
201    loadJSON(kVDSstatusFile, function(response)
202    {
203        // Reload the vds list with current data
204        vdsList = JSON.parse(response);
205        // Refresh each camera view
206        var views = document.getElementsByClassName("camcombo");
207        for (var quadrant of views)
208        {
209            //console.log(quadrant.id);
210            showView(quadrant.id);
211        }
212    });
213   
214}
215</script>
216</head>
217<body onload="init()">
218<div style="text-align: center; width:80%">
219CPTMS Camera Controller
220</div>
221<table width="80%">
222  <tr>
223    <td class="caption" width="50%"><img id="img1" src=""/><br>
224  Choose Route
225  <select id="R1" onchange='routechanged("R1","C1")'>
226    <option value="0"></option>
227  </select>
228  <br>Choose Camera
229  <select id="C1" class="camcombo" onchange='showView("C1")'>
230  </select></td>
231    <td class="caption"><img  id="img2"src=""/><br>
232  Choose Route
233  <select id="R2" onchange='routechanged("R2","C2")'>
234    <option value="0"></option>
235  </select>
236  <br>Choose Camera
237  <select id="C2" class="camcombo" onchange='showView("C2")'>
238  </select></td>
239  </tr>
240  <tr>
241    <td class="caption"><img id="img3" src=""/><br>
242  Choose Route
243  <select id="R3"  onchange='routechanged("R3","C3")'>
244    <option value="0"></option>
245  </select>
246  <br>Choose Camera
247  <select id="C3" class="camcombo" onchange='showView("C3")'>
248  </select>
249</td>
250    <td class="caption"><img id="img4" src=""/><br>
251  Choose Route
252  <select id="R4" onchange='routechanged("R4","C4")'>
253    <option value="0"></option>
254  </select>
255  <br>Choose Camera
256  <select id="C4" class="camcombo" onchange='showView("C4")'>
257</select>
258</td>
259  </tr>
260</table> 
261</body>
262</html>
Note: See TracBrowser for help on using the repository browser.