Permalink.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. /* Copyright (c) 2006-2011 by OpenLayers Contributors (see authors.txt for
  2. * full list of contributors). Published under the Clear BSD license.
  3. * See http://svn.openlayers.org/trunk/openlayers/license.txt 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.parentNode == this.div) {
  88. this.div.removeChild(this.element);
  89. }
  90. this.element = null;
  91. this.map.events.unregister('moveend', this, this.updateLink);
  92. OpenLayers.Control.prototype.destroy.apply(this, arguments);
  93. },
  94. /**
  95. * Method: setMap
  96. * Set the map property for the control.
  97. *
  98. * Parameters:
  99. * map - {<OpenLayers.Map>}
  100. */
  101. setMap: function(map) {
  102. OpenLayers.Control.prototype.setMap.apply(this, arguments);
  103. //make sure we have an arg parser attached
  104. for(var i=0, len=this.map.controls.length; i<len; i++) {
  105. var control = this.map.controls[i];
  106. if (control.CLASS_NAME == this.argParserClass.CLASS_NAME) {
  107. // If a permalink is added to the map, and an ArgParser already
  108. // exists, we override the displayProjection to be the one
  109. // on the permalink.
  110. if (control.displayProjection != this.displayProjection) {
  111. this.displayProjection = control.displayProjection;
  112. }
  113. break;
  114. }
  115. }
  116. if (i == this.map.controls.length) {
  117. this.map.addControl(new this.argParserClass(
  118. { 'displayProjection': this.displayProjection }));
  119. }
  120. },
  121. /**
  122. * Method: draw
  123. *
  124. * Returns:
  125. * {DOMElement}
  126. */
  127. draw: function() {
  128. OpenLayers.Control.prototype.draw.apply(this, arguments);
  129. if (!this.element && !this.anchor) {
  130. this.element = document.createElement("a");
  131. this.element.innerHTML = OpenLayers.i18n("Permalink");
  132. this.element.href="";
  133. this.div.appendChild(this.element);
  134. }
  135. this.map.events.on({
  136. 'moveend': this.updateLink,
  137. 'changelayer': this.updateLink,
  138. 'changebaselayer': this.updateLink,
  139. scope: this
  140. });
  141. // Make it so there is at least a link even though the map may not have
  142. // moved yet.
  143. this.updateLink();
  144. return this.div;
  145. },
  146. /**
  147. * Method: updateLink
  148. */
  149. updateLink: function() {
  150. var separator = this.anchor ? '#' : '?';
  151. var href = this.base;
  152. if (href.indexOf(separator) != -1) {
  153. href = href.substring( 0, href.indexOf(separator) );
  154. }
  155. href += separator + OpenLayers.Util.getParameterString(this.createParams());
  156. if (this.anchor && !this.element) {
  157. window.location.href = href;
  158. }
  159. else {
  160. this.element.href = href;
  161. }
  162. },
  163. /**
  164. * APIMethod: createParams
  165. * Creates the parameters that need to be encoded into the permalink url.
  166. *
  167. * Parameters:
  168. * center - {<OpenLayers.LonLat>} center to encode in the permalink.
  169. * Defaults to the current map center.
  170. * zoom - {Integer} zoom level to encode in the permalink. Defaults to the
  171. * current map zoom level.
  172. * layers - {Array(<OpenLayers.Layer>)} layers to encode in the permalink.
  173. * Defaults to the current map layers.
  174. *
  175. * Returns:
  176. * {Object} Hash of parameters that will be url-encoded into the
  177. * permalink.
  178. */
  179. createParams: function(center, zoom, layers) {
  180. center = center || this.map.getCenter();
  181. var params = OpenLayers.Util.getParameters(this.base);
  182. // If there's still no center, map is not initialized yet.
  183. // Break out of this function, and simply return the params from the
  184. // base link.
  185. if (center) {
  186. //zoom
  187. params.zoom = zoom || this.map.getZoom();
  188. //lon,lat
  189. var lat = center.lat;
  190. var lon = center.lon;
  191. if (this.displayProjection) {
  192. var mapPosition = OpenLayers.Projection.transform(
  193. { x: lon, y: lat },
  194. this.map.getProjectionObject(),
  195. this.displayProjection );
  196. lon = mapPosition.x;
  197. lat = mapPosition.y;
  198. }
  199. params.lat = Math.round(lat*100000)/100000;
  200. params.lon = Math.round(lon*100000)/100000;
  201. //layers
  202. layers = layers || this.map.layers;
  203. params.layers = '';
  204. for (var i=0, len=layers.length; i<len; i++) {
  205. var layer = layers[i];
  206. if (layer.isBaseLayer) {
  207. params.layers += (layer == this.map.baseLayer) ? "B" : "0";
  208. } else {
  209. params.layers += (layer.getVisibility()) ? "T" : "F";
  210. }
  211. }
  212. }
  213. return params;
  214. },
  215. CLASS_NAME: "OpenLayers.Control.Permalink"
  216. });