UTFGrid.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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/Handler/Hover.js
  8. * @requires OpenLayers/Handler/Click.js
  9. */
  10. /**
  11. * Class: OpenLayers.Control.UTFGrid
  12. *
  13. * This Control provides behavior associated with UTFGrid Layers.
  14. * These 'hit grids' provide underlying feature attributes without
  15. * calling the server (again). This control allows Mousemove, Hovering
  16. * and Click events to trigger callbacks that use the attributes in
  17. * whatever way you need.
  18. *
  19. * The most common example may be a UTFGrid layer containing feature
  20. * attributes that are displayed in a div as you mouseover.
  21. *
  22. * Example Code:
  23. *
  24. * (start code)
  25. * var world_utfgrid = new OpenLayers.Layer.UTFGrid(
  26. * 'UTFGrid Layer',
  27. * "http://tiles/world_utfgrid/${z}/${x}/${y}.json"
  28. * );
  29. * map.addLayer(world_utfgrid);
  30. *
  31. * var control = new OpenLayers.Control.UTFGrid({
  32. * layers: [world_utfgrid],
  33. * handlerMode: 'move',
  34. * callback: function(infoLookup) {
  35. * // do something with returned data
  36. *
  37. * }
  38. * })
  39. * (end code)
  40. *
  41. *
  42. * Inherits from:
  43. * - <OpenLayers.Control>
  44. */
  45. OpenLayers.Control.UTFGrid = OpenLayers.Class(OpenLayers.Control, {
  46. /**
  47. * APIProperty: autoActivate
  48. * {Boolean} Activate the control when it is added to a map. Default is
  49. * true.
  50. */
  51. autoActivate: true,
  52. /**
  53. * APIProperty: Layers
  54. * List of layers to consider. Must be Layer.UTFGrids
  55. * `null` is the default indicating all UTFGrid Layers are queried.
  56. * {Array} <OpenLayers.Layer.UTFGrid>
  57. */
  58. layers: null,
  59. /* Property: defaultHandlerOptions
  60. * The default opts passed to the handler constructors
  61. */
  62. defaultHandlerOptions: {
  63. 'delay': 300,
  64. 'pixelTolerance': 4,
  65. 'stopMove': false,
  66. 'single': true,
  67. 'double': false,
  68. 'stopSingle': false,
  69. 'stopDouble': false
  70. },
  71. /* APIProperty: handlerMode
  72. * Defaults to 'click'. Can be 'hover' or 'move'.
  73. */
  74. handlerMode: 'click',
  75. /**
  76. * APIMethod: setHandler
  77. * sets this.handlerMode and calls resetHandler()
  78. *
  79. * Parameters:
  80. * hm - {String} Handler Mode string; 'click', 'hover' or 'move'.
  81. */
  82. setHandler: function(hm) {
  83. this.handlerMode = hm;
  84. this.resetHandler();
  85. },
  86. /**
  87. * Method: resetHandler
  88. * Deactivates the old hanlder and creates a new
  89. * <OpenLayers.Handler> based on the mode specified in
  90. * this.handlerMode
  91. *
  92. */
  93. resetHandler: function() {
  94. if (this.handler) {
  95. this.handler.deactivate();
  96. this.handler.destroy();
  97. this.handler = null;
  98. }
  99. if (this.handlerMode == 'hover') {
  100. // Handle this event on hover
  101. this.handler = new OpenLayers.Handler.Hover(
  102. this,
  103. {'pause': this.handleEvent, 'move': this.reset},
  104. this.handlerOptions
  105. );
  106. } else if (this.handlerMode == 'click') {
  107. // Handle this event on click
  108. this.handler = new OpenLayers.Handler.Click(
  109. this, {
  110. 'click': this.handleEvent
  111. }, this.handlerOptions
  112. );
  113. } else if (this.handlerMode == 'move') {
  114. this.handler = new OpenLayers.Handler.Hover(
  115. this,
  116. // Handle this event while hovering OR moving
  117. {'pause': this.handleEvent, 'move': this.handleEvent},
  118. this.handlerOptions
  119. );
  120. }
  121. if (this.handler) {
  122. return true;
  123. } else {
  124. return false;
  125. }
  126. },
  127. /**
  128. * Constructor: <OpenLayers.Control.UTFGrid>
  129. *
  130. * Parameters:
  131. * options - {Object}
  132. */
  133. initialize: function(options) {
  134. options = options || {};
  135. options.handlerOptions = options.handlerOptions || this.defaultHandlerOptions;
  136. OpenLayers.Control.prototype.initialize.apply(this, [options]);
  137. this.resetHandler();
  138. },
  139. /**
  140. * Method: handleEvent
  141. * Internal method called when specified event is triggered.
  142. *
  143. * This method does several things:
  144. *
  145. * Gets the lonLat of the event.
  146. *
  147. * Loops through the appropriate hit grid layers and gathers the attributes.
  148. *
  149. * Passes the attributes to the callback
  150. *
  151. * Parameters:
  152. * evt - {<OpenLayers.Event>}
  153. */
  154. handleEvent: function(evt) {
  155. if (evt == null) {
  156. this.reset();
  157. return;
  158. }
  159. var lonLat = this.map.getLonLatFromPixel(evt.xy);
  160. if (!lonLat) {
  161. return;
  162. }
  163. var layers = this.findLayers();
  164. if (layers.length > 0) {
  165. var infoLookup = {};
  166. var layer, idx;
  167. for (var i=0, len=layers.length; i<len; i++) {
  168. layer = layers[i];
  169. idx = OpenLayers.Util.indexOf(this.map.layers, layer);
  170. infoLookup[idx] = layer.getFeatureInfo(lonLat);
  171. }
  172. this.callback(infoLookup, lonLat, evt.xy);
  173. }
  174. },
  175. /**
  176. * APIMethod: callback
  177. * Function to be called when a mouse event corresponds with a location that
  178. * includes data in one of the configured UTFGrid layers.
  179. *
  180. * Parameters:
  181. * infoLookup - {Object} Keys of this object are layer indexes and can be
  182. * used to resolve a layer in the map.layers array. The structure of
  183. * the property values depend on the data included in the underlying
  184. * UTFGrid and may be any valid JSON type.
  185. */
  186. callback: function(infoLookup) {
  187. // to be provided in the constructor
  188. },
  189. /**
  190. * Method: reset
  191. * Calls the callback with null.
  192. */
  193. reset: function(evt) {
  194. this.callback(null);
  195. },
  196. /**
  197. * Method: findLayers
  198. * Internal method to get the layers, independent of whether we are
  199. * inspecting the map or using a client-provided array
  200. *
  201. * The default value of this.layers is null; this causes the
  202. * findLayers method to return ALL UTFGrid layers encountered.
  203. *
  204. * Parameters:
  205. * None
  206. *
  207. * Returns:
  208. * {Array} Layers to handle on each event
  209. */
  210. findLayers: function() {
  211. var candidates = this.layers || this.map.layers;
  212. var layers = [];
  213. var layer;
  214. for (var i=candidates.length-1; i>=0; --i) {
  215. layer = candidates[i];
  216. if (layer instanceof OpenLayers.Layer.UTFGrid ) {
  217. layers.push(layer);
  218. }
  219. }
  220. return layers;
  221. },
  222. CLASS_NAME: "OpenLayers.Control.UTFGrid"
  223. });