Source: directives/map_controller.js

  1. /* global google */
  2. (function() {
  3. 'use strict';
  4. /**
  5. * @ngdoc controller
  6. * @name MapController
  7. * @requires $scope
  8. * @property {Hash} controls collection of Controls initiated within `map` directive
  9. * @property {Hash} markers collection of Markers initiated within `map` directive
  10. * @property {Hash} shapes collection of shapes initiated within `map` directive
  11. */
  12. var MapController = function($q, NavigatorGeolocation, GeoCoder, Attr2Options) {
  13. var parser = Attr2Options;
  14. var _this = this;
  15. var observeAndSet = function(attrs, attrName, object) {
  16. attrs.$observe(attrName, function(val) {
  17. if (val) {
  18. console.log('observing ', object, attrName, val);
  19. var setMethod = parser.camelCase('set-'+attrName);
  20. var optionValue = parser.toOptionValue(val, {key: attrName});
  21. console.log('setting ', object, attrName, 'with value', optionValue);
  22. if (object[setMethod]) { //if set method does exist
  23. /* if an location is being observed */
  24. if (attrName.match(/center|position/) &&
  25. typeof optionValue == 'string') {
  26. _this.getGeoLocation(optionValue).then(function(latlng) {
  27. object[setMethod](latlng);
  28. });
  29. } else {
  30. object[setMethod](optionValue);
  31. }
  32. }
  33. }
  34. });
  35. };
  36. this.map = null;
  37. this._objects = []; /* temporary collection of map objects */
  38. /**
  39. * Add an object to the collection of group
  40. * @memberof MapController
  41. * @function addObject
  42. * @param groupName the name of collection that object belongs to
  43. * @param obj an object to add into a collection, i.e. marker, shape
  44. */
  45. this.addObject = function(groupName, obj) {
  46. /**
  47. * objects, i.e. markers and shapes, are initialized before map is initialized
  48. * so, we collect those objects, then, we will add to map when map is initialized
  49. * However the case as in ng-repeat, we can directly add to map
  50. */
  51. if (this.map) {
  52. this.map[groupName] = this.map[groupName] || {};
  53. var len = Object.keys(this.map[groupName]).length;
  54. this.map[groupName][obj.id || len] = obj;
  55. if (groupName != "infoWindows" && obj.setMap) { //infoWindow.setMap works like infoWindow.open
  56. obj.setMap && obj.setMap(this.map);
  57. }
  58. if (obj.centered && obj.position) {
  59. this.map.setCenter(obj.position);
  60. }
  61. } else {
  62. obj.groupName = groupName;
  63. this._objects.push(obj);
  64. }
  65. };
  66. /**
  67. * Delete an object from the collection and remove from map
  68. * @memberof MapController
  69. * @function deleteObject
  70. * @param {Array} objs the collection of objects. i.e., map.markers
  71. * @param {Object} obj the object to be removed. i.e., marker
  72. */
  73. this.deleteObject = function(groupName, obj) {
  74. /* delete from group */
  75. var objs = obj.map[groupName];
  76. for (var name in objs) {
  77. objs[name] === obj && (delete objs[name]);
  78. }
  79. /* delete from map */
  80. obj.map && obj.setMap && obj.setMap(null);
  81. };
  82. /**
  83. * Add collected objects to map
  84. * @memberof MapController
  85. * @function addObjects
  86. * @param {Array} objects the collection of objects. i.e., map.markers
  87. */
  88. this.addObjects = function(objects) {
  89. for (var i=0; i<objects.length; i++) {
  90. var obj=objects[i];
  91. if (obj instanceof google.maps.Marker) {
  92. this.addObject('markers', obj);
  93. } else if (obj instanceof google.maps.Circle ||
  94. obj instanceof google.maps.Polygon ||
  95. obj instanceof google.maps.Polyline ||
  96. obj instanceof google.maps.Rectangle ||
  97. obj instanceof google.maps.GroundOverlay) {
  98. this.addObject('shapes', obj);
  99. } else {
  100. this.addObject(obj.groupName, obj);
  101. }
  102. }
  103. };
  104. /**
  105. * returns the location of an address or 'current-location'
  106. * @memberof MapController
  107. * @function getGeoLocation
  108. * @param {String} string an address to find the location
  109. * @returns {Promise} latlng the location of the address
  110. */
  111. this.getGeoLocation = function(string) {
  112. var deferred = $q.defer();
  113. if (!string || string.match(/^current/i)) { // current location
  114. NavigatorGeolocation.getCurrentPosition().then(
  115. function(position) {
  116. var lat = position.coords.latitude;
  117. var lng = position.coords.longitude;
  118. var latLng = new google.maps.LatLng(lat,lng);
  119. deferred.resolve(latLng);
  120. },
  121. function(error) {
  122. deferred.reject(error);
  123. }
  124. );
  125. } else {
  126. GeoCoder.geocode({address: string}).then(
  127. function(results) {
  128. deferred.resolve(results[0].geometry.location);
  129. },
  130. function(error) {
  131. deferred.reject(error);
  132. }
  133. );
  134. }
  135. return deferred.promise;
  136. };
  137. /**
  138. * watch changes of attribute values and do appropriate action based on attribute name
  139. * @memberof MapController
  140. * @function observeAttrSetObj
  141. * @param {Hash} orgAttrs attributes before its initialization
  142. * @param {Hash} attrs attributes after its initialization
  143. * @param {Object} obj map object that an action is to be done
  144. */
  145. this.observeAttrSetObj = function(orgAttrs, attrs, obj) {
  146. var attrsToObserve = parser.getAttrsToObserve(orgAttrs);
  147. if (Object.keys(attrsToObserve).length) {
  148. console.log(obj, "attributes to observe", attrsToObserve);
  149. }
  150. for (var i=0; i<attrsToObserve.length; i++) {
  151. observeAndSet(attrs, attrsToObserve[i], obj);
  152. }
  153. };
  154. }; // MapController
  155. MapController.$inject = ['$q', 'NavigatorGeolocation', 'GeoCoder', 'Attr2Options'];
  156. angular.module('ngMap').controller('MapController', MapController);
  157. })();