1 /** 2 * Mapstraction implementation for Geo Mashup maps. 3 * @fileOverview 4 */ 5 6 /** 7 * @name AjaxRequestOptions 8 * @class This type represents options used for an AJAX request. 9 * It has no constructor, but is instantiated as an object literal. 10 * 11 * @property {String} url The AJAX request URL. 12 */ 13 14 /** 15 * @name ContentFilter 16 * @class This type represents objects used to filter content. 17 * It has no constructor, but is instantiated as an object literal. 18 * 19 * @name ContentFilter#content 20 * @property {String} content HTML content to filter. 21 */ 22 23 /*global GeoMashup */ 24 /*global customizeGeoMashup, customizeGeoMashupMap, customGeoMashupColorIcon, customGeoMashupCategoryIcon */ 25 /*glboal customGeoMashupSinglePostIcon, customGeoMashupMultiplePostImage */ 26 /*global mxn */ 27 28 GeoMashup.loadFullPost = function( point ) { 29 var i, request, objects, object_ids; 30 31 this.getShowPostElement().innerHTML = '<div align="center"><img src="' + 32 this.opts.url_path + '/images/busy_icon.gif" alt="Loading..." /></div>'; 33 object_ids = []; 34 objects = this.getObjectsAtLocation( point ); 35 for( i = 0; i < objects.length; i += 1 ) { 36 object_ids.push( objects[i].object_id ); 37 } 38 request = { 39 url: this.geo_query_url + '&object_name=' + this.opts.object_name + 40 '&object_ids=' + object_ids.join( ',' ) + '&template=full-post' 41 }; 42 /** 43 * Requesting full post content. 44 * @name GeoMashup#fullPostRequest 45 * @event 46 * @param {Array} objects Objects included in the request 47 * @param {AjaxRequestOptions} options 48 */ 49 this.doAction( 'fullPostRequest', objects, request ); 50 jQuery.get( request.url, function( content ) { 51 var filter = {content: content}; 52 /** 53 * Loading full post content. 54 * @name GeoMashup#fullPostLoad 55 * @event 56 * @param {Array} objects Objects included in the request 57 * @param {ContentFilter} filter 58 */ 59 GeoMashup.doAction( 'fullPostLoad', objects, filter ); 60 jQuery( GeoMashup.getShowPostElement() ).html( filter.content ); 61 /** 62 * The full post display has changed. 63 * @name GeoMashup#fullPostChanged 64 * @event 65 */ 66 GeoMashup.doAction( 'fullPostChanged' ); 67 } ); 68 }; 69 70 GeoMashup.createCategoryLine = function ( category ) { 71 // Polylines are close, but the openlayers implementation at least cannot hide or remove a polyline 72 var options = {color: category.color, width: 5, opacity: 0.5}; 73 category.line = new mxn.Polyline(category.points); 74 /** 75 * A category line was created. 76 * @name GeoMashup#categoryLine 77 * @event 78 * @param {GeoMashupOptions} properties Geo Mashup configuration data 79 * @param {Polyline} line 80 */ 81 this.doAction( 'categoryLine', this.opts, category.line ); 82 /** 83 * A category will be added with the given options. 84 * @name GeoMashup#categoryLineOptions 85 * @event 86 * @param {GeoMashupOptions} properties Geo Mashup configuration data 87 * @param {Object} options Modifiable <a href="http://mapstraction.github.com/mxn/build/latest/docs/symbols/mxn.Polyline.html#addData">Mapstraction</a> 88 * or <a href="http://code.google.com/apis/maps/documentation/javascript/v2/reference.html#GPolylineOptions">Google</a> Polyline options 89 */ 90 this.doAction( 'categoryLineOptions', this.opts, options ); 91 this.map.addPolylineWithData( category.line, options ); 92 if (this.map.getZoom() > category.max_line_zoom) { 93 try { 94 category.line.hide(); 95 } catch( e ) { 96 // Not implemented? 97 this.map.removePolyline( category.line ); 98 } 99 } 100 }; 101 102 GeoMashup.openInfoWindow = function( marker ) { 103 var objects, request, object_ids = [], i, object_element, point = marker.location; 104 105 if ( this.open_window_marker && !this.opts.multiple_info_windows ) { 106 this.open_window_marker.closeBubble(); 107 } 108 if ( this.locations[point].loaded ) { 109 marker.openBubble(); 110 } else { 111 marker.setInfoBubble( '<div align="center"><img src="' + this.opts.url_path + 112 '/images/busy_icon.gif" alt="Loading..." /></div>' ); 113 marker.openBubble(); 114 this.open_window_marker = marker; 115 // Collect object ids 116 objects = this.getObjectsAtLocation( point ); 117 for( i = 0; i < objects.length; i += 1 ) { 118 object_ids.push( objects[i].object_id ); 119 } 120 // Do an AJAX query to get content for these objects 121 request = { 122 url: this.geo_query_url + '&object_name=' + this.opts.object_name + 123 '&object_ids=' + object_ids.join( ',' ) 124 }; 125 /** 126 * A marker's info window content is being requested. 127 * @name GeoMashup#markerInfoWindowRequest 128 * @event 129 * @param {Marker} marker 130 * @param {AjaxRequestOptions} request Modifiable property: url 131 */ 132 this.doAction( 'markerInfoWindowRequest', marker, request ); 133 jQuery.get( 134 request.url, 135 function( content ) { 136 var filter = {content: content}; 137 marker.closeBubble(); 138 /** 139 * A marker info window content is being loaded. 140 * @name GeoMashup#markerInfoWindowLoad 141 * @event 142 * @param {Marker} marker 143 * @param {ContentFilter} filter Modifiable property: content 144 */ 145 GeoMashup.doAction( 'markerInfoWindowLoad', marker, filter ); 146 marker.setInfoBubble( GeoMashup.parentizeLinksMarkup( filter.content ) ); 147 marker.openBubble(); 148 } 149 ); 150 } 151 }; 152 153 GeoMashup.closeInfoWindow = function( marker ) { 154 marker.closeBubble(); 155 }; 156 157 GeoMashup.addGlowMarker = function( marker ) { 158 var point = marker.location, 159 glow_options = { 160 clickable : true, 161 icon : this.opts.url_path + '/images/mm_20_glow.png', 162 iconSize : [ 22, 30 ], 163 iconAnchor : [ 11, 27 ] 164 }; 165 166 if ( this.glow_marker ) { 167 this.removeGlowMarker(); 168 } 169 /** 170 * A highlight "glow" marker is being created. 171 * @name GeoMashup#glowMarkerIcon 172 * @event 173 * @param {GeoMashupOptions} properties Geo Mashup configuration data 174 * @param {Object} glow_options Modifiable <a href="http://mapstraction.github.com/mxn/build/latest/docs/symbols/mxn.Marker.html#addData">Mapstraction</a> 175 * or <a href="http://code.google.com/apis/maps/documentation/javascript/v2/reference.html#GMarkerOptions">Google</a> marker options 176 */ 177 this.doAction( 'glowMarkerIcon', this.opts, glow_options ); 178 this.glow_marker = new mxn.Marker( point ); 179 this.glow_marker.addData( glow_options ); 180 this.glow_marker.click.addHandler( function() { 181 GeoMashup.deselectMarker(); 182 } ); 183 this.map.addMarker( this.glow_marker ); 184 }; 185 186 GeoMashup.removeGlowMarker = function() { 187 if ( this.glow_marker ) { 188 this.glow_marker.hide(); 189 this.map.removeMarker( this.glow_marker ); 190 this.glow_marker = null; 191 } 192 }; 193 194 GeoMashup.hideAttachments = function() { 195 var i, j, obj; 196 197 /* No removeOverlay (yet) 198 for ( i = 0; i < this.open_attachments.length; i += 1 ) { 199 this.map.removeOverlay( this.open_attachments[i] ); 200 } 201 this.open_attachments = []; 202 */ 203 }; 204 205 GeoMashup.showMarkerAttachments = function( marker ) { 206 var i, j, objects, object_ids=[], ajax_params = {action: 'geo_mashup_kml_attachments'}; 207 208 this.hideAttachments(); // check support 209 objects = this.getObjectsAtLocation( marker.location ); 210 for ( i = 0; i < objects.length; i += 1 ) { 211 object_ids.push( objects[i].object_id ); 212 } 213 ajax_params.post_ids = object_ids.join( ',' ); 214 jQuery.getJSON( this.opts.ajaxurl + '?callback=?', ajax_params, function( data ) { 215 jQuery.each( data, function( i, url ) { 216 GeoMashup.open_attachments.push( url ); 217 GeoMashup.map.addOverlay( url ); 218 } ); 219 } ); 220 }; 221 222 GeoMashup.addObjectIcon = function( obj ) { 223 if (typeof customGeoMashupCategoryIcon === 'function') { 224 obj.icon = customGeoMashupCategoryIcon(this.opts, obj.categories); 225 } 226 if (!obj.icon) { 227 if (obj.categories.length > 1) { 228 obj.icon = this.clone(this.multiple_category_icon); 229 } else if (obj.categories.length === 1) { 230 obj.icon = this.clone(this.categories[obj.categories[0]].icon); 231 } else { 232 obj.icon = this.colorIcon( 'red' ); 233 } 234 /** 235 * An icon is being assigned to an object. 236 * @name GeoMashup#objectIcon 237 * @event 238 * @param {GeoMashupOptions} properties Geo Mashup configuration data 239 * @param {GeoMashupObject} object 240 */ 241 this.doAction( 'objectIcon', this.opts, obj ); 242 } 243 }; 244 245 GeoMashup.createMarker = function(point,obj) { 246 var marker, marker_opts; 247 248 if ( !obj.icon ) { 249 this.addObjectIcon( obj ); 250 } 251 marker_opts = { 252 label: obj.title, 253 icon: obj.icon.image, 254 iconSize: obj.icon.iconSize, 255 iconShadow: obj.icon.iconShadow, 256 iconAnchor: obj.icon.iconAnchor, 257 iconShadowSize: obj.icon.shadowSize, 258 visible: true 259 }; 260 /** 261 * A marker is being created for an object. 262 * @name GeoMashup#objectMarkerOptions 263 * @event 264 * @param {GeoMashupOptions} properties Geo Mashup configuration data 265 * @param {Object} glow_options Modifiable <a href="http://mapstraction.github.com/mxn/build/latest/docs/symbols/mxn.Marker.html#addData">Mapstraction</a> 266 * or <a href="http://code.google.com/apis/maps/documentation/javascript/v2/reference.html#GMarkerOptions">Google</a> marker options 267 * @param {GeoMashupObject} object 268 */ 269 this.doAction( 'objectMarkerOptions', this.opts, marker_opts, obj ); 270 marker = new mxn.Marker( point ); 271 marker.addData( marker_opts ); 272 273 marker.click.addHandler( function() { 274 // Toggle marker selection 275 if ( marker == GeoMashup.selected_marker ) { 276 GeoMashup.deselectMarker(); 277 } else { 278 GeoMashup.selectMarker( marker ); 279 } 280 } ); 281 282 /** 283 * A marker was created. 284 * @name GeoMashup#marker 285 * @event 286 * @param {GeoMashupOptions} properties Geo Mashup configuration data 287 * @param {Marker} marker 288 */ 289 this.doAction( 'marker', this.opts, marker ); 290 291 return marker; 292 }; 293 294 GeoMashup.clickObjectMarker = function( object_id, try_count ) { 295 var obj = this.objects[object_id]; 296 if (typeof try_count === 'undefined') { 297 try_count = 1; 298 } 299 if ( obj && obj.marker && try_count < 4 ) { 300 // openlayers/mxn seems to have trouble displaying an infobubble right away 301 if ( try_count < 2 ) { 302 try_count += 1; 303 setTimeout(function () {GeoMashup.clickObjectMarker(object_id, try_count);}, 1000); 304 } else { 305 obj.marker.click.fire(); 306 } 307 } 308 }; 309 310 GeoMashup.colorIcon = function( color_name ) { 311 var icon = this.clone( this.base_color_icon ); 312 icon.image = this.opts.url_path + '/images/mm_20_' + color_name + '.png'; 313 return icon; 314 }; 315 316 GeoMashup.getMarkerLatLng = function( marker ) { 317 return marker.location; 318 }; 319 320 GeoMashup.hideMarker = function( marker ) { 321 if ( marker == this.selected_marker ) { 322 this.deselectMarker(); 323 } 324 marker.hide(); 325 }; 326 327 GeoMashup.showMarker = function( marker ) { 328 marker.show(); 329 }; 330 331 GeoMashup.hideLine = function( line ) { 332 try { 333 line.hide(); 334 } catch( e ) { 335 this.map.removePolyline( line ); 336 } 337 }; 338 339 GeoMashup.showLine = function( line ) { 340 try { 341 line.show(); 342 } catch( e ) { 343 this.map.addPolyline( line ); 344 } 345 }; 346 347 GeoMashup.newLatLng = function( lat, lng ) { 348 return new mxn.LatLonPoint( lat, lng ); 349 }; 350 351 GeoMashup.extendLocationBounds = function( latlng ) { 352 if ( this.location_bounds ) { 353 this.location_bounds.extend( latlng ); 354 } else { 355 this.location_bounds = new mxn.BoundingBox( latlng, latlng ); 356 } 357 }; 358 359 GeoMashup.addMarkers = function( markers ) { 360 this.forEach( markers, function( i, marker ) { 361 this.map.addMarker( marker ); 362 } ); 363 }; 364 365 GeoMashup.makeMarkerMultiple = function( marker ) { 366 var plus_image; 367 if (typeof customGeoMashupMultiplePostImage === 'function') { 368 plus_image = customGeoMashupMultiplePostImage(this.opts, marker); 369 } 370 if (!plus_image) { 371 plus_image = this.opts.url_path + '/images/mm_20_plus.png'; 372 } 373 marker.setIcon( plus_image ); 374 /** 375 * A marker representing multiple objects was created. 376 * @name GeoMashup#multiObjectMarker 377 * @event 378 * @param {GeoMashupOptions} properties Geo Mashup configuration data 379 * @param {Marker} marker 380 */ 381 this.doAction( 'multiObjectMarker', this.opts, marker ); 382 /** 383 * A marker representing multiple objects was created with this icon. 384 * @name GeoMashup#multiObjectIcon 385 * @event 386 * @param {GeoMashupOptions} properties Geo Mashup configuration data 387 * @param {String} plus_image Icon URL 388 */ 389 this.doAction( 'multiObjectIcon', this.opts, plus_image ); 390 }; 391 392 GeoMashup.autoZoom = function() { 393 var max_zoom; 394 this.map.autoCenterAndZoom(); 395 max_zoom = parseInt( this.opts.auto_zoom_max, 10 ); 396 if ( this.map.getZoom() > max_zoom ) { 397 this.map.setZoom( max_zoom ); 398 } 399 }; 400 401 GeoMashup.isMarkerVisible = function( marker ) { 402 var map_bounds; 403 try { 404 map_bounds = this.map.getBounds(); 405 } catch( e ) { 406 // No bounds available yet, no markers are visible 407 return false; 408 } 409 return ( marker.getAttribute( 'visible' ) && map_bounds && map_bounds.contains( marker.location ) ); 410 }; 411 412 GeoMashup.centerMarker = function( marker, zoom ) { 413 if ( typeof zoom === 'number' ) { 414 this.map.setCenterAndZoom( marker.location, zoom ); 415 } else { 416 this.map.setCenter( marker.location, {}, true ); 417 } 418 }; 419 420 GeoMashup.createMap = function(container, opts) { 421 var i, type_num, center_latlng, map_opts, map_types, request, url, objects, point, marker_opts, 422 clusterer_opts, single_marker, ov, credit_div, initial_zoom = 1, controls = {}, filter = {}; 423 424 this.container = container; 425 this.base_color_icon = {}; 426 this.base_color_icon.image = opts.url_path + '/images/mm_20_black.png'; 427 this.base_color_icon.iconShadow = opts.url_path + '/images/mm_20_shadow.png'; 428 this.base_color_icon.iconSize = [12, 20]; 429 this.base_color_icon.shadowSize = [22, 20]; 430 this.base_color_icon.iconAnchor = [6, 20]; 431 this.base_color_icon.infoWindowAnchor = [5, 1]; 432 this.multiple_category_icon = this.clone( this.base_color_icon ); 433 this.multiple_category_icon.image = opts.url_path + '/images/mm_20_mixed.png'; 434 435 // Falsify options to make tests simpler 436 this.forEach( opts, function( key, value ) { 437 if ( 'false' === value || 'FALSE' === value ) { 438 opts[key] = false; 439 } 440 } ); 441 442 // See if we have access to a parent frame 443 this.have_parent_access = false; 444 try { 445 if ( typeof parent === 'object' ) { 446 // Try access, throws an exception if prohibited 447 parent.document.getElementById( 'bogus-test' ); 448 // Access worked 449 this.have_parent_access = true; 450 } 451 } catch ( parent_exception ) { } 452 453 // For now, siteurl is the home url 454 opts.home_url = opts.siteurl; 455 456 map_types = { 457 'G_NORMAL_MAP' : mxn.Mapstraction.ROAD, 458 'G_SATELLITE_MAP' : mxn.Mapstraction.SATELLITE, 459 'G_HYBRID_MAP' : mxn.Mapstraction.HYBRID, 460 'G_PHYSICAL_MAP' : mxn.Mapstraction.PHYSICAL 461 }; 462 463 if (typeof opts.map_type === 'string') { 464 if ( map_types[opts.map_type] ) { 465 opts.map_type = map_types[opts.map_type] ; 466 } else { 467 type_num = parseInt(opts.map_type, 10); 468 if ( isNaN(type_num) || type_num > 2 ) { 469 opts.map_type = map_types.G_NORMAL_MAP; 470 } else { 471 opts.map_type = type_num; 472 } 473 } 474 } else if (typeof opts.map_type === 'undefined') { 475 opts.map_type = map_types.G_NORMAL_MAP; 476 } 477 this.map = new mxn.Mapstraction( this.container, opts.map_api ); 478 map_opts = {enableScrollWheelZoom: true, enableDragging: true}; 479 if ( 'enableGeoMashupExtras' in this.map ) { 480 this.map.enableGeoMashupExtras(); 481 } 482 /** 483 * The map options are being set. 484 * @name GeoMashup#mapOptions 485 * @event 486 * @param {GeoMashupOptions} properties Geo Mashup configuration data 487 * @param {Object} map_opts Modifiable <a href="http://mapstraction.github.com/mxn/build/latest/docs/symbols/mxn.Mapstraction.html#options">Mapstraction</a> 488 * or <a href="http://code.google.com/apis/maps/documentation/javascript/v2/reference.html#GMapOptions">Google</a> map options 489 */ 490 this.doAction( 'mapOptions', opts, map_opts ); 491 this.map.setOptions( map_opts ); 492 this.map.setCenterAndZoom(new mxn.LatLonPoint(0,0), 0); 493 494 /** 495 * The map was created. 496 * @name GeoMashup#newMap 497 * @event 498 * @param {GeoMashupOptions} properties Geo Mashup configuration data 499 * @param {Map} map 500 */ 501 this.doAction( 'newMap', opts, this.map ); 502 503 // Create the loading spinner icon and show it 504 this.spinner_div = document.createElement( 'div' ); 505 this.spinner_div.innerHTML = '<div id="gm-loading-icon" style="-moz-user-select: none; z-index: 100; position: absolute; left: ' + 506 ( jQuery(this.container).width() / 2 ) + 'px; top: ' + ( jQuery(this.container).height() / 2 ) + 'px;">' + 507 '<img style="border: 0px none ; margin: 0px; padding: 0px; width: 16px; height: 16px; -moz-user-select: none;" src="' + 508 opts.url_path + '/images/busy_icon.gif"/></a></div>'; 509 this.showLoadingIcon(); 510 this.map.load.addHandler( function() {GeoMashup.hideLoadingIcon();} ); 511 512 if (!opts.object_name) { 513 opts.object_name = 'post'; 514 } 515 this.opts = opts; 516 filter.url = opts.siteurl + '/?geo_mashup_content=geo-query&map_name=' + encodeURIComponent( opts.name ); 517 if ( 'lang' in opts ) { 518 filter.url += '&lang=' + encodeURIComponent( opts.lang ); 519 } 520 /** 521 * The base URL used for geo queries is being set. 522 * @name GeoMashup#geoQueryUrl 523 * @event 524 * @param {GeoMashupOptions} properties Geo Mashup configuration data 525 * @param {Object} filter Mofiable property: url 526 */ 527 this.doAction( 'geoQueryUrl', this.opts, filter ); 528 this.geo_query_url = filter.url; 529 530 // TODO: Try to deleselect markers with clicks? Need to make sure we don't get other object's clicks. 531 this.map.changeZoom.addHandler( function( old_zoom, new_zoom ) { 532 GeoMashup.adjustZoom( old_zoom, new_zoom ); 533 GeoMashup.adjustViewport(); 534 } ); 535 this.map.endPan.addHandler( function() {GeoMashup.adjustViewport();} ); 536 537 // No clustering available 538 539 if ( opts.zoom !== 'auto' && typeof opts.zoom === 'string' ) { 540 initial_zoom = parseInt(opts.zoom, 10); 541 }else { 542 initial_zoom = opts.zoom; 543 } 544 545 if (opts.load_kml) { 546 try { 547 if ( initial_zoom === 'auto' ) { 548 this.map.addOverlay( opts.load_kml, true ); 549 } else { 550 this.map.addOverlay( opts.load_kml ); 551 } 552 } catch (e) { 553 // Probably not implemented 554 } 555 } 556 557 this.buildCategoryHierarchy(); 558 559 try { 560 this.map.setMapType( opts.map_type ); 561 } catch ( map_type_ex) { 562 // Probably not implemented 563 } 564 if ( initial_zoom === 'auto' ) { 565 // Wait to center and zoom after loading 566 } else if (opts.center_lat && opts.center_lng) { 567 // Use the center from options 568 this.map.setCenterAndZoom(new mxn.LatLonPoint( parseFloat( opts.center_lat ), parseFloat( opts.center_lng ) ), initial_zoom ); 569 } else if (opts.object_data && opts.object_data.objects[0]) { 570 center_latlng = new mxn.LatLonPoint( parseFloat( opts.object_data.objects[0].lat ), parseFloat( opts.object_data.objects[0].lng ) ); 571 this.map.setCenterAndZoom( center_latlng, initial_zoom ); 572 } else { 573 // Center on the most recent located object 574 url = this.geo_query_url + '&limit=1'; 575 if (opts.map_cat) { 576 url += '&map_cat='+opts.map_cat; 577 } 578 jQuery.getJSON( url, function( objects ) { 579 if (objects.length>0) { 580 center_latlng = new mxn.LatLonPoint( parseFloat( objects[0].lat ), parseFloat( objects[0].lng ) ); 581 this.map.setCenterAndZoom( center_latlng, initial_zoom ); 582 } 583 } ); 584 } 585 586 this.location_bounds = null; 587 588 if (opts.map_content === 'single') 589 { 590 if (opts.center_lat && opts.center_lng && !opts.load_kml) 591 { 592 marker_opts = {visible: true}; 593 if (typeof customGeoMashupSinglePostIcon === 'function') { 594 marker_opts = customGeoMashupSinglePostIcon(this.opts); 595 } 596 if ( !marker_opts.image ) { 597 marker_opts = this.colorIcon( 'red' ); 598 marker_opts.icon = marker_opts.image; 599 } 600 /** 601 * A single map marker is being created with these options 602 * @name GeoMashup#singleMarkerOptions 603 * @event 604 * @param {GeoMashupOptions} properties Geo Mashup configuration data 605 * @param {Object} marker_opts Mofifiable Mapstraction or Google marker options 606 */ 607 this.doAction( 'singleMarkerOptions', this.opts, marker_opts ); 608 single_marker = new mxn.Marker( 609 new mxn.LatLonPoint( parseFloat( this.opts.center_lat ), parseFloat( this.opts.center_lng ) ) 610 ); 611 this.map.addMarkerWithData( single_marker, marker_opts ); 612 /** 613 * A single map marker was added to the map. 614 * @name GeoMashup#singleMarker 615 * @event 616 * @param {GeoMashupOptions} properties Geo Mashup configuration data 617 * @param {Marker} single_marker 618 */ 619 this.doAction( 'singleMarker', this.opts, single_marker ); 620 } 621 } else if (opts.object_data) { 622 this.addObjects(opts.object_data.objects,true); 623 } else { 624 // Request objects near visible range first 625 this.requestObjects(true); 626 627 // Request all objects 628 this.requestObjects(false); 629 } 630 631 if ('GSmallZoomControl' === opts.map_control || 'GSmallZoomControl3D' === opts.map_control) { 632 controls.zoom = 'small'; 633 } else if ('GSmallMapControl' === opts.map_control) { 634 controls.zoom = 'small'; 635 controls.pan = true; 636 } else if ('GLargeMapControl' === opts.map_control || 'GLargeMapControl3D' === opts.map_control) { 637 controls.zoom = 'large'; 638 controls.pan = true; 639 } 640 641 if (opts.add_map_type_control ) { 642 controls.map_type = true; 643 } 644 645 if (opts.add_overview_control) { 646 controls.overview = true; 647 } 648 this.map.addControls( controls ); 649 650 this.map.load.addHandler( function() {GeoMashup.updateVisibleList();} ); 651 if (typeof customizeGeoMashupMap === 'function') { 652 customizeGeoMashupMap(this.opts, this.map); 653 } 654 if (typeof customizeGeoMashup === 'function') { 655 customizeGeoMashup(this); 656 } 657 /** 658 * The map has loaded. 659 * @name GeoMashup#loadedMap 660 * @event 661 * @param {GeoMashupOptions} properties Geo Mashup configuration data 662 * @param {Map} map 663 */ 664 this.doAction( 'loadedMap', this.opts, this.map ); 665 666 }; 667