EventPane.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. /**
  2. * @requires SuperMap/Layer.js
  3. * @requires SuperMap/Util.js
  4. */
  5. /**
  6. * Class: SuperMap.Layer.EventPane
  7. * Base class for 3rd party layers. Create a new event pane layer with the
  8. * <SuperMap.Layer.EventPane> constructor.
  9. *
  10. * Inherits from:
  11. * - <SuperMap.Layer>
  12. */
  13. SuperMap.Layer.EventPane = SuperMap.Class(SuperMap.Layer, {
  14. /**
  15. * APIProperty: smoothDragPan
  16. * {Boolean} smoothDragPan determines whether non-public/internal API
  17. * methods are used for better performance while dragging EventPane
  18. * layers. When not in sphericalMercator mode, the smoother dragging
  19. * doesn't actually move north/south directly with the number of
  20. * pixels moved, resulting in a slight offset when you drag your mouse
  21. * north south with this option on. If this visual disparity bothers
  22. * you, you should turn this option off, or use spherical mercator.
  23. * Default is on.
  24. */
  25. smoothDragPan: true,
  26. /**
  27. * Property: isBaseLayer
  28. * {Boolean} EventPaned layers are always base layers, by necessity.
  29. */
  30. isBaseLayer: true,
  31. /**
  32. * APIProperty: isFixed
  33. * {Boolean} EventPaned layers are fixed by default.
  34. */
  35. isFixed: true,
  36. /**
  37. * Property: pane
  38. * {DOMElement} A reference to the element that controls the events.
  39. */
  40. pane: null,
  41. /**
  42. * Property: mapObject
  43. * {Object} This is the object which will be used to load the 3rd party library
  44. * in the case of the google layer, this will be of type GMap,
  45. * in the case of the ve layer, this will be of type VEMap
  46. */
  47. mapObject: null,
  48. /**
  49. * Constructor: SuperMap.Layer.EventPane
  50. * Create a new event pane layer
  51. *
  52. * Parameters:
  53. * name - {String}
  54. * options - {Object} Hashtable of extra options to tag onto the layer
  55. */
  56. initialize: function(name, options) {
  57. SuperMap.Layer.prototype.initialize.apply(this, arguments);
  58. if (this.pane == null) {
  59. this.pane = SuperMap.Util.createDiv(this.div.id + "_EventPane");
  60. }
  61. },
  62. /**
  63. * APIMethod: destroy
  64. * Deconstruct this layer.
  65. */
  66. destroy: function() {
  67. this.mapObject = null;
  68. this.pane = null;
  69. SuperMap.Layer.prototype.destroy.apply(this, arguments);
  70. },
  71. /**
  72. * Method: setMap
  73. * Set the map property for the layer. This is done through an accessor
  74. * so that subclasses can override this and take special action once
  75. * they have their map variable set.
  76. *
  77. * Parameters:
  78. * map - {<SuperMap.Map>}
  79. */
  80. setMap: function(map) {
  81. SuperMap.Layer.prototype.setMap.apply(this, arguments);
  82. this.pane.style.zIndex = parseInt(this.div.style.zIndex) + 1;
  83. this.pane.style.display = this.div.style.display;
  84. this.pane.style.width="100%";
  85. this.pane.style.height="100%";
  86. if (SuperMap.BROWSER_NAME == "msie") {
  87. this.pane.style.background =
  88. "url(" + SuperMap.Util.getImagesLocation() + "blank.gif)";
  89. }
  90. if (this.isFixed) {
  91. this.map.eventsDiv.appendChild(this.pane);
  92. } else {
  93. this.map.layerContainerDiv.appendChild(this.pane);
  94. }
  95. // once our layer has been added to the map, we can load it
  96. this.loadMapObject();
  97. // if map didn't load, display warning
  98. if (this.mapObject == null) {
  99. this.loadWarningMessage();
  100. }
  101. },
  102. /**
  103. * APIMethod: removeMap
  104. * On being removed from the map, we'll like to remove the invisible 'pane'
  105. * div that we added to it on creation.
  106. *
  107. * Parameters:
  108. * map - {<SuperMap.Map>}
  109. */
  110. removeMap: function(map) {
  111. if (this.pane && this.pane.parentNode) {
  112. this.pane.parentNode.removeChild(this.pane);
  113. }
  114. SuperMap.Layer.prototype.removeMap.apply(this, arguments);
  115. },
  116. /**
  117. * Method: loadWarningMessage
  118. * If we can't load the map lib, then display an error message to the
  119. * user and tell them where to go for help.
  120. *
  121. * This function sets up the layout for the warning message. Each 3rd
  122. * party layer must implement its own getWarningHTML() function to
  123. * provide the actual warning message.
  124. */
  125. loadWarningMessage:function() {
  126. this.div.style.backgroundColor = "darkblue";
  127. var viewSize = this.map.getSize();
  128. var msgW = Math.min(viewSize.w, 300);
  129. var msgH = Math.min(viewSize.h, 200);
  130. var size = new SuperMap.Size(msgW, msgH);
  131. var centerPx = new SuperMap.Pixel(viewSize.w/2, viewSize.h/2);
  132. var topLeft = centerPx.add(-size.w/2, -size.h/2);
  133. var div = SuperMap.Util.createDiv(this.name + "_warning",
  134. topLeft,
  135. size,
  136. null,
  137. null,
  138. null,
  139. "auto");
  140. div.style.padding = "7px";
  141. div.style.backgroundColor = "yellow";
  142. div.innerHTML = this.getWarningHTML();
  143. this.div.appendChild(div);
  144. },
  145. /**
  146. * Method: getWarningHTML
  147. * To be implemented by subclasses.
  148. *
  149. * Returns:
  150. * {String} String with information on why layer is broken, how to get
  151. * it working.
  152. */
  153. getWarningHTML:function() {
  154. //should be implemented by subclasses
  155. return "";
  156. },
  157. /**
  158. * Method: display
  159. * Set the display on the pane
  160. *
  161. * Parameters:
  162. * display - {Boolean}
  163. */
  164. display: function(display) {
  165. SuperMap.Layer.prototype.display.apply(this, arguments);
  166. this.pane.style.display = this.div.style.display;
  167. },
  168. /**
  169. * Method: setZIndex
  170. * Set the z-index order for the pane.
  171. *
  172. * Parameters:
  173. * zIndex - {int}
  174. */
  175. setZIndex: function (zIndex) {
  176. SuperMap.Layer.prototype.setZIndex.apply(this, arguments);
  177. this.pane.style.zIndex = parseInt(this.div.style.zIndex) + 1;
  178. },
  179. /**
  180. * Method: moveByPx
  181. * Move the layer based on pixel vector. To be implemented by subclasses.
  182. *
  183. * Parameters:
  184. * dx - {Number} The x coord of the displacement vector.
  185. * dy - {Number} The y coord of the displacement vector.
  186. */
  187. moveByPx: function(dx, dy) {
  188. SuperMap.Layer.prototype.moveByPx.apply(this, arguments);
  189. if (this.dragPanMapObject) {
  190. this.dragPanMapObject(dx, -dy);
  191. } else {
  192. this.moveTo(this.map.getCachedCenter());
  193. }
  194. },
  195. /**
  196. * Method: moveTo
  197. * Handle calls to move the layer.
  198. *
  199. * Parameters:
  200. * bounds - {<SuperMap.Bounds>}
  201. * zoomChanged - {Boolean}
  202. * dragging - {Boolean}
  203. */
  204. moveTo:function(bounds, zoomChanged, dragging) {
  205. SuperMap.Layer.prototype.moveTo.apply(this, arguments);
  206. if (this.mapObject != null) {
  207. var newCenter = this.map.getCenter();
  208. var newZoom = this.map.getZoom();
  209. if (newCenter != null) {
  210. var moOldCenter = this.getMapObjectCenter();
  211. var oldCenter = this.getOLLonLatFromMapObjectLonLat(moOldCenter);
  212. var moOldZoom = this.getMapObjectZoom();
  213. var oldZoom= this.getOLZoomFromMapObjectZoom(moOldZoom);
  214. if ( !(newCenter.equals(oldCenter)) ||
  215. !(newZoom == oldZoom) ) {
  216. if (!zoomChanged && oldCenter && this.dragPanMapObject &&
  217. this.smoothDragPan) {
  218. var oldPx = this.map.getViewPortPxFromLonLat(oldCenter);
  219. var newPx = this.map.getViewPortPxFromLonLat(newCenter);
  220. this.dragPanMapObject(newPx.x-oldPx.x, oldPx.y-newPx.y);
  221. } else {
  222. var center = this.getMapObjectLonLatFromOLLonLat(newCenter);
  223. var zoom = this.getMapObjectZoomFromOLZoom(newZoom);
  224. this.setMapObjectCenter(center, zoom, dragging);
  225. }
  226. }
  227. }
  228. }
  229. },
  230. /********************************************************/
  231. /* */
  232. /* Baselayer Functions */
  233. /* */
  234. /********************************************************/
  235. /**
  236. * Method: getLonLatFromViewPortPx
  237. * Get a map location from a pixel location
  238. *
  239. * Parameters:
  240. * viewPortPx - {<SuperMap.Pixel>}
  241. *
  242. * Returns:
  243. * {<SuperMap.LonLat>} An SuperMap.LonLat which is the passed-in view
  244. * port SuperMap.Pixel, translated into lon/lat by map lib
  245. * If the map lib is not loaded or not centered, returns null
  246. */
  247. getLonLatFromViewPortPx: function (viewPortPx) {
  248. var lonlat = null;
  249. if ( (this.mapObject != null) &&
  250. (this.getMapObjectCenter() != null) ) {
  251. var moPixel = this.getMapObjectPixelFromOLPixel(viewPortPx);
  252. var moLonLat = this.getMapObjectLonLatFromMapObjectPixel(moPixel);
  253. lonlat = this.getOLLonLatFromMapObjectLonLat(moLonLat);
  254. }
  255. return lonlat;
  256. },
  257. /**
  258. * Method: getViewPortPxFromLonLat
  259. * Get a pixel location from a map location
  260. *
  261. * Parameters:
  262. * lonlat - {<SuperMap.LonLat>}
  263. *
  264. * Returns:
  265. * {<SuperMap.Pixel>} An SuperMap.Pixel which is the passed-in
  266. * SuperMap.LonLat, translated into view port pixels by map lib
  267. * If map lib is not loaded or not centered, returns null
  268. */
  269. getViewPortPxFromLonLat: function (lonlat) {
  270. var viewPortPx = null;
  271. if ( (this.mapObject != null) &&
  272. (this.getMapObjectCenter() != null) ) {
  273. var moLonLat = this.getMapObjectLonLatFromOLLonLat(lonlat);
  274. var moPixel = this.getMapObjectPixelFromMapObjectLonLat(moLonLat);
  275. viewPortPx = this.getOLPixelFromMapObjectPixel(moPixel);
  276. }
  277. return viewPortPx;
  278. },
  279. /********************************************************/
  280. /* */
  281. /* Translation Functions */
  282. /* */
  283. /* The following functions translate Map Object and */
  284. /* OL formats for Pixel, LonLat */
  285. /* */
  286. /********************************************************/
  287. //
  288. // TRANSLATION: MapObject LatLng <-> SuperMap.LonLat
  289. //
  290. /**
  291. * Method: getOLLonLatFromMapObjectLonLat
  292. * Get an OL style map location from a 3rd party style map location
  293. *
  294. * Parameters
  295. * moLonLat - {Object}
  296. *
  297. * Returns:
  298. * {<SuperMap.LonLat>} An SuperMap.LonLat, translated from the passed in
  299. * MapObject LonLat
  300. * Returns null if null value is passed in
  301. */
  302. getOLLonLatFromMapObjectLonLat: function(moLonLat) {
  303. var olLonLat = null;
  304. if (moLonLat != null) {
  305. var lon = this.getLongitudeFromMapObjectLonLat(moLonLat);
  306. var lat = this.getLatitudeFromMapObjectLonLat(moLonLat);
  307. olLonLat = new SuperMap.LonLat(lon, lat);
  308. }
  309. return olLonLat;
  310. },
  311. /**
  312. * Method: getMapObjectLonLatFromOLLonLat
  313. * Get a 3rd party map location from an OL map location.
  314. *
  315. * Parameters:
  316. * olLonLat - {<SuperMap.LonLat>}
  317. *
  318. * Returns:
  319. * {Object} A MapObject LonLat, translated from the passed in
  320. * SuperMap.LonLat
  321. * Returns null if null value is passed in
  322. */
  323. getMapObjectLonLatFromOLLonLat: function(olLonLat) {
  324. var moLatLng = null;
  325. if (olLonLat != null) {
  326. moLatLng = this.getMapObjectLonLatFromLonLat(olLonLat.lon,
  327. olLonLat.lat);
  328. }
  329. return moLatLng;
  330. },
  331. //
  332. // TRANSLATION: MapObject Pixel <-> SuperMap.Pixel
  333. //
  334. /**
  335. * Method: getOLPixelFromMapObjectPixel
  336. * Get an OL pixel location from a 3rd party pixel location.
  337. *
  338. * Parameters:
  339. * moPixel - {Object}
  340. *
  341. * Returns:
  342. * {<SuperMap.Pixel>} An SuperMap.Pixel, translated from the passed in
  343. * MapObject Pixel
  344. * Returns null if null value is passed in
  345. */
  346. getOLPixelFromMapObjectPixel: function(moPixel) {
  347. var olPixel = null;
  348. if (moPixel != null) {
  349. var x = this.getXFromMapObjectPixel(moPixel);
  350. var y = this.getYFromMapObjectPixel(moPixel);
  351. olPixel = new SuperMap.Pixel(x, y);
  352. }
  353. return olPixel;
  354. },
  355. /**
  356. * Method: getMapObjectPixelFromOLPixel
  357. * Get a 3rd party pixel location from an OL pixel location
  358. *
  359. * Parameters:
  360. * olPixel - {<SuperMap.Pixel>}
  361. *
  362. * Returns:
  363. * {Object} A MapObject Pixel, translated from the passed in
  364. * SuperMap.Pixel
  365. * Returns null if null value is passed in
  366. */
  367. getMapObjectPixelFromOLPixel: function(olPixel) {
  368. var moPixel = null;
  369. if (olPixel != null) {
  370. moPixel = this.getMapObjectPixelFromXY(olPixel.x, olPixel.y);
  371. }
  372. return moPixel;
  373. },
  374. CLASS_NAME: "SuperMap.Layer.EventPane"
  375. });