PageSourceSearch

https://www.lamar.edu/about-lu/campus-map/v-1.1.0/v1.0/src/map.js

js lamar.edu collected 2026-10-01 10:25:27 UTC 54,613 bytes, 1,799 lines download raw bytes

1var app = angular.module('campusMapApp', ['ui.toggle', 'ngRoute']);
2
3app.service('supportingFunctions', function ()
4{
5  this.jsUcfirst = function (string)
6  {
7    return string.charAt(0).toUpperCase() + string.slice(1);
8  }
9  this.jsLcfirst = function (string)
10  {
11    return string.charAt(0).toLowerCase() + string.slice(1);
12  }
13
14  this.jsonToTable = function (json)
15  {
16    var html = '<table border="1">';
17    $.each(json, function (key, value)
18    {
19      html += '<tr>';
20      html += '<td>' + key + '</td>';
21      html += '<td>' + value + '</td>';
22      html += '</tr>';
23    });
24    html += '</table>';
25
26    return html;
27  }
28});
29
30app.service('map', ['supportingFunctions', 'mapData', '$http', function (supportingFunctions, mapData, $http)
31{
32
33  var northEast = new google.maps.LatLng(30.046800, -94.066490);
34  var southWest = new google.maps.LatLng(30.031910, -94.0801);
35  var bounds = new google.maps.LatLngBounds(southWest, northEast);
36  var centerPoint = new google.maps.LatLng(30.039939, -94.074748);
37  var directionsDisplay = new google.maps.DirectionsRenderer;
38  var directionsService = new google.maps.DirectionsService;
39  var geocoder = new google.maps.Geocoder();
40  var currentPos = null;
41  var markerForCurrentLocation = null;
42  var map = null;
43  var infoWindow = null;
44  var _this = this;
45  var markers = {};
46  var locationDetectedFirstTime = true;
47  var markerCounter = 0; // unique id for each marker.
48  if ($(window).height() < 800)
49  {
50    $('html').addClass('mobile');
51    smallScreen = true;
52  }
53  var mobile = $('html').hasClass('mobile') ? true : false;
54  //alert(mobile);
55
56  this.init = function ()
57  {
58
59    var options = {
60      center: centerPoint,
61      zoom: 16,
62      mapTypeId: google.maps.MapTypeId.ROADMAP,
63      maxZoom: 200,
64      minZoom: 0,
65      // mapTypeControlOptions: {
66      //   mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.SATELLITE, google.maps.MapTypeId.HYBRID, google.maps.MapTypeId.TERRAIN],
67      //   style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
68      // },
69      zoomControlOptions: {
70        position: google.maps.ControlPosition.LEFT_CENTER
71      },
72      fullscreenControl: false,
73      zoomControl: true,
74      scaleControl: false,
75      mapTypeControl: false,
76      streetViewControl: false,
77      styles: [
78        {
79          "elementType": "geometry",
80          "stylers": [{
81            "color": "#f5f5f5"
82          }]
83        },
84        {
85          "elementType": "labels.icon",
86          "stylers": [{
87            "visibility": "off"
88          }]
89        },
90        {
91          "elementType": "labels.text.fill",
92          "stylers": [{
93            "color": "#616161"
94          }]
95        },
96        {
97          "elementType": "labels.text.stroke",
98          "stylers": [{
99            "color": "#f5f5f5"
100          }]
101        },
102        {
103          "featureType": "administrative.land_parcel",
104          "elementType": "labels",
105          "stylers": [{
106            "visibility": "off"
107          }]
108        },
109        {
110          "featureType": "administrative.land_parcel",
111          "elementType": "labels.text.fill",
112          "stylers": [{
113            "color": "#bdbdbd"
114          }]
115        },
116        {
117          "featureType": "landscape.man_made",
118          "elementType": "geometry.fill",
119          "stylers": [{
120            "visibility": "off"
121          },
122          {
123            "weight": 1.5
124          }
125          ]
126        },
127        {
128          "featureType": "poi",
129          "elementType": "geometry",
130          "stylers": [{
131            "color": "#eeeeee"
132          }]
133        },
134        {
135          "featureType": "poi",
136          "elementType": "labels.text",
137          "stylers": [{
138            "visibility": "off"
139          }]
140        },
141        {
142          "featureType": "poi",
143          "elementType": "labels.text.fill",
144          "stylers": [{
145            "color": "#757575"
146          }]
147        },
148        {
149          "featureType": "poi.park",
150          "elementType": "geometry",
151          "stylers": [{
152            "color": "#e5e5e5"
153          }]
154        },
155        {
156          "featureType": "poi.park",
157          "elementType": "labels.text.fill",
158          "stylers": [{
159            "color": "#9e9e9e"
160          }]
161        },
162        {
163          "featureType": "road",
164          "elementType": "geometry",
165          "stylers": [{
166            "color": "#ffffff"
167          }]
168        },
169        {
170          "featureType": "road.arterial",
171          "elementType": "labels.text.fill",
172          "stylers": [{
173            "color": "#757575"
174          }]
175        },
176        {
177          "featureType": "road.highway",
178          "elementType": "geometry",
179          "stylers": [{
180            "color": "#dadada"
181          }]
182        },
183        {
184          "featureType": "road.highway",
185          "elementType": "labels.text.fill",
186          "stylers": [{
187            "color": "#616161"
188          }]
189        },
190        {
191          "featureType": "road.local",
192          "elementType": "labels",
193          "stylers": [{
194            "visibility": "off"
195          }]
196        },
197        {
198          "featureType": "road.local",
199          "elementType": "labels.text.fill",
200          "stylers": [{
201            "color": "#9e9e9e"
202          }]
203        },
204        {
205          "featureType": "transit.line",
206          "elementType": "geometry",
207          "stylers": [{
208            "color": "#e5e5e5"
209          }]
210        },
211        {
212          "featureType": "transit.station",
213          "elementType": "geometry",
214          "stylers": [{
215            "color": "#eeeeee"
216          }]
217        },
218        {
219          "featureType": "water",
220          "elementType": "geometry",
221          "stylers": [{
222            "color": "#c9c9c9"
223          }]
224        },
225        {
226          "featureType": "water",
227          "elementType": "geometry.fill",
228          "stylers": [{
229            "color": "#6db3ff"
230          }]
231        },
232        {
233          "featureType": "water",
234          "elementType": "labels.text.fill",
235          "stylers": [{
236            "color": "#9e9e9e"
237          }]
238        }
239      ]
240    }
241    if (mobile)
242    {
243      options["zoom"] = 15;
244      options["mapTypeControl"] = false;
245      options["zoomControl"] = false;
246    }
247    //Initialize map object
248    map = new google.maps.Map(
249      document.getElementById("map"), options
250    );
251    /**
252     * Overlay is set of tiles 
253     * each has its own bounds and image
254     */
255    //Tile 1
256    var tile1_northEast = new google.maps.LatLng(30.04722076052011, -94.07272164294598);
257    var tile1_southWest = new google.maps.LatLng(30.04196015197183, -94.0807238542655);
258    var tile1_bounds = new google.maps.LatLngBounds(tile1_southWest, tile1_northEast);
259
260    var tileObj1 = new LamarTileOvelay(tile1_bounds, "v1.0/images/tiles/google-overlay-slice_01.png", map);
261
262    //Tile 2
263    var tile2_northEast = new google.maps.LatLng(30.0472443506421, -94.0659990834491);
264    var tile2_southWest = new google.maps.LatLng(30.04194379521872, -94.07272219106879);
265    var tile2_bounds = new google.maps.LatLngBounds(tile2_southWest, tile2_northEast);
266
267    var tileObj2 = new LamarTileOvelay(tile2_bounds, "v1.0/images/tiles/google-overlay-slice_02.png", map);
268
269
270    //Tile 3
271    var tile3_northEast = new google.maps.LatLng(30.04196329365754, -94.07288819639068);
272    var tile3_southWest = new google.maps.LatLng(30.03577716853072, -94.0806665762687);
273    var tile3_bounds = new google.maps.LatLngBounds(tile3_southWest, tile3_northEast);
274
275    var tileObj3 = new LamarTileOvelay(tile3_bounds, "v1.0/images/tiles/google-overlay-slice_03.png", map);
276
277    //Tile 4
278    var tile4_northEast = new google.maps.LatLng(30.04195107727692, -94.06598629172862);
279    var tile4_southWest = new google.maps.LatLng(30.03581117127335, -94.07288103140067);
280    var tile4_bounds = new google.maps.LatLngBounds(tile4_southWest, tile4_northEast);
281
282    var tileObj4 = new LamarTileOvelay(tile4_bounds, "v1.0/images/tiles/google-overlay-slice_04.png", map);
283
284    //Tile 5
285    var tile5_northEast = new google.maps.LatLng(30.03579259006426, -94.0659511053024);
286    var tile5_southWest = new google.maps.LatLng(30.03110409070911, -94.07291422029608);
287    var tile5_bounds = new google.maps.LatLngBounds(tile5_southWest, tile5_northEast);
288
289    var tileObj5 = new LamarTileOvelay(tile5_bounds, "v1.0/images/tiles/google-overlay-slice_05.png", map);
290
291    //Tile 6
292    var tile6_northEast = new google.maps.LatLng(30.03577468959246, -94.07290414279537);
293    var tile6_southWest = new google.maps.LatLng(30.03103841622551, -94.08049571030975);
294    var tile6_bounds = new google.maps.LatLngBounds(tile6_southWest, tile6_northEast);
295
296    var tileObj6 = new LamarTileOvelay(tile6_bounds, "v1.0/images/tiles/google-overlay-slice_06.png", map);
297
298    //Directions setup
299    directionsDisplay.setOptions({
300      suppressMarkers: true,
301      clickable: false,
302      suppressInfoWindows: true
303    });
304    directionsDisplay.setMap(map);
305    //Info window & geolocation 
306    infoWindow = new google.maps.InfoWindow;
307
308    /**
309     * Place a marker when click on a building
310     */
311
312    google.maps.event.addListener(map, 'click', function (event)
313    {
314      geocoder.geocode({
315        'latLng': event.latLng
316      }, function (results, status)
317      {
318        if (status == google.maps.GeocoderStatus.OK)
319        {
320          if (results[0])
321          {
322            console.log("----------------------------------------");
323            console.log(results);
324
325            var tempCounter = 0; //Keep looping untill you find a match for the building in local DB                      
326            var found = false;
327            while (!found && tempCounter < 2)
328            {
329              console.log("%c Trying to use address: ", 'background: #222; color: #bada55', results[tempCounter]["formatted_address"]);
330
331              //console.log(results[tempCounter]["formatted_address"]);
332              let search_token = results[tempCounter]["formatted_address"];
333
334
335              if (notActiveLocation(search_token)) return;
336              //special cases
337
338              if (specialCase(search_token))
339              {
340                search_token = results[0]["place_id"] + "-" + results[1]["place_id"];
341                mapData.searchLocationsbasedonAddress(search_token, function (result)
342                {
343                  var markerName = "marker-tile" + markerCounter++;
344                  if (result.length > 0)
345                  {
346                    _this.addMarkerWithInfoWindow(markerName, result[0], "buildings", "marker.png", null, null);
347                    $(".clear").css('display', 'block');
348                    found = true;
349                  } else
350                  {
351                    search_token = results[tempCounter]["formatted_address"];
352                  }
353                });
354              } else if ((search_token.toLowerCase().indexOf("unnamed road") != -1))
355              {
356                search_token = results[tempCounter]["place_id"]
357              }
358              if (!found)
359              {
360                mapData.searchLocationsbasedonAddress(search_token, function (result)
361                {
362                  var markerName = "marker-tile" + markerCounter++;
363                  if (result.length > 0)
364                  {
365                    _this.addMarkerWithInfoWindow(markerName, result[0], "buildings", "marker.png", null, null);
366                    $(".clear").css('display', 'block');
367                    found = true;
368                  }
369                  if (!found) { console.log('%c Trying another address! ', 'background: Red; color: #bada55'); }
370                });
371                tempCounter++;
372              }
373            }
374          }
375        }
376      });
377    });
378  }
379
380  function specialCase(address)
381  {
382    //special case addresses
383    if (address == "Galloway Business, Beaumont, TX 77705, USA" ||
384      address == "4400 S M L King Jr Pkwy, Beaumont, TX 77705, USA" ||
385      address == "Rolfe Christopher & E. Florida, Beaumont, TX 77705, USA" ||
386      address == "922 Jim Gilligan Way, Beaumont, TX 77705, USA" ||
387      address == "950 Jim Gilligan Way, Beaumont, TX 77705, USA" ||
388      address == "960 Jim Gilligan Way, Beaumont, TX 77705, USA" ||
389      address == "5550 Jimmy Simmons Blvd, Beaumont, TX 77705, USA" ||
390      address == "960 Jim Gilligan Way, Beaumont, TX 77705, USA" ||
391      address == " Lucas Engineering, Beaumont, TX 77705, USA" ||
392      address == "4810 Rolfe Christopher Dr, Beaumont, TX 77705, USA" ||
393      address == "Family and Consumer Science, Beaumont, TX 77705, USA" ||
394      address == "4405 Jimmy Simmons Blvd, Beaumont, TX 77705, USA" ||
395      address == "857 E Virginia St, Beaumont, TX 77705, USA")
396
397      return true;
398
399    return false;
400  }
401
402  function notActiveLocation(address)
403  {
404    if (address == "4460 Jimmy Simmons Blvd, Beaumont, TX 77705, USA")
405      return true;
406
407    return false;
408  }
409  /**
410   * Custom overlays
411   */
412  LamarTileOvelay.prototype = new google.maps.OverlayView();
413
414  /** @constructor */
415  function LamarTileOvelay(bounds, image, map)
416  {
417
418    // Now initialize all properties.
419    this.bounds_ = bounds;
420    this.image_ = image;
421    this.map_ = map;
422
423    // Define a property to hold the image's div. We'll
424    // actually create this div upon receipt of the onAdd()
425    // method so we'll leave it null for now.
426    this.div_ = null;
427
428    // Explicitly call setMap on this overlay
429    this.setMap(map);
430  }
431  LamarTileOvelay.prototype.onAdd = function ()
432  {
433
434    var div = document.createElement('div');
435    div.style.border = 'none';
436    div.style.borderWidth = '0px';
437    div.style.position = 'absolute';
438
439    // Create the img element and attach it to the div.
440    var img = document.createElement('img');
441    img.src = this.image_;
442    img.style.width = '100%';
443    img.style.height = '100%';
444    div.appendChild(img);
445
446    this.div_ = div;
447
448    // Add the element to the "overlayImage" pane.
449    var panes = this.getPanes();
450    //panes.overlayImage.appendChild(this.div_);
451    //panes.overlayMouseTarget.appendChild(this.div_);
452    panes.overlayLayer.appendChild(this.div_);
453
454    // set this as locally scoped var so event does not get confused
455    var me = this;
456
457  };
458  LamarTileOvelay.prototype.draw = function ()
459  {
460
461    // We use the south-west and north-east
462    // coordinates of the overlay to peg it to the correct position and size.
463    // To do this, we need to retrieve the projection from the overlay.
464    var overlayProjection = this.getProjection();
465
466    // Retrieve the south-west and north-east coordinates of this overlay
467    // in LatLngs and convert them to pixel coordinates.
468    // We'll use these coordinates to resize the div.
469    var sw = overlayProjection.fromLatLngToDivPixel(this.bounds_.getSouthWest
469());
470    var ne = overlayProjection.fromLatLngToDivPixel(this.bounds_.getNorthEast());
471
472    // Resize the image's div to fit the indicated dimensions.
473    var div = this.div_;
474    div.style.left = sw.x + 'px';
475    div.style.top = ne.y + 'px';
476    div.style.width = (ne.x - sw.x) + 'px';
477    div.style.height = (sw.y - ne.y) + 'px';
478  };
479  LamarTileOvelay.prototype.onRemove = function ()
480  {
481    this.div_.parentNode.removeChild(this.div_);
482  };
483  // Set the visibility to 'hidden' or 'visible'.
484  LamarTileOvelay.prototype.hide = function ()
485  {
486    if (this.div_)
487    {
488      // The visibility property must be a string enclosed in quotes.
489      this.div_.style.visibility = 'hidden';
490    }
491  };
492  LamarTileOvelay.prototype.show = function ()
493  {
494    if (this.div_)
495    {
496      this.div_.style.visibility = 'visible';
497    }
498  };
499
500  this.updateCurrentLocation = function (position)
501  {
502    currentPos = position;
503    this.addMarkerForCurrentLocation(currentPos);
504  }
505
506  this.loadCurrentLocation = function ()
507  {
508    var options = {
509      enableHighAccuracy: true,
510      maximumAge: 0
511    };
512
513    navigator.geolocation.getCurrentPosition(function (position)
514    {
515      //console.log("found current location");
516      currentPos = {
517        lat: position.coords.latitude,
518        lng: position.coords.longitude
519      };
520      //console.log(currentPos);
521      _this.addMarkerForCurrentLocation(currentPos);
522      // }
523    }, function (error)
524    {
525      //console.log(error);
526    });
527  }
528
529  this.autoUpdateCurrentLocation = function ()
530  {
531    _this = this;
532
533    navigator.geolocation.watchPosition(function (position)
534    {
535      //console.log("Location found");
536      //console.log(position);
537      var location = { lat: position.coords.latitude, lng: position.coords.longitude };
538      _this.updateCurrentLocation(location);
539    }, function (error)
540    {
541      if (error.code == error.PERMISSION_DENIED)
542        console.log("No permission for location");
543    }, {
544      enableHighAccuracy: true
545    });
546
547  }
548  /*
549   * Set route between origin and destination
550   * 3 ways supported DRIVING,WALKING,BICYCLING
551   */
552  this.goDestinationFromCurrentPlace = function (travelMode, destination)
553  {
554    this.calculateAndDisplayRoute(travelMode, currentPos, destination);
555  }
556
557  this.calculateAndDisplayRoute = function (travelMode, origin, destination)
558  {
559    var _this = this;
560    if ($('.direc-toggle').attr('aria-expanded') == 'true')
561    {
562      $('.direc-toggle').click();
563    }
564
565
566    directionsService.route({
567      origin: {
568        lat: origin.lat,
569        lng: origin.lng
570      },
571      destination: {
572        lat: destination.lat,
573        lng: destination.lng
574      },
575      travelMode: google.maps.TravelMode[travelMode]
576    }, function (response, status)
577    {
578      if (status == 'OK')
579      {
580        directionsDisplay.setMap(map);
581        directionsDisplay.setDirections(response);
582
583        $(".clear").css('display', 'block');
584        //_this.removeAllMarkers();
585      } else
586      {
587        ////console.log('Directions request failed due to ' + status);
588      }
589    });
590  }
591
592  this.handleLocationError = function (browserHasGeolocation, infoWindow, pos)
593  {
594    infoWindow.setPosition(pos);
595    infoWindow.setContent(browserHasGeolocation ?
596      'Error: The Geolocation service failed.' :
597      'Error: Your browser doesn\'t support geolocation.');
598    infoWindow.open(map);
599  }
600
601  this.resetDefaultZoom = function ()
602  {
603    if (mobile)
604    {
605      map.setCenter(centerPoint);
606      map.setZoom(15);
607    }
608  }
609  /*
610   * Add marker with pop up window     
611   */
612  this.addMarkerForCurrentLocation = function (position)
613  {
614    var iconPath = "v1.0/images/currentlocation.png";
615
616    if (markerForCurrentLocation)
617      markerForCurrentLocation.setMap(null);
618    if (locationDetectedFirstTime)
619    {
620      markerForCurrentLocation = new google.maps.Marker({
621        map: map,
622        position: position,
623        icon: iconPath,
624        animation: google.maps.Animation.DROP
625      });
626      locationDetectedFirstTime = false;
627    } else
628    {
629      markerForCurrentLocation = new google.maps.Marker({
630        map: map,
631        position: position,
632        icon: iconPath,
633      });
634    }
635  }
636
637  this.addAbstractMarker = function (location, icon)
638  {
639    var iconPath = "v1.0/images/";
640    if (icon == null)
641      iconPath += "library.png";
642    else
643      iconPath += icon;
644
645    this.marker = new google.maps.Marker({
646      map: map,
647      position: new google.maps.LatLng(location.lat, location.lng),
648      icon: iconPath,
649      animation: google.maps.Animation.DROP
650    });
651  }
652
653  //Only one at a time
654  this.addMarker = function (location, icon)
655  {
656    map.setZoom(18);
657    map.setCenter(new google.maps.LatLng(location.lat, location.lng));
658    var iconPath = "v1.0/images/";
659    if (icon == null)
660      iconPath += "library.png";
661    else
662      iconPath += icon;
663
664    var image = {
665      url: iconPath, // image is 512 x 512
666      scaledSize: new google.maps.Size(45, 45)
667    };
668
669    if (this.marker) this.marker.setMap(null);
670
671    this.marker = new google.maps.Marker({
672      map: map,
673      position: new google.maps.LatLng(location.lat, location.lng),
674      icon: image,
675      animation: google.maps.Animation.DROP
676    });
677
678  }
679
680  this.addMarkerAsDestination = function (markerName, entity, entityType, icon, size, destinationType)
681  { //destination Type can be walking, driving  or bicycling
682    _this = this;
683    var iconPath = "v1.0/images/";
684
685    if (icon == null)
686      iconPath += "marker.png";
687    else
688      iconPath += icon;
689
690    if (typeof size == "undefined")
691    {
692      size = "45";
693    }
694
695    var image = {
696      url: iconPath, // image is 512 x 512
697      scaledSize: new google.maps.Size(size, size)
698    };
699
700    var marker = new google.maps.Marker({
701      map: map,
702      position: new google.maps.LatLng(entity.lat, entity.lng),
703      icon: iconPath
704    });
705
706
707
708    markers[markerName] = marker;
709
710    google.maps.event.addListener(marker, 'click', function ()
711    {
712      var location = {
713        lat: entity.lat,
714        lng: entity.lng
715      };
716      _this.calculateAndDisplayRoute("WALKING", currentPos, location);
717    });
718  }
719
720
721  //Marker has info-window //use this only when show group of markers for a category
722  this.addMarkerWithInfoWindow = function (markerName, entity, entityType, icon, customTitle, customMessage, openInfoWindow)
723  {
724    _this = this;
725    var iconPath = "v1.0/images/";
726    var imagePath = "v1.0/assets/" + supportingFunctions.jsLcfirst(entityType) + "/" + entity.image;
727
728
729    if (icon == null)
730      iconPath += "marker.png";
731    else
732      iconPath += icon;
733
734    var markerImage = {
735      url: iconPath,
736      scaledSize: new google.maps.Size(50, 50)
737    };
738
739    // InfoWindow content
740    var content;
741    if (customMessage != null)
742    {
743      content = '<div id="iw-container">' +
744        '<div class="iw-title">' + supportingFunctions.jsUcfirst(customTitle) + '</div>' +
745        '<div class="iw-content">' +
746        '<p>' + (entity.hasOwnProperty("description") ? customMessage : "") + '</p>' +
747        '</div>' +
748        '<div class="iw-bottom-gradient"></div>' +
749        '</div>';
750    } else
751    {
752      content = '<div id="iw-container">' +
753        '<div class="iw-title">' + supportingFunctions.jsUcfirst(entity.name) + '</div>' +
754        '<div class="iw-content">' +
755        '<div class="iw-subTitle">' + supportingFunctions.jsUcfirst(entity.label) + '</div>' +
756        ((entity.hasOwnProperty("image") && entity.image.length > "0") ? '<img src="' + imagePath + '" alt="' + entity.name + '" height="100%" width="100%"/>' : "") +
757        '<p>' + (entity.hasOwnProperty("description") ? entity.description : "") + '</p>' +
758        '</div>' +
759        '<div class="iw-bottom-gradient"></div>' +
760        '</div>';
761    }
762
763    var marker = new google.maps.Marker({
764      map: map,
765      position: new google.maps.LatLng(entity.lat, entity.lng),
766      icon: markerImage,
767      animation: google.maps.Animation.DROP,
768      title: entity.name
769    });
770
771    markers[markerName] = marker;
772
773    var infowindow = new google.maps.InfoWindow({
774      content: content,
775      maxWidth: 350
776    });
777
778    google.maps.event.addListener(marker, 'click', function ()
779    {
780      infowindow.open(map, this);
781    });
782
783    google.maps.event.addListener(infowindow, 'domready', function ()
784    {
785
786
787
788      // If the content of infowindow not exceed the set maximum height, then the gradient is removed.
789      if ($('.iw-content').height() < 140)
790      {
791        $('.iw-bottom-gradient').css({
792          display: 'none'
793        });
794      }
795
796    });
797
798  }
799
800  this.addMarkerWithInfoWindowAsDestination = function (markerName, entity, entityType, icon, customTitle, customMessage)
801  {
802    _this = this;
803    var iconPath = "v1.0/images/";
804    var imagePath = "v1.0/assets/" + supportingFunctions.jsLcfirst(entityType) + "/" + entity.image;
805
806    if (icon == null)
807      iconPath += "marker.png";
808    else
809      iconPath += icon;
810
811    var markerImage = {
812      url: iconPath, // image is 512 x 512
813      scaledSize: new google.maps.Size(50, 50)
814    };
815
816    // InfoWindow content
817    var content;
818    if (customMessage != null)
819    {
820      content = '<div id="iw-container">' +
821        '<div class="iw-title">' + supportingFunctions.jsUcfirst(customTitle) + '</div>' +
822        '<div class="iw-content">' +
823        '<p>' + (entity.hasOwnProperty("description") ? customMessage : "") + '</p>' +
824        '</div>' +
825        '<div class="iw-bottom-gradient"></div>' +
826        '</div>';
827    } else
828    {
829
830      content = '<div id="iw-container">' +
831        '<div class="iw-title">' + supportingFunctions.jsUcfirst(entity.name) + '</div>' +
832        '<div class="iw-content">' +
833        '<div class="iw-subTitle">' + supportingFunctions.jsUcfirst(entity.label) + '</div>' +
834        ((entity.hasOwnProperty("image") && entity.image.length > "0") ? '<img src="' + imagePath + '" alt="' + entity.name + '" height="100%" width="100%"/>' : "") +
835        '<p>' + (entity.hasOwnProperty("description") ? entity.description : "") + '</p>' +
836        '</div>' +
837        '<div class="iw-bottom-gradient"></div>' +
838        '</div>';
839    }
840    var marker = new google.maps.Marker({
841      map: map,
842      position: new google.maps.LatLng(entity.lat, entity.lng),
843      icon: markerImage,
844      animation: google.maps.Animation.DROP,
845      title: entity.name
846    });
847
848    markers[markerName] = marker;
849
850
851    var infowindow = new google.maps.InfoWindow({
852      content: content,
853      maxWidth: 350
854    });
855
856    google.maps.event.addListener(marker, 'click', function ()
857    {
858      infowindow.open(map, this);
859      var location = {
860        lat: entity.lat,
861        lng: entity.lng
862      };
863      _this.calculateAndDisplayRoute("WALKING", currentPos, location);
864    });
865
866    google.maps.event.addListener(infowindow, 'domready', function ()
867    {
868
869      // Reference to the DIV that wraps the bottom of infowindow
870      var iwOuter = $('.gm-style-iw');
871
872      /* Since this div is in a position prior to .gm-div style-iw.
873       * We use jQuery and create a iwBackground variable,
874       * and took advantage of the existing reference .gm-style-iw for the previous div with .prev().
875       */
876      var iwBackground = iwOuter.prev();
877
878      // Removes background shadow DIV
879      iwBackground.children(':nth-child(2)').css({
880        'display': 'none'
881      });
882
883      // Removes white background DIV
884      iwBackground.children(':nth-child(4)').css({
885        'display': 'none'
886      });
887
888      // Moves the infowindow 115px to the right.
889      iwOuter.parent().parent().css({
890        left: '0'
891      });
892
893      // Moves the shadow of the arrow 76px to the left margin.
894      iwBackground.children(':nth-child(1)').attr('style', function (i, s)
895      {
896        return s + 'left: 76px !important;'
897      });
898
899      // Moves the arrow 76px to the left margin.
900      iwBackground.children(':nth-child(3)').attr('style', function (i, s)
901      {
902        return s + 'left: 76px !important;'
903      });
904
905      // Changes the desired tail shadow color.
906      iwBackground.children(':nth-child(3)').find('div').children().css({
907        'box-shadow': 'rgba(72, 181, 233, 0.6) 0px 1px 6px',
908        'z-index': '1'
909      });
910
911      // Reference to the div that groups the close button elements.
912      var iwCloseBtn = iwOuter.next();
913
914      //Get real clsoe button that fires close event for infowidno
915      var realCloseButton = iwCloseBtn.next();
916
917      // Apply the desired effect to the close button
918      iwCloseBtn.css({
919        width: '27',
920        height: '27',
921        opacity: '1',
922        right: '38px',
923        top: '3px',
924        border: '7px solid #48b5e9',
925        'border-radius': '13px',
926        'box-shadow': '0 0 5px #3990B9'
927      });
928
929      // Apply the desired effect to the close button
930      realCloseButton.css({
931        right: '38px'
932      });
933
934      // If the content of infowindow not exceed the set maximum height, then the gradient is removed.
935      if ($('.iw-content').height() < 140)
936      {
937        $('.iw-bottom-gradient').css({
938          display: 'none'
939        });
940      }
941
942      // The API automatically applies 0.7 opacity to the button after the mouseout event. This function reverses this event to the desired value.
943      iwCloseBtn.mouseout(function ()
944      {
945        $(this).css({
946          opacity: '1'
947        });
948      });
949    });
950
951  }
952
953  this.addMarkerWithInfoWindowAndDestination = function (markerName, entity, entityType, icon, customTitle, customMessage)
954  {
955    _this = this;
956    var iconPath = "v1.0/images/";
957    var imagePath = "v1.0/assets/" + supportingFunctions.jsLcfirst(entityType) + "/" + entity.image;
958
959    if (icon == null)
960      iconPath += "marker.png";
961    else
962      iconPath += icon;
963
964    var markerImage = {
965      url: iconPath, // image is 512 x 512
966      scaledSize: new google.maps.Size(50, 50)
967    };
968
969    // InfoWindow content
970    var content;
971    if (customMessage != null)
972    {
973      content = '<div id="iw-container">' +
974        '<div class="iw-title">' + supportingFunctions.jsUcfirst(customTitle) + '</div>' +
975        '<div class="iw-content">' +
976        '<p>' + (entity.hasOwnProperty("description") ? customMessage : "") + '</p>' +
977        '</div>' +
978        '<div class="iw-bottom-gradient"></div>' +
979        '</div>';
980    } else
981    {
982
983      content = '<div id="iw-container">' +
984        '<div class="iw-title">' + supportingFunctions.jsUcfirst(entity.name) + '</div>' +
985        '<div class="iw-content">' +
986        '<div class="iw-subTitle">' + supportingFunctions.jsUcfirst(entity.label) + '</div>' +
987        ((entity.hasOwnProperty("image") && entity.image.length > "0") ? '<img src="' + imagePath + '" alt="' + entity.name + '" height="100%" width="100%"/>' : "") +
988        '<p>' + (entity.hasOwnProperty("description") ? entity.description : "") + '</p>' +
989        '</div>' +
990        '<div class="iw-bottom-gradient"></div>' +
991        '</div>';
992    }
993    var marker = new google.maps.Marker({
994      map: map,
995      position: new google.maps.LatLng(entity.lat, entity.lng),
996      icon: markerImage,
997      animation: google.maps.Animation.DROP,
998      title: entity.name
999    });
1000
1001    markers[markerName] = marker;
1002
1003
1004    var infowindow = new google.maps.InfoWindow({
1005      content: content,
1006      maxWidth: 350
1007    });
1008
1009    google.maps.event.addListener(marker, 'click', function ()
1010    {
1011      infowindow.open(map, this);
1012    });
1013    var location = {
1014      lat: entity.lat,
1015      lng: entity.lng
1016    };
1017
1018    currentPos = {
1019      lat: 30.036212,
1020      lng: -94.073537
1021    };
1022    _this.calculateAndDisplayRoute("WALKING", currentPos, location);
1023
1024    google.maps.event.addListener(infowindow, 'domready', function ()
1025    {
1026
1027      // Reference to the DIV that wraps the bottom of infowindow
1028      var iwOuter = $('.gm-style-iw');
1029
1030      /* Since this div is in a position prior to .gm-div style-iw.
1031       * We use jQuery and create a iwBackground variable,
1032       * and took advantage of the existing reference .gm-style-iw for the previous div with .prev().
1033       */
1034      var iwBackground = iwOuter.prev();
1035
1036      // Removes background shadow DIV
1037      iwBackground.children(':nth-child(2)').css({
1038        'display': 'none'
1039      });
1040
1041      // Removes white background DIV
1042      iwBackground.children(':nth-child(4)').css({
1043        'display': 'none'
1044      });
1045
1046      // Moves the infowindow 115px to the right.
1047      iwOuter.parent().parent().css({
1048        left: '0'
1049      });
1050
1051      // Moves the shadow of the arrow 76px to the left margin.
1052      iwBackground.children(':nth-child(1)').attr('style', function (i, s)
1053      {
1054        return s + 'left: 76px !important;'
1055      });
1056
1057      // Moves the arrow 76px to the left margin.
1058      iwBackground.children(':nth-child(3)').attr('style', function (i, s)
1059      {
1060        return s + 'left: 76px !important;'
1061      });
1062
1063      // Changes the desired tail shadow color.
1064      iwBackground.children(':nth-child(3)').find('div').children().css({
1065        'box-shadow': 'rgba(72, 181, 233, 0.6) 0px 1px 6px',
1066        'z-index': '1'
1067      });
1068
1069      // Reference to the div that groups the close button elements.
1070      var iwCloseBtn = iwOuter.next();
1071
1072      //Get real clsoe button that fires close event for infowidno
1073      var realCloseButton = iwCloseBtn.next();
1074
1075      // Apply the desired effect to the close button
1076      iwCloseBtn.css({
1077        width: '27',
1078        height: '27',
1079        opacity: '1',
1080        right: '38px',
1081        top: '3px',
1082        border: '7px solid #48b5e9',
1083        'border-radius': '13px',
1084        'box-shadow': '0 0 5px #3990B9'
1085      });
1086
1087      // Apply the desired effect to the close button
1088      realCloseButton.css({
1089        right: '38px'
1090      });
1091
1092      // If the content of infowindow not exceed the set maximum height, then the gradient is removed.
1093      if ($('.iw-content').height() < 140)
1094      {
1095        $('.iw-bottom-gradient').css({
1096          display: 'none'
1097        });
1098      }
1099
1100      // The API automatically applies 0.7 opacity to the button after the mouseout event. This function reverses this event to the desired value.
1101      iwCloseBtn.mouseout(function ()
1102      {
1103        $(this).css({
1104          opacity: '1'
1105        });
1106      });
1107    });
1108
1109  }
1110  //Marker has info-window //use this only when show group of markers for a category          
1111
1112  this.removeMarker = function (markerName, location, icon)
1113  {
1114    markers[markerName].setMap(null);
1115    delete markers[markerName];
1116  }
1117
1118  this.removeAllMarkers = function ()
1119  {
1120
1121    for (var key in markers)
1122    {
1123      if (markers.hasOwnProperty(key))
1124      {
1125        markers[key].setMap(null);
1126        delete markers[key];
1127      }
1128    }
1129
1130  }
1131
1132  this.clear = function ()
1133  {
1134    this.removeAllMarkers();
1135
1136    if (this.marker != null)
1137      this.marker.setMap(null);
1138
1139    if (directionsDisplay != null)
1140      directionsDisplay.setMap(null);
1141    if (mobile)
1142      map.setZoom(15);
1143    else
1144      map.setZoom(16);
1145
1146    map.setCenter(centerPoint);
1147  }
1148
1149  this.resize = function ()
1150  {
1151    google.maps.event.trigger(map, 'resize');
1152    map.setCenter(centerPoint);
1153    map.setZoom(16);
1154
1155    google.maps.event.addDomListener(map, 'drag', function (e)
1156    {
1157      google.maps.event.trigger(map, 'resize');
1158    });
1159  }
1160}]);
1161
1162app.controller('mapCtrl', ['$http', '$document', '$route', '$scope', 'map', 'mapData', '$routeParams', 'supportingFunctions', '$rootScope',
1163  function ($http, $document, $route, $scope, Map, mapData, $routeParams, supportingFunctions, $rootScope)
1164  {
1165
1166    $scope.features = [
1167      {
1168        id: 0,
1169        checked: false,
1170        name: "art"
1171      },
1172      {
1173        id: 1,
1174        checked: false,
1175        name: "emergency-phones"
1176      },
1177      {
1178        id: 2,
1179        checked: false,
1180        name: "food"
1181      },
1182      {
1183        id: 3,
1184        checked: false,
1185        name: "charging-stations"
1186      },
1187      {
1188        id: 4,
1189        checked: false,
1190        name: "map-features-all"
1191      },
1192      {
1193        id: 5,
1194        checked: false,
1195        name: "parking-visitor"
1196      },
1197      {
1198        id: 6,
1199        checked: false,
1200        name: "parking-student"
1201      },
1202      {
1203        id: 7,
1204        checked: false,
1205        name: "parking-faculty-staff"
1206      },
1207      {
1208        id: 8,
1209        checked: false,
1210        name: "parking-motorcycle"
1211      },
1212      {
1213        id: 9,
1214        checked: false,
1215        name: "parking-accessibility"
1216      },
1217      {
1218        id: 10,
1219        checked: false,
1220        name: "parking-all"
1221      },
1222      {
1223        id: 11,
1224        checked: false,
1225        name: "accessibility-entrances"
1226      },
1227      {
1228        id: 12,
1229        checked: false,
1230        name: "accessibility-all"
1231      },
1232      {
1233        id: 13,
1234        checked: false,
1235        name: "athletic-fields"
1236      },
1237      {
1238        id: 14,
1239        checked: false,
1240        name: "senior-students"
1241      },
1242      {
1243        id: 15,
1244        checked: false,
1245        name: "points-of-interest"
1246      },
1247        {
1248        id: 16,
1249        checked: false,
1250        name: "gated"
1251      }
1252    ];
1253    $scope.checked = false;
1254    $scope.counter = 0;
1255    $scope.buildings = mapData.buildings;
1256    $scope.navigatorItems = 21;
1257    $scope.toGoPlace = null;
1258    $scope.version = "V 1.0.3";
1259    var randomId = 0;
1260
1261    $scope.$on('$routeChangeSuccess', function (ev, current, previous)
1262    {
1263      var apiLocation = $route.current.params.locationName;
1264      var course_number = $route.current.params.course_number;
1265
1266      //Directory intgeration
1267      var department = $route.current.params.department;
1268      var first_name = $route.current.params.first_name;
1269      var last_name = $route.current.params.last_name;
1270      var office_phonenumber = $route.current.params.office_phonenumber;
1271
1272      if (apiLocation)
1273      {
1274        mapData.searchLocations(apiLocation, function (result)
1275        {
1276          var onlyTopResult = result[0];
1277          if (onlyTopResult)
1278            Map.addMarkerWithInfoWindowAsDestination("apiLocation", onlyTopResult, "buildings", "marker.png", null, null);
1279
1280        });
1281      }
1282      if (course_number)
1283      {
1284        mapData.getCourses(course_number, function (result)
1285        {
1286          for (var i = 0; i < result.length; i++)
1287          {
1288            var sLcoation = result[i];
1289            var courseLocation = sLcoation["Room_No"];
1290            mapData.searchLocations(courseLocation, function (result)
1291            {
1292              var onlyTopResult = result[0];
1293              if (onlyTopResult)
1294                Map.addMarkerWithInfoWindowAsDestination("apiLocation", onlyTopResult, "apiLocation", "marker.png", sLcoation["Subject"], supportingFunctions.jsonToTable(sLcoation));
1295            });
1296          }
1297        });
1298      }
1299
1300      if (department)
1301      {
1302        mapData.searchDepartments(department, function (result)
1303        {
1304          var onlyTopResult = result[0];
1305          console.log(onlyTopResult);
1306          if (onlyTopResult)
1307            Map.addMarkerWithInfoWindowAndDestination("apiLocation", onlyTopResult, "buildings", "marker.png", first_name + " " + last_name, null);
1308        });
1309      }
1310    });
1311
1312    $scope.changeToggle = function (feature)
1313    {
1314      Map.resetDefaultZoom();
1315      if (feature["name"] == "emergency-phones")
1316      {
1317        if (feature["checked"])
1318          this.addMarkersForCategoryAsDestination(feature["name"], mapData.emergencyPhones, "emergency.png");
1319        else
1320          this.removeMarkersForCategory(feature["name"], mapData.emergencyPhones);
1321      } else if (feature["name"] == "athletic-fields")
1322      {
1323        if (feature["checked"])
1324          this.addMarkersForCategory(feature["name"], mapData.athleticFields, "athelticfields.png");
1325        else
1326          this.removeMarkersForCategory(feature["name"], mapData.athleticFields);
1327      } else if (feature["name"] == "food")
1328      {
1329        if (feature["checked"])
1330          this.addMarkersForCategory(feature["name"], mapData.foodPlaces, "restaurant.png");
1331        else
1332          this.removeMarkersForCategory(feature["name"], mapData.foodPlaces);
1333      } else if (feature["name"] == "art")
1334      {
1335        if (feature["checked"])
1336          this.addMarkersForCategory(feature["name"], mapData.art, "art.png");
1337        else
1338          this.removeMarkersForCategory(feature["name"], mapData.art);
1339      } else if (feature["name"] == "charging-stations")
1340      {
1341        if (feature["checked"])
1342          mapData.filterParking("C", function (result)
1343          {
1344            $scope.addMarkersForCategoryAsDestination(feature["name"], result, "chargingstation.png");
1345          });
1346        else
1347          mapData.filterParking("C", function (result)
1348          {
1349            $scope.removeMarkersForCategory(feature["name"], result);
1350          });
1351      } else if (feature["name"] == "parking-all")
1352      {
1353        if (feature["checked"])
1354          this.addMarkersForCategory(feature["name"], mapData.parkingLots, "parking.png");
1355        else
1356          this.removeMarkersForCategory(feature["name"], mapData.parkingLots);
1357      } else if (feature["name"] == "parking-visitor")
1358      {
1359
1360        if (feature["checked"])
1361          mapData.filterParking("V", function (result)
1362          {
1363            $scope.addMarkersForCategoryAsDestination(feature["name"], result, "parking.png");
1364          });
1365        else
1366          mapData.filterParking("V", function (result)
1367          {
1368            $scope.removeMarkersForCategory(feature["name"], result);
1369          });
1370      } else if (feature["name"] == "parking-student")
1371      {
1372        if (feature["checked"])
1373          mapData.filterParking("L", function (result)
1374          {
1375            $scope.addMarkersForCategoryAsDestination(feature["name"], result, "parking.png");
1376          });
1377        else
1378          mapData.filterParking("L", function (result)
1379          {
1380            $scope.removeMarkersForCategory(feature["name"], result);
1381          });
1382      } else if (feature["name"] == "parking-faculty-staff")
1383      {
1384        if (feature["checked"])
1385          mapData.filterParking("E", function (result)
1386          {
1387            $scope.addMarkersForCategoryAsDestination(feature["name"], result, "parking.png");
1388          });
1389        else
1390          mapData.filterParking("E", function (result)
1391          {
1392            $scope.removeMarkersForCategory(feature["name"], result);
1393          });
1394      } else if (feature["name"] == "parking-motorcycle")
1395      {
1396        if (feature["checked"])
1397          mapData.filterParking("M", function (result)
1398          {
1399            $scope.addMarkersForCategoryAsDestination(feature["name"], result, "parking.png");
1400          });
1401        else
1402          mapData.filterParking("M", function (result)
1403          {
1404            $scope.removeMarkersForCategory(feature["name"], result);
1405          });
1406      } else if (feature["name"] == "senior-students")
1407      {
1408        if (feature["checked"])
1409          mapData.filterParking("S", function (result)
1410          {
1411            $scope.addMarkersForCategoryAsDestination(feature["name"], result, "parking.png");
1412          });
1413        else
1414          mapData.filterParking("S", function (result)
1415          {
1416            $scope.removeMarkersForCategory(feature["name"], result);
1417          });
1418      } else if (feature["name"] == "gated")
1419      {
1420        if (feature["checked"])
1421          mapData.filterParking("G", function (result)
1422          {
1423            $scope.addMarkersForCategoryAsDestination(feature["name"], result, "parking.png");
1424          });
1425        else
1426          mapData.filterParking("G", function (result)
1427          {
1428            $scope.removeMarkersForCategory(feature["name"], result);
1429          });
1430      }
1431       else if (feature["name"] == "parking-accessibility")
1432      {
1433        if (feature["checked"])
1434          mapData.filterParking("A", function (result)
1435          {
1436            $scope.addMarkersForCategoryAsDestination(feature["name"], result, "parking.png");
1437          });
1438        else
1439          mapData.filterParking("A", function (result)
1440          {
1441            $scope.removeMarkersForCategory(feature["name"], result);
1442          });
1443      } else if (feature["name"] == "accessibility-entrances")
1444      {
1445        if (feature["checked"])
1446          this.addMarkersForCategoryAsDestinationWithIconSize(feature["name"], mapData.accessibilityEntrances, "accessibilityentrances.png", "15");
1447        else
1448          this.removeMarkersForCategory(feature["name"], mapData.accessibilityEntrances);
1449      } else if (feature["name"] == "accessibility-all")
1450      {
1451        if (feature["checked"])
1452          mapData.filterParking("A", function (result)
1453          {
1454            $scope.addMarkersForCategoryAsDestination(feature["name"], result, "parking.png");
1455          });
1456        else
1457          mapData.filterParking("A", function (result)
1458          {
1459            $scope.removeMarkersForCategory(feature["name"], result);
1460          });
1461      } else if (feature["name"] == "points-of-interest")
1462      {
1463        if (feature["checked"])
1464          this.addMarkersForCategory(feature["name"], mapData.pointsofinterest, "marker.png");
1465        else
1466          this.removeMarkersForCategory(feature["name"], mapData.pointsofinterest);
1467      }
1468      
1469
1470      //add disclaimer says seniors 7am-12am
1471    };
1472
1473    $scope.addMarkersForCategory = function (featureName, featuresObject, featureMarker)
1474    {
1475      $(".clear").css('display', 'block');
1476      for (let i = 0; i < featuresObject.length; i++)
1477      {
1478        Map.addMarkerWithInfoWindow(featureName + i, featuresObject[i], featureName, featureMarker, null, null, false);
1479      }
1480    }
1481
1482    $scope.addMarkersForCategoryAsDestination = function (featureName, featuresObject, featureMarker)
1483    {
1484      $(".clear").css('display', 'block');
1485      for (let i = 0; i < featuresObject.length; i++)
1486      {
1487        Map.addMarkerAsDestination(featureName + i, featuresObject[i], featureName, featureMarker);
1488      }
1489    }
1490
1491    $scope.addMarkersForCategoryAsDestinationWithIconSize = function (featureName, featuresObject, featureMarker, size)
1492    {
1493      $(".clear").css('display', 'block');
1494      for (let i = 0; i < featuresObject.length; i++)
1495      {
1496        Map.addMarkerAsDestination(featureName + i, featuresObject[i], featureName, featureMarker, size, null);
1497      }
1498    }
1499
1500    $scope.removeMarkersForCategory = function (featureName, featuresObject)
1501    {
1502      for (let i = 0; i < featuresObject.length; i++)
1503      {
1504        Map.removeMarker(featureName + i, featuresObject[i]);
1505      }
1506    }
1507
1508    //Navigator 
1509    $scope.showHide = function ()
1510    {
1511      $("#navigatorAccess").toggle();
1512    }
1513
1514    //Navigator 
1515    $scope.showFullList = function ()
1516    {
1517      $scope.navigatorItems = $scope.navigatorItems == mapData.buildings.length ? 21 : mapData.buildings.length;
1518      console.log($(".showmore").text());
1519      console.log("------");
1520      $(".showmore").text($(".showmore").text() == "Show less..." ? "Show more..." : "Show less...");
1521    }
1522
1523    $scope.searchLocationForDirections = function ()
1524    {
1525      mapData.searchLocations($scope.searchedKeyword, function (result)
1526      {
1527        $scope.navSerachResult = result;
1528      });
1529    }
1530
1531    $scope.addDestination = function (location)
1532    {
1533
1534      $scope.toGoPlace = location;
1535      $scope.searchedKeyword = location.name;
1536      $scope.navSerachResult = []; //reset serch result
1537
1538      var destiantion = {
1539        "lat": location.lat,
1540        "lng": location.lng
1541      };
1542
1543      Map.addMarker(location);
1544      Map.goDestinationFromCurrentPlace($scope.travelMode, destiantion);
1545    };
1546    /*
1547     *Quich search "Search map test field"
1548     */
1549    $scope.quickSearch = function ()
1550    {
1551      mapData.searchLocations($scope.quickSearchPlace, function (result)
1552      {
1553        console.log(result);
1554
1555        $("#searchedList").toggle();
1556        $scope.quickSearchResult = result;
1557      });
1558    }
1559
1560
1561    $scope.addGenericMarkerForQuickSearchResult = function (place)
1562    {
1563      $("#searchedList").toggle();
1564      $(".clear").css('display', 'block');
1565      var markerName = "marker" + randomId++;
1566      let type = mapData.whatTypeIsThisPlace(place);
1567      Map.addMarkerWithInfoWindow(markerName, place, type, "marker.png", null, null, false);
1568    }
1569
1570    $scope.addMarkerForQuickSearchResult = function (place)
1571    {
1572      $("#searchedList").toggle();
1573      $(".clear").css('display', 'block');
1574      var markerName = "marker" + randomId++;
1575      Map.addMarkerWithInfoWindow(markerName, place, "buildings", "marker.png", null, null, true);
1576    }
1577
1578    $scope.addMarker = function (entity)
1579    {
1580      $(".clear").css('display', 'block');
1581      var markerName = entity["name"] + randomId++;
1582      Map.addMarkerWithInfoWindow(markerName, entity, "buildings", "marker.png", null, null, true);
1583    };
1584
1585    $scope.clear = function (place)
1586    {
1587      $(".clear").hide();
1588      Map.clear();
1589      //Turn off all toggle options for features
1590      for (var i = 0, len = $scope.features.length; i < len; i++)
1591      {
1592        var feature = $scope.features[i];
1593        feature.checked = false;
1594      }
1595      $(".dropdown-menu").removeClass("show");
1596
1597
1598      $('.navbar-toggle').each(function (index)
1599      {
1600        if ($(this).attr('aria-expanded') == 'true')
1601        {
1602          $(this).click();
1603        }
1604      });
1605    }
1606
1607    //Voice recognition
1608    //Get quick search by voice
1609    $scope.getQuickSearchByVoice = function ()
1610    {
1611      //   $("#speachOverlay").toggle();
1612      //   setTimeout(
1613      //     function () {
1614
1615      //       if ($("#speachOverlay").css('display') == "block") {
1616      //         $("#speachOverlay").toggle();
1617      //       };
1618      //     }, 12000);
1619
1620      //   voiceRecognition.getTheWord(function (status) {
1621      //   });
1622    }
1623
1624    $rootScope.$on('failedToGetRecognizeVoice', function (event, args)
1625    {
1626      if (!$("#speachOverlay").css('display') == "block")
1627      {
1628        $("#speachOverlay").toggle();
1629      };
1630    });
1631
1632    $rootScope.$on('testEvent', function (event, args)
1633    {
1634      $("#speachOverlay").toggle();
1635      $scope.quickSearchPlace = args.destination;
1636      mapData.searchLocations(args.destination, function (result)
1637      {
1638        $("#searchedList").show();
1639
1640        if (result.length == 1)
1641        {
1642          $scope.addMarkerForQuickSearchResult(result[0]);
1643        } else
1644        {
1645          $scope.quickSearchResult = result;
1646        }
1647        $scope.$apply();
1648      });
1649    });
1650
1651    $scope.hideVROverlay = function ()
1652    {
1653      $("#speachOverlay").toggle();
1654      //   voiceRecognition.stopVR(function (status) {
1655      //   });
1656    }
1657
1658    // $rootScope.$on('voiceRecognitionIsNotSupported', function (event, args) {
1659    //   $(".vrSpeech").prop("disabled", true);
1660    // });
1661
1662
1663    Map.init();
1664    Map.autoUpdateCurrentLocation();
1665
1666    //get alerts/messages
1667    $document.ready(function ()
1668    {
1669
1670      $http({
1671        method: "GET",
1672        url: "messages.json",
1673        dataType: "json"
1674      }).then(function (response)
1675      {
1676        for (var i = 0; i < response.data.length; i++)
1677        {
1678          var obj = response.data[i];
1679          var message =
1680            '<div class="' + obj["type"] + ' alert" role="alert">'
1681            + '<span>' + obj["message"] + '</span>'
1682            + '</div>'
1683
1684          $("#messages").append(message);
1685        }
1686      });
1687    });
1688
1689  }]);
1690
1691/**
1692 * App Routes
1693 * Location route with lcoationname to show amrker for that lcoation
1694 * course route to show the buildign that host the coure lecture
1695 */
1696app.config(function ($routeProvider, $locationProvider)
1697{
1698  $routeProvider
1699    //route for the home page
1700    .when('/', {
1701      templateUrl: 'index.html',
1702      controller: 'msapCtrl'
1703    })
1704    .when('/location/:locationName', {
1705      templateUrl: 'index.html',
1706      controller: 'mapCtrl',
1707    })
1708    .when('/Course_Reference_Number/:course_number', {
1709      templateUrl: 'index.html',
1710      controller: 'mapCtrl',
1711    })
1712    // /directory/department/library/first_name/charla/last_name/pate/office_phonenumber/444
1713    .when('/directory/department/:department/first_name/:first_name/last_name/:last_name/office_phonenumber/:office_phonenumber', {
1714      templateUrl: 'index.html',
1715      controller: 'mapCtrl',
1716    })
1717    .otherwise({
1718      redirectTo: '/'
1719    });
1720});
1721//----------------------------------------
1722
1723
1724$(document).ready(function ()
1725{
1726  $('.dropdown').children(".dropdown-toggle").on({
1727    "click": function ()
1728    {
1729      $(this).parent().attr('closable', true);
1730
1731      $('.dropdown').each(function (index)
1732      {
1733
1734        if ($(this).hasClass('show') && ($(this).attr('closable') == 'false'))
1735        {
1736          $(this).find('.dropdown-toggle').click();
1737        }
1738
1739      });
1740
1741      $(this).parent().attr('closable', true);
1742
1743    }
1744  });
1745
1746  $('.dropdown').on({
1747    "shown.bs.dropdown": function ()
1748    {
1749      $(this).attr('closable', false);
1750    },
1751    "click": function () { }, // For some reason a click() is sent when Bootstrap tries and fails hide.bs.dropdown
1752    "hide.bs.dropdown": function ()
1753    {
1754      return $(this).attr('closable') == 'true';
1755    }
1756  });
1757
1758  navigator.geolocation.watchPosition(function (position)
1759  {
1760  }, function (error)
1761  {
1762    if (error.code == error.PERMISSION_DENIED)
1763      console.log("No permission for location");
1764  }, {
1765    enableHighAccuracy: false
1766  });
1767
1768  var forEach = function (t, o, r) { if ("[object Object]" === Object.prototype.toString.call(t)) for (var c in t) Object.prototype.hasOwnProperty.call(t, c) && o.call(r, t[c], c, t); else for (var e = 0, l = t.length; l > e; e++)o.call(r, t[e], e, t) };
1769
1770  var hamburgers = document.querySelectorAll(".hamburger");
1771  if (hamburgers.length > 0)
1772  {
1773    forEach(hamburgers, function (hamburger)
1774    {
1775      hamburger.addEventListener("click", function ()
1776      {
1777        this.classList.toggle("is-active");
1778      }, false);
1779    });
1780  }
1781
1782  setInterval(function ()
1783  {
1784    $(".hamburger.hamburger--collapse").toggleClass("is-active");
1785  }, 1200);
1786
1787  setInterval(function ()
1788  {
1789    $(".hamburger.hamburger--elastic").toggleClass("is-active");
1790  }, 1200);
1791
1792  setInterval(function ()
1793  {
1794    $(".hamburger.hamburger--emphatic").toggleClass("is-active");
1795  }, 1200);
1796
1797});
1798
1799

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.