mxn.google.core.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. mxn.register('google', {
  2. Mapstraction: {
  3. init: function(element,api) {
  4. var me = this;
  5. if (GMap2) {
  6. if (GBrowserIsCompatible()) {
  7. this.maps[api] = new GMap2(element);
  8. GEvent.addListener(this.maps[api], 'click', function(marker,location) {
  9. if ( marker && marker.mapstraction_marker ) {
  10. marker.mapstraction_marker.click.fire();
  11. }
  12. else if ( location ) {
  13. me.click.fire({'location': new mxn.LatLonPoint(location.y, location.x)});
  14. }
  15. // If the user puts their own Google markers directly on the map
  16. // then there is no location and this event should not fire.
  17. if ( location ) {
  18. me.clickHandler(location.y,location.x,location,me);
  19. }
  20. });
  21. GEvent.addListener(this.maps[api], 'moveend', function() {
  22. me.moveendHandler(me);
  23. me.endPan.fire();
  24. });
  25. GEvent.addListener(this.maps[api], 'zoomend', function() {
  26. me.changeZoom.fire();
  27. });
  28. this.loaded[api] = true;
  29. me.load.fire();
  30. }
  31. else {
  32. alert('browser not compatible with Google Maps');
  33. }
  34. }
  35. else {
  36. alert(api + ' map script not imported');
  37. }
  38. },
  39. applyOptions: function(){
  40. var map = this.maps[this.api];
  41. if(this.options.enableScrollWheelZoom){
  42. map.enableContinuousZoom();
  43. map.enableScrollWheelZoom();
  44. }
  45. if (this.options.enableDragging) {
  46. map.enableDragging();
  47. } else {
  48. map.disableDragging();
  49. }
  50. },
  51. resizeTo: function(width, height){
  52. this.currentElement.style.width = width;
  53. this.currentElement.style.height = height;
  54. this.maps[this.api].checkResize();
  55. },
  56. addControls: function( args ) {
  57. var map = this.maps[this.api];
  58. // remove old controls
  59. if (this.controls) {
  60. while ((ctl = this.controls.pop())) {
  61. // Google specific method
  62. map.removeControl(ctl);
  63. }
  64. } else {
  65. this.controls = [];
  66. }
  67. c = this.controls;
  68. // Google has a combined zoom and pan control.
  69. if (args.zoom || args.pan) {
  70. if (args.zoom == 'large'){
  71. this.addLargeControls();
  72. } else {
  73. this.addSmallControls();
  74. }
  75. }
  76. if (args.scale) {
  77. this.controls.unshift(new GScaleControl());
  78. map.addControl(this.controls[0]);
  79. this.addControlsArgs.scale = true;
  80. }
  81. if (args.overview) {
  82. c.unshift(new GOverviewMapControl());
  83. map.addControl(c[0]);
  84. this.addControlsArgs.overview = true;
  85. }
  86. if (args.map_type) {
  87. this.addMapTypeControls();
  88. }
  89. },
  90. addSmallControls: function() {
  91. var map = this.maps[this.api];
  92. this.controls.unshift(new GSmallMapControl());
  93. map.addControl(this.controls[0]);
  94. this.addControlsArgs.zoom = 'small';
  95. this.addControlsArgs.pan = true;
  96. },
  97. addLargeControls: function() {
  98. var map = this.maps[this.api];
  99. this.controls.unshift(new GLargeMapControl());
  100. map.addControl(this.controls[0]);
  101. this.addControlsArgs.zoom = 'large';
  102. this.addControlsArgs.pan = true;
  103. },
  104. addMapTypeControls: function() {
  105. var map = this.maps[this.api];
  106. this.controls.unshift(new GMapTypeControl());
  107. map.addControl(this.controls[0]);
  108. this.addControlsArgs.map_type = true;
  109. },
  110. setCenterAndZoom: function(point, zoom) {
  111. var map = this.maps[this.api];
  112. var pt = point.toProprietary(this.api);
  113. map.setCenter(pt, zoom);
  114. },
  115. addMarker: function(marker, old) {
  116. var map = this.maps[this.api];
  117. var gpin = marker.toProprietary(this.api);
  118. map.addOverlay(gpin);
  119. GEvent.addListener(gpin, 'infowindowopen', function() {
  120. marker.openInfoBubble.fire();
  121. });
  122. GEvent.addListener(gpin, 'infowindowclose', function() {
  123. marker.closeInfoBubble.fire();
  124. });
  125. return gpin;
  126. },
  127. removeMarker: function(marker) {
  128. var map = this.maps[this.api];
  129. map.removeOverlay(marker.proprietary_marker);
  130. },
  131. removeAllMarkers: function() {
  132. var map = this.maps[this.api];
  133. // FIXME: got a feeling this doesn't only delete markers
  134. map.clearOverlays();
  135. },
  136. declutterMarkers: function(opts) {
  137. throw 'Not implemented';
  138. },
  139. addPolyline: function(polyline, old) {
  140. var map = this.maps[this.api];
  141. gpolyline = polyline.toProprietary(this.api);
  142. map.addOverlay(gpolyline);
  143. return gpolyline;
  144. },
  145. removePolyline: function(polyline) {
  146. var map = this.maps[this.api];
  147. map.removeOverlay(polyline.proprietary_polyline);
  148. },
  149. getCenter: function() {
  150. var map = this.maps[this.api];
  151. var pt = map.getCenter();
  152. var point = new mxn.LatLonPoint(pt.lat(),pt.lng());
  153. return point;
  154. },
  155. setCenter: function(point, options) {
  156. var map = this.maps[this.api];
  157. var pt = point.toProprietary(this.api);
  158. if(options && options.pan) {
  159. map.panTo(pt);
  160. }
  161. else {
  162. map.setCenter(pt);
  163. }
  164. },
  165. setZoom: function(zoom) {
  166. var map = this.maps[this.api];
  167. map.setZoom(zoom);
  168. },
  169. getZoom: function() {
  170. var map = this.maps[this.api];
  171. return map.getZoom();
  172. },
  173. getZoomLevelForBoundingBox: function( bbox ) {
  174. var map = this.maps[this.api];
  175. // NE and SW points from the bounding box.
  176. var ne = bbox.getNorthEast();
  177. var sw = bbox.getSouthWest();
  178. var gbox = new GLatLngBounds( sw.toProprietary(this.api), ne.toProprietary(this.api) );
  179. var zoom = map.getBoundsZoomLevel( gbox );
  180. return zoom;
  181. },
  182. setMapType: function(type) {
  183. var map = this.maps[this.api];
  184. switch(type) {
  185. case mxn.Mapstraction.ROAD:
  186. map.setMapType(G_NORMAL_MAP);
  187. break;
  188. case mxn.Mapstraction.SATELLITE:
  189. map.setMapType(G_SATELLITE_MAP);
  190. break;
  191. case mxn.Mapstraction.HYBRID:
  192. map.setMapType(G_HYBRID_MAP);
  193. break;
  194. default:
  195. map.setMapType(type || G_NORMAL_MAP);
  196. }
  197. },
  198. getMapType: function() {
  199. var map = this.maps[this.api];
  200. var type = map.getCurrentMapType();
  201. switch(type) {
  202. case G_NORMAL_MAP:
  203. return mxn.Mapstraction.ROAD;
  204. case G_SATELLITE_MAP:
  205. return mxn.Mapstraction.SATELLITE;
  206. case G_HYBRID_MAP:
  207. return mxn.Mapstraction.HYBRID;
  208. default:
  209. return null;
  210. }
  211. },
  212. getBounds: function () {
  213. var map = this.maps[this.api];
  214. var ne, sw, nw, se;
  215. var gbox = map.getBounds();
  216. sw = gbox.getSouthWest();
  217. ne = gbox.getNorthEast();
  218. return new mxn.BoundingBox(sw.lat(), sw.lng(), ne.lat(), ne.lng());
  219. },
  220. setBounds: function(bounds){
  221. var map = this.maps[this.api];
  222. var sw = bounds.getSouthWest();
  223. var ne = bounds.getNorthEast();
  224. var gbounds = new GLatLngBounds(new GLatLng(sw.lat,sw.lon),new GLatLng(ne.lat,ne.lon));
  225. map.setCenter(gbounds.getCenter(), map.getBoundsZoomLevel(gbounds));
  226. },
  227. addImageOverlay: function(id, src, opacity, west, south, east, north, oContext) {
  228. var map = this.maps[this.api];
  229. map.getPane(G_MAP_MAP_PANE).appendChild(oContext.imgElm);
  230. this.setImageOpacity(id, opacity);
  231. this.setImagePosition(id);
  232. GEvent.bind(map, "zoomend", this, function() {
  233. this.setImagePosition(id);
  234. });
  235. GEvent.bind(map, "moveend", this, function() {
  236. this.setImagePosition(id);
  237. });
  238. },
  239. setImagePosition: function(id, oContext) {
  240. var map = this.maps[this.api];
  241. var topLeftPoint; var bottomRightPoint;
  242. topLeftPoint = map.fromLatLngToDivPixel( new GLatLng(oContext.latLng.top, oContext.latLng.left) );
  243. bottomRightPoint = map.fromLatLngToDivPixel( new GLatLng(oContext.latLng.bottom, oContext.latLng.right) );
  244. oContext.pixels.top = topLeftPoint.y;
  245. oContext.pixels.left = topLeftPoint.x;
  246. oContext.pixels.bottom = bottomRightPoint.y;
  247. oContext.pixels.right = bottomRightPoint.x;
  248. },
  249. addOverlay: function(url, autoCenterAndZoom) {
  250. var map = this.maps[this.api];
  251. var geoXML = new GGeoXml(url);
  252. map.addOverlay(geoXML, function() {
  253. if(autoCenterAndZoom) {
  254. geoXML.gotoDefaultViewport(map);
  255. }
  256. });
  257. },
  258. addTileLayer: function(tile_url, opacity, copyright_text, min_zoom, max_zoom, map_type) {
  259. var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)), 0, "copyleft");
  260. var copyrightCollection = new GCopyrightCollection(copyright_text);
  261. copyrightCollection.addCopyright(copyright);
  262. var tilelayers = [];
  263. tilelayers[0] = new GTileLayer(copyrightCollection, min_zoom, max_zoom);
  264. tilelayers[0].isPng = function() {
  265. return true;
  266. };
  267. tilelayers[0].getOpacity = function() {
  268. return opacity;
  269. };
  270. tilelayers[0].getTileUrl = function (a, b) {
  271. url = tile_url;
  272. url = url.replace(/\{Z\}/g,b);
  273. url = url.replace(/\{X\}/g,a.x);
  274. url = url.replace(/\{Y\}/g,a.y);
  275. return url;
  276. };
  277. if(map_type) {
  278. var tileLayerOverlay = new GMapType(tilelayers, new GMercatorProjection(19), copyright_text, {
  279. errorMessage:"More "+copyright_text+" tiles coming soon"
  280. });
  281. this.maps[this.api].addMapType(tileLayerOverlay);
  282. } else {
  283. tileLayerOverlay = new GTileLayerOverlay(tilelayers[0]);
  284. this.maps[this.api].addOverlay(tileLayerOverlay);
  285. }
  286. this.tileLayers.push( [tile_url, tileLayerOverlay, true] );
  287. return tileLayerOverlay;
  288. },
  289. toggleTileLayer: function(tile_url) {
  290. for (var f=0; f<this.tileLayers.length; f++) {
  291. if(this.tileLayers[f][0] == tile_url) {
  292. if(this.tileLayers[f][2]) {
  293. this.maps[this.api].removeOverlay(this.tileLayers[f][1]);
  294. this.tileLayers[f][2] = false;
  295. }
  296. else {
  297. this.maps[this.api].addOverlay(this.tileLayers[f][1]);
  298. this.tileLayers[f][2] = true;
  299. }
  300. }
  301. }
  302. },
  303. getPixelRatio: function() {
  304. var map = this.maps[this.api];
  305. var projection = G_NORMAL_MAP.getProjection();
  306. var centerPoint = map.getCenter();
  307. var zoom = map.getZoom();
  308. var centerPixel = projection.fromLatLngToPixel(centerPoint, zoom);
  309. // distance is the distance in metres for 5 pixels (3-4-5 triangle)
  310. var distancePoint = projection.fromPixelToLatLng(new GPoint(centerPixel.x + 3, centerPixel.y + 4), zoom);
  311. //*1000(km to m), /5 (pythag), *2 (radius to diameter)
  312. return 10000/distancePoint.distanceFrom(centerPoint);
  313. },
  314. mousePosition: function(element) {
  315. var locDisp = document.getElementById(element);
  316. if (locDisp !== null) {
  317. var map = this.maps[this.api];
  318. GEvent.addListener(map, 'mousemove', function (point) {
  319. var loc = point.lat().toFixed(4) + ' / ' + point.lng().toFixed(4);
  320. locDisp.innerHTML = loc;
  321. });
  322. locDisp.innerHTML = '0.0000 / 0.0000';
  323. }
  324. }
  325. },
  326. LatLonPoint: {
  327. toProprietary: function() {
  328. return new GLatLng(this.lat,this.lon);
  329. },
  330. fromProprietary: function(googlePoint) {
  331. this.lat = googlePoint.lat();
  332. this.lon = googlePoint.lng();
  333. }
  334. },
  335. Marker: {
  336. toProprietary: function() {
  337. var infoBubble, event_action, infoDiv, div;
  338. var options = {};
  339. if(this.labelText){
  340. options.title = this.labelText;
  341. }
  342. if(this.iconUrl){
  343. var icon = new GIcon(G_DEFAULT_ICON, this.iconUrl);
  344. icon.printImage = icon.mozPrintImage = icon.image;
  345. if(this.iconSize) {
  346. icon.iconSize = new GSize(this.iconSize[0], this.iconSize[1]);
  347. var anchor;
  348. if(this.iconAnchor) {
  349. anchor = new GPoint(this.iconAnchor[0], this.iconAnchor[1]);
  350. }
  351. else {
  352. // FIXME: hard-coding the anchor point
  353. anchor = new GPoint(this.iconSize[0]/2, this.iconSize[1]/2);
  354. }
  355. icon.iconAnchor = anchor;
  356. }
  357. if(typeof(this.iconShadowUrl) != 'undefined') {
  358. icon.shadow = this.iconShadowUrl;
  359. if(this.iconShadowSize) {
  360. icon.shadowSize = new GSize(this.iconShadowSize[0], this.iconShadowSize[1]);
  361. }
  362. } else { // turn off shadow
  363. icon.shadow = '';
  364. icon.shadowSize = '';
  365. }
  366. if(this.transparent) {
  367. icon.transparent = this.transparent;
  368. }
  369. if(this.imageMap) {
  370. icon.imageMap = this.imageMap;
  371. }
  372. options.icon = icon;
  373. }
  374. if(this.draggable){
  375. options.draggable = this.draggable;
  376. }
  377. var gmarker = new GMarker( this.location.toProprietary('google'),options);
  378. if(this.infoBubble){
  379. infoBubble = this.infoBubble;
  380. if(this.hover) {
  381. event_action = "mouseover";
  382. }
  383. else {
  384. event_action = "click";
  385. }
  386. GEvent.addListener(gmarker, event_action, function() {
  387. gmarker.openInfoWindowHtml(infoBubble, {
  388. maxWidth: 100
  389. });
  390. });
  391. }
  392. if(this.hoverIconUrl){
  393. GEvent.addListener(gmarker, "mouseover", function() {
  394. gmarker.setImage(this.hoverIconUrl);
  395. });
  396. GEvent.addListener(gmarker, "mouseout", function() {
  397. gmarker.setImage(this.iconUrl);
  398. });
  399. }
  400. if(this.infoDiv){
  401. infoDiv = this.infoDiv;
  402. div = this.div;
  403. if(this.hover) {
  404. event_action = "mouseover";
  405. }
  406. else {
  407. event_action = "click";
  408. }
  409. GEvent.addListener(gmarker, event_action, function() {
  410. document.getElementById(div).innerHTML = infoDiv;
  411. });
  412. }
  413. return gmarker;
  414. },
  415. openBubble: function() {
  416. var gpin = this.proprietary_marker;
  417. gpin.openInfoWindowHtml(this.infoBubble);
  418. },
  419. hide: function() {
  420. this.proprietary_marker.hide();
  421. },
  422. show: function() {
  423. this.proprietary_marker.show();
  424. },
  425. update: function() {
  426. point = new mxn.LatLonPoint();
  427. point.fromGoogle(this.proprietary_marker.getPoint());
  428. this.location = point;
  429. }
  430. },
  431. Polyline: {
  432. toProprietary: function() {
  433. var gpoints = [];
  434. for (var i = 0, length = this.points.length ; i< length; i++){
  435. gpoints.push(this.points[i].toProprietary('google'));
  436. }
  437. if (this.closed || gpoints[0].equals(gpoints[length-1])) {
  438. return new GPolygon(gpoints, this.color, this.width, this.opacity, this.fillColor || "#5462E3", this.opacity || "0.3");
  439. } else {
  440. return new GPolyline(gpoints, this.color, this.width, this.opacity);
  441. }
  442. },
  443. show: function() {
  444. throw 'Not implemented';
  445. },
  446. hide: function() {
  447. throw 'Not implemented';
  448. }
  449. }
  450. });