<!DOCTYPE html>
<html>

  <head lang="en">
    <meta charset="utf-8">
    <link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
    <link href="app.css" rel="stylesheet">
    <title>AngularGM Example</title>
  </head>
  
  <body data-spy="scroll" data-target=".gm-docs-sidenav">
    <div class="container-fluid">
      <div class="row-fluid">
        <div class="span3 gm-docs-sidenav">
          <ul class="nav nav-list bs-docs-sidenav affix">
            <li><a href="#simple-map"><i class="icon-chevron-right"></i> Simple Map</a></li>
            <li><a href="#map-with-markers"><i class="icon-chevron-right"></i> Map With Markers</a></li>
            <li><a href="#infowindows"><i class="icon-chevron-right"></i> InfoWindows</a></li>
            <li><a href="#infowindows2"><i class="icon-chevron-right"></i> InfoWindows2</a></li>
            <li><a href="#multiple-maps"><i class="icon-chevron-right"></i> Multiple Maps</a></li>
            <li><a href="#lots-of-markers"><i class="icon-chevron-right"></i> Lots of Markers</a></li>
            <li><a href="#filter-markers"><i class="icon-chevron-right"></i> Filter Markers</a></li>
            <li><a href="#drag-marker"><i class="icon-chevron-right"></i> Drag Marker</a></li>

          </ul>
        </div>
        <div class="span9" ng-app="Example" ng-cloak>
          
          <h3 id="simple-map">Simple Map</h3>
          <div class="row-fluid margin-bottom60" ng-controller="SimpleMapCtrl">
            <div class="span6">     
              <gm-map gm-map-id="'simpleMap'" gm-center="center" gm-zoom="zoom" class="map"></gm-map>
            </div>
            <div class="span6">
              <p>
                <label>Center:</label>
                <input type="number" ng-model="centerLat" ng-change="updateCenter(centerLat, centerLng)">, 
                <input type="number" ng-model="centerLng" ng-change="updateCenter(centerLat, centerLng)">
              </p>
              <p>
                <label>Zoom:</label>
                <input type="number" ng-model="zoom">
              </p>
            </div>
          </div>
        
          <h3 id="map-with-markers">Map with Markers</h3>
          <div class="row-fluid margin-bottom60" ng-controller="MapWithMarkersCtrl">
            <div class="span6">
              <gm-map gm-map-id="'mapWithMarkers'" gm-center="center" gm-zoom="zoom" gm-map-options="options.map" class="map">
                <gm-markers gm-objects="volcanoes"
                            gm-get-lat-lng="{ lat: object.location.lat, lng: object.location.lng }"
                            gm-get-marker-options="getVolcanoOpts(object)"
                            gm-on-click="selectVolcano(object, marker)">
                </gm-markers>
              </gm-map>
            </div>
            <div class="span6">
              <h5 class="muted" ng-show="!volcano">Select a marker!</h5>
              <div ng-show="volcano">
                <h5>{{ volcano.name }}, {{ volcano.elevationMeters }}m</h5>
                <img class="volcano img-rounded" ng-src="{{ volcano.img }}"></img>
              </div>
            </div>
          </div>
          
          <h3 id="infowindows">InfoWindows</h3>
          <div class="row-fluid margin-bottom60" ng-controller="InfoWindowsCtrl">
            <div class="span6">
              <div gm-info-window="infoWindow">
                <h4>{{selectedVolcano.name}}</h4>
                {{selectedVolcano.elevationMeters}}m
              </div>
              <gm-map gm-map-id="'infoWindows'" gm-center="center" gm-zoom="zoom" gm-map-options="options.map" class="map">
                <gm-markers gm-objects="volcanoes"
                            gm-get-lat-lng="{ lat: object.location.lat, lng: object.location.lng }"
                            gm-get-marker-options="{ title: object.name }"
                            gm-on-click="selectedVolcano = object; infoWindow.open(marker.getMap(), marker);">
                </gm-markers>
              </gm-map>
            </div>
          </div>
          
          <h3 id="infowindows2">InfoWindows2</h3>
          <div class="row-fluid margin-bottom60" ng-controller="InfoWindows2Ctrl">
            <div class="span6">
              <div gm-info-window="infoWindow">
                <h4>{{selectedVolcano.name}}</h4>
                {{selectedVolcano.elevationMeters}}m
              </div>
              <gm-map gm-map-id="'infoWindows2'" gm-center="center" gm-zoom="zoom" gm-map-options="options.map" class="map">
                <gm-markers gm-objects="volcanoes"
                            gm-get-lat-lng="{ lat: object.location.lat, lng: object.location.lng }"
                            gm-get-marker-options="{ title: object.name, clickable: false }"
                            gm-events="markerEvents"
                            gm-on-openinfowindow="selectedVolcano = object; infoWindow.open(marker.getMap(), marker);">
                </gm-markers>
              </gm-map>
            </div>
            <div class="span6">
              <div ng-repeat="volcano in volcanoes">
                <button class="btn" ng-click="openInfoWindow(volcano)">More about {{volcano.name}}</button>
              </div>
            </div>
          </div>
          
          <h3 id="multiple-maps">Multiple Maps</h3>
          <div class="row-fluid margin-bottom60" ng-controller="SimpleMapCtrl">
            <div class="row-fluid margin-bottom30">
              <div class="span3">
                <label>Zoom 1:</label>
                <input type="number" ng-model="zoom1">
              </div>
              <div class="span6 center">
                <label>The centers are linked to the same scope variable:</label>
                <input type="number" ng-model="centerLat" ng-change="updateCenter(centerLat, centerLng)">, 
                <input type="number" ng-model="centerLng" ng-change="updateCenter(centerLat, centerLng)">
              </div>
              <div class="span3">
                <label>Zoom 2:</label>
                <input type="number" ng-model="zoom2">
              </div>
            </div>
            <div class="row-fluid">
              <div class="span4">
                <gm-map gm-map-id="'multipleMaps1'" gm-center="center" gm-zoom="zoom1" class="map"></gm-map>
              </div>
              <div class="span4">
              </div>
              <div class="span4">
                <gm-map gm-map-id="'multipleMaps2'" gm-center="center" gm-zoom="zoom2" class="map"></gm-map>
              </div>
            </div>
          </div>
          
          <h3 id="lots-of-markers">Lots of Markers</h3>
          <div class="row-fluid margin-bottom60" ng-controller="LotsOfMarkersCtrl">
            <div class="span6">     
              <gm-map gm-map-id="'lotsOfMarkersMap'" gm-center="center" gm-zoom="zoom" gm-map-options="options.map" class="map">
                <gm-markers gm-objects="myObjects"
                            gm-get-lat-lng="{ lat: object.lat, lng: object.lng }">
              </gm-map>
            </div>
            <div class="span6">
             <p><button class="btn" ng-click="generate()">Generate</button> Marker count: {{ myObjects.length }} </p>
             <p>
             <label>Start Latitude:</label><input type="number" ng-model="startLat">
             <label>End Latitude:</label><input type="number" ng-model="endLat">
             </p>
             <p>
             <label>Start Longitude:</label><input type="number" ng-model="startLng">
             <label>End Longitude:</label><input type="number" ng-model="endLng">
             </p>
            </div>
          </div>

          <h3 id="filter-markers">Filter Markers</h3>
          <div class="row-fluid margin-bottom60" ng-controller="FilterMarkersCtrl">
            <div class="span6">     
              <gm-map gm-map-id="'filterMarkersMap'" gm-center="center" gm-zoom="zoom" gm-map-options="options.map" class="map">
                <gm-markers gm-objects="people"
                            gm-get-lat-lng="{ lat: object.location.lat, lng: object.location.lng }"
                            gm-get-marker-options="getMarkerOptions(object)"></gm-markers>
              </gm-map>
            </div>
            <div class="span6">
              <label class="inline">Name: </label><input class="inline" ng-model="filters.name" ng-change="filterPeople()"> <br /><br />
              <input type="checkbox" ng-model="filters.male"   ng-change="filterPeople()"> Male <br />
              <input type="checkbox" ng-model="filters.female" ng-change="filterPeople()"> Female
              <div class="well person-list">
                <li ng-repeat="(id, person) in filteredPeople">
                  {{person.name}}, {{person.gender}}
                </li>
              </div>
            </div>
          </div>
          
          <h3 id="drag-marker">Drag Marker</h3>
          <div class="row-fluid margin-bottom60" ng-controller="DragMarkerCtrl">
            <div class="span6">
              <gm-map gm-map-id="'dragMarkerMap'" gm-center="center" gm-zoom="zoom" gm-map-options="options.map" class="map">
                <gm-markers gm-objects="houses"
                            gm-get-lat-lng="{ lat: object.lat, lng: object.lng}"
                            gm-get-marker-options="options.marker"
                            gm-on-dragend="setHouseLocation(object, marker)"></gm-markers>
              </gm-map>
            </div>
            <div class="span6">
              <p>
                Drag the marker to a location.
              </p>
              <p>
                <label>Current location:</label>
                {{houses[0].lat | number:2}}, {{houses[0].lng | number:2}}
              </p>
            </div>
          </div>
          
        </div>
      </div>
    </div>
  
    <script src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
    <script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
    <script src="http://angulargm.herokuapp.com/angular-gm-0.3.1.min.js"></script>
    <script src="app.js"></script>
    <script src="simple-map.js"></script>
    <script src="map-with-markers.js"></script>
    <script src="infowindows.js"></script>
    <script src="infowindows2.js"></script>
    <script src="lots-of-markers.js"></script>
    <script src="filter-markers.js"></script>
    <script src="drag-marker.js"></script>
  </body>
  
</html>
(function() {
  angular.module('Example', ['AngularGM']);    
})();
.map {
  height: 300px;
}

/* 
Fixes Bootstrap issues with Google Maps
see http://stackoverflow.com/a/9170756 
*/
.map img { 
  max-width: none;
}

[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
  display: none;
}

.margin-bottom60 {
  margin-bottom: 60px;
}

.margin-bottom30 {
  margin-bottom: 30px;
}

.center {
  text-align: center;
}

input {
  width: 140px;
}

img.volcano {
  height: 200px;
  width: 250px;
}

.inline {
  display: inline;
}

.person-list {
  overflow-y: scroll;
  height: 150px;
}

/* From Bootstrap's docs */
.bs-docs-sidenav {
    background-color: #FFFFFF;
    border-radius: 6px 6px 6px 6px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.067);
    margin: 30px 0 0;
    padding: 0;
    width: 228px;
}
.bs-docs-sidenav > li > a {
    border: 1px solid #E5E5E5;
    display: block;
    margin: 0 0 -1px;
    padding: 8px 14px;
}
.bs-docs-sidenav > li:first-child > a {
    border-radius: 6px 6px 0 0;
}
.bs-docs-sidenav > li:last-child > a {
    border-radius: 0 0 6px 6px;
}
.bs-docs-sidenav > .active > a {
    border: 0 none;
    box-shadow: 1px 0 0 rgba(0, 0, 0, 0.1) inset, -1px 0 0 rgba(0, 0, 0, 0.1) inset;
    padding: 9px 15px;
    position: relative;
    text-shadow: 0 1px 0 rgba(0, 0, 0, 0.15);
    z-index: 2;
}
.bs-docs-sidenav .icon-chevron-right {
    float: right;
    margin-right: -6px;
    margin-top: 2px;
    opacity: 0.25;
}
.bs-docs-sidenav > li > a:hover {
    background-color: #F5F5F5;
}
.bs-docs-sidenav a:hover .icon-chevron-right {
    opacity: 0.5;
}
.bs-docs-sidenav .active .icon-chevron-right, .bs-docs-sidenav .active a:hover .icon-chevron-right {
    background-image: url("../img/glyphicons-halflings-white.png");
    opacity: 1;
}
.bs-docs-sidenav.affix {
    top: 40px;
}
.bs-docs-sidenav.affix-bottom {
    bottom: 270px;
    position: absolute;
    top: auto;
}
(function() {
  angular.module('Example').
  
  controller('SimpleMapCtrl', function($scope) {
    $scope.$watch('center', function(center) {
     if (center) {
       $scope.centerLat = center.lat();
       $scope.centerLng = center.lng();
     }
    });
    
    $scope.updateCenter = function(lat, lng) {
      $scope.center = new google.maps.LatLng(lat, lng);
    };
  });
})();
(function() {
  angular.module('Example').
  
  controller('MapWithMarkersCtrl', function($scope) {
    $scope.options = {
      map: {
        center: new google.maps.LatLng(48, -121),
        zoom: 6,
        mapTypeId: google.maps.MapTypeId.TERRAIN
      },
      volcanoes: {
        icon: 'https://maps.gstatic.com/mapfiles/ms2/micons/red-dot.png',
      },
      selected: {
        icon: 'https://maps.gstatic.com/mapfiles/ms2/micons/yellow-dot.png',
      }
    };
    
    $scope.volcanoes = [
      {
        name: 'Mount Rainier',
        img: 'http://www.thetrackerfoundation.org/Images/MountRainier_SM.jpg',
        elevationMeters: 4392,
        location: {
          lat: 46.852947, 
          lng: -121.760424
        }
      },
      {
        name: 'Mount Baker',
        img: 'http://www.destination360.com/north-america/us/washington/images/s/washington-mt-baker-ski.jpg',
        elevationMeters: 3287,
        location: {
          lat: 48.776797, 
          lng: -121.814467
        }
      },
      {
        name: 'Glacier Peak',
        img: 'http://www.rhinoclimbs.com/Images/Glacier.9.jpg',
        elevationMeters: 3207,
        location: {
          lat: 48.111844, 
          lng: -121.11412
        }
      }
    ];

    $scope.getVolcanoOpts = function(volcano) {
     return angular.extend(
       { title: volcano.name },
       $scope.options.volcanoes
      );
    };
    
    $scope.selectVolcano = function(volcano, marker) {
      $scope.volcano = volcano;
      if ($scope.prev) {
        $scope.prev.setOptions($scope.options.volcanoes);
      }
      $scope.prev = marker;
      marker.setOptions($scope.options.selected);
    };
  });
})();
(function() {
  angular.module('Example').
  
  controller('LotsOfMarkersCtrl', function($scope) {
    $scope.options = {
      map: {
        center: new google.maps.LatLng(0, 0),
        zoom: 1,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      }
    };
    
    $scope.startLat = -50;
    $scope.endLat = 50;
    $scope.startLng = -10;
    $scope.endLng = 10;
    
    $scope.generate = function() {
      var lat = $scope.startLat && $scope.endLat;
      var lng = $scope.startLng && $scope.endLng;
      if (lat && lng) {      
        $scope.myObjects = [];
        for (var i = $scope.startLat; i < $scope.endLat; i++) {
          for (var j = $scope.startLng; j < $scope.endLng; j++) {
            $scope.myObjects.push({
              id: i,
              lat: i,
              lng: j
            });
          }
        }
      }
    };
  });
})();
(function() {
  angular.module('Example').

  controller('FilterMarkersCtrl', function($scope) {
    $scope.icons = {
      gray: 'http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_gray.png',
      red: 'http://maps.gstatic.com/mapfiles/ridefinder-images/mm_20_red.png',
    }
    
    $scope.options = {
      map: {
        center: new google.maps.LatLng(0, 0),
        zoom: 3,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      },
      highlighted: {
        icon: $scope.icons.red
      },
      unhighlighted: {
        icon: $scope.icons.gray
      },
    };

    $scope.filters = {
      name: null,
      male: true,
      female: true
    }
   
    $scope.getMarkerOptions = function(person) {
      var opts = {title: person.name};
      if (person.id in $scope.filteredPeople) {
        return angular.extend(opts, $scope.options.highlighted);
      } else {
        return angular.extend(opts, $scope.options.unhighlighted);
      }
    };
    
    $scope.filterPeople = function() {
      $scope.filteredPeople = {};
      angular.forEach($scope.people, function(person) {
        var nameMatch = ($scope.filters.name) ? ~person.name.indexOf($scope.filters.name) : true;
        var isMale = person.gender === 'male';
        var genderMatch = ($scope.filters.male && isMale) ||
                          ($scope.filters.female && !isMale);
        if (nameMatch && genderMatch) {
          $scope.filteredPeople[person.id] = person;
        }
      });
      $scope.$broadcast('gmMarkersRedraw', 'people');
    };
    
    $scope.$watch('people', function() {
      $scope.filterPeople();
    });

    $scope.people = [{"id":1,"name":"Gianna Hodges","gender":"male","location":{"lat":4,"lng":21}},{"id":2,"name":"Isabella Davidson","gender":"female","location":{"lat":21,"lng":-11}},{"id":3,"name":"Aubrey Mercer","gender":"female","location":{"lat":-13,"lng":-22}},{"id":4,"name":"Hailey Milton","gender":"female","location":{"lat":-18,"lng":-17}},{"id":5,"name":"Charlotte Davidson","gender":"female","location":{"lat":18,"lng":7}},{"id":6,"name":"Isabella Higgins","gender":"male","location":{"lat":-15,"lng":-23}},{"id":7,"name":"Riley Brooks","gender":"male","location":{"lat":3,"lng":8}},{"id":8,"name":"Jessica Oldridge","gender":"female","location":{"lat":-25,"lng":-13}},{"id":9,"name":"Gianna Sheldon","gender":"male","location":{"lat":9,"lng":21}},{"id":10,"name":"Zoey Cook","gender":"female","location":{"lat":16,"lng":18}},{"id":11,"name":"Lily Turner","gender":"male","location":{"lat":3,"lng":-7}},{"id":12,"name":"Riley Hardman","gender":"male","location":{"lat":19,"lng":-14}},{"id":13,"name":"Bella Clapton","gender":"female","location":{"lat":1,"lng":-24}},{"id":14,"name":"Trinity Higgins","gender":"male","location":{"lat":2,"lng":-17}},{"id":15,"name":"Sydney Neal","gender":"male","location":{"lat":17,"lng":15}},{"id":16,"name":"Bailey Ford","gender":"female","location":{"lat":9,"lng":-7}},{"id":17,"name":"Hannah Hodges","gender":"male","location":{"lat":-1,"lng":-21}},{"id":18,"name":"Evelyn Sherlock","gender":"female","location":{"lat":-3,"lng":-7}},{"id":19,"name":"Evelyn Nelson","gender":"male","location":{"lat":20,"lng":15}},{"id":20,"name":"Maya Gibbs","gender":"male","location":{"lat":4,"lng":12}},{"id":21,"name":"Sofia Carter","gender":"female","location":{"lat":-13,"lng":-18}},{"id":22,"name":"Victoria Conors","gender":"male","location":{"lat":-13,"lng":15}},{"id":23,"name":"Savannah Galbraith","gender":"female","location":{"lat":15,"lng":-2}},{"id":24,"name":"Eva Brooks","gender":"female","location":{"lat":-6,"lng":-7}},{"id":25,"name":"Caroline White","gender":"female","location":{"lat":-10,"lng":9}},{"id":26,"name":"Audrey WifKinson","gender":"female","location":{"lat":-22,"lng":-2}},{"id":27,"name":"Faith Brown","gender":"male","location":{"lat":10,"lng":-7}},{"id":28,"name":"Serenity Nash","gender":"male","location":{"lat":4,"lng":5}},{"id":29,"name":"Mariah Nathan","gender":"female","location":{"lat":6,"lng":19}},{"id":30,"name":"Makayla White","gender":"female","location":{"lat":0,"lng":20}},{"id":31,"name":"Katherine Thornton","gender":"female","location":{"lat":-9,"lng":14}},{"id":32,"name":"Nevaeh Cramer","gender":"female","location":{"lat":9,"lng":-18}},{"id":33,"name":"Valeria Hoggarth","gender":"male","location":{"lat":20,"lng":17}},{"id":34,"name":"Aaliyah Carrington","gender":"male","location":{"lat":23,"lng":13}},{"id":35,"name":"Aaliyah Gilmore","gender":"female","location":{"lat":-25,"lng":6}},{"id":36,"name":"Faith Wesley","gender":"male","location":{"lat":-1,"lng":-11}},{"id":37,"name":"Emily Bush","gender":"male","location":{"lat":-24,"lng":19}},{"id":38,"name":"Jessica Gardner","gender":"female","location":{"lat":12,"lng":-22}},{"id":39,"name":"Elizabeth Crossman","gender":"female","location":{"lat":-3,"lng":-19}},{"id":40,"name":"Payton Ward","gender":"male","location":{"lat":-22,"lng":-3}},{"id":41,"name":"Jocelyn Freeman","gender":"female","location":{"lat":11,"lng":-15}},{"id":42,"name":"Serenity Hoggarth","gender":"female","location":{"lat":5,"lng":-17}},{"id":43,"name":"Kayla Vaughan","gender":"female","location":{"lat":20,"lng":9}},{"id":44,"name":"Arianna Hancock","gender":"male","location":{"lat":25,"lng":3}},{"id":45,"name":"Katherine Haig","gender":"male","location":{"lat":-2,"lng":-12}},{"id":46,"name":"Zoe Gerald","gender":"male","location":{"lat":-12,"lng":8}},{"id":47,"name":"Sofia Molligan","gender":"male","location":{"lat":16,"lng":7}},{"id":48,"name":"Mia Day","gender":"female","location":{"lat":13,"lng":17}},{"id":49,"name":"Amelia Carey","gender":"female","location":{"lat":10,"lng":-12}},{"id":50,"name":"Kimberly Gerald","gender":"female","location":{"lat":7,"lng":-8}}]
  });
 
})();
(function() {
  angular.module('Example').

  controller('DragMarkerCtrl', function($scope) {
    
    $scope.houses = [{
      name: 'myHouse',
      lat: 46,
      lng: -122
    }];
    
    $scope.options = {
      map: {
        center: new google.maps.LatLng(46, -122),
        zoom: 3,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      },
      marker: {
        clickable: false,
        draggable: true
      }
    };
    
    $scope.setHouseLocation = function(house, marker) {
      var position = marker.getPosition();
      house.lat = position.lat();
      house.lng = position.lng();
    };

  });
 
})();
(function() {
  angular.module('Example').
  
  controller('InfoWindowsCtrl', function($scope) {
    $scope.options = {
      map: {
        center: new google.maps.LatLng(48, -121),
        zoom: 6,
        mapTypeId: google.maps.MapTypeId.TERRAIN
      },
    };
    
    $scope.volcanoes = [
      {
        name: 'Mount Rainier',
        elevationMeters: 4392,
        location: {
          lat: 46.852947, 
          lng: -121.760424
        }
      },
      {
        name: 'Mount Baker',
        elevationMeters: 3287,
        location: {
          lat: 48.776797, 
          lng: -121.814467
        }
      },
      {
        name: 'Glacier Peak',
        elevationMeters: 3207,
        location: {
          lat: 48.111844, 
          lng: -121.11412
        }
      }
    ];

  });
})();
(function() {
  angular.module('Example').
  
  controller('InfoWindows2Ctrl', function($scope, angulargmUtils) {
    $scope.options = {
      map: {
        center: new google.maps.LatLng(48, -121),
        zoom: 6,
        mapTypeId: google.maps.MapTypeId.TERRAIN
      },
    };
    
    $scope.volcanoes = [
      {
        name: 'Mount Rainier',
        elevationMeters: 4392,
        location: {
          lat: 46.852947, 
          lng: -121.760424
        }
      },
      {
        name: 'Mount Baker',
        elevationMeters: 3287,
        location: {
          lat: 48.776797, 
          lng: -121.814467
        }
      },
      {
        name: 'Glacier Peak',
        elevationMeters: 3207,
        location: {
          lat: 48.111844, 
          lng: -121.11412
        }
      }
    ];
    
    $scope.openInfoWindow = function(volcano) {
      $scope.markerEvents = [
        {
          event: 'openinfowindow',
          locations: [angulargmUtils.objToLatLng(volcano.location)]
        },
      ];
    }

  });
})();