Permalink.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
  2. * full list of contributors). Published under the 2-clause BSD license.
  3. * See license.txt in the OpenLayers distribution or repository for the
  4. * full text of the license. */
  5. /**
  6. * @requires OpenLayers/Control.js
  7. * @requires OpenLayers/Control/ArgParser.js
  8. * @requires OpenLayers/Lang.js
  9. */
  10. /**
  11. * Class: OpenLayers.Control.Permalink
  12. * The Permalink control is hyperlink that will return the user to the
  13. * current map view. By default it is drawn in the lower right corner of the
  14. * map. The href is updated as the map is zoomed, panned and whilst layers
  15. * are switched.
  16. *
  17. * Inherits from:
  18. * - <OpenLayers.Control>
  19. */
  20. OpenLayers.Control.Permalink = OpenLayers.Class(OpenLayers.Control, {
  21. /**
  22. * APIProperty: argParserClass
  23. * {Class} The ArgParser control class (not instance) to use with this
  24. * control.
  25. */
  26. argParserClass: OpenLayers.Control.ArgParser,
  27. /**
  28. * Property: element
  29. * {DOMElement}
  30. */
  31. element: null,
  32. /**
  33. * APIProperty: anchor
  34. * {Boolean} This option changes 3 things:
  35. * the character '#' is used in place of the character '?',
  36. * the window.href is updated if no element is provided.
  37. * When this option is set to true it's not recommend to provide
  38. * a base without provide an element.
  39. */
  40. anchor: false,
  41. /**
  42. * APIProperty: base
  43. * {String}
  44. */
  45. base: '',
  46. /**
  47. * APIProperty: displayProjection
  48. * {<OpenLayers.Projection>} Requires proj4js support. Projection used
  49. * when creating the coordinates in the link. This will reproject the
  50. * map coordinates into display coordinates. If you are using this
  51. * functionality, the permalink which is last added to the map will
  52. * determine the coordinate type which is read from the URL, which
  53. * means you should not add permalinks with different
  54. * displayProjections to the same map.
  55. */
  56. displayProjection: null,
  57. /**
  58. * Constructor: OpenLayers.Control.Permalink
  59. *
  60. * Parameters:
  61. * element - {DOMElement}
  62. * base - {String}
  63. * options - {Object} options to the control.
  64. *
  65. * Or for anchor:
  66. * options - {Object} options to the control.
  67. */
  68. initialize: function(element, base, options) {
  69. if (element !== null && typeof element == 'object' && !OpenLayers.Util.isElement(element)) {
  70. options = element;
  71. this.base = document.location.href;
  72. OpenLayers.Control.prototype.initialize.apply(this, [options]);
  73. if (this.element != null) {
  74. this.element = OpenLayers.Util.getElement(this.element);
  75. }
  76. }
  77. else {
  78. OpenLayers.Control.prototype.initialize.apply(this, [options]);
  79. this.element = OpenLayers.Util.getElement(element);
  80. this.base = base || document.location.href;
  81. }
  82. },
  83. /**
  84. * APIMethod: destroy
  85. */
  86. destroy: function() {
  87. if (this.element && this.element.parentNode == this.div) {
  88. this.div.removeChild(this.element);
  89. this.element = null;
  90. }
  91. if (this.map) {
  92. this.map.events.unregister('moveend', this, this.updateLink);
  93. }
  94. OpenLayers.Control.prototype.destroy.apply(this, arguments);
  95. },
  96. /**
  97. * Method: setMap
  98. * Set the map property for the control.
  99. *
  100. * Parameters:
  101. * map - {<OpenLayers.Map>}
  102. */
  103. setMap: function(map) {
  104. OpenLayers.Control.prototype.setMap.apply(this, arguments);
  105. //make sure we have an arg parser attached
  106. for(var i=0, len=this.map.controls.length; i<len; i++) {
  107. var control = this.map.controls[i];
  108. if (control.CLASS_NAME == this.argParserClass.CLASS_NAME) {
  109. // If a permalink is added to the map, and an ArgParser already
  110. // exists, we override the displayProjection to be the one
  111. // on the permalink.
  112. if (control.displayProjection != this.displayProjection) {
  113. this.displayProjection = control.displayProjection;
  114. }
  115. break;
  116. }
  117. }
  118. if (i == this.map.controls.length) {
  119. this.map.addControl(new this.argParserClass(
  120. { 'displayProjection': this.displayProjection }));
  121. }
  122. },
  123. /**
  124. * Method: draw
  125. *
  126. * Returns:
  127. * {DOMElement}
  128. */
  129. draw: function() {
  130. OpenLayers.Control.prototype.draw.apply(this, arguments);
  131. if (!this.element && !this.anchor) {
  132. this.element = document.createElement("a");
  133. this.element.innerHTML = OpenLayers.i18n("Permalink");
  134. this.element.href="";
  135. this.div.appendChild(this.element);
  136. }
  137. this.map.events.on({
  138. 'moveend': this.updateLink,
  139. 'changelayer': this.updateLink,
  140. 'changebaselayer': this.updateLink,
  141. scope: this
  142. });
  143. // Make it so there is at least a link even though the map may not have
  144. // moved yet.
  145. this.updateLink();
  146. return this.div;
  147. },
  148. /**
  149. * Method: updateLink
  150. */
  151. updateLink: function() {
  152. var separator = this.anchor ? '#' : '?';
  153. var href = this.base;
  154. var anchor = null;
  155. if (href.indexOf("#") != -1 && this.anchor == false) {
  156. anchor = href.substring( href.indexOf("#"), href.length);
  157. }
  158. if (href.indexOf(separator) != -1) {
  159. href = href.substring( 0, href.indexOf(separator) );
  160. }
  161. var splits = href.split("#");
  162. href = splits[0] + separator+ OpenLayers.Util.getParameterString(this.createParams());
  163. if (anchor) {
  164. href += anchor;
  165. }
  166. if (this.anchor && !this.element) {
  167. window.location.href = href;
  168. }
  169. else {
  170. this.element.href = href;
  171. }
  172. },
  173. /**
  174. * APIMethod: createParams
  175. * Creates the parameters that need to be encoded into the permalink url.
  176. *
  177. * Parameters:
  178. * center - {<OpenLayers.LonLat>} center to encode in the permalink.
  179. * Defaults to the current map center.
  180. * zoom - {Integer} zoom level to encode in the permalink. Defaults to the
  181. * current map zoom level.
  182. * layers - {Array(<OpenLayers.Layer>)} layers to encode in the permalink.
  183. * Defaults to the current map layers.
  184. *
  185. * Returns:
  186. * {Object} Hash of parameters that will be url-encoded into the
  187. * permalink.
  188. */
  189. createParams: function(center, zoom, layers) {
  190. center = center || this.map.getCenter();
  191. var params = OpenLayers.Util.getParameters(this.base);
  192. // If there's still no center, map is not initialized yet.
  193. // Break out of this function, and simply return the params from the
  194. // base link.
  195. if (center) {
  196. //zoom
  197. params.zoom = zoom || this.map.getZoom();
  198. //lon,lat
  199. var lat = center.lat;
  200. var lon = center.lon;
  201. if (this.displayProjection) {
  202. var mapPosition = OpenLayers.Projection.transform(
  203. { x: lon, y: lat },
  204. this.map.getProjectionObject(),
  205. this.displayProjection );
  206. lon = mapPosition.x;
  207. lat = mapPosition.y;
  208. }
  209. params.lat = Math.round(lat*100000)/100000;
  210. params.lon = Math.round(lon*100000)/100000;
  211. //layers
  212. layers = layers || this.map.layers;
  213. params.layers = '';
  214. for (var i=0, len=layers.length; i<len; i++) {
  215. var layer = layers[i];
  216. if (layer.isBaseLayer) {
  217. params.layers += (layer == this.map.baseLayer) ? "B" : "0";
  218. } else {
  219. params.layers += (layer.getVisibility()) ? "T" : "F";
  220. }
  221. }
  222. }
  223. return params;
  224. },
  225. CLASS_NAME: "OpenLayers.Control.Permalink"
  226. });