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

source: tmcsimulator/trunk/stms_map_v52.html @ 275

Revision 275, 11.3 KB checked in by jdalbey, 7 years ago (diff)

version .52 of stms map

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