<!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)]
},
];
}
});
})();