- Timestamp:
- 03/10/2019 01:54:49 PM (7 years ago)
- Location:
- trunk/src/cptms
- Files:
-
- 1 added
- 1 edited
- 8 moved
-
cptms_map.html (modified) (8 diffs)
-
images/CPTMSImages (added)
-
images/CPTMSImages/btnDepressed_CCTV.png (moved) (moved from trunk/src/cptms/images/btnDepressed_CCTV.png)
-
images/CPTMSImages/btnDepressed_CMS.png (moved) (moved from trunk/src/cptms/images/btnDepressed_CMS.png)
-
images/CPTMSImages/btnDepressed_VDS.png (moved) (moved from trunk/src/cptms/images/btnDepressed_VDS.png)
-
images/CPTMSImages/btnReady_CCTV.png (moved) (moved from trunk/src/cptms/images/btnReady_CCTV.png)
-
images/CPTMSImages/btnReady_CMS.png (moved) (moved from trunk/src/cptms/images/btnReady_CMS.png)
-
images/CPTMSImages/btnReady_VDS.png (moved) (moved from trunk/src/cptms/images/btnReady_VDS.png)
-
images/CPTMSImages/icon_cmsBlue.png (moved) (moved from trunk/src/cptms/images/icon_cmsBlue.png)
-
images/CPTMSImages/icon_cmsYellow.png (moved) (moved from trunk/src/cptms/images/icon_cmsYellow.png)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/cptms/cptms_map.html
r293 r302 2 2 <html> 3 3 <head> 4 <!-- Launch with python -m CGIHTTPServer 8080 --> 4 5 <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> 5 <title>CPTMS Map v0.5. 5</title>6 <title>CPTMS Map v0.5.6</title> 6 7 <style> 8 @font-face { 9 font-family: Scoreboard; 10 src: url('scoreboard.ttf'); 11 } 7 12 /* Set the size of the div element that contains the map */ 8 13 #mapdiv { … … 16 21 padding: 0; 17 22 } 23 textarea { 24 height: 33px; 25 width: 272px; 26 resize: none; 27 font-family: Scoreboard; 28 font-size: xx-large; 29 background-color: #2F4F4F; 30 color: yellow; 31 } 32 input { 33 border: thin solid #333; 34 padding: 2px; 35 font-family: monospace; 36 font-size: large; 37 } 18 38 #search-input { 19 39 background-color: #17263c; /* #CD853F; /*#E6E6FA; /* lavender */ … … 40 60 cursor: pointer; 41 61 } 62 #cms-info-label { 63 height: 20px; 64 width: 540px; 65 overflow: hidden; 66 background-color: #A8C5FF; /*#ECECFB; */ 67 border: thin solid #BDBDBD; 68 padding: 5px; 69 } 70 #message-display { 71 height: 172px; 72 width: 300px; 73 overflow: hidden; 74 float: left; 75 } 76 #message-input { 77 height: 122px; 78 width: 135px; 79 background-color: #729FFF; 80 float: left; 81 } 82 #buttonPanel { 83 height: 122px; 84 width: 100px; 85 background-color: #729FFF; 86 border-left: none; 87 float: left; 88 padding: 20px; 89 } 90 .wrapper { 91 position: relative;\ 92 } 93 #dialog { 94 position: absolute; 95 top: 10%; 96 right: 20%; 97 background-color: #729FFF; /* #ECECFB; */ 98 margin: auto; 99 padding: 20px; 100 border: 1px solid #888; 101 width: 52%; 102 display: none; 103 } 104 .unstyled-button { 105 border: 0 none; 106 padding: 0; 107 background: none; 108 cursor: pointer; 109 } 110 /* The Close Button */ 111 .close { 112 color: orange; 113 float: right; 114 font-size: 20px; 115 font-weight: bold; 116 } 117 .close:hover, 118 .close:focus { 119 color: red; 120 text-decoration: none; 121 cursor: pointer; 122 } 42 123 43 124 </style> 44 125 </head> 45 126 <body> 46 <!-- Version 5.5 renames title to CPTMS, loads static data on startup and dynamic data 127 <!-- 128 Version 5.6 integrates CMS features 129 Version 5.5 renames title to CPTMS, loads static data on startup and dynamic data 47 130 every ten seconds. 48 131 Version 5.4 adds Search box and Center button … … 61 144 <!--The div element where the map appears --> 62 145 <div id="mapdiv"></div> 63 <!--The div element where the center button appears --> 64 <div id="ctrButton">⊕</div> 146 <!--The div element where the buttons appears --> 147 <div id="ctrButton" class="unstyled-button">⊕</div> 148 <button id="cmsButton" class="unstyled-button"><img id="cmsBtnImg" src="images/CPTMSImages/btnDepressed_CMS.png"></button> 149 <button id="vdsButton" class="unstyled-button"><img id="vdsBtnImg" src="images/CPTMSImages/btnDepressed_VDS.png"></button> 150 <!-- The div element for the popup dialog --> 151 <div id="dialog" style="display:none;"> 152 <span class="close">×</span> 153 <br> 154 <div id="cms-info-label" style="font-family:monospace">CMS ID: xxx LOCATION: </div> 155 <br> 156 <div><pre>Proposed: Current:</pre></div> 157 <input id='cmsID' value="" type='hidden'/> 158 <div id="message-input"> 159 <input id="msgcontent1" size="16" maxlength="16" type="text"/><br><br> 160 <input id="msgcontent2" size="16" maxlength="16"/><br><br> 161 <input id="msgcontent3" size="16" maxlength="16"/> 162 </div> 163 <div id="buttonPanel" style="display: block;"> 164 <button onclick="handleSubmit();">Send >></button><br> 165 <button onclick="handleClear();">Clear >></button><br> 166 <button onclick="handleClose();">Close </button> 167 </div> 168 <div id="message-display" style="display: block;"> 169 <textarea readonly id="msgdisplay1" maxlength="16" rows="1" cols="16"></textarea> 170 <textarea readonly id="msgdisplay2" maxlength="16" rows="1" cols="16"></textarea> 171 <textarea readonly id="msgdisplay3" maxlength="16" rows="1" cols="16"></textarea> 172 </div> 173 </div> 174 65 175 <script> 66 176 // a global variable for the google map … … 84 194 // white means a disabled spot 85 195 var colorZvalues = {"white":5,"lime":10,"yellow":20,"red":30}; 196 var kMapStartupFile = "cmsStatusD12.json"; 197 var blueFlag = "images/CPTMSImages/icon_cmsBlue.png"; 198 var yellowFlag = "images/CPTMSImages/icon_cmsYellow.png"; 199 var messageList; 200 var cms_info; 201 var markerList = []; 202 var cms_showing = true; 203 var vds_showing = true; 86 204 87 205 // Build a solid colored icon to use instead of the classic pin … … 197 315 } 198 316 199 // Load the dynamic highways file via ajax317 // Load the dynamic json file for highways, etc. 200 318 // Ref: https://codepen.io/KryptoniteDove/post/load-json-file-locally-using-pure-javascript 201 function loadJSON(callback) { 202 203 var xobj = new XMLHttpRequest(); 204 xobj.overrideMimeType("application/json"); 205 xobj.open('GET', kMapPointsFile, true); 206 xobj.onreadystatechange = function () { 207 if (xobj.readyState == 4 && xobj.status == "200") { 208 // Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode 209 callback(xobj.responseText); 210 } 211 }; 212 xobj.send(null); 213 } 214 319 function loadJSON(inFile, callback) 320 { 321 var xobj = new XMLHttpRequest(); 322 xobj.overrideMimeType("application/json"); 323 xobj.open('GET', inFile, true); 324 xobj.onreadystatechange = function() 325 { 326 if (xobj.readyState == 4 && xobj.status == "200") 327 { 328 callback(xobj.responseText); 329 } 330 }; 331 // We want ajax to ignore any cached responses 332 xobj.setRequestHeader('If-Modified-Since', 'Sat, 01 Jan 2000 01:01:01 GMT') 333 xobj.send(null); 334 } 215 335 // Load the highways dynamic json file and update the map 216 336 function updateMap() 217 337 { 218 338 var parsed_JSON; 219 loadJSON( function(response)339 loadJSON(kMapPointsFile,function(response) 220 340 { 221 341 // Parse JSON string into object … … 313 433 placePins = []; 314 434 } 435 // Initialize the view/hide buttons 436 function initButton() 437 { 438 var cmsBtnDiv = document.getElementById('cmsButton'); 439 map.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(cmsBtnDiv) 440 cmsBtnDiv.title = 'Click to toggle cms view'; 441 442 // Setup the click event listeners to toggle icon display 443 cmsBtnDiv.addEventListener('click', function() { 444 cms_showing = !cms_showing; 445 // reveal or hide all the icons 446 for (var i = 0; i < markerList.length; i++) 447 { 448 markerList[i].setVisible(cms_showing); 449 } 450 // Determine which button image to show 451 if (cms_showing) 452 { 453 pic = "images/CPTMSImages/btnDepressed_CMS.png" 454 } 455 else 456 { 457 pic = "images/CPTMSImages/btnReady_CMS.png" 458 } 459 document.getElementById('cmsBtnImg').src=pic; 460 }); 461 var vdsBtnDiv = document.getElementById('vdsButton'); 462 map.controls[google.maps.ControlPosition.LEFT_BOTTOM].push(vdsBtnDiv) 463 vdsBtnDiv.title = 'Click to toggle vds view'; 464 465 // Setup the click event listeners to toggle icon display 466 vdsBtnDiv.addEventListener('click', function() { 467 vds_showing = !vds_showing; 468 // reveal or hide all the icons 469 alert("Not implemented yet") 470 // Determine which button image to show 471 if (vds_showing) 472 { 473 pic = "btnDepressed_VDS.png" 474 } 475 else 476 { 477 pic = "btnReady_VDS.png" 478 } 479 document.getElementById('vdsBtnImg').src=pic; 480 }); 481 } 482 function setMarkers() 483 { 484 var simpleImage = ""; 485 loadcmsJSON(function(response) 486 { 487 // Parse JSON string into object 488 cms_info = JSON.parse(response); 489 console.log(cms_info.data[0].cms); 490 // Process each new marker 491 for (var i = 0; i < cms_info.data.length; i++) 492 { 493 var cms = cms_info.data[i].cms; 494 var currLat = Number(cms.location.latitude); 495 var currLong = Number(cms.location.longitude); 496 // load a yellow flag if there's currently no message 497 if (messageList[i] == "||") 498 simpleImage = yellowFlag; 499 else 500 simpleImage = blueFlag; 501 var directionCode = cms.location.direction.charAt(0); 502 var locationInfo = directionCode + " " + cms.location 503 .route + " " + cms.location.postmile + " " + cms 504 .location.locationName 505 markerList[i] = new google.maps.Marker( 506 { 507 position: 508 { 509 lat: currLat, 510 lng: currLong 511 }, 512 map: map, 513 icon: simpleImage, 514 title: "#"+i+" " +locationInfo, 515 cmsid: "" + i, 516 location: locationInfo 517 }); 518 google.maps.event.addListener(markerList[i], 'click', 519 function() 520 { 521 var dialog = document.getElementById('dialog'); 522 dialog.style.display = 'block'; 523 // fetch the sequential msg # 524 cmsID = Number(this.cmsid); 525 // Assign to the hidden field 526 document.getElementById('cmsID').value = cmsID; 527 getMessage(cmsID); // note: this is async 528 document.getElementById('cms-info-label').innerHTML = "CMS ID: " + 529 cmsID + " LOCATION: " + this.location; 530 // clear input fields 531 document.getElementById('msgcontent1').value = ""; 532 document.getElementById('msgcontent2').value = ""; 533 document.getElementById('msgcontent3').value = ""; 534 document.getElementById('msgcontent1').focus(); 535 var span = document.getElementsByClassName("close")[0] 536 // When the user clicks on <span> (x), close the modal 537 span.onclick = function() { 538 handleClose(); 539 } 540 }); 541 } 542 }); 543 } 544 545 function loadcmsJSON(callback) 546 { 547 var xobj = new XMLHttpRequest(); 548 xobj.overrideMimeType("application/json"); 549 xobj.open('GET', kMapStartupFile, true); 550 xobj.onreadystatechange = function() 551 { 552 if (xobj.readyState == 4 && xobj.status == "200") 553 { 554 callback(xobj.responseText); 555 } 556 }; 557 // We want ajax to ignore any cached responses 558 xobj.setRequestHeader('If-Modified-Since', 'Sat, 01 Jan 2000 01:01:01 GMT') 559 xobj.send(null); 560 } 561 562 function handleSubmit() 563 { 564 // recover the user's response 565 var response1 = document.getElementById('msgcontent1').value; 566 var response2 = document.getElementById('msgcontent2').value; 567 var response3 = document.getElementById('msgcontent3').value; 568 var newMsg = response1+response2+response3; 569 if (newMsg.length == 0) 570 { 571 alert("Nothing to Send ... Proposed is empty."); 572 } 573 else 574 { 575 document.getElementById('msgdisplay1').value = response1; 576 document.getElementById('msgdisplay2').value = response2; 577 document.getElementById('msgdisplay3').value = response3; 578 saveMessage(response1 + "|" + response2 + "|" + response3); 579 } 580 } 581 582 function handleClose() 583 { 584 // hide the display 585 document.getElementById('dialog').style.display = 'none' 586 } 587 588 function handleClear() 589 { 590 document.getElementById('msgdisplay1').value = ""; 591 document.getElementById('msgdisplay2').value = ""; 592 document.getElementById('msgdisplay3').value = ""; 593 saveMessage("||"); 594 } 595 // retrieve the current cms message file 596 function getMessage(cmsID) 597 { 598 loadJSON("http://localhost:8080/messagefile.txt", function(response) 599 { 600 // Parse JSON string into object 601 messageList = JSON.parse(response); 602 // select a message from json for the given cmsID 603 console.log("get by cmsID=" + cmsID); 604 var cmsSign = document.getElementById('msgdisplay1'); 605 messageparts = messageList[cmsID].split("|"); 606 cmsSign.value = messageparts[0]; 607 document.getElementById('msgdisplay2').value = messageparts[1]; 608 document.getElementById('msgdisplay3').value = messageparts[2]; 609 }); 610 } 611 // Save an updated cms message to the file 612 // NB: cms id's are one-based, json array is zero-based. 613 function saveMessage(outMessage, cmsID) 614 { 615 var cmsID = document.getElementById('cmsID').value; 616 console.log("Saving " + outMessage + " for cmsID " + cmsID) 617 messageList[cmsID] = outMessage; 618 // Change icon if something was saved 619 if (outMessage == "||") 620 markerList[cmsID].setIcon(yellowFlag); 621 else 622 markerList[cmsID].setIcon(blueFlag); 623 624 var xhttp = new XMLHttpRequest(); 625 xhttp.open("GET", "http://localhost:8080/cgi-bin/saveMessage.py?msg=" + JSON 626 .stringify(messageList), true); 627 xhttp.send(); 628 // Using POST might be a better idea ... haven't tried this yet 629 // var xhr = new XMLHttpRequest(); 630 // xhr.open("POST", "/cgi-bin/saveMessage.py?", true); 631 // xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8'); 632 // send the collected data as JSON 633 // xhr.send(JSON.stringify(messageList)); 634 } 315 635 316 636 // Initialize the map and load the points … … 329 649 initSearch(); 330 650 initCenter(); 651 initButton(); 652 getMessage(1); // load the current message file 653 setMarkers(); 331 654 332 655 loadMapData(); // go load the map data
Note: See TracChangeset
for help on using the changeset viewer.
