Warning: Can't use blame annotator:
svn blame failed on trunk/stms_map_v53.html: ("Can't find a temporary directory: Internal error", 20014)

source: tmcsimulator/trunk/stms_map_v53.html @ 279

Revision 279, 11.4 KB checked in by jdalbey, 7 years ago (diff)

STMS map ver 5.3 now refreshes every 10 sec

RevLine 
1<!DOCTYPE html>
2<html>
3  <head>
4  <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
5    <title>STMS Map v0.53</title> 
6    <style>
7      /* Set the size of the div element that contains the map */
8      #mapdiv {
9        height: 100%;
10        width: 100%; 
11       }
12        /* Makes the page fill the window. */
13      html, body {
14        height: 100%;
15        margin: 0;
16        padding: 0;
17      }
18    </style>
19  </head>
20  <body>
21    <!--The div element where the map appears -->
22    <div id="mapdiv"></div>
23    <!-- Version 5.3 fixed dot color update defect, increased refresh rate to 10 sec.
24         Version 5.2 places red dots overlapping yellow dots.
25         Version 5.1 removes the map and street view buttons and the H3 tag.
26         Version 5 uses precomputed perpendicular vector in dot adjustment function
27         Version 4 Adjust the spacing between dots when the map is zoomed.
28         Version 3 does loadGeoJson only once, and subsequently does an ajax load
29         of the highways file, and selectively updates only those markers whose
30         color has changed.
31         @author jdalbey  2019.2.17
32    -->
33    <script>
34    // a global variable for the google map
35    var map; 
36    // Constant name of json data file
37    var kMapPointsFile = "highways.json";
38    // Constant for map center location: The John Wayne Airport
39    var centerPoint = {lat: 33.687228, lng: -117.872148};
40    // Initial map zoom
41    var initZoom = 12;
42    // Dot colors used in traffic model to indicate free-flowing, slowed, and stopped traffic
43    // and their associated zvalues so slower traffic dots are more visible.
44    var colorZvalues = {"lime":10,"yellow":20,"red":30};
45
46    // Build a solid colored icon to use instead of the classic pin
47    // Use a diamond on N and E directions, circle on S and W directions
48    function dotSymbol(color,postmileID) //,direction)
49    {
50        var circle = google.maps.SymbolPath.CIRCLE;
51        var diamond = 'M -1,0 0,-1 1,0 0,1 z';
52        var myShape = circle;
53        // See if postmile name contains N or W letters
54        if ((postmileID.indexOf('N') != -1) || (postmileID.indexOf('W') != -1))
55        {
56           myShape = diamond
57        }
58        return {
59            path: myShape,
60            scale: 5,
61            strokeColor: "black", // the border color
62            strokeWeight: 1,      // the border thickness
63            fillColor: color,
64            fillOpacity: 1.0
65        };
66    }
67
68    // Load the map data from a json file and style all the points
69    function loadMapData()
70    {
71        // Load the map data
72        map.data.loadGeoJson(kMapPointsFile);
73        // Style the map data by applying the desired properties to each feature (marker)
74        map.data.setStyle(function(feature) 
75        {
76            // Get the desired color value
77            var ptColor = feature.getProperty("color");
78            // Get the postmile id
79            var name = feature.getId();
80            var street = feature.getProperty("street");
81            // Build the marker
82            var iconSymbol = dotSymbol(ptColor,name);
83            // return the StyleOptions
84            return {
85                    icon: iconSymbol,
86                    title: name + " @" + street,  // set rollover text
87                    // set zIndex for slowed traffic to a higher value so they overlap
88                    zIndex: colorZvalues[ptColor]
89                   };
90        });
91    }
92
93    // magic formula controls distance between dots proportionate to zoom factor
94    function calcDistanceFactor()
95    {
96        // 15 is maximum zoom, the point at which no adjusment is needed
97        return (.0005*(15-map.getZoom())); 
98    }
99
100    // Adjust the coordinates of dots so they appear side-by-side
101    // The perpendicular vector for each dot has been provided,
102    // so we just need to multiply by a scaling factor (adjAmount)
103    // @param adjAmount amount by which to adjust coordinate
104    function adjustCoords(adjAmount)
105    {
106        //console.log("adjusting coordinates");
107        // Adjust the NB points a slight amount
108        map.data.forEach(function(feature)
109        {
110            // get the name of the current feature
111            var name = feature.getId();
112            // lookup the name in the list of markers
113            var marker = parsed_JSON.features.find(function(element)
114                {
115                    return element.id == name;
116                });
117            // extract the original coordinates
118            origLat = marker.geometry.coordinates[1];
119            origLong = marker.geometry.coordinates[0];
120
121            //retrieve the perpendicular vector (precomputed)
122            var perpx = feature.getProperty("perpx")
123            var perpy = feature.getProperty("perpy")
124            // Make adjustment and save it
125            var myLat = origLat + perpy * adjAmount
126            var myLong = origLong + perpx * adjAmount
127            feature.setGeometry({lat:myLat, lng:myLong});
128        });
129    }
130
131     // update the color (as needed) for a given marker
132     function updateMarker(marker)
133     {
134        target = marker.id;
135        newColor = marker.properties.color;
136        // see if new color is different than current color
137        currentFeature = map.data.getFeatureById(target);
138        currentColor = currentFeature.getProperty("color");
139        //console.log("current color:",currentColor," newColor: ",newColor);
140        // if a new color is desired then assign it to the feature's color property
141        if (currentColor != newColor)
142        {
143            currentFeature.setProperty("color",newColor);
144            // set zIndex for slowed traffic to a higher value so they overlap
145            currentFeature.setProperty("zIndex", colorZvalues[newColor]);
146            //console.log(target+" updated to "+newColor);
147        }
148     }
149
150    // Load the highways file via ajax
151    // Ref: https://codepen.io/KryptoniteDove/post/load-json-file-locally-using-pure-javascript
152     function loadJSON(callback) {   
153
154        var xobj = new XMLHttpRequest();
155            xobj.overrideMimeType("application/json");
156        xobj.open('GET', kMapPointsFile, true); 
157        xobj.onreadystatechange = function () {
158              if (xobj.readyState == 4 && xobj.status == "200") {
159                // Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
160                callback(xobj.responseText);
161              }
162        };
163        xobj.send(null); 
164     }
165
166     var parsed_JSON;
167     // Load the highways json file and update the map
168     function updateMap()
169     {
170        loadJSON(function(response)
171        {
172            // Parse JSON string into object
173            parsed_JSON = JSON.parse(response);
174            // Process each new marker - lookup in current map
175            parsed_JSON.features.forEach(updateMarker);
176        });
177     }
178
179    // Initialize the map and load the points
180    function initMap() 
181    {
182        // Declare the map and where it belongs on the page
183        map = new google.maps.Map( document.getElementById('mapdiv'), 
184        {
185            zoom: initZoom, 
186            center: centerPoint,
187            styles: night_mode,
188            mapTypeControl: false,
189            streetViewControl: false 
190        });
191        loadMapData();  // go load the map data
192        // After a brief pause to let map finish loading ...
193        quiktimer = setTimeout("updateMap()",3000);
194        // go adjust the marker coordinates so dots don't overlap
195        quiktimer = setTimeout("adjustCoords(calcDistanceFactor())",3500); 
196        // Start a time to refresh the map every 10 seconds
197        var myTimer = setInterval(updateMap, 10000);
198        // Listen for zoom changes and move the markers so as to keep a nice
199        // visual distance between them appropriate to the zoom factor
200        map.addListener('zoom_changed', function() {
201            // fetch how much the map is currently zoomed
202            currentZoom = map.getZoom(); 
203            //console.log("Zoom changed to ",currentZoom);
204            // only bother adjusting within this range
205            if ((currentZoom <16) && (currentZoom>10))
206            {
207                // magic formula controls distance between dots
208                factor = (.0005*(15-currentZoom)); 
209                adjustCoords(calcDistanceFactor());
210            }
211        });
212
213    }
214
215    // Styles array for Night Mode map
216    // Ref: https://developers.google.com/maps/documentation/javascript/styling
217    var night_mode = [
218                {elementType: 'geometry', stylers: [{color: '#242f3e'}]},
219                {elementType: 'labels.text.stroke', stylers: [{color: '#242f3e'}]},
220                {elementType: 'labels.text.fill', stylers: [{color: '#746855'}]},
221                {
222                  featureType: 'administrative.locality',
223                  elementType: 'labels.text.fill',
224                  stylers: [{color: '#d59563'}]
225                },
226                {
227                  featureType: 'poi',
228                  elementType: 'labels.text.fill',
229                  stylers: [{color: '#d59563'}]
230                },
231                {
232                  featureType: 'poi.park',
233                  elementType: 'geometry',
234                  stylers: [{color: '#263c3f'}]
235                },
236                {
237                  featureType: 'poi.park',
238                  elementType: 'labels.text.fill',
239                  stylers: [{color: '#6b9a76'}]
240                },
241                {
242                  featureType: 'road',
243                  elementType: 'geometry',
244                  stylers: [{color: '#38414e'}]
245                },
246                {
247                  featureType: 'road',
248                  elementType: 'geometry.stroke',
249                  stylers: [{color: '#212a37'}]
250                },
251                {
252                  featureType: 'road',
253                  elementType: 'labels.text.fill',
254                  stylers: [{color: '#9ca5b3'}]
255                },
256                {
257                  featureType: 'road.highway',
258                  elementType: 'geometry',
259                  stylers: [{color: '#746855'}]
260                },
261                {
262                  featureType: 'road.highway',
263                  elementType: 'geometry.stroke',
264                  stylers: [{color: '#1f2835'}]
265                },
266                {
267                  featureType: 'road.highway',
268                  elementType: 'labels.text.fill',
269                  stylers: [{color: '#f3d19c'}]
270                },
271                {
272                  featureType: 'transit',
273                  elementType: 'geometry',
274                  stylers: [{color: '#2f3948'}]
275                },
276                {
277                  featureType: 'transit.station',
278                  elementType: 'labels.text.fill',
279                  stylers: [{color: '#d59563'}]
280                },
281                {
282                  featureType: 'water',
283                  elementType: 'geometry',
284                  stylers: [{color: '#17263c'}]
285                },
286                {
287                  featureType: 'water',
288                  elementType: 'labels.text.fill',
289                  stylers: [{color: '#515c6d'}]
290                },
291                {
292                  featureType: 'water',
293                  elementType: 'labels.text.stroke',
294                  stylers: [{color: '#17263c'}]
295                }
296              ]
297
298    // Using John's API Key
299    </script>
300    <script async defer
301    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyD6iTyN0DjP-9OVkAgicyp4tkC10naE_B8&callback=initMap">
302    </script>
303  </body>
304</html>
Note: See TracBrowser for help on using the repository browser.