1 mxn.register('google', {
\r
5 init: function(element,api) {
\r
8 if (GBrowserIsCompatible()) {
\r
9 this.maps[api] = new GMap2(element);
\r
11 GEvent.addListener(this.maps[api], 'click', function(marker,location) {
\r
13 if ( marker && marker.mapstraction_marker ) {
\r
14 marker.mapstraction_marker.click.fire();
\r
16 else if ( location ) {
\r
17 me.click.fire({'location': new mxn.LatLonPoint(location.y, location.x)});
\r
20 // If the user puts their own Google markers directly on the map
\r
21 // then there is no location and this event should not fire.
\r
23 me.clickHandler(location.y,location.x,location,me);
\r
27 GEvent.addListener(this.maps[api], 'moveend', function() {
\r
28 me.moveendHandler(me);
\r
32 GEvent.addListener(this.maps[api], 'zoomend', function() {
\r
33 me.changeZoom.fire();
\r
36 this.loaded[api] = true;
\r
40 alert('browser not compatible with Google Maps');
\r
44 alert(api + ' map script not imported');
\r
48 applyOptions: function(){
\r
49 var map = this.maps[this.api];
\r
51 if(this.options.enableScrollWheelZoom){
\r
52 map.enableContinuousZoom();
\r
53 map.enableScrollWheelZoom();
\r
56 if (this.options.enableDragging) {
\r
57 map.enableDragging();
\r
59 map.disableDragging();
\r
64 resizeTo: function(width, height){
\r
65 this.currentElement.style.width = width;
\r
66 this.currentElement.style.height = height;
\r
67 this.maps[this.api].checkResize();
\r
70 addControls: function( args ) {
\r
71 var map = this.maps[this.api];
\r
73 // remove old controls
\r
74 if (this.controls) {
\r
75 while ((ctl = this.controls.pop())) {
\r
76 // Google specific method
\r
77 map.removeControl(ctl);
\r
84 // Google has a combined zoom and pan control.
\r
85 if (args.zoom || args.pan) {
\r
86 if (args.zoom == 'large'){
\r
87 this.addLargeControls();
\r
89 this.addSmallControls();
\r
94 this.controls.unshift(new GScaleControl());
\r
95 map.addControl(this.controls[0]);
\r
96 this.addControlsArgs.scale = true;
\r
99 if (args.overview) {
\r
100 c.unshift(new GOverviewMapControl());
\r
101 map.addControl(c[0]);
\r
102 this.addControlsArgs.overview = true;
\r
104 if (args.map_type) {
\r
105 this.addMapTypeControls();
\r
109 addSmallControls: function() {
\r
110 var map = this.maps[this.api];
\r
111 this.controls.unshift(new GSmallMapControl());
\r
112 map.addControl(this.controls[0]);
\r
113 this.addControlsArgs.zoom = 'small';
\r
114 this.addControlsArgs.pan = true;
\r
117 addLargeControls: function() {
\r
118 var map = this.maps[this.api];
\r
119 this.controls.unshift(new GLargeMapControl());
\r
120 map.addControl(this.controls[0]);
\r
121 this.addControlsArgs.zoom = 'large';
\r
122 this.addControlsArgs.pan = true;
\r
125 addMapTypeControls: function() {
\r
126 var map = this.maps[this.api];
\r
127 this.controls.unshift(new GMapTypeControl());
\r
128 map.addControl(this.controls[0]);
\r
129 this.addControlsArgs.map_type = true;
\r
132 setCenterAndZoom: function(point, zoom) {
\r
133 var map = this.maps[this.api];
\r
134 var pt = point.toProprietary(this.api);
\r
135 map.setCenter(pt, zoom);
\r
138 addMarker: function(marker, old) {
\r
139 var map = this.maps[this.api];
\r
140 var gpin = marker.toProprietary(this.api);
\r
141 map.addOverlay(gpin);
\r
143 GEvent.addListener(gpin, 'infowindowopen', function() {
\r
144 marker.openInfoBubble.fire();
\r
146 GEvent.addListener(gpin, 'infowindowclose', function() {
\r
147 marker.closeInfoBubble.fire();
\r
152 removeMarker: function(marker) {
\r
153 var map = this.maps[this.api];
\r
154 map.removeOverlay(marker.proprietary_marker);
\r
157 removeAllMarkers: function() {
\r
158 var map = this.maps[this.api];
\r
159 // FIXME: got a feeling this doesn't only delete markers
\r
160 map.clearOverlays();
\r
163 declutterMarkers: function(opts) {
\r
164 throw 'Not implemented';
\r
167 addPolyline: function(polyline, old) {
\r
168 var map = this.maps[this.api];
\r
169 gpolyline = polyline.toProprietary(this.api);
\r
170 map.addOverlay(gpolyline);
\r
174 removePolyline: function(polyline) {
\r
175 var map = this.maps[this.api];
\r
176 map.removeOverlay(polyline.proprietary_polyline);
\r
179 getCenter: function() {
\r
180 var map = this.maps[this.api];
\r
181 var pt = map.getCenter();
\r
182 var point = new mxn.LatLonPoint(pt.lat(),pt.lng());
\r
186 setCenter: function(point, options) {
\r
187 var map = this.maps[this.api];
\r
188 var pt = point.toProprietary(this.api);
\r
189 if(options && options.pan) {
\r
197 setZoom: function(zoom) {
\r
198 var map = this.maps[this.api];
\r
199 map.setZoom(zoom);
\r
202 getZoom: function() {
\r
203 var map = this.maps[this.api];
\r
204 return map.getZoom();
\r
207 getZoomLevelForBoundingBox: function( bbox ) {
\r
208 var map = this.maps[this.api];
\r
209 // NE and SW points from the bounding box.
\r
210 var ne = bbox.getNorthEast();
\r
211 var sw = bbox.getSouthWest();
\r
212 var gbox = new GLatLngBounds( sw.toProprietary(this.api), ne.toProprietary(this.api) );
\r
213 var zoom = map.getBoundsZoomLevel( gbox );
\r
217 setMapType: function(type) {
\r
218 var map = this.maps[this.api];
\r
220 case mxn.Mapstraction.ROAD:
\r
221 map.setMapType(G_NORMAL_MAP);
\r
223 case mxn.Mapstraction.SATELLITE:
\r
224 map.setMapType(G_SATELLITE_MAP);
\r
226 case mxn.Mapstraction.HYBRID:
\r
227 map.setMapType(G_HYBRID_MAP);
\r
230 map.setMapType(type || G_NORMAL_MAP);
\r
234 getMapType: function() {
\r
235 var map = this.maps[this.api];
\r
236 var type = map.getCurrentMapType();
\r
239 return mxn.Mapstraction.ROAD;
\r
240 case G_SATELLITE_MAP:
\r
241 return mxn.Mapstraction.SATELLITE;
\r
243 return mxn.Mapstraction.HYBRID;
\r
249 getBounds: function () {
\r
250 var map = this.maps[this.api];
\r
251 var ne, sw, nw, se;
\r
252 var gbox = map.getBounds();
\r
253 sw = gbox.getSouthWest();
\r
254 ne = gbox.getNorthEast();
\r
255 return new mxn.BoundingBox(sw.lat(), sw.lng(), ne.lat(), ne.lng());
\r
258 setBounds: function(bounds){
\r
259 var map = this.maps[this.api];
\r
260 var sw = bounds.getSouthWest();
\r
261 var ne = bounds.getNorthEast();
\r
262 var gbounds = new GLatLngBounds(new GLatLng(sw.lat,sw.lon),new GLatLng(ne.lat,ne.lon));
\r
263 map.setCenter(gbounds.getCenter(), map.getBoundsZoomLevel(gbounds));
\r
266 addImageOverlay: function(id, src, opacity, west, south, east, north, oContext) {
\r
267 var map = this.maps[this.api];
\r
268 map.getPane(G_MAP_MAP_PANE).appendChild(oContext.imgElm);
\r
269 this.setImageOpacity(id, opacity);
\r
270 this.setImagePosition(id);
\r
271 GEvent.bind(map, "zoomend", this, function() {
\r
272 this.setImagePosition(id);
\r
274 GEvent.bind(map, "moveend", this, function() {
\r
275 this.setImagePosition(id);
\r
279 setImagePosition: function(id, oContext) {
\r
280 var map = this.maps[this.api];
\r
281 var topLeftPoint; var bottomRightPoint;
\r
283 topLeftPoint = map.fromLatLngToDivPixel( new GLatLng(oContext.latLng.top, oContext.latLng.left) );
\r
284 bottomRightPoint = map.fromLatLngToDivPixel( new GLatLng(oContext.latLng.bottom, oContext.latLng.right) );
\r
286 oContext.pixels.top = topLeftPoint.y;
\r
287 oContext.pixels.left = topLeftPoint.x;
\r
288 oContext.pixels.bottom = bottomRightPoint.y;
\r
289 oContext.pixels.right = bottomRightPoint.x;
\r
292 addOverlay: function(url, autoCenterAndZoom) {
\r
293 var map = this.maps[this.api];
\r
294 var geoXML = new GGeoXml(url);
\r
295 map.addOverlay(geoXML, function() {
\r
296 if(autoCenterAndZoom) {
\r
297 geoXML.gotoDefaultViewport(map);
\r
302 addTileLayer: function(tile_url, opacity, copyright_text, min_zoom, max_zoom, map_type) {
\r
303 var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90,180)), 0, "copyleft");
\r
304 var copyrightCollection = new GCopyrightCollection(copyright_text);
\r
305 copyrightCollection.addCopyright(copyright);
\r
306 var tilelayers = [];
\r
307 tilelayers[0] = new GTileLayer(copyrightCollection, min_zoom, max_zoom);
\r
308 tilelayers[0].isPng = function() {
\r
311 tilelayers[0].getOpacity = function() {
\r
314 tilelayers[0].getTileUrl = function (a, b) {
\r
316 url = url.replace(/\{Z\}/g,b);
\r
317 url = url.replace(/\{X\}/g,a.x);
\r
318 url = url.replace(/\{Y\}/g,a.y);
\r
322 var tileLayerOverlay = new GMapType(tilelayers, new GMercatorProjection(19), copyright_text, {
\r
323 errorMessage:"More "+copyright_text+" tiles coming soon"
\r
325 this.maps[this.api].addMapType(tileLayerOverlay);
\r
327 tileLayerOverlay = new GTileLayerOverlay(tilelayers[0]);
\r
328 this.maps[this.api].addOverlay(tileLayerOverlay);
\r
330 this.tileLayers.push( [tile_url, tileLayerOverlay, true] );
\r
331 return tileLayerOverlay;
\r
334 toggleTileLayer: function(tile_url) {
\r
335 for (var f=0; f<this.tileLayers.length; f++) {
\r
336 if(this.tileLayers[f][0] == tile_url) {
\r
337 if(this.tileLayers[f][2]) {
\r
338 this.maps[this.api].removeOverlay(this.tileLayers[f][1]);
\r
339 this.tileLayers[f][2] = false;
\r
342 this.maps[this.api].addOverlay(this.tileLayers[f][1]);
\r
343 this.tileLayers[f][2] = true;
\r
349 getPixelRatio: function() {
\r
350 var map = this.maps[this.api];
\r
352 var projection = G_NORMAL_MAP.getProjection();
\r
353 var centerPoint = map.getCenter();
\r
354 var zoom = map.getZoom();
\r
355 var centerPixel = projection.fromLatLngToPixel(centerPoint, zoom);
\r
356 // distance is the distance in metres for 5 pixels (3-4-5 triangle)
\r
357 var distancePoint = projection.fromPixelToLatLng(new GPoint(centerPixel.x + 3, centerPixel.y + 4), zoom);
\r
358 //*1000(km to m), /5 (pythag), *2 (radius to diameter)
\r
359 return 10000/distancePoint.distanceFrom(centerPoint);
\r
363 mousePosition: function(element) {
\r
364 var locDisp = document.getElementById(element);
\r
365 if (locDisp !== null) {
\r
366 var map = this.maps[this.api];
\r
367 GEvent.addListener(map, 'mousemove', function (point) {
\r
368 var loc = point.lat().toFixed(4) + ' / ' + point.lng().toFixed(4);
\r
369 locDisp.innerHTML = loc;
\r
371 locDisp.innerHTML = '0.0000 / 0.0000';
\r
378 toProprietary: function() {
\r
379 return new GLatLng(this.lat,this.lon);
\r
382 fromProprietary: function(googlePoint) {
\r
383 this.lat = googlePoint.lat();
\r
384 this.lon = googlePoint.lng();
\r
391 toProprietary: function() {
\r
392 var infoBubble, event_action, infoDiv, div;
\r
394 if(this.labelText){
\r
395 options.title = this.labelText;
\r
398 var icon = new GIcon(G_DEFAULT_ICON, this.iconUrl);
\r
399 icon.printImage = icon.mozPrintImage = icon.image;
\r
400 if(this.iconSize) {
\r
401 icon.iconSize = new GSize(this.iconSize[0], this.iconSize[1]);
\r
403 if(this.iconAnchor) {
\r
404 anchor = new GPoint(this.iconAnchor[0], this.iconAnchor[1]);
\r
407 // FIXME: hard-coding the anchor point
\r
408 anchor = new GPoint(this.iconSize[0]/2, this.iconSize[1]/2);
\r
410 icon.iconAnchor = anchor;
\r
412 if(typeof(this.iconShadowUrl) != 'undefined') {
\r
413 icon.shadow = this.iconShadowUrl;
\r
414 if(this.iconShadowSize) {
\r
415 icon.shadowSize = new GSize(this.iconShadowSize[0], this.iconShadowSize[1]);
\r
417 } else { // turn off shadow
\r
419 icon.shadowSize = '';
\r
421 if(this.transparent) {
\r
422 icon.transparent = this.transparent;
\r
424 if(this.imageMap) {
\r
425 icon.imageMap = this.imageMap;
\r
427 options.icon = icon;
\r
429 if(this.draggable){
\r
430 options.draggable = this.draggable;
\r
432 var gmarker = new GMarker( this.location.toProprietary('google'),options);
\r
434 if(this.infoBubble){
\r
435 infoBubble = this.infoBubble;
\r
437 event_action = "mouseover";
\r
440 event_action = "click";
\r
442 GEvent.addListener(gmarker, event_action, function() {
\r
443 gmarker.openInfoWindowHtml(infoBubble, {
\r
449 if(this.hoverIconUrl){
\r
450 GEvent.addListener(gmarker, "mouseover", function() {
\r
451 gmarker.setImage(this.hoverIconUrl);
\r
453 GEvent.addListener(gmarker, "mouseout", function() {
\r
454 gmarker.setImage(this.iconUrl);
\r
459 infoDiv = this.infoDiv;
\r
462 event_action = "mouseover";
\r
465 event_action = "click";
\r
467 GEvent.addListener(gmarker, event_action, function() {
\r
468 document.getElementById(div).innerHTML = infoDiv;
\r
475 openBubble: function() {
\r
476 var gpin = this.proprietary_marker;
\r
477 gpin.openInfoWindowHtml(this.infoBubble);
\r
481 this.proprietary_marker.hide();
\r
485 this.proprietary_marker.show();
\r
488 update: function() {
\r
489 point = new mxn.LatLonPoint();
\r
490 point.fromGoogle(this.proprietary_marker.getPoint());
\r
491 this.location = point;
\r
498 toProprietary: function() {
\r
500 for (var i = 0, length = this.points.length ; i< length; i++){
\r
501 gpoints.push(this.points[i].toProprietary('google'));
\r
503 if (this.closed || gpoints[0].equals(gpoints[length-1])) {
\r
504 return new GPolygon(gpoints, this.color, this.width, this.opacity, this.fillColor || "#5462E3", this.opacity || "0.3");
\r
506 return new GPolyline(gpoints, this.color, this.width, this.opacity);
\r
511 throw 'Not implemented';
\r
515 throw 'Not implemented';
\r