map.totaltraffic.com
Open in
urlscan Pro
3.94.222.241
Public Scan
Submitted URL: http://map.totaltraffic.com/
Effective URL: https://map.totaltraffic.com/map/
Submission: On March 25 via api from US — Scanned from US
Effective URL: https://map.totaltraffic.com/map/
Submission: On March 25 via api from US — Scanned from US
Form analysis
1 forms found in the DOMPOST ./
<form method="post" action="./" id="ctl01" autocomplete="off">
<div class="aspNetHidden">
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="">
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="">
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="ejZbtX6EVKQdtn6zJUErEEwZtRgnyfFvJSDFjJYVH82rK1/PH04z2HZH5u9y+lt1kO9cwaHj99jU0ubIgDyrjvOGqCwH2EX8N0DzdwEjhL4=">
</div>
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['ctl01'];
if (!theForm) {
theForm = document.ctl01;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
<script src="/bundles/MsAjaxJs?v=D6VN0fHlwFSIWjbVzi6mZyE9Ls-4LNrSSYVGRU46XF81" type="text/javascript"></script>
<script src="../Scripts/umd/popper.min.js" type="text/javascript"></script>
<script src="../Scripts/jquery-3.5.1.min.js" type="text/javascript"></script>
<script src="../Scripts/bootstrap.min.js" type="text/javascript"></script>
<script src="/bundles/WebFormsJs?v=N8tymL9KraMLGAMFuPycfH3pXe6uUlRXdhtYv8A_jUU1" type="text/javascript"></script>
<script src="../Scripts/moment.min.js" type="text/javascript"></script>
<script src="../Scripts/moment-timezone-with-data.min.js" type="text/javascript"></script>
<div class="aspNetHidden">
<input type="hidden" name="__VIEWSTATEGENERATOR" id="__VIEWSTATEGENERATOR" value="9477F8F5">
<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION"
value="7WbR41b+hmeRDQv8mtvFPIqbNAr+G1o1gyreaEk/nwV8L1J+BsItG9ZI4GsHvAQ1oxlIjphfdHzUKkWWDDiiy/rZz8mV3G8flWBLLfRhA+d6zSd4JhuNSEJ9qiTJjmHG6Mr2hJvfsMLoKMbMoq294p3sPeFzg+oEZjR8gPjMIKQHtetXxGss98BAxGE95O+pzkMAHLRlpShanx9ipYG/gnEFKkYlCwaePLPFRP5lz4VtQjRk+zY8LcRG5K1++Wr5G8ZaDpGtagO8n6fKY/Snyw==">
</div>
<script type="text/javascript">
//<![CDATA[
Sys.WebForms.PageRequestManager._initialize('ctl00$ctl08', 'ctl01', [], [], [], 90, 'ctl00');
//]]>
</script>
<script type="text/javascript" src="/Scripts/custom/config.js?ver=0.0056"></script>
<script type="text/javascript" src="/Scripts/custom/utility.js?ver=0.0056"></script>
<script type="text/javascript" src="/Scripts/custom/ui.js?ver=0.0056"></script>
<!-- dialog box (modal) -->
<div id="pnlMasterDialog" class="master-dialog modal fade" tabindex="-1" data-backdrop="true" data-keyboard="false" aria-labelledby="pnlMasterDialog_Title" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="padding: 5px 5px; background-color: #eee;">
<div id="pnlMasterDialog_Title" class="modal-title font-18" style="font-weight: bold;"></div>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body"></div>
<div class="modal-footer"></div>
</div>
</div>
</div>
<!-- window (modal) -->
<div id="pnlMasterWindow" class="master-window modal fade" tabindex="-1" data-backdrop="static" data-keyboard="false" aria-labelledby="pnlMasterWindow_Title" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header" style="padding: 5px 5px; background-color: #eee;">
<div id="pnlMasterWindow_Title" class="modal-title font-16" style="width: 95%; font-weight: bold;"></div>
<div id="pnlMasterWindow_TitleMenu" class="modal-title-menu font-16" style="width: 5%; float: right; text-align: right; padding-right: 5px;"></div>
<button type="button" class="close modal-close-btn" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body embed-responsive overflow-hidden" style="padding: 0; margin: 0;"></div>
<div class="modal-footer font-14" style="display: none; padding: 3px 5px; background-color: #eee;"></div>
</div>
</div>
</div>
<!-- push notification -->
<div id="pnlMasterNotification" class="master-notification font-dark" aria-live="polite" aria-atomic="true" style="position: relative;">
<div id="pnlMasterNotification_Content" class="master-notification-content" style="position: absolute; top: 0; right: 0;"></div>
</div>
<!-- left column overlay -->
<div id="pnlMasterLeftOverlay" class="master-overlay-left overlay card border-top-0" style="display: none; position: absolute; left: 0; z-index: 3; height: 100%;">
<div id="pnlMasterLeftOverlay_Content" class="overlay-content" style="display: inline-block; width: 100%; padding-right: 5px; overflow-x: hidden; overflow-y: auto;">
</div>
</div>
<!-- right column overlay -->
<div id="pnlMasterRightOverlay" class="master-overlay-right overlay card shadow-lg border-top-0" style="display: none; position: absolute; right: 0; z-index: 3; height: 100%;">
<div id="pnlMasterRightOverlay_Header" class="overlay-header border" style="display: inline-block; width: 100%; min-height: 27px; padding: 3px 8px; background-color: #eee; overflow-x: hidden; overflow-y: auto;">
<button type="button" class="close" aria-label="Close" onclick="ShowRightOverlay(false)">
<span aria-hidden="true">×</span>
</button>
<div class="overlay-title font-16" style="padding-top: 3px; font-weight: bold;"></div>
</div>
<div class="overlay-content" style="display: inline-block; width: 100%; padding: 3px 7px; overflow-x: hidden; overflow-y: auto;">
</div>
</div>
<!-- right column (static) -->
<div id="pnlMasterRight" class="master-right card shadow" style="display: none; float: right; margin-left: 5px; overflow: hidden; border-left: 1px solid rgb(238, 238, 238);">
<div id="pnlMasterRight_Header" class="master-right-header border" style="display: inline-block; width: 100%; min-height: 27px; padding: 3px 8px; background-color: #eee; overflow-x: hidden; overflow-y: auto;">
<button type="button" class="close" aria-label="Close" onclick="ShowRightPanel(false)">
<span aria-hidden="true">×</span>
</button>
<div class="master-right-title font-16" style="padding-top: 3px; font-weight: bold;"></div>
</div>
<div id="pnlMasterRight_Content" class="master-right-content" style="display: inline-block; width: 100%; padding: 3px 7px; overflow-x: hidden; overflow-y: auto;">
</div>
</div>
<!-- main body (static) -->
<div id="pnlMasterContent" class="master-content" data-section="" data-subsection="" style="width: 1600px; padding: 2px 4px; float: right; overflow: hidden auto; height: 1113px;">
<input type="hidden" name="ctl00$MainContent$Demo" id="MainContent_Demo">
<input type="hidden" name="ctl00$MainContent$Key" id="MainContent_Key">
<input type="hidden" name="ctl00$MainContent$Alias" id="MainContent_Alias">
<input type="hidden" name="ctl00$MainContent$Tagline" id="MainContent_Tagline">
<input type="hidden" name="ctl00$MainContent$Position" id="MainContent_Position">
<input type="hidden" name="ctl00$MainContent$LatLng" id="MainContent_LatLng">
<input type="hidden" name="ctl00$MainContent$Zoom" id="MainContent_Zoom" value="11">
<input type="hidden" name="ctl00$MainContent$CityID" id="MainContent_CityID" value="0">
<div id="pnlMap" class="font-14 border shadow-sm rounded" style="width: 100%; margin: 0px; padding: 0px; overflow: hidden; height: 1109px;">
<div id="map" class="map mapboxgl-map" style="overflow: hidden; width: 1590px; height: 1107px;">
<div class="mapboxgl-canary" style="visibility: hidden;"></div>
<div class="mapboxgl-canvas-container mapboxgl-interactive mapboxgl-touch-drag-pan mapboxgl-touch-zoom-rotate"><canvas class="mapboxgl-canvas" tabindex="0" aria-label="Map" role="region" width="1590" height="1107"
style="width: 1590px; height: 1107px;"></canvas></div>
<div class="mapboxgl-control-container">
<div class="mapboxgl-ctrl-top-left"></div>
<div class="mapboxgl-ctrl-top-right">
<div class="mapboxgl-ctrl mapboxgl-ctrl-group"><button class="mapboxgl-ctrl-zoom-in" type="button" title="Zoom in" aria-label="Zoom in" aria-disabled="false"><span class="mapboxgl-ctrl-icon" aria-hidden="true"></span></button><button
class="mapboxgl-ctrl-zoom-out" type="button" title="Zoom out" aria-label="Zoom out" aria-disabled="false"><span class="mapboxgl-ctrl-icon" aria-hidden="true"></span></button><button class="mapboxgl-ctrl-compass" type="button"
title="Reset bearing to north" aria-label="Reset bearing to north"><span class="mapboxgl-ctrl-icon" aria-hidden="true" style="transform: rotate(0deg);"></span></button></div>
</div>
<div class="mapboxgl-ctrl-bottom-left">
<div class="mapboxgl-ctrl" style="display: block;"><a class="mapboxgl-ctrl-logo" target="_blank" rel="noopener nofollow" href="https://www.mapbox.com/" aria-label="Mapbox logo"></a></div>
</div>
<div class="mapboxgl-ctrl-bottom-right">
<div class="mapboxgl-ctrl mapboxgl-ctrl-attrib"><button class="mapboxgl-ctrl-attrib-button" title="Toggle attribution" aria-label="Toggle attribution"></button>
<div class="mapboxgl-ctrl-attrib-inner" role="list"><a href="https://www.mapbox.com/about/maps/" target="_blank" title="Mapbox" aria-label="Mapbox">© Mapbox</a>
<a href="https://www.openstreetmap.org/about/" target="_blank" title="OpenStreetMap" aria-label="OpenStreetMap">© OpenStreetMap</a>
<a class="mapbox-improve-map" href="https://apps.mapbox.com/feedback/?owner=ttwn&id=ckg15d94d02cw19mxew101vv2&access_token=pk.eyJ1IjoidHR3biIsImEiOiJjajIxM3FtZWQwMDB0MndxaXFyZXIzNDR1In0.FHH0LU0K4tnSB3vPf5jUEA" target="_blank" title="Map feedback" aria-label="Map feedback" rel="noopener nofollow">Improve this map</a>
</div>
</div>
</div>
</div>
</div>
<!-- map overlay form: traffic (exactly same as the map-right-overlay so we can have toggle between the two without rebuilding them) -->
<div class="map-right-traffic-overlay ui-progressbar-overlay card shadow-lg" style="position: absolute; z-index: 5; width: 25%; opacity: 0.9; right: 4px; top: 0px; height: 1111px;" data-position="">
<div class="overlay-header border" style="width: 100%; min-height: 27px; max-height: 35px; padding: 3px 8px; background-color: rgb(238, 238, 238); overflow: hidden;">
<button type="button" class="close" aria-label="Close" onclick="ShowMapTrafficInfo(false)">
<span aria-hidden="true">×</span>
</button>
<div class="overlay-title font-16" style="padding-top: 3px; font-weight: bold;">Traffic within view</div>
</div>
<div class="overlay-content" style="display: inline-block; width: 100%; height: calc(100% - 35px); padding: 3px 7px; overflow-x: hidden; overflow-y: auto;">
<div class="row" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; height: 25px; margin: 0 1px; padding: 5px 5px; overflow: hidden;">Traffic<span style="display: inline-block; float: right; margin-top: 4px; font-size: 11px; font-style: italic;">* delay in
minutes</span></div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;">Delay</div>
</div>
<div id="CCT-42443325" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Long-term road construction in Decatur on I-285 Outer loop between Flat Shoals Rd (GA-155)/Exit 48 and Glenwood Rd/Exit 44. Reported by GDOT</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;">23</div>
</div>
<div id="CCT-42443328" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Long-term road construction in Panthersville on I 20 EB between Columbia Dr/Exit 66 (EB) and Evans Mill Rd/Exit 74. Reported by GDOT</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;">7</div>
</div>
<div id="CCT-43124351" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Long-term road construction in Buckhead on GA-400 NB/SB between Old Toll Plaza and I-285/Exit 4. Reported by GDOT</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;">5</div>
</div>
<div id="CCT-42815119" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Repaving work in Georgia Tech on Howell Mill Rd NW NB/SB between 8th St NW and Holmes St NW/Chattahoochee Ave NW. Reported by ATLDOT</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;">2</div>
</div>
<div id="CCT-42443329" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Long-term road construction in Decatur on I-285 Inner loop between Glenwood Rd/Exit 44 and Flat Shoals Rd (GA-155)/Exit 48. Reported by GDOT</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;">1</div>
</div>
<div id="CCT-43226868" class="traffic row severity-moderate" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Road work. Off-ramp partially blocked in Doraville on I-285 EB off-ramp to NB I-85. Reported by GDOT<br><i class="font-12">ETC 4pm</i></div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;"></div>
</div>
<div id="CCT-43226416" class="traffic row severity-minor" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Road construction. Right lane closed in Sandy Springs on GA-400 NB at Glenridge Connector/Exit 3 (SB). Reported by GDOT<br><i class="font-12">ETC 3pm</i></div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;"></div>
</div>
<div id="CCT-43203079" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Bridge closed in Morningside on Cheshire Bridge Rd NB/SB between Liddell Dr NE and Faulkner Rd. Reported by ATLDOT</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;"></div>
</div>
<div id="CCT-43079856" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Water main replacement in Decatur on E Ponce De Leon Ave EB/WB between Grove Place and N Clarendon Ave. Reported by Press Release</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;"></div>
</div>
<div id="CCT-42956213" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Closed due to road construction in Atlanta on Lavista Rd EB/WB between Cheshire Bridge Rd and Lavista Walk. Reported by ATLDOT</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;"></div>
</div>
<div id="CCT-43112556" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Roundabout installation in South Fulton on Butner Rd EB/WB at Union Rd. Reported by GDOT</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;"></div>
</div>
<div id="CCT-42533167" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Road work. HOV lane closed in Smyrna on I 75 NB between Akers Mill Rd/Exit 258 (HOV NB) and I-75 Express Lanes/Exit 260 (NB). Reported by GDOT</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;"></div>
</div>
<div id="CCT-42866343" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Beltline Construction in Midtown on 10th St EB/WB at Monroe Dr. Reported by ATLDOT</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;"></div>
</div>
<div id="CCT-42896689" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Long-term road construction in Cumberland on Cumberland Blvd SE at Overton Park Dr</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;"></div>
</div>
<div id="CCT-41792284" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Long-term road construction in Marietta on Callaway Rd SW NB/SB between Austell Rd and Al Bishop Drive. Reported by GDOT</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;"></div>
</div>
<div id="CCT-41792273" class="traffic row severity-construction" style="width: 100%; margin: 1px 0; padding: 0;">
<div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">Long-term road construction in Conley on I-285 EB/WB between Moreland Ave (US-23)/Exit 53 and Bouldercrest Rd/Exit 51. Reported by GDOT</div>
<div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;"></div>
</div>
</div>
</div>
<!-- map affiliate overlay -->
<div class="map-affiliate-overlay ui-progressbar-overlay card shadow-lg" style="display: none; position: absolute; z-index: 3; width: calc(100% - 8px); opacity: 0.90;" data-position="">
<div class="overlay-header border" style="display: none; width: 100%; min-height: 27px; max-height: 35px; padding: 3px 8px; background-color: #eee; overflow: hidden;">
<button type="button" class="close" aria-label="Close" onclick="ShowMapOverlay({ type: 'affiliate', show: false})">
<span aria-hidden="true">×</span>
</button>
<div class="overlay-title font-16" style="padding-top: 3px; font-weight: bold;"></div>
</div>
<div class="overlay-content" style="display: inline-block; width: 100%; height: calc(100% - 35px); padding: 3px 7px; overflow-x: hidden; overflow-y: auto;"></div>
</div>
<!-- map route overlay -->
<div class="map-route-overlay ui-progressbar-overlay card shadow-lg" style="display: none; position: absolute; z-index: 5; width: calc(100% - 8px); opacity: 0.9; height: 85px;">
<div class="overlay-header border" style="display: none; width: 100%; min-height: 27px; max-height: 35px; padding: 3px 8px; background-color: #eee; overflow: hidden;">
<button type="button" class="close" aria-label="Close" onclick="ShowMapOverlay({ type: 'route', show: false })">
<span aria-hidden="true">×</span>
</button>
<div class="overlay-title font-16" style="padding-top: 3px; font-weight: bold;"></div>
</div>
<div class="overlay-content" style="display: inline-block; width: 100%; height: 80px; padding: 3px 7px; overflow: hidden auto;"></div>
</div>
<!-- map overlay form: top, left, right, bottom -->
<div class="map-top-overlay ui-progressbar-overlay card shadow-lg" style="display: none; position: absolute; z-index: 5; width: calc(100% - 8px); opacity: 0.90;">
<div class="overlay-header border" style="display: none; width: 100%; min-height: 27px; max-height: 35px; padding: 3px 8px; background-color: #eee; overflow: hidden;">
<button type="button" class="close" aria-label="Close" onclick="ShowMapOverlay({ type: 'top', show: false })">
<span aria-hidden="true">×</span>
</button>
<div class="overlay-title font-16" style="padding-top: 3px; font-weight: bold;"></div>
</div>
<div class="overlay-content" style="display: inline-block; width: 100%; height: calc(100% - 35px); padding: 3px 7px; overflow-x: hidden; overflow-y: auto;"></div>
</div>
<div class="map-left-overlay ui-progressbar-overlay card shadow-lg" style="position: absolute; z-index: 5; width: 170px; opacity: 0.9; left: 4px; top: 0px; height: 1111px;" data-position="">
<div class="overlay-header border" style="width: 100%; min-height: 27px; max-height: 35px; padding: 3px 8px; background-color: rgb(238, 238, 238); overflow: hidden;">
<button type="button" class="close" aria-label="Close" onclick="ShowMapMenu(false)" style="display: none;">
<span aria-hidden="true">×</span>
</button>
<div class="overlay-title font-16" style="padding-top: 3px; font-weight: bold;"><span class="clickable" style="display: inline-block; font-weight: bolder; opacity: 1.0 !important; margin-top: -7px !important; float: left;" title="Settings"
onclick="ShowMapMenu(false)"><span class="material-icons-outlined md-32">menu</span></span><span style="display: inline-block; margin-left: 10px; margin-top: -2px; float: left;">Settings</span></div>
</div>
<div class="overlay-content" style="display: inline-block; width: 100%; height: calc(100% - 35px); padding: 3px 7px; overflow-x: hidden; overflow-y: auto;">
<div id="pnlMenu"><span id="pnlMenuCity" style="display: block; margin: 2px 2px;" data-visible="true"><span class="font-bold header clickable" style="display: block;" onclick="Menu_ShowSection({ type: 'city' })">Change cities</span><span
class="content" style="display: block;"><select id="selMarket" class="form-control form-control-sm" onchange="Map_SwitchMarket(this.value)">
<option value="0" selected="" disabled="" hidden="">Select a city</option>
<option class="form-control-sm" value="33">Albany</option>
<option class="form-control-sm" value="96">Albuquerque</option>
<option class="form-control-sm" value="99">Allentown</option>
<option class="form-control-sm" value="202">Appleton/Oshkosh</option>
<option class="form-control-sm" value="157">Asheville</option>
<option class="form-control-sm" value="1">Atlanta</option>
<option class="form-control-sm" value="51">Augusta</option>
<option class="form-control-sm" value="63">Austin</option>
<option class="form-control-sm" value="117">Bakersfield</option>
<option class="form-control-sm" value="64">Baltimore</option>
<option class="form-control-sm" value="145">Baton Rouge</option>
<option class="form-control-sm" value="116">Biloxi-Gulfport</option>
<option class="form-control-sm" value="125">Binghamton</option>
<option class="form-control-sm" value="43">Birmingham</option>
<option class="form-control-sm" value="75">Boston</option>
<option class="form-control-sm" value="76">Buffalo</option>
<option class="form-control-sm" value="169">Cedar Rapids/Iowa City </option>
<option class="form-control-sm" value="34">Charleston</option>
<option class="form-control-sm" value="67">Charlotte</option>
<option class="form-control-sm" value="59">Chattanooga</option>
<option class="form-control-sm" value="18">Chicago</option>
<option class="form-control-sm" value="77">Cincinnati</option>
<option class="form-control-sm" value="50">Ciudad de Mexico, D. F.</option>
<option class="form-control-sm" value="78">Cleveland</option>
<option class="form-control-sm" value="90">Colorado Springs</option>
<option class="form-control-sm" value="73">Columbia</option>
<option class="form-control-sm" value="79">Columbus</option>
<option class="form-control-sm" value="168">Columbus, GA</option>
<option class="form-control-sm" value="179">Corpus Christi</option>
<option class="form-control-sm" value="2">Dallas</option>
<option class="form-control-sm" value="171">Davenport</option>
<option class="form-control-sm" value="112">Dayton</option>
<option class="form-control-sm" value="3">Denver</option>
<option class="form-control-sm" value="124">Des Moines</option>
<option class="form-control-sm" value="17">Detroit</option>
<option class="form-control-sm" value="139">El Paso</option>
<option class="form-control-sm" value="127">Erie</option>
<option class="form-control-sm" value="178">Florida Keys</option>
<option class="form-control-sm" value="89">Fort Collins</option>
<option class="form-control-sm" value="93">Fort Myers</option>
<option class="form-control-sm" value="94">Frederick</option>
<option class="form-control-sm" value="138">Fresno</option>
<option class="form-control-sm" value="164">Ft Wayne</option>
<option class="form-control-sm" value="186">Gainesville-Ocala</option>
<option class="form-control-sm" value="21">Grand Rapids</option>
<option class="form-control-sm" value="210">Green Bay, WI</option>
<option class="form-control-sm" value="68">Greensboro</option>
<option class="form-control-sm" value="53">Greenville</option>
<option class="form-control-sm" value="23">Harrisburg</option>
<option class="form-control-sm" value="160">Harrisonburg</option>
<option class="form-control-sm" value="47">Hartford/New Haven</option>
<option class="form-control-sm" value="191">Hattiesburg/Laurel</option>
<option class="form-control-sm" value="110">Honolulu</option>
<option class="form-control-sm" value="4">Houston</option>
<option class="form-control-sm" value="226">Huntington-Charleston</option>
<option class="form-control-sm" value="48">Huntsville</option>
<option class="form-control-sm" value="5">Indianapolis</option>
<option class="form-control-sm" value="158">Jackson</option>
<option class="form-control-sm" value="81">Jacksonville</option>
<option class="form-control-sm" value="72">Kansas City</option>
<option class="form-control-sm" value="161">Knoxville</option>
<option class="form-control-sm" value="6">Las Vegas</option>
<option class="form-control-sm" value="140">Lexington</option>
<option class="form-control-sm" value="91">Little Rock</option>
<option class="form-control-sm" value="56">Los Angeles</option>
<option class="form-control-sm" value="7">Louisville</option>
<option class="form-control-sm" value="22">Macon</option>
<option class="form-control-sm" value="115">Madison</option>
<option class="form-control-sm" value="114">McAllen</option>
<option class="form-control-sm" value="42">Memphis</option>
<option class="form-control-sm" value="82">Miami/Fort Lauderdale</option>
<option class="form-control-sm" value="66">Milwaukee</option>
<option class="form-control-sm" value="41">Minneapolis</option>
<option class="form-control-sm" value="83">Mobile/Pensacola</option>
<option class="form-control-sm" value="159">Monterey-Salinas</option>
<option class="form-control-sm" value="141">Montgomery</option>
<option class="form-control-sm" value="146">Montreal</option>
<option class="form-control-sm" value="187">Myrtle Beach</option>
<option class="form-control-sm" value="65">Nashville</option>
<option class="form-control-sm" value="55">New Orleans</option>
<option class="form-control-sm" value="24">Norfolk</option>
<option class="form-control-sm" value="12">NYC</option>
<option class="form-control-sm" value="62">Oklahoma City</option>
<option class="form-control-sm" value="30">Omaha</option>
<option class="form-control-sm" value="69">Orlando</option>
<option class="form-control-sm" value="147">Ottawa</option>
<option class="form-control-sm" value="182">Pachuca, MX</option>
<option class="form-control-sm" value="119">Panama City</option>
<option class="form-control-sm" value="224">Parkersburg/Marietta</option>
<option class="form-control-sm" value="11">Philadelphia</option>
<option class="form-control-sm" value="8">Phoenix</option>
<option class="form-control-sm" value="37">Pittsburgh</option>
<option class="form-control-sm" value="39">Portland</option>
<option class="form-control-sm" value="88">Portsmouth/Manchester</option>
<option class="form-control-sm" value="80">Providence</option>
<option class="form-control-sm" value="184">Puebla, MX</option>
<option class="form-control-sm" value="183">Queretara, MX</option>
<option class="form-control-sm" value="70">Raleigh-Durham</option>
<option class="form-control-sm" value="142">Reading</option>
<option class="form-control-sm" value="111">Richmond</option>
<option class="form-control-sm" value="170">Roanoke/Lynchburg</option>
<option class="form-control-sm" value="87">Rochester, NY</option>
<option class="form-control-sm" value="57">Sacramento</option>
<option class="form-control-sm" value="54">Salt Lake City</option>
<option class="form-control-sm" value="9">San Antonio</option>
<option class="form-control-sm" value="36">San Diego</option>
<option class="form-control-sm" value="35">San Francisco/San Jose</option>
<option class="form-control-sm" value="121">Sarasota</option>
<option class="form-control-sm" value="52">Savannah</option>
<option class="form-control-sm" value="84">Seattle</option>
<option class="form-control-sm" value="60">Spokane</option>
<option class="form-control-sm" value="46">Springfield</option>
<option class="form-control-sm" value="192">Springfield, MO</option>
<option class="form-control-sm" value="19">St. Louis</option>
<option class="form-control-sm" value="151">Stockton / Modesto</option>
<option class="form-control-sm" value="44">Syracuse</option>
<option class="form-control-sm" value="118">Tallahassee</option>
<option class="form-control-sm" value="20">Tampa</option>
<option class="form-control-sm" value="25">Toledo</option>
<option class="form-control-sm" value="148">Toronto</option>
<option class="form-control-sm" value="10">Tucson</option>
<option class="form-control-sm" value="61">Tulsa</option>
<option class="form-control-sm" value="49">Tuscaloosa</option>
<option class="form-control-sm" value="152">Vancouver</option>
<option class="form-control-sm" value="40">Washington</option>
<option class="form-control-sm" value="85">West Palm Beach/Treasure Coast</option>
<option class="form-control-sm" value="97">Wheeling</option>
<option class="form-control-sm" value="155">Wichita</option>
<option class="form-control-sm" value="165">Wilkes-Barre</option>
<option class="form-control-sm" value="172">Williamsport</option>
<option class="form-control-sm" value="98">Worcester</option>
<option class="form-control-sm" value="177">Youngstown</option>
</select></span></span><span id="pnlMenuFeature" class="font-14" style="display: block; margin: 2px 2px;" data-visible="true"><span class="font-bold header clickable"
style="display: block; margin-bottom: 5px; margin-top: 15px !important;" onclick="Menu_ShowSection({ type: 'feature' })">Toggle view on/off</span><span class="content" style="display: block;"><span
class="form-major-roadway-item form-check form-check-inline"><input class="form-check-input" type="checkbox" checked="checked" value="0,1,2,3" id="chkMajorRoadway" onchange="Map_SettingsOnChange()"><label class="form-check-label"
for="chkMajorRoadway" style="width: 100%;">Major roadway</label></span><span class="form-local-roadway-item form-check form-check-inline"><input class="form-check-input" type="checkbox" value="4,5,6,7" id="chkLocalRoadway"
onchange="Map_SettingsOnChange()"><label class="form-check-label" for="chkLocalRoadway" style="width: 100%;">Local roadway</label></span><span class="form-traffic-item form-check form-check-inline"><input class="form-check-input"
type="checkbox" checked="checked" value="true" id="chkTraffic" onchange="Map_SettingsOnChange()"><label class="form-check-label" for="chkTraffic" style="width: 100%;">Traffic icon</label></span><span
class="form-traffic-list-item form-check form-check-inline"><input class="form-check-input" type="checkbox" checked="checked" value="true" id="chkTrafficList" onchange="Map_SettingsOnChange()"><label class="form-check-label"
for="chkTrafficList" style="width: 100%;">Traffic list</label></span><span class="form-camera-stream-item form-check form-check-inline"><input class="form-check-input" type="checkbox" checked="checked" value="true"
id="chkCamStream" onchange="Map_SettingsOnChange()"><label class="form-check-label" for="chkCamStream" style="width: 100%;">Camera stream</label></span><span class="form-camera-still-item form-check form-check-inline"><input
class="form-check-input" type="checkbox" checked="checked" value="true" id="chkCamStill" onchange="Map_SettingsOnChange()"><label class="form-check-label" for="chkCamStill" style="width: 100%;">Camera
still</label></span></span></span><span id="pnlMenuAction" class="font-14" style="display: block; margin: 2px 2px; margin-top: 15px !important;" data-visible="true"><span class="font-bold header clickable"
style="display: block; margin-bottom: 5px;" onclick="Menu_ShowSection({ type: 'action' })">Click map action</span><span class="content" style="display: block;"><span class="form-action-route-item form-check form-check-inline"><input
class="form-check-input" type="radio" checked="checked" id="chkActionSpeed" name="chkPageAction" value="speed" onchange="Page_ActionOnChange()"><label class="form-check-label" for="chkActionSpeed" style="width: 100%;">Show
speed</label></span><span class="form-action-route-item form-check form-check-inline"><input class="form-check-input" type="radio" id="chkActionRoute" name="chkPageAction" value="route" onchange="Page_ActionOnChange()"><label
class="form-check-label" for="chkActionRoute" style="width: 100%;">Build route</label></span></span></span><span style="position: absolute; bottom: 35px;"><span id="pnlMenuHelp" style="display: block;" data-visible="false"><span
class="font-bold header clickable" style="display: block;" onclick="Menu_ShowSection({ type: 'help' })">Help</span><span class="content" style="display: none;"><span class="font-13"
style="display: block;"><a class="reverse" href="/About" target="_blank">Contact us</a></span><span class="font-13" style="display: block;"><a class="reverse" href="/Privacy" target="_blank">Pricacy policy</a></span><span
class="font-13" style="display: block;"><a class="reverse" href="/Terms" target="_blank">Terms of service</a></span></span></span><span id="pnlMenuLegend" style="display: block; margin-top: 15px;" data-visible="false"><span
class="font-bold header clickable" style="display: block;" onclick="Menu_ShowSection({ type: 'legend' })">Legend</span><span class="content" style="display: none;"><span class="font-13" style="display: block;"><span
class="severity-key-extreme severity-extreme shadow rounded" style="display: inline-block; float: left; width: 21px; height: 8px; margin-top: 6px;"></span><span style="display: inline-block; margin-left: 5px;">Stopped
traffic</span></span><span class="font-13" style="display: block;"><span class="severity-key-major severity-major shadow rounded"
style="display: inline-block; float: left; width: 21px; height: 8px; margin-top: 6px;"></span><span style="display: inline-block; margin-left: 5px;">Stop and go traffic</span></span><span class="font-13"
style="display: block;"><span class="severity-key-moderate severity-moderate shadow rounded" style="display: inline-block; float: left; width: 21px; height: 8px; margin-top: 6px;"></span><span
style="display: inline-block; margin-left: 5px;">Slow traffic</span></span><span class="font-13" style="display: block;"><span class="severity-key-minor severity-minor shadow rounded"
style="display: inline-block; float: left; width: 21px; height: 8px; margin-top: 6px;"></span><span style="display: inline-block; margin-left: 5px;">Heavy traffic</span></span><span class="font-13" style="display: block;"><span
class="severity-key-freely severity-freely shadow rounded" style="display: inline-block; float: left; width: 21px; height: 8px; margin-top: 6px;"></span><span style="display: inline-block; margin-left: 5px;">No
congestion</span></span><span class="font-11" style="display: block; margin-top: 10px;">* click any congestion lines to get details</span></span></span></span></div>
</div>
</div>
<div class="map-right-overlay ui-progressbar-overlay card shadow-lg" style="display: none; position: absolute; z-index: 5; width: calc(100% - 8px); opacity: 0.90;">
<div class="overlay-header border" style="display: none; width: 100%; min-height: 27px; max-height: 35px; padding: 3px 8px; background-color: #eee; overflow: hidden;">
<button type="button" class="close" aria-label="Close" onclick="ShowMapOverlay({ type: 'right', show: false })">
<span aria-hidden="true">×</span>
</button>
<div class="overlay-title font-16" style="padding-top: 3px; font-weight: bold;"></div>
</div>
<div class="overlay-content" style="display: inline-block; width: 100%; height: calc(100% - 35px); padding: 3px 7px; overflow-x: hidden; overflow-y: auto;"></div>
</div>
<div class="map-bottom-overlay ui-progressbar-overlay card shadow-lg" style="position: absolute; z-index: 6; width: 170px; opacity: 0.9; bottom: 2px; height: 29px;" data-position="">
<div class="overlay-header border" style="display: none; width: 100%; min-height: 27px; max-height: 35px; padding: 3px 8px; background-color: #eee; overflow: hidden;">
<button type="button" class="close" aria-label="Close" onclick="ShowMapOverlay({ type: 'bottom', show: false})">
<span aria-hidden="true">×</span>
</button>
<div class="overlay-title font-16" style="padding-top: 3px; font-weight: bold;"></div>
</div>
<div class="overlay-content" style="display: inline-block; width: 100%; height: 27px; padding: 3px 7px; overflow: hidden;"><span data-toggle="tooltip" data-placement="top"
style="display: inline-block; cursor: default; white-space: nowrap; overflow: hidden;">Last updated: <b>11:13 AM</b></span></div>
</div>
</div>
<script type="text/javascript">
//define page global variables
var demo = '';
var key = '';
var alias = '';
var tagline = '';
var position = '';
var latlng = '';
var zoom = '11';
var cityId = '0';
var oCity = null;
var maxSavedRoute = 7;
//validate parameters passed in
if (typeof demo == 'string' && demo > '') demo = parseInt(demo);
else demo = 0;
if (typeof zoom == 'string' && zoom > '') zoom = parseInt(zoom);
else zoom = 11;
if (typeof cityId == 'string' && cityId > '') cityId = parseInt(cityId);
else cityId = 0;
if (latlng == '') latlng = null;
//determine which site theme color: [classic, light]
var theme = "";
if (theme == null || theme == 'classic') theme = '';
//define the language / speed type = [mph, kph]
var speedType = "mph";
var language = "EN";
if (language != 'EN') speedType = "kph";
//get window dimension
var wdWidth = $(window).width();
var wdHeight = $(window).height();
//map default panel overlay dimension (if available)
var minPanelWidth = 500;
var minPanelHeight = 650;
var plWidth = 170;
var pbHeight = 29;
var plIconWidth = 50;
var plIconHeight = 48;
var prWidth = "25%";
if (typeof isMobile != 'undefined' && typeof mobileType != 'undefined' && isMobile == true) {
prWidth = "40%";
}
//default map settings
var defaultAction = 'speed'; //action = [speed (default), travel] when roadway is clicked/right-clicked
//define the default settings: traffic, camera, travel
//NOTE: congestiontype = [speed (pure speed), speedoverride (allow override speed)]
var defaulMenuSettings = {
city: true,
feature: true,
action: true,
help: false,
legend: false
};
var defaultCameraSettings = {
stream: true,
still: true
};
var defaultTrafficSettings = {
congestion: true,
congestiontype: "speedoverride",
type: "flow,incident,construction,event,transit",
list: true,
frc: "0,1,2,3"
};
if (typeof isMobile != 'undefined' && typeof mobileType != 'undefined' && isMobile == true && mobileType != 'ipad') defaultTrafficSettings.list = false;
var defaultRouteSettings = {
id: null,
city: 0,
title: null,
description: null,
start: null,
end: null,
routes: null
};
//update default settings for demo account (preview account)
if (demo == 1) {
defaultTrafficSettings.list = false;
}
//get all accessible market object
var accessibleCityId = null;
if (typeof gblValidCityId != 'undefined' && gblValidCityId != null && gblValidCityId.length > 0) accessibleCityId = gblValidCityId.join(",");
var marketOptions = [];
var arrMarket = GetCityData({
fetch: true,
map: true,
id: accessibleCityId,
sort: "name"
});
if (typeof arrMarket == 'undefined' || arrMarket == null) arrMarket = [];
if (arrMarket.length > 0) {
//add first item
var item = '<option value="0" selected disabled hidden>Select a city</option>';
marketOptions.push(item);
//build the menu options (only once)
var lenMarket = arrMarket.length;
for (var i = 0; i < lenMarket; i++) {
var aCity = arrMarket[i];
if (typeof aCity.properties != 'undefined') aCity = aCity.properties;
var aId = aCity.id;
var aName = aCity.name;
var isValid = true;
if (isValid == true && typeof aCity.status != 'undefined' && aCity.status != null && typeof aCity.status.active != 'undefined' && aCity.status.active != null && aCity.status.active == false) isValid = false;
if (isValid == true && typeof aCity.status != 'undefined' && aCity.status != null && typeof aCity.status.private != 'undefined' && aCity.status.private != null && aCity.status.private == true) isValid = false;
//error check T3 markets
if (aName.indexOf("-T3") >= 0) {
aName = aName.replace("-T3", "").trim();
//validate if this market name is already used
var chkName = arrMarket.find(x => x.properties.name == aName && x.properties.id != aId);
if (chkName != null) {
//another market exists with same name
isValid = false;
} else {
//no other market contains this, rename it
aCity.name = aName;
}
}
if (isValid == true) {
var item = '<option class="form-control-sm" value="' + aId + '">' + aName + '</option>';
marketOptions.push(item);
}
}
}
//validate the latlng (if needed)
if (latlng != null && typeof latlng == 'string' && latlng > '') {
var aLat = null;
var aLng = null;
//error check the delimitor passed in, convert to comma
latlng = latlng.trim();
if (latlng.indexOf("/") > 0) latlng = latlng.replace("/", ",");
else if (latlng.indexOf(";") > 0) latlng = latlng.replace(";", ",");
else if (latlng.indexOf(" ") > 0) latlng = latlng.replace(" ", ",");
else if (latlng.indexOf("|") > 0) latlng = latlng.replace("|", ",");
var aLatLng = latlng.split(",");
if (aLatLng != null && aLatLng.length == 2) {
aLat = aLatLng[0];
aLng = aLatLng[1];
if (typeof aLat == 'string') aLat = parseFloat(aLat);
if (typeof aLng == 'string') aLng = parseFloat(aLng);
}
//get nearest cityId (if available)
if (cityId <= 0 && arrMarket != null && arrMarket.length > 0 && aLat != null && aLng != null) {
oCity = GetCityData({
data: arrMarket,
nearestlatlng: latlng,
nearest: true,
fetch: true
});
if (oCity != null) {
if (typeof oCity.properties != 'undefined') oCity = oCity.properties;
//get this nearby market's location to go to
if (typeof oCity.location != 'undefined' && oCity.location != null && typeof oCity.location.lat != 'undefined' && typeof oCity.location.lng != 'undefined' && oCity.location.lat != null && oCity.location.lng != null) {
aLat = oCity.location.lat;
aLng = oCity.location.lng;
}
if (typeof oCity.id != 'undefined' && oCity.id != null) cityId = oCity.id;
if (typeof cityId == 'string') cityId = parseInt(cityId);
} else {
oCity = null;
}
}
if (aLat != null && aLng != null) latlng = new LatLng(aLat, aLng);
else latlng = null;
}
//OVERWRITE: get previously saved viewstate info to overwrite when no params passed in: city, map
if (latlng == null && cityId <= 0) {
//only load previous info (if no param passed in)
var pCity = GetViewstateProp("city");
if (pCity != null) {
if (typeof pCity.properties != 'undefined') pCity = pCity.properties;
//save it
oCity = pCity;
cityId = oCity.id;
}
//get the previously viewed center point
var pMap = GetViewstateProp("map");
if (pMap != null) {
if (typeof pMap.center != 'undefined') latlng = pMap.center;
if (typeof pMap.zoom != 'undefined') zoom = pMap.zoom;
}
}
//DEFAULT: auto-load Atlanta first time hitting the site
if (cityId <= 0) {
cityId = 1;
latlng = null;
}
//initialize variables (market and lat/lng info if needed)
if (cityId > 0 && (oCity == null || latlng == null)) {
if (oCity == null) {
oCity = GetCityData({
data: arrMarket,
id: cityId,
fetch: true
});
if (typeof oCity.properties != 'undefined') oCity = oCity.properties;
}
if (latlng == null && oCity != null && typeof oCity.location != 'undefined' && oCity.location != null && typeof oCity.location.lat != 'undefined' && typeof oCity.location.lng != 'undefined' && oCity.location.lat != null && oCity.location
.lng != null) {
latlng = new LatLng(oCity.location.lat, oCity.location.lng);
}
}
//save viewstate info: city
if (oCity != null) {
SaveViewstateProp({
city: oCity
});
}
//current page viewstate
var oPage = {
id: "map",
menu: Object.copy(defaulMenuSettings),
action: defaultAction,
traffic: Object.copy(defaultTrafficSettings),
camera: Object.copy(defaultCameraSettings),
route: Object.copy(defaultRouteSettings)
};
//DISABLE "action" (until route logic figured out)
//get previous session page viewstate (if saved) latest settings and update the page variables
if (demo == 0) {
//if NOT demo account, get saved viewstate to use as initial page variables
var pPage = GetPageViewstate();
if (typeof pPage != 'undefined' && pPage != null) {
if (typeof pPage.action != 'undefined' && pPage.action != null) oPage.action = pPage.action;
if (typeof pPage.traffic != 'undefined' && pPage.traffic != null) oPage.traffic = pPage.traffic;
if (typeof pPage.camera != 'undefined' && pPage.camera != null) oPage.camera = pPage.camera;
if (typeof pPage.menu != 'undefined' && pPage.menu != null) oPage.menu = pPage.menu;
}
}
//DISABLE "action" (until route logic figured out)
//FEATURE: (1) allow saving a "previous" created route's they built (similar to how google tracks your previous map searches for easy access)
//NOTE: format similar to travel settings but only the settings part since we will need to fetch the latest speed data for each location
//format: { id: {roadwayId}_{dirCode}_{startId}_{endId}, roadway: null, dircode: null, start: null, end: null, title: null }
var arrRoute = [];
//var pRoute = GetRouteViewstate();
//if (typeof pRoute != 'undefined' && pRoute != null && pRoute.length > 0)
// arrRoute = pRoute;
////remove all local storage data
//DeleteAllStorage();
//get affiliate info
var oAffiliate = null;
if (key != null && key > '') {
oAffiliate = GetAffiliateData({
callsign: key,
fetch: true
});
if (Array.isArray(oAffiliate) == true) {
if (oAffiliate.length > 0) oAffiliate = oAffiliate[0];
else oAffiliate = null;
}
}
if (demo == 1) {
//demo version, override affiliate object
//if no account exists, create "fake" account
if (oAffiliate == null) oAffiliate = {
id: "",
active: false,
callsign: "",
name: "",
alias: "",
logo: "",
url: "",
description: "",
notes: "",
position: null,
lat: null,
lng: null,
geopoint: null,
cityid: 0,
accessiblecity: null
};
//override some properites (if passed in)
if (cityId != null && cityId > 0) oAffiliate.cityid = cityId;
if (key != null && key > '') oAffiliate.callsign = key;
if (alias != null && alias > '') oAffiliate.alias = alias;
if (tagline != null && tagline > '') oAffiliate.description = tagline;
if (position != null && position > '') oAffiliate.position = position;
if (latlng != null && typeof latlng == 'string' && latlng > '') {
var aLat = null;
var aLng = null;
var aLatLng = latlng.split(",");
if (aLatLng != null && aLatLng.length == 2) {
aLat = aLatLng[0];
aLng = aLatLng[1];
if (typeof aLat == 'string') aLat = parseFloat(aLat);
if (typeof aLng == 'string') aLng = parseFloat(aLng);
//save it
oAffiliate.lat = aLat;
oAffiliate.lng = aLng;
}
}
}
/* MENU FUNCTIONS */
//handler to manage the action for click/right-click on the map
function Page_ActionOnChange() {
//get the action value
var pnlMenu = $("#pnlMenu");
var action = pnlMenu.find("input[name='chkPageAction']:checked").val();
//save the page settings
var oRouteSettings = Object.copy(defaultRouteSettings);
SavePageProp([{
name: "action",
value: action
}, {
name: "route",
value: oRouteSettings
}]);
//save the traffic congestion flag FIRST, before updating to new one when switching between the two actions?
//turn on/off flow layers
if (action == 'speed') {
//turn back on flow layers: (a) turn on what needs to be visible
Map_ShowCongestion();
//hide any route info
Route_ClearMap();
ShowRouteMenu(false);
} else if (action == 'route') {
//turn off flow layers: (a) show all possible features, (b) set visibility=0
Map_ShowCongestion(false);
//show the route menu UI
ShowRouteMenu();
}
//save latest map viewstate changes
SavePageProp({
traffic: oPage.traffic
});
SaveMapViewstate();
}
//show / hide affiliate info on map (if available)
function ShowAffiliateOnMap(options) {
var show = true;
var width = null;
var height = null;
var overlayPosition = null;
var opacity = null;
//get options passed in
if (options != null && typeof options != 'undefined') {
if (typeof options == 'object') {
if (typeof options.show != 'undefined') show = options.show;
if (typeof options.width != 'undefined') width = options.width;
if (typeof options.height != 'undefined') height = options.height;
if (typeof options.position != 'undefined') overlayPosition = options.position;
if (typeof options.opacity != 'undefined') opacity = options.opacity;
} else if (typeof options == 'boolean') {
show = options;
} else {
show = (options.toString().toLowerCase() == 'true');
}
}
//error check
if (width == null) width = plIconWidth;
if (height == null) height = plIconHeight;
if (overlayPosition == null) overlayPosition = "bottom";
if (opacity == null) opacity = 0.90;
//error check screen size (if too small do not show)
//validate: (1) only show if there is an affiliate object (or demo object), (2) must have logo/text
var logo = "";
if (oAffiliate == null) show = false;
else if (oAffiliate != null) {
//get the position (if available)
if (typeof oAffiliate.position != 'undefined' && oAffiliate.position != null && oAffiliate.position > '') {
overlayPosition = oAffiliate.position;
}
//logo/text priority: (1) logo, (2) text
if (typeof oAffiliate.logo != 'undefined' && oAffiliate.logo != null && oAffiliate.logo > '') {
//image logo
logo = '<img width="25px" height="25px" src="' + oAffiliate.logo + '" />';
} else {
//text: {alias, callsign, name}: {tagline}
if (typeof oAffiliate.alias != 'undefined' && oAffiliate.alias != null && oAffiliate.alias > '') logo = oAffiliate.alias;
else if (typeof oAffiliate.callsign != 'undefined' && oAffiliate.callsign != null && oAffiliate.callsign > '') logo = oAffiliate.callsign.toUpperCase();
else if (typeof oAffiliate.name != 'undefined' && oAffiliate.name != null && oAffiliate.name > '') logo = oAffiliate.name;
//add tagline
if (typeof oAffiliate.description != 'undefined' && oAffiliate.description != null && oAffiliate.description > '') {
if (logo > '') logo += ": ";
logo += oAffiliate.description;
}
}
//validate position = menu (MUST have a logo icon)
if (overlayPosition == 'menu' && logo != null && logo.indexOf('<img') < 0) {
//no icon exists for position=menu, change it to display at bottom
overlayPosition = 'bottom';
}
}
//validate: (1) logo/text exists, (2) not position=menu (this will be replacing the settings icon)
if (logo == null || logo == "") show = false;
if (show == true && overlayPosition != null && overlayPosition == 'menu') show = false;
//make sure the page size is correct
PageResize();
//determine action to take
if (show == true) {
var content = '<span class="logo font-16 font-bold" style="padding: 2px 0; white-space: nowrap;">' + logo + '</span>';
ShowMapOverlay({
type: "affiliate",
close: false,
position: overlayPosition,
float: "right",
height: "30px",
content: content,
overflow: "hidden",
opacity: opacity
});
//adjust the width/height based on the content's width/height
Affiliate_OnResize();
} else {
//hide panel
ShowMapOverlay({
type: "affiliate",
show: false
});
}
}
//handler to move/resize the affiliate logo/text overlay
function Affiliate_OnResize(options) {
var oOverlay = $(".map-affiliate-overlay");
var oOverlayContent = oOverlay.find(".overlay-content");
var oOverlayLogo = oOverlayContent.find(".logo");
//initialize variables
var width = null;
var height = null;
var opacity = null;
var overlayPosition = null;
var marginLeft = null;
var marginRight = null;
var marginTop = null;
var marginBottom = null;
//get options passed in
if (options != null && typeof options != 'undefined') {
if (typeof options == 'object') {
if (typeof options.width != 'undefined') width = options.width;
if (typeof options.height != 'undefined') height = options.height;
if (typeof options.opacity != 'undefined') opacity = options.opacity;
if (typeof options.position != 'undefined') overlayPosition = options.position;
if (typeof options.marginleft != 'undefined') marginLeft = options.marginleft;
if (typeof options.marginright != 'undefined') marginRight = options.marginright;
if (typeof options.margintop != 'undefined') marginTop = options.margintop;
if (typeof options.marginbottom != 'undefined') marginBottom = options.marginbottom;
}
}
if (oOverlay.length > 0 && oOverlay.is(":visible") == true) {
//get default: (a) position
if (overlayPosition == null || overlayPosition == '') {
//get data from overlay panel (if available)
overlayPosition = oOverlay.attr("data-position");
if (typeof overlayPosition == 'undefined' || overlayPosition == null) overlayPosition = '';
}
//determine the width/height
if (width == null || height == null) {
//define the size
var padding = 10;
var paddingWidth = 6;
var paddingHeight = 4;
width = oOverlayLogo.width() + padding + paddingWidth;
height = oOverlayLogo.height() + padding + paddingHeight;
}
//determine the margin info
if (overlayPosition == 'top' || overlayPosition == 'bottom') {
//get default (or reset to default)
if (overlayPosition == "top") {
marginTop = "12px";
marginRight = "45px";
} else {
marginBottom = "20px";
}
//determine any special movement: (1) right panel is open: (a) speed overlay, (b) traffic overlay
var isSpeedOverlayOpen = IsMapOverlayOpen("right");
var isTrafficOverlayOpen = IsMapOverlayOpen("right-traffic");
if ((isSpeedOverlayOpen == true || isTrafficOverlayOpen == true) && (overlayPosition == 'top' || overlayPosition == 'bottom')) {
if (overlayPosition == 'top') {
marginTop = "3px";
} else if (overlayPosition == 'bottom') {
marginBottom = "4px";
}
}
}
//resize/move overlay
if (width != null || height != null || opacity != null || marginLeft != null || marginRight != null || marginTop != null || marginBottom != null) ResizeMapOverlay({
type: "affiliate",
width: width,
height: height,
opacity: opacity,
marginleft: marginLeft,
marginright: marginRight,
margintop: marginTop,
marginbottom: marginBottom
});
}
}
//show / hide map menu options on the left panel
function ShowMapMenu(options) {
var show = true;
var width = null;
var height = null;
//get options passed in
if (options != null && typeof options != 'undefined') {
if (typeof options == 'object') {
if (typeof options.show != 'undefined') show = options.show;
if (typeof options.width != 'undefined') width = options.width;
if (typeof options.height != 'undefined') height = options.height;
} else if (typeof options == 'boolean') {
show = options;
} else {
show = (options.toString().toLowerCase() == 'true');
}
}
//error check
if (width == null) width = plWidth;
if (wdWidth <= minPanelWidth) width = "100%";
//error check screen size (if too small do not show)
//make sure the page size is correct
PageResize();
if (show == true) {
//close any map info window (if opened)
CloseInfoWindow();
//get the current menu options
var oMenuSettings = GetPageProp("menu");
//show: show OPEN menu options
var icon =
'<span class="clickable" style="display: inline-block; font-weight: bolder; opacity: 1.0 !important; margin-top: -7px !important; float: left;" title="Settings" onclick="ShowMapMenu(false)"><span class="material-icons-outlined md-32">menu</span></span>';
var title = icon + '<span style="display: inline-block; margin-left: 10px; margin-top: -2px; float: left;">Settings</span>';
//FUTURE: build city menu options (allow user to jump to specific markets)
var menuMarkets = '';
if (marketOptions != null && marketOptions.length > 0) {
var selMarkets = '<select id="selMarket" class="form-control form-control-sm" onchange="Map_SwitchMarket(this.value)">';
selMarkets += marketOptions.join("");
selMarkets += '</select>';
//deteremine visibility state
var secMarketVisible = "true";
var secMarketDisplay = "block";
if (oMenuSettings != null && typeof oMenuSettings.city != 'undefined' && oMenuSettings.city == false) {
secMarketVisible = "false";
secMarketDisplay = "none";
}
menuMarkets = '<span id="pnlMenuCity" style="display: block; margin: 2px 2px;" data-visible="' + secMarketVisible + '">';
menuMarkets += '<span class="font-bold header clickable" style="display: block;" onclick="Menu_ShowSection({ type: \'city\' })">Change cities</span>';
menuMarkets += '<span class="content" style="display: ' + secMarketDisplay + ';">' + selMarkets + '</span>';
menuMarkets += '</span>';
}
//get current map settings for the checkboxes
var oTrafficSettings = GetPageProp("traffic");
var oCameraSettings = GetPageProp("camera");
var chkMajorRoadway = '';
var chkLocalRoadway = '';
var chkTraffic = '';
var chkTrafficList = '';
var cssTrafficList = '';
var chkCameraStream = '';
var cssCameraStream = '';
var chkCameraStill = '';
if (typeof oTrafficSettings.frc != 'undefined') {
var chkFrc = oTrafficSettings.frc;
if (Array.isArray(chkFrc) == false) {
if (typeof chkFrc != 'string') chkFrc = chkFrc.toString();
chkFrc = chkFrc.split(',');
}
if (chkFrc.indexOf("2") >= 0) chkMajorRoadway = 'checked="checked"';
if (chkFrc.indexOf("6") >= 0) chkLocalRoadway = 'checked="checked"';
}
if (typeof oTrafficSettings.type != 'undefined' && oTrafficSettings.type != null && oTrafficSettings.type > '') chkTraffic = 'checked="checked"';
if (typeof oTrafficSettings.list != 'undefined' && oTrafficSettings.list != null && oTrafficSettings.list == true) chkTrafficList = 'checked="checked"';
if (oCameraSettings != null) {
if (typeof oCameraSettings.stream != 'undefined' && oCameraSettings.stream != null && oCameraSettings.stream == true) chkCameraStream = 'checked="checked"';
if (typeof oCameraSettings.still != 'undefined' && oCameraSettings.still != null && oCameraSettings.still == true) chkCameraStill = 'checked="checked"';
}
if (typeof isMobile != 'undefined' && typeof mobileType != 'undefined' && isMobile == true && mobileType != 'ipad') {
cssTrafficList = ' style="display: none;"';
cssCameraStream = ' style="display: none;"';
}
//deteremine visibility state
var secFeatureVisible = "true";
var secFeatureDisplay = "block";
if (oMenuSettings != null && typeof oMenuSettings.feature != 'undefined' && oMenuSettings.feature == false) {
secFeatureVisible = "false";
secFeatureDisplay = "none";
}
//build menu features options: (1) turn on/off the congestion layer (major and local roadways), (2) turn on/off traffic icons, (2) turn on/off cameras (stream, still)
var menuMajorRoadway = '<span class="form-major-roadway-item form-check form-check-inline"><input class="form-check-input" type="checkbox" ' + chkMajorRoadway +
' value="0,1,2,3" id="chkMajorRoadway" onchange="Map_SettingsOnChange()" /><label class="form-check-label" for="chkMajorRoadway" style="width: 100%;">Major roadway</label></span>';
var menuLocalRoadway = '<span class="form-local-roadway-item form-check form-check-inline"><input class="form-check-input" type="checkbox" ' + chkLocalRoadway +
' value="4,5,6,7" id="chkLocalRoadway" onchange="Map_SettingsOnChange()" /><label class="form-check-label" for="chkLocalRoadway" style="width: 100%;">Local roadway</label></span>';
var menuTraffic = '<span class="form-traffic-item form-check form-check-inline"><input class="form-check-input" type="checkbox" ' + chkTraffic +
' value="true" id="chkTraffic" onchange="Map_SettingsOnChange()" /><label class="form-check-label" for="chkTraffic" style="width: 100%;">Traffic icon</label></span>';
var menuTrafficList = '<span class="form-traffic-list-item form-check form-check-inline"' + cssTrafficList + '><input class="form-check-input" type="checkbox" ' + chkTrafficList +
' value="true" id="chkTrafficList" onchange="Map_SettingsOnChange()" /><label class="form-check-label" for="chkTrafficList" style="width: 100%;">Traffic list</label></span>';
var menuCameraStream = '<span class="form-camera-stream-item form-check form-check-inline"' + cssCameraStream + '><input class="form-check-input" type="checkbox" ' + chkCameraStream +
' value="true" id="chkCamStream" onchange="Map_SettingsOnChange()" /><label class="form-check-label" for="chkCamStream" style="width: 100%;">Camera stream</label></span>';
var menuCameraStill = '<span class="form-camera-still-item form-check form-check-inline"><input class="form-check-input" type="checkbox" ' + chkCameraStill +
' value="true" id="chkCamStill" onchange="Map_SettingsOnChange()" /><label class="form-check-label" for="chkCamStill" style="width: 100%;">Camera still</label></span>';
var featureContent = '<span class="content" style="display: ' + secFeatureDisplay + ';">' + menuMajorRoadway + menuLocalRoadway + menuTraffic + menuTrafficList + menuCameraStream + menuCameraStill + '</span>';
var menuFeature = '<span id="pnlMenuFeature" class="font-14" style="display: block; margin: 2px 2px;" data-visible="' + secFeatureVisible + '">';
menuFeature += '<span class="font-bold header clickable" style="display: block; margin-bottom: 5px; margin-top: 15px !important;" style="display: block;" onclick="Menu_ShowSection({ type: \'feature\' })">Toggle view on/off</span>';
menuFeature += featureContent;
menuFeature += '</span>';
////DISABLE "action" (until route logic figured out)
//var menuAction = '';
//build map action feature: (1) show roadway speed info, (2) build route
//deteremine visibility state
var secActionVisible = "true";
var secActionDisplay = "block";
if (oMenuSettings != null && typeof oMenuSettings.action != 'undefined' && oMenuSettings.action == false) {
secActionVisible = "false";
secActionDisplay = "none";
}
var chkActionSpeed = '';
var chkActionRoute = '';
if (typeof oPage.action != 'undefined' && oPage.action != null) {
if (oPage.action == 'route') chkActionRoute = 'checked="checked"';
else chkActionSpeed = 'checked="checked"';
}
var menuActionRoute = '<span class="form-action-route-item form-check form-check-inline"><input class="form-check-input" type="radio" ' + chkActionRoute +
' id="chkActionRoute" name="chkPageAction" value="route" onchange="Page_ActionOnChange()" /><label class="form-check-label" for="chkActionRoute" style="width: 100%;">Build route</label></span>';
var menuActionSpeed = '<span class="form-action-route-item form-check form-check-inline"><input class="form-check-input" type="radio" ' + chkActionSpeed +
' id="chkActionSpeed" name="chkPageAction" value="speed" onchange="Page_ActionOnChange()" /><label class="form-check-label" for="chkActionSpeed" style="width: 100%;">Show speed</label></span>';
var actionContent = '<span class="content" style="display: ' + secActionDisplay + ';">' + menuActionSpeed + menuActionRoute + '</span>';
var menuAction = '<span id="pnlMenuAction" class="font-14" style="display: block; margin: 2px 2px; margin-top: 15px !important;" data-visible="' + secActionVisible + '">';
menuAction += '<span class="font-bold header clickable" style="display: block; margin-bottom: 5px;" onclick="Menu_ShowSection({ type: \'action\' })">Click map action</span>';
menuAction += actionContent;
menuAction += '</span>';
//DISABLE "action" (until route logic figured out)
var menuRoute = "";
////show saved built routes (if available)
////deteremine visibility state
//var secRouteVisible = "true";
//var secRouteDisplay = "block";
//if (oMenuSettings != null && typeof oMenuSettings.route != 'undefined' && oMenuSettings.route == false) {
// secRouteVisible = "false";
// secRouteDisplay = "none";
//}
//var sShowRoute = 'none';
//var sRouteMenu = '';
//if (typeof oPage.action != 'undefined' && oPage.action != null && oPage.action == 'route' && arrRoute != null && arrRoute.length > 0) {
// sShowRoute = 'block';
// sRouteMenu = Route_BuildSavedMenu();
// if (sRouteMenu == '') {
// //no data to show
// sShowRoute = "none";
// secRouteVisible = "false";
// secRouteDisplay = "none";
// }
//}
//var btnClearRoute = '<span style="display: inline-block; height: 20px; float: right; padding-top: 1px; overflow: hidden;" title="Clear history"><button type="button" class="close" aria-label="Close" onclick="Route_ClearSaved()"><span style="font-size: 18px; float: left;" aria-hidden="true">×</span></button></span>';
//var menuRoute = '<span id="pnlMenuRoute" class="font-14" style="display: ' + sShowRoute + '; margin: 2px 2px; margin-top: 15px !important;" data-visible="' + secRouteVisible + '">';
//menuRoute += '<span class="font-bold header clickable" style="display: block;" onclick="Menu_ShowSection({ type: \'route\' })">' + btnClearRoute + 'Previous routes</span>';
//menuRoute += '<span class="font-13 content" style="display: ' + secRouteDisplay + ';">' + sRouteMenu + '</span>';
//menuRoute += '</span>';
//show links for privacy, terms, etc...
//deteremine visibility state
var secHelpVisible = "true";
var secHelpDisplay = "block";
if (oMenuSettings != null && typeof oMenuSettings.help != 'undefined' && oMenuSettings.help == false) {
secHelpVisible = "false";
secHelpDisplay = "none";
}
var cssHelp = 'block';
if (typeof isMobile != 'undefined' && typeof mobileType != 'undefined' && isMobile == true) {
if (wdHeight <= (minPanelHeight - 200)) cssHelp = 'none';
}
var lnkContact = '<span class="font-13" style="display: block;"><a class="reverse" href="/About" target="_blank">Contact us</a></span>';
var lnkPrivacy = '<span class="font-13" style="display: block;"><a class="reverse" href="/Privacy" target="_blank">Pricacy policy</a></span>';
var lnkTerms = '<span class="font-13" style="display: block;"><a class="reverse" href="/Terms" target="_blank">Terms of service</a></span>';
var lnkContent = '<span class="content" style="display: ' + secHelpDisplay + ';">' + lnkContact + lnkPrivacy + lnkTerms + '</span>';
var links = '<span id="pnlMenuHelp" style="display: ' + cssHelp + ';" data-visible="' + secHelpVisible + '"><span class="font-bold header clickable" style="display: block;" onclick="Menu_ShowSection({ type: \'help\' })">Help</span>' +
lnkContent + '</span>';
//build the keys/legend, show speed range with event name
//deteremine visibility state
var secLegendVisible = "true";
var secLegendDisplay = "block";
if (oMenuSettings != null && typeof oMenuSettings.legend != 'undefined' && oMenuSettings.legend == false) {
secLegendVisible = "false";
secLegendDisplay = "none";
}
var cssLegend = 'block';
if (typeof isMobile != 'undefined' && typeof mobileType != 'undefined' && isMobile == true) {
if (wdHeight <= minPanelHeight) cssLegend = 'none';
}
var thmExtremeCss = 'severity-key-extreme severity-extreme';
var thmMajorCss = 'severity-key-major severity-major';
var thmModerateCss = 'severity-key-moderate severity-moderate';
var thmMinorCss = 'severity-key-minor severity-minor';
var thmFreelyCss = 'severity-key-freely severity-freely';
if (theme > '') {
thmExtremeCss = 'severity-key-extreme severity-extreme-' + theme;
thmMajorCss = 'severity-key-major severity-major-' + theme;
thmModerateCss = 'severity-key-moderate severity-moderate-' + theme;
thmMinorCss = 'severity-key-minor severity-minor-' + theme;
thmFreelyCss = 'severity-key-freely severity-freely-' + theme;
}
var keyExtreme = '<span class="font-13" style="display: block;"><span class="' + thmExtremeCss +
' shadow rounded" style="display: inline-block; float: left; width: 21px; height: 8px; margin-top: 6px;"></span><span style="display: inline-block; margin-left: 5px;">Stopped traffic</span></span>';
var keyMajor = '<span class="font-13" style="display: block;"><span class="' + thmMajorCss +
' shadow rounded" style="display: inline-block; float: left; width: 21px; height: 8px; margin-top: 6px;"></span><span style="display: inline-block; margin-left: 5px;">Stop and go traffic</span></span>';
var keyModerate = '<span class="font-13" style="display: block;"><span class="' + thmModerateCss +
' shadow rounded" style="display: inline-block; float: left; width: 21px; height: 8px; margin-top: 6px;"></span><span style="display: inline-block; margin-left: 5px;">Slow traffic</span></span>';
var keyMinor = '<span class="font-13" style="display: block;"><span class="' + thmMinorCss +
' shadow rounded" style="display: inline-block; float: left; width: 21px; height: 8px; margin-top: 6px;"></span><span style="display: inline-block; margin-left: 5px;">Heavy traffic</span></span>';
var keyFreely = '<span class="font-13" style="display: block;"><span class="' + thmFreelyCss +
' shadow rounded" style="display: inline-block; float: left; width: 21px; height: 8px; margin-top: 6px;"></span><span style="display: inline-block; margin-left: 5px;">No congestion</span></span>';
var keyNotes = '<span class="font-11" style="display: block; margin-top: 10px;">* click any congestion lines to get details</span>';
var legendContent = '<span class="content" style="display: ' + secLegendDisplay + ';">' + keyExtreme + keyMajor + keyModerate + keyMinor + keyFreely + keyNotes + '</span>';
var legend = '<span id="pnlMenuLegend" style="display: ' + cssLegend + '; margin-top: 15px;" data-visible="' + secLegendVisible +
'"><span class="font-bold header clickable" style="display: block;" onclick="Menu_ShowSection({ type: \'legend\' })">Legend</span>' + legendContent + '</span>';
//show items at the bottom of the page
var bottom = '<span style="position: absolute; bottom: 35px;">' + links + legend + '</span>';
//combine the options
var content = '<div id="pnlMenu">' + menuMarkets + menuFeature + menuAction + menuRoute + bottom + '</div>';
//show panel
//var content = "<p>Toggle show/hide options menus here.</p><p>Initially have the icon display but not open, and when click, it opens and displays the possible menu options</p><p>Maybe show key options at the bottom?</p> ";
ShowMapOverlay({
type: "left",
width: width,
title: title,
content: content,
close: false,
onclose: "ShowMapMenu(false)"
});
} else {
//hide: show panel BUT only show the menu icon
var icon = '<span class="clickable" style="font-weight: bolder; opacity: 1.0 !important;" title="Settings" onclick="ShowMapMenu()"><span class="material-icons-outlined md-32">menu</span></span>';
ShowMapOverlay({
type: "left",
close: false,
height: plIconHeight,
width: plIconWidth,
content: icon,
opacity: 0.50
});
}
//adjust the route UI (if exists)
ShowRouteMenu_OnResize();
}
//handler to show/hide the menu sections
function Menu_ShowSection(options) {
var show = null;
var type = null;
//get options passed in
if (options != null && typeof options != 'undefined') {
if (typeof options == 'object') {
if (typeof options.show != 'undefined') show = options.show;
if (typeof options.type != 'undefined') type = options.type;
} else if (typeof options == 'boolean') {
show = options;
} else {
show = (options.toString().toLowerCase() == 'true');
}
}
//get menu
var oMenu = null;
if (type != null) {
switch (type) {
case "city":
oMenu = $("#pnlMenuCity");
break;
case "feature":
oMenu = $("#pnlMenuFeature");
break;
case "action":
oMenu = $("#pnlMenuAction");
break;
case "route":
oMenu = $("#pnlMenuRoute");
break;
case "help":
oMenu = $("#pnlMenuHelp");
break;
case "legend":
oMenu = $("#pnlMenuLegend");
break;
}
}
if (oMenu != null && oMenu.length > 0) {
//toggle show/hide based on current view state
if (show == null) {
var curShow = oMenu.attr("data-visible");
if (typeof curShow == 'string') curShow = (curShow.toLowerCase() == 'true');
if (curShow == true) show = false;
else show = true;
}
//determine show/hide the contents
if (show == true) {
//show the content
oMenu.find(".content").slideDown();
} else {
//hide the content
oMenu.find(".content").slideUp();
}
//update the data value
oMenu.attr("data-visible", show);
}
}
/* SPEED (A.K.A. SENSOR) PANEL FUNCTIONS */
//show roadway speed panel
function ShowRoadwaySpeedPanel(options) {
var show = true;
var width = null;
var height = null;
var tmcId = null;
var roadId = null;
var roadwayId = null;
var dirCode = null;
var showInternal = false;
var clickable = null;
//get options passed in
if (options != null && typeof options != 'undefined') {
if (typeof options == 'object') {
if (typeof options.show != 'undefined') show = options.show;
if (typeof options.width != 'undefined') width = options.width;
if (typeof options.height != 'undefined') height = options.height;
if (typeof options.tmc != 'undefined') tmcId = options.tmc;
if (typeof options.road != 'undefined') roadId = options.road;
if (typeof options.roadway != 'undefined') roadwayId = options.roadway;
if (typeof options.dircode != 'undefined') dirCode = options.dircode;
if (typeof options.internal != 'undefined' && options.internal != null) showInternal = options.internal;
if (typeof options.clickable != 'undefined') clickable = options.clickable;
} else if (typeof options == 'boolean') {
show = options;
} else {
show = (options.toString().toLowerCase() == 'true');
}
}
//error check
if (width == null) width = prWidth;
if (wdWidth <= minPanelWidth) width = "100%";
if (tmcId == null && roadId == null && roadwayId == null) show = false;
if (clickable != null && typeof clickable == 'string') clickable = (clickable.toLowerCase() == 'true');
//error check screen size (if too small do not show)
//make sure the page size is correct
PageResize();
//keep track of visibility of traffic panel
var oTrafficPanel = $(".map-right-traffic-overlay");
if (show == true) {
//close any map info window (if opened)
CloseInfoWindow();
//show roadway info
var oRoadway = null;
var arrRoads = [];
//get necessary parameters
if (tmcId != null && roadId == null) {
//get specific roadway and direction of travel
var oProp = GetTmcIdProp(tmcId);
if (oProp != null) {
roadId = "CC-" + oProp.ltn + "-" + oProp.locid;
//check for direction
if (dirCode == null && oProp.dirSymbol > '') {
if (oProp.dirSymbol == "-") dirCode = 1;
else dirCode = 0;
}
}
}
if (roadId != null && roadwayId == null) {
//get the roadway this road is on
var oRoad = GetRoadData({
id: roadId,
fetch: true
});
if (oRoad != null) {
if (typeof oRoad.properties != 'undefined') oRoad = oRoad.properties;
if (typeof oRoad.toplinearid != 'undefined' && oRoad.toplienarid != null && oRoad.toplinearid > '') roadwayId = oRoad.toplinearid;
else if (typeof oRoad.mainid != 'undefined' && oRoad.mainid != null && oRoad.mainid > '') roadwayId = oRoad.mainid;
}
}
//get info for this roadway
if (roadwayId != null) {
oRoadway = GetRoadwayData({
id: roadwayId,
fetch: true
});
//get all cross streets related to this roadway
arrRoads = FetchRoadData({
action: "roadway",
value: roadwayId,
city: cityId,
alias: true,
speed: true,
fetchoverride: true,
async: false,
global: true
});
if (arrRoads == null) arrRoads = [];
//assign speed object to internal roads (based on direction of travel) (if available)
if (arrRoads.length > 0) arrRoads = AssignSpeedDataToInternalRoad({
data: arrRoads,
roadway: roadwayId
});
}
//build the display
var title = '';
var content = '';
if (oRoadway != null && arrRoads != null && arrRoads.length > 0) {
//get roadway info
var roadwayName = null;
var roadwayDirNeg = null;
var roadwayDirPos = null;
if (typeof oRoadway.combine != 'undefined' && oRoadway.combine != null && oRoadway.combine > '') roadwayName = oRoadway.combine;
if (roadwayName == null && typeof oRoadway.alias != 'undefined' && oRoadway.alias != null && oRoadway.alias > '') roadwayName = oRoadway.alias;
if (roadwayName == null && typeof oRoadway.name != 'undefined' && oRoadway.name != null && oRoadway.name > '') roadwayName = oRoadway.name;
if (typeof oRoadway.dirneg != 'undefined' && oRoadway.dirneg != null && oRoadway.dirneg > '') roadwayDirNeg = oRoadway.dirneg;
if (typeof oRoadway.dirpos != 'undefined' && oRoadway.dirpos != null && oRoadway.dirpos > '') roadwayDirPos = oRoadway.dirpos;
if (roadwayDirNeg != null && roadwayDirNeg > '') roadwayDirNeg = GetAbbrDirName(roadwayDirNeg);
if (roadwayDirPos != null && roadwayDirPos > '') roadwayDirPos = GetAbbrDirName(roadwayDirPos);
if (roadwayDirNeg == null) roadwayDirNeg = "Neg";
if (roadwayDirPos == null) roadwayDirPos = "Pos";
//LOGIC: (1) display roads in the positive direction of travel (arrPosRoads), (2) positive columns use the positive direction of travel speed array (arrPosRoads), (3) negative column use the direction of travel array (arrNegRoads)
var arrPosRoads = [];
var arrNegRoads = [];
if (arrRoads != null && arrRoads.length > 0) arrPosRoads = arrRoads.copy();
if (arrPosRoads != null && arrPosRoads.length > 0) {
//get the negative direction of travel
var oSort = {
type: "decimal",
field: "roadorder",
order: -1
};
arrNegRoads = GetRoadData({
data: arrPosRoads,
sort: oSort
});
if (arrNegRoads == null) arrNegRoads = [];
//assign speed object to internal roads (based on direction of travel) (if available)
arrNegRoads = AssignSpeedDataToInternalRoad({
data: arrNegRoads,
roadway: roadwayId,
dircode: -1
});
}
//build location/speed info
var pnlSpeedInfo = '';
if (arrPosRoads != null && arrPosRoads.length > 0) {
//build the header/content
var notes = '<span style="display: inline-block; float: right; margin-top: 4px; font-size: 11px; font-style: italic;">* Note: speed are in mph</span>';
var header = '<div class="row" style="width: 100%; margin: 1px 0; padding: 0;"><div class="col" style="min-width: 75%; height: 25px; margin: 0 1px; padding: 5px 5px; overflow: hidden;">' + notes +
'</div><div class="col" style="max-width: 40px; margin: 0 1px; padding: 5px 5px; text-align: center; font-weight: bold;">' + roadwayDirPos +
'</div><div class="col" style="max-width: 40px; margin: 0 1px; padding: 5px 5px; text-align: center; font-weight: bold;">' + roadwayDirNeg + '</div></div>';
if (dirCode != null) {
if (dirCode == 1) header = '<div class="row" style="width: 100%; margin: 1px 0; padding: 0;"><div class="col" style="min-width: calc(100% - 50px); height: 25px; margin: 0 1px; padding: 5px 5px; overflow: hidden;">' + notes +
'</div><div class="col" style="max-width: 40px; margin: 0 1px; padding: 5px 5px; text-align: center; font-weight: bold;">' + roadwayDirNeg + '</div></div>';
else header = '<div class="row" style="width: 100%; margin: 1px 0; padding: 0;"><div class="col" style="min-width: calc(100% - 50px); height: 25px; margin: 0 1px; padding: 5px 5px; overflow: hidden;">' + notes +
'</div><div class="col" style="max-width: 40px; margin: 0 1px; padding: 5px 5px; text-align: center; font-weight: bold;">' + roadwayDirPos + '</div></div>';
}
var arrSpeed = [];
var arrDirTravel = arrPosRoads.copy();
if (dirCode != null && dirCode == 1) arrDirTravel = arrNegRoads.copy();
var lenRoads = arrDirTravel.length;
for (var i = 0; i < lenRoads; i++) {
var oRoad = arrDirTravel[i];
if (typeof oRoad.properties != 'undefined') oRoad = oRoad.properties;
//initialize variables
var aRoadId = null;
var aName = null;
var aGeopoint = null;
var aNegSpeed = null;
var aNegSeverity = null;
var aPosSpeed = null;
var aPosSeverity = null;
//get the negative direction of travel object
if (aRoadId == null && typeof oRoad.roadid != 'undefined' && oRoad.roadid != null && oRoad.roadid > '') aRoadId = oRoad.roadid;
else if (aRoadId == null && typeof oRoad.id != 'undefined' && oRoad.id != null && oRoad.id > '') aRoadId = oRoad.id;
var oRoadNeg = null;
if (aRoadId != null && arrNegRoads != null && arrNegRoads.length > 0) {
oRoadNeg = arrNegRoads.find(x => (typeof x.properties != 'undefined' && ((typeof x.properties.roadid != 'undefined' && x.properties.roadid == aRoadId) || (typeof x.properties.id != 'undefined' && x.properties.id == aRoadId))) || ((
typeof x.roadid != 'undefined' && x.roadid == aRoadId) || (typeof x.id != 'undefined' && x.id == aRoadId)));
if (oRoadNeg != null && typeof oRoadNeg.properties != 'undefined') oRoadNeg = oRoadNeg.properties;
}
if (typeof oRoadNeg == 'undefined' || oRoadNeg == null) oRoadNeg = oRoad;
//validate if location should be shown
var isValid = true;
if (showInternal == false && aRoadId.indexOf("CC-") < 0) isValid = false;
if (isValid == true) {
//get road name
if (typeof oRoad.combine != 'undefined' && oRoad.combine != null && oRoad.combine > '') aName = oRoad.combine;
if (aName == null && typeof oRoad.alias != 'undefined' && oRoad.alias != null && oRoad.alias > '') aName = oRoad.alias;
if (aName == null && typeof oRoad.name != 'undefined' && oRoad.name != null && oRoad.name > '') aName = oRoad.name;
//get geopoint (if available)
if (typeof oRoad.location != 'undefined' && oRoad.location != null && typeof oRoad.location.geopoint != 'undefined' && oRoad.location.geopoint != null) aGeopoint = oRoad.location.geopoint;
else if (typeof oRoad.geopoint != 'undefined' && oRoad.geopoint != null) aGeopoint = oRoad.geopoint;
//get speed data
//(2) positive columns use the positive direction of travel speed array (arrRoads), (3) negative column use the direction of travel array (arrRoadsDirOfTravel)
if (typeof oRoad.posspeed != 'undefined' && oRoad.posspeed != null) {
if (typeof oRoad.posspeed.speed != 'undefined' && oRoad.posspeed.speed != null) aPosSpeed = oRoad.posspeed.speed;
if (typeof oRoad.posspeed.severity != 'undefined' && oRoad.posspeed.severity != null) aPosSeverity = oRoad.posspeed.severity;
}
if (typeof oRoadNeg.negspeed != 'undefined' && oRoadNeg.negspeed != null) {
if (typeof oRoadNeg.negspeed.speed != 'undefined' && oRoadNeg.negspeed.speed != null) aNegSpeed = oRoadNeg.negspeed.speed;
if (typeof oRoadNeg.negspeed.severity != 'undefined' && oRoadNeg.negspeed.severity != null) aNegSeverity = oRoadNeg.negspeed.severity;
}
//get speed override (if available)
if (typeof oRoad.posspeedoverride != 'undefined' && oRoad.posspeedoverride != null) {
if (typeof oRoad.posspeedoverride.speed != 'undefined' && oRoad.posspeedoverride.speed != null) aPosSpeed = oRoad.posspeedoverride.speed;
if (typeof oRoad.posspeedoverride.severity != 'undefined' && oRoad.posspeedoverride.severity != null) aPosSeverity = oRoad.posspeedoverride.severity;
}
if (typeof oRoadNeg.negspeedoverride != 'undefined' && oRoadNeg.negspeedoverride != null) {
if (typeof oRoadNeg.negspeedoverride.speed != 'undefined' && oRoadNeg.negspeedoverride.speed != null) aNegSpeed = oRoadNeg.negspeedoverride.speed;
if (typeof oRoadNeg.negspeedoverride.severity != 'undefined' && oRoadNeg.negspeedoverride.severity != null) aNegSeverity = oRoadNeg.negspeedoverride.severity;
}
//round the values
if (aNegSpeed != null) aNegSpeed = Math.round(aNegSpeed);
if (aPosSpeed != null) aPosSpeed = Math.round(aPosSpeed);
//error check data
var negCss = '';
var posCss = '';
if (aNegSpeed == null) {
aNegSpeed = 'n/a';
negCss = 'border';
} else {
//aNegSpeed += ' mph';
negCss = 'severity-' + aNegSeverity;
if (theme > '') negCss += "-" + theme;
}
if (aPosSpeed == null) {
aPosSpeed = 'n/a';
posCss = 'border';
} else {
//aPosSpeed += ' mph';
posCss = 'severity-' + aPosSeverity;
if (theme > '') posCss += "-" + theme;
}
//determine if item clickable
var cssItem = '';
var onClick = '';
if (clickable == true) {
cssItem += " clickable";
onClick = ' onclick="Map_MoveTo({ lnglat: \'' + aGeopoint + '\'})"';
}
//build the item
var item = '<div id="' + aRoadId + '" class="sensor row' + cssItem + '" style="width: 100%; margin: 1px 0; padding: 0;"><div class="col border font-bold" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">' + aName +
'</div><div class="col ' + posCss + '" style="max-width: 40px; margin: 0 1px; padding: 5px 5px; text-align: center;">' + aPosSpeed + '</div><div class="col ' + negCss +
'" style="max-width: 40px; margin: 0 1px; padding: 5px 5px; text-align: center;">' + aNegSpeed + '</div></div>';
if (dirCode != null) {
if (dirCode == 1) item = '<div id="' + aRoadId + '" class="sensor row' + cssItem + '" style="width: 100%; margin: 1px 0; padding: 0;"' + onClick +
'><div class="col border font-bold" style="min-width: calc(100% - 50px); margin: 0 1px; padding: 5px 5px;">' + aName + '</div><div class="col ' + negCss +
'" style="max-width: 40px; margin: 0 1px; padding: 5px 5px; text-align: center;">' + aNegSpeed + '</div></div>';
else item = '<div id="' + aRoadId + '" class="sensor row' + cssItem + '" style="width: 100%; margin: 1px 0; padding: 0;"' + onClick +
'><div class="col border font-bold" style="min-width: calc(100% - 50px); margin: 0 1px; padding: 5px 5px;">' + aName + '</div><div class="col ' + posCss +
'" style="max-width: 40px; margin: 0 1px; padding: 5px 5px; text-align: center;">' + aPosSpeed + '</div></div>';
}
arrSpeed.push(item);
}
}
pnlSpeedInfo = '';
if (arrSpeed.length > 0) {
pnlSpeedInfo = header + arrSpeed.join("");
} else {
pnlSpeedInfo = '';
}
}
//build traffic list along this path
//get traffic along this roadway/dir
var pnlTrafficInfo = '';
var arrTraffic = GetTrafficData({
roadway: roadwayId,
dircode: dirCode,
fetch: true
});
if (arrTraffic != null && arrTraffic.length > 0) {
pnlTrafficInfo = BuildMapTrafficList({
data: arrTraffic,
clickable: true,
sort: {
type: "numeric",
field: "path.sortorder",
order: dirCode
}
});
}
//build the title/content
title = roadwayName;
if (dirCode != null) {
if (dirCode == 1) title += ' ' + roadwayDirNeg;
else title += ' ' + roadwayDirPos;
}
if (pnlSpeedInfo > '' && pnlTrafficInfo > '') {
content = '<div id="pnlSpeed" class="border" style="height: calc(60% - 10px); margin-bottom: 10px; overflow-x: hidden; overflow-y: auto;">' + pnlSpeedInfo +
'</div><div id="pnlTraffic" class="border" style="height: calc(40% - 10px); margin-top: 10px; overflow-x: hidden; overflow-y: auto;">' + pnlTrafficInfo + '</div>';
} else if (pnlSpeedInfo > '') {
content = pnlSpeedInfo;
} else if (pnlTrafficInfo > '') {
content = pnlTrafficInfo;
}
}
//show panel
if (content != null && content > '') {
//hide right traffic panel (if opened)
if (oTrafficPanel.is(":visible") == true) ChangeMapOverlayVisibility({
type: "right-traffic",
show: false
});
//show this panel
ShowMapOverlay({
type: "right",
width: width,
title: title,
content: content,
onclose: "ShowRoadwaySpeedPanel(false)"
});
//hover over effect on each item
var oPanel = $(".map-right-overlay");
oPanel.find(".sensor").hover(function() {
//hover over:
$(this).addClass("highlight-background");
}, function() {
//hover out:
$(this).removeClass("highlight-background");
}, );
//check if there is a scroll bar, if so, go to specific area where the road was selected
var oContent = oPanel.find(".overlay-content");
if (oContent.find("#pnlSpeed").length > 0) oContent = oContent.find("#pnlSpeed");
var isScrollExists = oContent.hasScrollBar();
if (isScrollExists == true && roadId != null) {
//show this item in the middle of the panel: (itemPos - panelPos) - (panelHeight / 2)
var oItem = oContent.find("#" + roadId);
oContent.animate({
scrollTop: (oItem.offset().top - oContent.offset().top) - (oContent.height() / 2)
});
//highlight the location for 5 seconds
oItem.addClass("active-shadow");
setTimeout(function() {
oItem.removeClass("active-shadow");
}, 5000);
} else if (roadId != null) {
var oItem = oContent.find("#" + roadId);
//highlight the location for 5 seconds
oItem.addClass("active-shadow");
setTimeout(function() {
oItem.removeClass("active-shadow");
}, 5000);
}
} else {
ShowMapOverlay({
type: "right",
show: false
});
}
} else {
//hide panel
ShowMapOverlay({
type: "right",
show: false
});
//check if previously opened speed sensor panel
if (oTrafficPanel.find(".traffic").length > 0) {
//previously open and was just hidden when the traffic panel was open
ChangeMapOverlayVisibility({
type: "right-traffic",
show: true
});
}
}
//adjust affiliate logo
Affiliate_OnResize();
}
/* ROUTE PANEL FUNCTIONS */
//handler to clear/reset route travel info on the map
function Route_ClearMap() {
//get current route settings
var oRouteSettings = GetPageProp("route");
if (typeof oRouteSettings == 'undefined' || oRouteSettings == null) oRouteSettings = Object.copy(defaultRouteSettings);
//clear route UI
var oStartTextbox = $(".route-start-textbox");
var oDestinationTextbox = $(".route-destination-textbox");
var pnlTravel = $(".route-travel-panel");
if (oRouteSettings.start == null && oRouteSettings.end == null) {
//reset the textbox
oStartTextbox.val("");
oDestinationTextbox.val("");
//hide the travel info
pnlTravel.hide();
//resize the overlay
ShowRouteMenu_OnResize();
}
//clear the Directions API polyline
ClearDirectionsPath();
}
//handler to dynamically build the route info based on selection of start/end road along a roadway
function Route_BuildRouteInfo(options, onHandler) {
var show = true;
var oData = null;
//get options passed in
if (options != null && typeof options != 'undefined') {
if (typeof options == 'object') {
if (typeof options.show != 'undefined') show = options.show;
if (typeof options.data != 'undefined' && options.data != null) oData = Object.copy(options.data);
} else if (typeof options == 'boolean') {
show = options;
} else if (typeof options == 'string') {
show = (options.toString().toLowerCase() == 'true');
}
}
//get current route settings
var oRouteSettings = GetPageProp("route");
if (typeof oRouteSettings == 'undefined' || oRouteSettings == null) oRouteSettings = Object.copy(defaultRouteSettings);
//route UI
var oStartTextbox = $(".route-start-textbox");
var oDestinationTextbox = $(".route-destination-textbox");
if (oRouteSettings.start == null && oRouteSettings.end == null) {
//reset the textbox / map
Route_ClearMap();
}
if (show == true) {
//show
//determine what the data is (start or end)
if (oData != null) {
if (typeof oData.properties != 'undefined' && oData.properties != null) oData = oData.properties;
//get data
var geopoint = null;
var roadId = null;
var roadwayId = null;
var dirCode = null;
if (typeof oData.id != 'undefined' && oData.id != null && oData.id > '') roadId = oData.id;
if (typeof oData.roadway != 'undefined' && oData.roadway != null && typeof oData.roadway.id != 'undefined' && oData.roadway.id != null && oData.roadway.id > '') roadwayId = oData.roadway.id;
if (typeof oData.direction != 'undefined' && oData.direction != null && typeof oData.direction.code != 'undefined' && oData.direction.code != null) dirCode = oData.direction.code;
if (typeof oData.location != 'undefined' && oData.location != null && typeof oData.location.geopoint != 'undefined' && oData.location.geopoint != null) geopoint = oData.location.geopoint;
else if (typeof oData.geopoint != 'undefined' && oData.geopoint != null) geopoint = oData.geopoint;
//validate data
if (oRouteSettings.start == null) {
//save start location
oRouteSettings.start = {
id: roadId,
roadway: roadwayId,
geopoint: geopoint
};
//show the lat/lng in textbox
oStartTextbox.val(geopoint.join(','));
//show the starting icon
DrawDirectionsPath({
start: oRouteSettings.start
});
} else if (oRouteSettings.start != null && oRouteSettings.end == null) {
oRouteSettings.end = {
id: roadId,
roadway: roadwayId,
geopoint: geopoint
};
//show the lat/lng in textbox
oDestinationTextbox.val(geopoint.join(','));
//get the route's result
var startEnd = [oRouteSettings.start.geopoint, oRouteSettings.end.geopoint];
var oData = GetMapDirectionsData({
type: "driving-traffic",
lnglat: startEnd
});
//console.log("DATA: " + JSON.stringify(oData));
//update the route menu UI info
ShowRouteMenu_UpdateInfo(oData);
//draw the route
if (oData != null && typeof oData.route != 'undefined' && oData.route != null && oData.route.length > 0) {
//draw the primary route (0)
DrawDirectionsPath({
format: "simple",
data: oData
});
}
//reset
oRouteSettings = Object.copy(defaultRouteSettings);
}
}
} else {
//hide
//reset
oRouteSettings = Object.copy(defaultRouteSettings);
//clear map of any items related to this
Route_ClearMap();
}
//save the route viewstate
SavePageProp({
route: oRouteSettings
});
//execute onHandler commands
if (typeof onHandler != 'undefined') {
if (typeof onHandler == 'function') onHandler();
else eval(onHandler);
}
}
//show/hide the route UI/form overlay
function ShowRouteMenu(options) {
var show = true;
var width = null;
var height = null;
var overlayPosition = null;
var opacity = null;
//get options passed in
if (options != null && typeof options != 'undefined') {
if (typeof options == 'object') {
if (typeof options.show != 'undefined') show = options.show;
if (typeof options.width != 'undefined') width = options.width;
if (typeof options.height != 'undefined') height = options.height;
if (typeof options.position != 'undefined') overlayPosition = options.position;
if (typeof options.opacity != 'undefined') opacity = options.opacity;
} else if (typeof options == 'boolean') {
show = options;
} else {
show = (options.toString().toLowerCase() == 'true');
}
}
//error check
//if (width == null)
// width = plIconWidth;
//if (height == null)
// height = plIconHeight;
if (overlayPosition == null) overlayPosition = "top";
if (opacity == null) opacity = 0.90;
//make sure the page size is correct
PageResize();
//determine the action to take
if (show == true) {
var marginLeft = 50;
var oSettingsMenu = $(".map-left-overlay");
if (oSettingsMenu.length > 0 && oSettingsMenu.is(":visible") == true) {
var mWidth = oSettingsMenu.width();
if (mWidth > marginLeft) marginLeft = mWidth + 5;
}
//build the content
var content = '';
//start row
var sRow = '<span style="display: inline-block; width: 100%; float: left;">';
sRow += '<span style="display: inline-block; float: left; width: 31px; height: 31px; overflow: hidden;"><span class="svg-route-start" style="display: inline-block; width: 32px; height: 26px; margin-top: 2px;"></span></span>';
sRow += '<span style="display: inline-block; float: left; width: calc(100% - 31px);"><input type="text" class="route-start-textbox form-control form-control-sm" value="" placeholder="Starting place" readonly="readonly" /></span>';
//sRow += '<span style="display: inline-block; float: left; width: 25px;"> </span>';
sRow += '</span>';
//end row: with "save" button
var eRow = '<span style="display: inline-block; width: 100%; float: left; margin-top: 3px;">';
eRow += '<span style="display: inline-block; float: left; width: 31px; height: 31px; overflow: hidden;"><span class="svg-route-stop" style="display: inline-block; width: 32px; height: 26px; margin-top: 2px;"></span></span>';
eRow += '<span style="display: inline-block; float: left; width: calc(100% - 31px);"><input type="text" class="route-destination-textbox form-control form-control-sm" value="" placeholder="Destination" readonly="readonly" /></span>';
//eRow += '<span style="display: inline-block; float: left; width: 25px;">button</span>';
eRow += '</span>';
//travel time row
var tRow = '<span class="route-travel-panel" style="display: none; width: 100%; float: left; margin-top: 10px;">';
tRow += '<span style="display: inline-block; float: left; width: 31px;"><span class="material-icons-outlined md-24" style="float: left; margin-left: 5px; padding-top: 1px;">commute</span></span>';
tRow += '<span class="route-travel-info" style="display: inline-block; float: left; width: calc(100% - 31px); padding-left: 8px; padding-top: 3px;"></span>';
tRow += '</span>';
if (sRow > '' && eRow > '') content = sRow + eRow + tRow;
//show panel
ShowMapOverlay({
type: "route",
close: false,
position: overlayPosition,
width: "300px",
height: "80px",
marginleft: marginLeft,
content: content,
overflow: "hidden",
opacity: opacity
});
} else {
//hide panel
ShowMapOverlay({
type: "route",
show: false
});
}
}
//handler to update route menu info
function ShowRouteMenu_UpdateInfo(options) {
var start = null;
var end = null;
var distance = null;
var duration = null;
var durationTypical = null;
//define local variables
var offsetMetersToMi = 0.000621371;
//get options passed in
if (options != null && typeof options != 'undefined') {
if (typeof options == 'object') {
if (typeof options.start != 'undefined' && options.start != null) {
//get the starting location name
if (typeof options.start == 'object' && options.start != null && typeof options.start.name != 'undefined' && options.start.name != null && options.start.name > '') {
//object
start = options.start.name;
} else if (typeof options.start == 'string') {
//text
start = options.start;
}
}
if (typeof options.end != 'undefined' && options.end != null) {
//get the destination location name
if (typeof options.end == 'object' && options.end != null && typeof options.end.name != 'undefined' && options.end.name != null && options.end.name > '') {
//object
end = options.end.name;
} else if (typeof options.end == 'string') {
//text
end = options.end;
}
}
if (typeof options.route != 'undefined' && options.route != null && options.route.length > 0) {
if (typeof options.route[0].distance != 'undefined' && options.route[0].distance != null) distance = options.route[0].distance;
if (typeof options.route[0].duration != 'undefined' && options.route[0].duration != null) duration = options.route[0].duration;
if (typeof options.route[0].durationtypical != 'undefined' && options.route[0].durationtypical != null) durationTypical = options.route[0].durationtypical;
//distance ==> meters, time ==> seconds
//convert meters ==> miles
if (typeof distance != 'undefined' && distance != null) {
if (typeof distance == 'string') distance = parseFloat(distance);
distance = distance * offsetMetersToMi;
}
}
if (typeof options.distance != 'undefined' && options.distance != null) distance = options.distance;
if (typeof options.duration != 'undefined' && options.duration != null) duration = options.duration;
if (typeof options.durationtypical != 'undefined' && options.durationtypical != null) durationTypical = options.durationtypical;
}
}
var oStartTextbox = $(".route-start-textbox");
var oDestinationTextbox = $(".route-destination-textbox");
var pnlTravel = $(".route-travel-panel");
var oTravelInfo = $(".route-travel-info");
//update textboxes
if (oStartTextbox.length > 0 && oDestinationTextbox.length > 0) {
if (start != null && end != null && start > '' && end > '') {
oStartTextbox.val(start);
oDestinationTextbox.val(end);
}
}
if (distance != null || duration != null) {
//calculate the duration in min/seconds
var time = '';
var delayTime = "";
if (duration != null) {
//calculate the delay (if available)
if (durationTypical != null) {
if (duration > durationTypical) {
//calculate the delay time
var delay = duration - durationTypical;
if (delay > 3600) {
//more than 1 hour
var hour = Math.floor(delay / 60);
delay = delay % 60;
var min = Math.round(delay / 60);
delayTime = hour + " hr, " + min + ' min';
} else if (delay > 60) {
//more than 1 min
var min = Math.round(delay / 60);
delayTime = min + " min";
}
}
}
//convert duration to hr/min
if (duration > 3600) {
//more than 1 hour
var hour = Math.floor(duration / 60);
duration = duration % 60;
var min = Math.round(duration / 60);
time = hour + " hr, " + min + ' min';
} else if (duration > 60) {
//more than 1 min
var min = Math.round(duration / 60);
time = min + " min";
}
}
//round distance 2 decimal
if (distance != null && distance > 0) {
distance = Round(distance, 2);
} else {
distance = null;
}
var info = '<b class="font-16">' + time + '</b>';
if (delayTime != null && delayTime > '') {
info += ', <span class="font-alert"> delay of ' + delayTime + '</span>';
}
if (distance != null) info += " (" + distance + " mi)";
oTravelInfo.html(info);
pnlTravel.show();
} else {
pnlTravel.hide();
}
//resize the overlay
ShowRouteMenu_OnResize();
}
//handler to move the route UI based on resize (i.e. open/close of the settings menu)
function ShowRouteMenu_OnResize() {
var oRouteMenu = $(".map-route-overlay");
var oSettingsMenu = $(".map-left-overlay");
//define the margin
var marginLeft = 50;
if (oSettingsMenu.length > 0 && oSettingsMenu.is(":visible") == true) {
var mWidth = oSettingsMenu.width();
if (mWidth > marginLeft) marginLeft = mWidth + 5;
}
if (oRouteMenu.length > 0 && oRouteMenu.is(":visible") == true) {
//update the overlay appropriately
oRouteMenu.css({
"margin-left": marginLeft + "px"
});
}
//resize overlay height (based on travel info visible or not)
var oRouteBody = oRouteMenu.find(".overlay-content");
var pnlTravel = oRouteMenu.find(".route-travel-panel");
var height = 80;
if (pnlTravel.length > 0 && pnlTravel.is(":visible") == true) {
//extra height
height = 110;
}
oRouteBody.css({
"height": height + "px"
});
oRouteMenu.css({
"height": (height + 5) + "px"
});
}
/* TRAFFIC PANEL FUNCTIONS */
//build the traffic content
function BuildMapTrafficList(options) {
var result = '';
var arrData = [];
var sort = null;
var clickable = null;
//get options passed in
if (options != null && typeof options != 'undefined') {
if (Array.isArray(options) == true) {
arrData = options.copy();
} else if (typeof options == 'object') {
if (typeof options.data != 'undefined' && options.data != null) arrData = options.data.copy();
if (typeof options.clickable != 'undefined') clickable = options.clickable;
if (typeof options.sort != 'undefined') {
if (typeof options.sort == 'object') sort = options.sort;
else sort = {
type: "string",
field: options.sort,
order: 1
};
}
}
}
//error check the data
if (arrData == null) arrData = [];
if (arrData.length <= 0) {
//get all traffic within map's viewport, i.e. saved to gblMapTraffic
arrData = GetGlobalVariableData({
type: "map-traffic",
format: "array"
});
if (typeof arrData == 'undefined' || arrData == null) arrData = GetTrafficData({
city: cityId,
fetch: true
});
if (typeof arrData == 'undefined' || arrData == null) arrData = [];
}
if (sort == null) {
sort = {
type: "numeric",
field: "travel.delaytime",
order: -1
}
}
if (clickable != null && typeof clickable == 'string') clickable = (clickable.toLowerCase() == 'true');
if (arrData != null && arrData.length > 1) {
//sort by most delay
arrData = SortArrayBy({
array: arrData,
order: sort.order,
type: sort.type,
value: sort.field
});
}
//build the list
if (arrData != null && arrData.length > 0) {
//build the header: description, delay? OR just description??
var header =
'<div class="row" style="width: 100%; margin: 1px 0; padding: 0;"><div class="col" style="min-width: 75%; height: 25px; margin: 0 1px; padding: 5px 5px; overflow: hidden;">Traffic<span style="display: inline-block; float: right; margin-top: 4px; font-size: 11px; font-style: italic;">* delay in minutes</span></div><div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;">Delay</div></div>';
var arrItem = [];
var lenData = arrData.length;
for (var i = 0; i < lenData; i++) {
var oData = arrData[i];
if (typeof oData.properties != 'undefined') oData = oData.properties;
//initialize variables
var aId = '';
var aSeverity = '';
var aDescription = '';
var aNotes = '';
var aDelay = '';
var aGeopoint = null;
//get the data
if (typeof oData.id != 'undefined' && oData.id != null && oData.id > '') aId = oData.id;
if (typeof oData.severity != 'undefined' && oData.severity != null && typeof oData.severity.type != 'undefined' && oData.severity.type != null && oData.severity.type > '') aSeverity = oData.severity.type;
if (typeof oData.description != 'undefined' && oData.description != null && oData.description > '') aDescription = oData.description;
if (typeof oData.notes != 'undefined' && oData.notes != null && typeof oData.notes.public != 'undefined' && oData.notes.public != null && oData.notes.public > '') aNotes = oData.notes.public;
if (typeof oData.travel != 'undefined' && oData.travel != null) {
if (typeof oData.travel.delaytime != 'undefined' && oData.travel.delaytime != null) {
aDelay = Math.round(oData.travel.delaytime);
if (aDelay <= 0) aDelay = '';
}
}
if (typeof oData.location != 'undefined' && oData.location != null && typeof oData.location.geopoint != 'undefined' && oData.location.geopoint != null) aGeopoint = oData.location.geopoint;
//combine description/notes
if (aDescription > '' && aNotes > '') {
aDescription += '<br /><i class="font-12">' + aNotes + '</i>';
}
//build the style
var cssTraffic = 'severity-' + aSeverity;
if (theme > '' && theme != 'classic') cssTraffic += '-' + theme;
//determine if item clickable
var onClick = '';
if (clickable == true) {
if (cssTraffic > '') cssTraffic += ' ';
cssTraffic += "clickable";
onClick = ' onclick="Map_MoveTo({ lnglat: \'' + aGeopoint + '\'})"';
}
//build sort/search parameters
var sortParam = '';
var searchParam = '';
//build the item
var item = '<div id="' + aId + '" class="traffic row ' + cssTraffic + '" style="width: 100%; margin: 1px 0; padding: 0;"' + onClick + '><div class="col" style="min-width: 75%; margin: 0 1px; padding: 5px 5px;">' + aDescription +
'</div><div class="col" style="max-width: 50px; margin: 0 1px; padding: 5px 5px; text-align: center;">' + aDelay + '</div></div>';
arrItem.push(item);
}
if (arrItem.length > 0) {
result = header + arrItem.join("");
} else {
result = '';
}
}
return result;
}
//show traffic info within map view (right panel)
function ShowMapTrafficInfo(options) {
var show = true;
var width = null;
var height = null;
var data = null;
//get the current traffic settings
var oTrafficSettings = GetPageProp("traffic");
//get options passed in
if (options != null && typeof options != 'undefined') {
if (typeof options == 'object') {
if (typeof options.show != 'undefined') show = options.show;
if (typeof options.width != 'undefined') width = options.width;
if (typeof options.height != 'undefined') height = options.height;
if (typeof options.data != 'undefined') data = options.data;
} else if (typeof options == 'boolean') {
show = options;
} else {
show = (options.toString().toLowerCase() == 'true');
}
}
//error check
if (width == null) width = prWidth;
if (wdWidth <= minPanelWidth) width = "100%";
//error check
if (oTrafficSettings != null && typeof oTrafficSettings.list != 'undefined' && oTrafficSettings.list != null && oTrafficSettings.list == true && typeof oTrafficSettings.type != 'undefined' && oTrafficSettings.type > '') {
//valid
} else {
//no traffic data requested
show = false;
}
if (data != null && data.length <= 0) show = false;
//error check screen size (if too small do not show)
//make sure the page size is correct
PageResize();
//keep track of the speed panel
var oSpeedPanel = $(".map-right-overlay");
if (show == true) {
//close any map info window (if opened)
CloseInfoWindow();
//hide right panel (if opened)
if (oSpeedPanel.is(":visible") == true) ChangeMapOverlayVisibility({
type: "right",
show: false
});
//build the display
var title = 'Traffic within view';
var content = BuildMapTrafficList({
data: data
});
//show this panel
ShowMapOverlay({
type: "right-traffic",
width: width,
title: title,
content: content,
onclose: "ShowMapTrafficInfo(false)"
});
//hover over effect on each item
var oPanel = $(".map-right-traffic-overlay");
oPanel.find(".traffic").hover(function() {
//hover over:
$(this).addClass("hover");
}, function() {
//hover out:
$(this).removeClass("hover");
}, );
////check if there is a scroll bar, if so, go to specific area where the road was selected
//var oContent = oPanel.find(".overlay-content");
//var isScrollExists = oContent.hasScrollBar();
//if (isScrollExists == true && roadId != null) {
// //show this item in the middle of the panel: (itemPos - panelPos) - (panelHeight / 2)
// var oItem = oContent.find("#" + roadId);
// oContent.animate({ scrollTop: (oItem.offset().top - oContent.offset().top) - (oContent.height() / 2) });
// //highlight the location for 5 seconds
// oItem.addClass("active-shadow");
// setTimeout(function () { oItem.removeClass("active-shadow"); }, 5000);
//} else if (roadId != null) {
// var oItem = oContent.find("#" + roadId);
// //highlight the location for 5 seconds
// oItem.addClass("active-shadow");
// setTimeout(function () { oItem.removeClass("active-shadow"); }, 5000);
//}
} else {
//hide panel
ShowMapOverlay({
type: "right-traffic",
show: false
});
//check if previously opened speed sensor panel
if (oSpeedPanel.find(".sensor").length > 0) {
//previously open and was just hidden when the traffic panel was open
ChangeMapOverlayVisibility({
type: "right",
show: true
});
}
}
//adjust affiliate logo
Affiliate_OnResize();
}
/* MAP FUNCTIONS */
//OVERLOAD FUNCTION: this map function (within mapbox-draw.js)
//handler to rebuild the traffic info panel and display new content
function ShowMapTrafficList(options, onHandler) {
var show = true;
var data = [];
var oTrafficPanel = $(".map-right-traffic-overlay");
var oSpeedPanel = $(".map-right-overlay");
//get options passed in
if (options != null && typeof options != 'undefined') {
if (Array.isArray(options) == true) {
data = options.copy();
} else if (typeof options == 'object') {
if (typeof options.show != 'undefined') show = options.show;
if (typeof options.data != 'undefined' && options.data != null) data = options.data.copy();
} else if (typeof options == 'boolean') {
show = options;
} else if (typeof options == 'string') {
show = (options.toString().toLowerCase() == 'true');
}
}
//error check: (1) no data or (2) speed panel showing do not show the traffic listing
if (data != null && data.length <= 0) show = false;
if (oSpeedPanel.is(":visible") == true) show = false;
if (show == true) {
//validate if panel is open/closed
if (oTrafficPanel.is(":visible") == true) {
//rebuild this list
var content = BuildMapTrafficList({
data: data
});
WriteMapOverlayContent({
type: "right-traffic",
data: content
});
} else {
//build new list
ShowMapTrafficInfo({
data: data,
show: show
});
}
} else {
//hide
if (oTrafficPanel.is(":visible") == true || oSpeedPanel.is(":visible") == true) ShowMapTrafficInfo(false);
}
//execute onHandler commands
if (typeof onHandler != 'undefined') {
if (typeof onHandler == 'function') onHandler();
else eval(onHandler);
}
}
//handler to show congestion layer
function Map_ShowCongestion(options) {
var show = true;
//get options passed in
if (options != null && typeof options != 'undefined') {
if (typeof options == 'object') {
if (typeof options.show != 'undefined') show = options.show;
} else if (typeof options == 'boolean') {
show = options;
} else {
show = (options.toString().toLowerCase() == 'true');
}
}
if (show == true) {
//show the congestion layer: (1) update oPage variable, (2) update mapViewstate variable
oPage.traffic.congestion = true;
mapViewstate.traffic.congestion = true;
CongestionMap_ShowLayer();
} else {
//hide the congestio layer: (1) update oPage variable, (2) update mapViewstate variable
oPage.traffic.congestion = false;
mapViewstate.traffic.congestion = false;
CongestionMap_ShowLayer({
show: false,
opacity: 0
});
}
}
//handler to move the map to the specific lnglat location
//ARGUMENT: lnglat = [lng lat], {object with lat, lng property}, lat, lng
function Map_MoveTo(options) {
var lnglat = null;
var zoom = null;
//get options passed in
if (options != null && typeof options != 'undefined') {
if (Array.isArray(options) == true) {
lnglat = options;
} else if (typeof options == 'object') {
if (typeof options.lnglat != 'undefined') {
if (Array.isArray(options.lnglat) == true) lnglat = options.lnglat;
else if (typeof options.lnglat == 'string') lnglat = options.lnglat.split(',').map(Number);
else lnglat = options.lnglat;
}
if (typeof options.zoom != 'undefined') zoom = options.zoom;
} else if (typeof options == 'string' && options.indexOf(",") >= 0) {
lnglat = options.split(',').map(Number);
}
}
if (lnglat != null) {
var cOptions = {
action: 'fly',
latlng: lnglat,
zoom: zoom
};
ChangeLocation(cOptions);
}
}
//handler to clear map
//NOTE: if no type passed in ==> clear all
//type = [route]
function Map_OnClear(options) {
var arrType = [];
var arrPolylineId = [];
//get options passed in
if (options != null && typeof options != 'undefined') {
if (Array.isArray(options) == true) {
arrType = options;
} else if (typeof options == 'object') {
if (typeof options.type != 'undefined') {
if (Array.isArray(options.type) == true) arrType = options.type;
else if (typeof options.type == 'string' && options.type > '') arrType = options.type.split(",");
}
if (typeof options.polylineid != 'undefined' && options.polylineid != null) {
if (Array.isArray(options.polylineid) == true) arrPolylineId = options.polylineid;
else if (typeof options.polylineid == 'string' && options.polylineid > '') arrPolylineId = options.polylineid.split(",");
}
} else if (typeof options == 'string' && options > '') {
arrType = options.split(",");
}
}
//close any map info window (if opened)
CloseInfoWindow();
//clear any items related to route
if (arrType.length <= 0 || arrType.indexOf("route") >= 0) {
//clear the Directions API polyline
ClearDirectionsPath();
////clear map markers
//ClearMarker({ type: "startpoint" });
////determine how to clear out the polyline
//if (arrPolylineId != null && arrPolylineId.length > 0) {
// //clear out specific polyline items
// var lenPolylineId = arrPolylineId.length;
// for (var i = 0; i < lenPolylineId; i++) {
// var aPolylineId = arrPolylineId[i];
// //remove from global list
// if (arrPolyline != null && arrPolyline.length > 0) {
// var iIndex = arrPolyline.findIndex(x => x.id == aPolylineId);
// if (iIndex >= 0) {
// //item found, remove it
// arrPolyline.splice(iIndex, 1);
// //remove map features
// ClearPolyline({ id: aPolylineId });
// }
// }
// }
//} else {
// //clear map polyline
// ResetPolyline();
//}
}
}
//handler to manage what action to take when user click/right-click the map
//action = [speed (default), route]
function Map_OnClickAction(event, onHandler) {
//get the current action
var action = oPage.action;
//determine action to take
if (action == 'speed') {
Map_ShowRoadwaySpeedPanel(event, onHandler);
} else if (action == 'route') {
Map_BuildRouteInfo(event, onHandler);
}
}
//handler on map when click to show the map speed data
function Map_ShowRoadwaySpeedPanel(event, onHandler) {
if (map != null && event != null) {
var oData = GetMapFeatureData({
event: event
});
if (oData != null) {
if (typeof oData.properties != 'undefined' && oData.properties != null) oData = oData.properties;
var roadId = null;
var roadwayId = null;
var dirCode = null;
if (typeof oData.id != 'undefined' && oData.id != null && oData.id > '') roadId = oData.id;
if (typeof oData.roadway != 'undefined' && oData.roadway != null && typeof oData.roadway.id != 'undefined' && oData.roadway.id != null && oData.roadway.id > '') roadwayId = oData.roadway.id;
if (typeof oData.direction != 'undefined' && oData.direction != null && typeof oData.direction.code != 'undefined' && oData.direction.code != null) dirCode = oData.direction.code;
//show the panel
if (roadId != null || roadwayId != null) {
ShowRoadwaySpeedPanel({
roadway: roadwayId,
road: roadId,
dircode: dirCode,
clickable: true
});
}
//execute onHandler commands
if (typeof onHandler != 'undefined') {
if (typeof onHandler == 'function') onHandler();
else eval(onHandler);
}
}
}
}
//handler on map when click to build the route
function Map_BuildRouteInfo(event, onHandler) {
if (map != null && event != null) {
var oData = GetMapFeatureData({
event: event
});
if (oData == null) {
//NO visible features detected, so just pass in the location where the mouse was clicked
//USING: MapBox Directions API, you only need to have [lng lat] for start and end and it finds the route needed
oData = {
geopoint: [event.lngLat.lng, event.lngLat.lat]
};
}
if (oData != null) {
if (typeof oData.properties != 'undefined' && oData.properties != null) oData = oData.properties;
//show the building route travel info feature
if (oData != null) {
Route_BuildRouteInfo({
data: oData
});
}
//execute onHandler commands
if (typeof onHandler != 'undefined') {
if (typeof onHandler == 'function') onHandler();
else eval(onHandler);
}
}
}
}
//handler for checkbox changes
function Map_SettingsOnChange() {
//get the latest settings: congestion, traffic, camera, congestion type
var isMajorRoadway = $("#chkMajorRoadway").prop("checked");
var isLocalRoadway = $("#chkLocalRoadway").prop("checked");
var isTraffic = $("#chkTraffic").prop("checked");
var isTrafficList = $("#chkTrafficList").prop("checked");
var isCamera = $("#chkCamStream").prop("checked");
var isCameraStill = $("#chkCamStill").prop("checked");
//define the frc for major/minor
var frcMajorRoadway = $("#chkMajorRoadway").attr("value");
var frcLocalRoadway = $("#chkLocalRoadway").attr("value");
//define what to show/hide
var congestionType = 'speedoverride';
var isCongestion = true;
var frc = frcMajorRoadway;
var incidentType = 'flow,incident,construction,event,transit';
if (isTraffic == false) incidentType = '';
if (isMajorRoadway == false && isLocalRoadway == false) {
isCongestion = false;
frc = '';
} else {
frc = '';
if (isMajorRoadway == true) {
if (frc > '') frc += ',';
frc += frcMajorRoadway;
}
if (isLocalRoadway == true) {
if (frc > '') frc += ',';
frc += frcLocalRoadway;
}
}
//define the traffic settings and save to viewstate
var oTrafficSettings = {
congestion: isCongestion,
congestiontype: congestionType,
type: incidentType,
list: isTrafficList,
frc: frc
};
//define the camera settings and save to viewsate
var oCameraSettings = {
stream: isCamera,
still: isCameraStill
};
//save the traffic/camera settings
SavePageProp({
traffic: oTrafficSettings,
camera: oCameraSettings
});
//update map viewstate
mapViewstate.traffic = oTrafficSettings;
mapViewstate.camera = oCameraSettings;
SaveMapViewstate();
//note: since the map is NOT moving, it will not call the function to close the traffic when set to false
var oTrafficPanel = $(".map-right-traffic-overlay");
if (oTrafficPanel.is(":visible") == true && isTrafficList == false) ShowMapTrafficInfo(false);
//redraw the map
DrawMap({
wait: 500
});
}
//handler to switch to a different market
function Map_SwitchMarket(options) {
var aCityId = null;
//get parameters
if (typeof options != 'undefined') {
if (typeof options == 'object' && typeof options.city != 'undefined') {
if (typeof options.city != 'undefined') aCityId = options.city;
} else if (typeof options == 'number' || typeof options == 'string') {
aCityId = options;
}
}
//error check
if (aCityId != null && typeof aCityId == 'string') aCityId = parseInt(aCityId);
if (aCityId != null && aCityId > 0) {
////DISABLE (3/8/24): allow users to move freely
////reset the maxbounds so you can goto new location
//ChangeMapMaxBounds(null);
//update local variable
cityId = aCityId;
//get the city object
oCity = GetCityData({
data: arrMarket,
id: cityId,
fetch: true
});
if (typeof oCity.properties != 'undefined') oCity = oCity.properties;
if (typeof oCity.location != 'undefined' && oCity.location != null && typeof oCity.location.lat != 'undefined' && typeof oCity.location.lng != 'undefined' && oCity.location.lat != null && oCity.location.lng != null) {
latlng = new LatLng(oCity.location.lat, oCity.location.lng);
}
//save the viewstate of the market change
SaveViewstateProp({
city: oCity
});
//move map to new market
var cOptions = {
action: 'fly',
latlng: latlng,
zoom: 11
};
ChangeLocation(cOptions);
//close any panels that are open
var closePanel = 'top,right,right-traffic';
CloseMapOverlays(closePanel);
//clear any previously set map features
Map_OnClear();
////define the new market's boundary so they can not move/pan outisde the bounds
//var maxBounds = null;
//if (oCity != null && typeof oCity.boundary != 'undefined' && oCity.boundary != null && typeof oCity.boundary.nw != 'undefined' && typeof oCity.boundary.se != 'undefined' && oCity.boundary.nw != null && oCity.boundary.se != null) {
// //maxbounds = array of lng/lat (2 records): first item = SouthWest lng/lat, second item = NorthEast lng/lat
// if (typeof oCity.boundary.nw.Lat != 'undefined') {
// //upper case for some reason, maybe old cache?
// var swLngLat = [oCity.boundary.nw.Lng, oCity.boundary.se.Lat];
// var neLngLat = [oCity.boundary.se.Lng, oCity.boundary.nw.Lat];
// maxBounds = [swLngLat, neLngLat];
// } else if (typeof oCity.boundary.nw.lat != 'undefined') {
// //lower case
// var swLngLat = [oCity.boundary.nw.lng, oCity.boundary.se.lat];
// var neLngLat = [oCity.boundary.se.lng, oCity.boundary.nw.lat];
// maxBounds = [swLngLat, neLngLat];
// }
//}
//if (maxBounds != null) {
// //wait a little bit for the map to pan over there, then set the new maxbounds variable
// setTimeout(function () { ChangeMapMaxBounds(maxBounds); }, 2000);
//}
//display this page's title on the window
//format: {SiteName}: {CityName}
if (oCity != null) {
var title = window.document.title;
if (typeof gblSiteAbbr != 'undefined' && gblSiteAbbr != null && gblSiteAbbr > '') title = gblSiteAbbr;
else title = title.substr(0, title.lastIndexOf(":")).trim();
if (typeof oCity.name != 'undefined' && oCity.name != null && oCity.name > '') title += ': ' + oCity.name;
window.document.title = title;
}
}
}
//initialize the map
function InitMap() {
//get the size of the map panel
var oMap = $("#pnlMap .map");
var mWidth = oMap.width();
var mHeight = oMap.height();
//define the default map settings
var mapId = oMap.attr("id");
//get page settings
var oTrafficSettings = GetPageProp("traffic");
var oCameraSettings = GetPageProp("camera");
////DISABLE (3/8/24): allow users to move freely
////define the new market's boundary so they can not move/pan outisde the bounds
//var maxBounds = null;
//if (oCity != null && typeof oCity.boundary != 'undefined' && oCity.boundary != null && typeof oCity.boundary.nw != 'undefined' && typeof oCity.boundary.se != 'undefined' && oCity.boundary.nw != null && oCity.boundary.se != null) {
// //maxbounds = array of lng/lat (2 records): first item = SouthWest lng/lat, second item = NorthEast lng/lat
// if (typeof oCity.boundary.nw.Lat != 'undefined') {
// //upper case for some reason, maybe old cache?
// var swLngLat = [oCity.boundary.nw.Lng, oCity.boundary.se.Lat];
// var neLngLat = [oCity.boundary.se.Lng, oCity.boundary.nw.Lat];
// maxBounds = [swLngLat, neLngLat];
// } else if (typeof oCity.boundary.nw.lat != 'undefined') {
// //lower case
// var swLngLat = [oCity.boundary.nw.lng, oCity.boundary.se.lat];
// var neLngLat = [oCity.boundary.se.lng, oCity.boundary.nw.lat];
// maxBounds = [swLngLat, neLngLat];
// }
//}
//show the map
var leftMenu = {
active: true,
type: "polyline",
polylineclick: Map_OnClickAction
};
var contextMenu = {
active: true,
type: "polyline",
polylineclick: Map_OnClickAction
};
var mOptions = {
id: mapId,
control: "navigation",
menu: contextMenu,
leftmenu: leftMenu,
traffic: oTrafficSettings,
camera: oCameraSettings,
width: mWidth,
height: mHeight,
zoom: zoom,
latlng: latlng
};
InitializeMap(mOptions);
}
/* LAYOUT */
//keep track of when browser is resized (in order to resize the map)
var isMapResize = true;
//resize the page layout
function PageResize() {
var oContent = $(".master-content");
var width = oContent.width();
var height = oContent.height();
var offset = 0;
//get updated window dimension
wdWidth = $(window).width();
wdHeight = $(window).height();
if (isMapResize == true) {
//define the panel sizes
var pnlMap = $("#pnlMap");
var htMap = height - offset;
pnlMap.css({
"height": htMap + "px"
});
//define the map panel dimension
var mWidth = pnlMap.width();
var mHeight = pnlMap.height();
if (pnlMap.is(":visible") == true) {
var oMap = pnlMap.find(".map");
oMap.css({
"width": mWidth + "px",
"height": mHeight + "px"
});
ResizeMap();
}
//resize the menu panel (if open)
var oLeftOverlay = $(".map-left-overlay");
var oRightOverlay = $(".map-right-overlay");
var oRightTrafficOverlay = $(".map-right-traffic-overlay");
if (oLeftOverlay.is(":visible") == true && oLeftOverlay.find("#pnlMenu").length > 0) ResizeMapOverlay({
type: "left",
width: plWidth
});
if (oRightOverlay.is(":visible") == true) ResizeMapOverlay({
type: "right",
width: prWidth
});
if (oRightTrafficOverlay.is(":visible") == true) ResizeMapOverlay({
type: "right-traffic",
width: prWidth
});
//reset the variable
isMapResize = false;
}
//SPECIAL MOBILE: (1) hide menu legend and/or help links
var pnlMenuLegend = $("#pnlMenuLegend");
var pnlMenuHelp = $("#pnlMenuHelp");
if ((pnlMenuLegend.length > 0 || pnlMenuHelp.length > 0) && (typeof isMobile != 'undefined' && typeof mobileType != 'undefined' && isMobile == true)) {
if (pnlMenuLegend.length > 0) {
if (wdHeight <= minPanelHeight) {
//hide the legend
pnlMenuLegend.hide();
} else {
//show it
pnlMenuLegend.show();
}
}
if (pnlMenuHelp.length > 0) {
if (wdHeight <= (minPanelHeight - 200)) {
//hide the help links
pnlMenuHelp.hide();
} else {
//show it
pnlMenuHelp.show();
}
}
}
}
/* LOADING */
//initialize the page
function InitPage() {
//show menu (default to show unless mobile device)
var isShowMenu = true;
if (typeof isMobile != 'undefined' && typeof mobileType != 'undefined' && isMobile == true && mobileType != 'ipad') isShowMenu = false;
//update default settings for demo account (preview account)
if (demo == 1) {
isShowMenu = false;
}
//show/hide the settings menu
ShowMapMenu(isShowMenu);
ShowAffiliateOnMap();
//determine if we need to show the route UI
if (oPage.action == 'route') ShowRouteMenu();
//initialize map
InitMap();
}
$(document).ready(function() {
//display this page's title on the window
if (oCity != null) {
var title = window.document.title;
if (typeof gblSiteAbbr != 'undefined' && gblSiteAbbr != null && gblSiteAbbr > '') title = gblSiteAbbr;
else title = title.substr(0, title.lastIndexOf("-")).trim();
if (typeof oCity.name != 'undefined' && oCity.name != null && oCity.name > '') title += ': ' + oCity.name;
window.document.title = title;
}
//resize this page right away
MasterPageResize();
//REQUIRED
setTimeout(function() {
InitPage();
}, 100);
});
//execute resize function when user resizes the browser
$(window).resize(function() {
isMapResize = true;
MasterPageResize();
});
</script>
</div>
</form>
Text Content
× × × × © Mapbox © OpenStreetMap Improve this map × Traffic within view Traffic* delay in minutes Delay Long-term road construction in Decatur on I-285 Outer loop between Flat Shoals Rd (GA-155)/Exit 48 and Glenwood Rd/Exit 44. Reported by GDOT 23 Long-term road construction in Panthersville on I 20 EB between Columbia Dr/Exit 66 (EB) and Evans Mill Rd/Exit 74. Reported by GDOT 7 Long-term road construction in Buckhead on GA-400 NB/SB between Old Toll Plaza and I-285/Exit 4. Reported by GDOT 5 Repaving work in Georgia Tech on Howell Mill Rd NW NB/SB between 8th St NW and Holmes St NW/Chattahoochee Ave NW. Reported by ATLDOT 2 Long-term road construction in Decatur on I-285 Inner loop between Glenwood Rd/Exit 44 and Flat Shoals Rd (GA-155)/Exit 48. Reported by GDOT 1 Road work. Off-ramp partially blocked in Doraville on I-285 EB off-ramp to NB I-85. Reported by GDOT ETC 4pm Road construction. Right lane closed in Sandy Springs on GA-400 NB at Glenridge Connector/Exit 3 (SB). Reported by GDOT ETC 3pm Bridge closed in Morningside on Cheshire Bridge Rd NB/SB between Liddell Dr NE and Faulkner Rd. Reported by ATLDOT Water main replacement in Decatur on E Ponce De Leon Ave EB/WB between Grove Place and N Clarendon Ave. Reported by Press Release Closed due to road construction in Atlanta on Lavista Rd EB/WB between Cheshire Bridge Rd and Lavista Walk. Reported by ATLDOT Roundabout installation in South Fulton on Butner Rd EB/WB at Union Rd. Reported by GDOT Road work. HOV lane closed in Smyrna on I 75 NB between Akers Mill Rd/Exit 258 (HOV NB) and I-75 Express Lanes/Exit 260 (NB). Reported by GDOT Beltline Construction in Midtown on 10th St EB/WB at Monroe Dr. Reported by ATLDOT Long-term road construction in Cumberland on Cumberland Blvd SE at Overton Park Dr Long-term road construction in Marietta on Callaway Rd SW NB/SB between Austell Rd and Al Bishop Drive. Reported by GDOT Long-term road construction in Conley on I-285 EB/WB between Moreland Ave (US-23)/Exit 53 and Bouldercrest Rd/Exit 51. Reported by GDOT × × × × menuSettings Change citiesSelect a cityAlbanyAlbuquerqueAllentownAppleton/OshkoshAshevilleAtlantaAugustaAustinBakersfieldBaltimoreBaton RougeBiloxi-GulfportBinghamtonBirminghamBostonBuffaloCedar Rapids/Iowa City CharlestonCharlotteChattanoogaChicagoCincinnatiCiudad de Mexico, D. F.ClevelandColorado SpringsColumbiaColumbusColumbus, GACorpus ChristiDallasDavenportDaytonDenverDes MoinesDetroitEl PasoErieFlorida KeysFort CollinsFort MyersFrederickFresnoFt WayneGainesville-OcalaGrand RapidsGreen Bay, WIGreensboroGreenvilleHarrisburgHarrisonburgHartford/New HavenHattiesburg/LaurelHonoluluHoustonHuntington-CharlestonHuntsvilleIndianapolisJacksonJacksonvilleKansas CityKnoxvilleLas VegasLexingtonLittle RockLos AngelesLouisvilleMaconMadisonMcAllenMemphisMiami/Fort LauderdaleMilwaukeeMinneapolisMobile/PensacolaMonterey-SalinasMontgomeryMontrealMyrtle BeachNashvilleNew OrleansNorfolkNYCOklahoma CityOmahaOrlandoOttawaPachuca, MXPanama CityParkersburg/MariettaPhiladelphiaPhoenixPittsburghPortlandPortsmouth/ManchesterProvidencePuebla, MXQueretara, MXRaleigh-DurhamReadingRichmondRoanoke/LynchburgRochester, NYSacramentoSalt Lake CitySan AntonioSan DiegoSan Francisco/San JoseSarasotaSavannahSeattleSpokaneSpringfieldSpringfield, MOSt. LouisStockton / ModestoSyracuseTallahasseeTampaToledoTorontoTucsonTulsaTuscaloosaVancouverWashingtonWest Palm Beach/Treasure CoastWheelingWichitaWilkes-BarreWilliamsportWorcesterYoungstownToggle view on/offMajor roadwayLocal roadwayTraffic iconTraffic listCamera streamCamera stillClick map actionShow speedBuild routeHelpContact usPricacy policyTerms of serviceLegendStopped trafficStop and go trafficSlow trafficHeavy trafficNo congestion* click any congestion lines to get details × × Last updated: 11:13 AM