1 /** 2 * Google API v2 implementation for Geo Mashup maps. 3 * @fileOverview 4 */ 5 6 /*global GeoMashup */ 7 /*global customizeGeoMashup, customizeGeoMashupMap, customGeoMashupColorIcon, customGeoMashupCategoryIcon */ 8 /*global customGeoMashupSinglePostIcon, customGeoMashupMultiplePostImage */ 9 /*global jQuery, google, G_DEFAULT_ICON, mxn, ClusterMarker, MarkerClusterer */ 10 /*jslint browser:true, white: true, vars: true, sloppy: true, evil: true */ 11 12 GeoMashup.createTermLine = function ( term_data ) { 13 14 term_data.line = new google.maps.Polyline( term_data.points, term_data.color); 15 16 google.maps.Event.addListener( term_data.line, 'click', function () { 17 GeoMashup.map.zoomIn(); 18 } ); 19 20 this.doAction( 'termLine', term_data.line ); 21 this.doAction( 'categoryLine', GeoMashup.opts, term_data.line ); 22 23 this.map.addOverlay( term_data.line ); 24 25 if ( this.map.getZoom() > term_data.max_line_zoom ) { 26 term_data.line.hide(); 27 } 28 29 }; 30 31 GeoMashup.openMarkerInfoWindow = function( marker, content_node, window_opts ) { 32 var latlng = marker.getLatLng(); 33 this.doAction( 'markerInfoWindowOptions', this.opts, this.locations[latlng], window_opts ); 34 marker.openInfoWindow( content_node, window_opts ); 35 }; 36 37 GeoMashup.loadMaxContent = function( marker, regular_node, info_window_max_url, cache ) { 38 var info_window_max_request = new google.maps.XmlHttp.create(); 39 var request_options = {url: info_window_max_url}; 40 /** 41 * A marker's maximized info window content is being requested. 42 * @name GeoMashup#markerInfoWindowMaxRequest 43 * @event 44 * @param {Marker} marker 45 * @param {AjaxRequestOptions} request_options 46 */ 47 this.doAction( 'markerInfoWindowMaxRequest', marker, request_options ); 48 info_window_max_request.open( 'GET', request_options.url, true ); 49 info_window_max_request.onreadystatechange = function() { 50 var max_node, max_options, filter; 51 if (info_window_max_request.readyState === 4 && info_window_max_request.status === 200 ) { 52 filter = {content: info_window_max_request.responseText}; 53 /** 54 * A marker's maximized info window content is being loaded. 55 * @name GeoMashup#markerInfoWindowMaxLoad 56 * @event 57 * @param {Marker} marker 58 * @param {ContentFilter} filter 59 */ 60 GeoMashup.doAction( 'markerInfoWindowMaxLoad', marker, filter ); 61 max_node = document.createElement( 'div' ); 62 max_node.innerHTML = filter.content; 63 GeoMashup.parentizeLinks( max_node ); 64 cache.info_window_options = {maxContent: max_node}; 65 GeoMashup.openMarkerInfoWindow( marker, regular_node, cache.info_window_options ); 66 } // end max readState === 4 67 }; // end max onreadystatechange function 68 info_window_max_request.send( null ); 69 }; 70 71 GeoMashup.openInfoWindow = function( marker ) { 72 var object_ids, cache_key, cache, i, request_options, info_window_request, object_element, point = marker.getPoint(); 73 74 this.map.closeInfoWindow(); 75 76 object_ids = this.getOnObjectIDs( this.getMarkerObjects( marker ) ); 77 cache_key = 'info-window-' + object_ids.join(','); 78 cache = this.locationCache( point, cache_key ); 79 if ( cache.info_node ) { 80 marker.openInfoWindow( cache.info_node, cache.info_window_options ); 81 } else { 82 marker.openInfoWindowHtml('<div align="center"><img src="' + 83 this.opts.url_path + 84 '/images/busy_icon.gif" alt="Loading..." /></div>'); 85 request_options = { 86 url: this.geo_query_url + '&object_name=' + this.opts.object_name + 87 '&object_ids=' + object_ids.join( ',' ) 88 }; 89 this.doAction( 'markerInfoWindowRequest', marker, request_options ); 90 info_window_request = new google.maps.XmlHttp.create(); 91 info_window_request.open('GET', request_options.url, true); 92 info_window_request.onreadystatechange = function() { 93 var node, info_window_max_request, filter; 94 95 if (info_window_request.readyState === 4 && info_window_request.status === 200) { 96 filter = {content: info_window_request.responseText}; 97 GeoMashup.doAction( 'markerInfoWindowLoad', marker, filter ); 98 node = document.createElement('div'); 99 node.innerHTML = filter.content; 100 GeoMashup.parentizeLinks( node ); 101 cache.info_node = node; 102 if ( 'post' === GeoMashup.opts.object_name ) { 103 GeoMashup.loadMaxContent( marker, node, request_options.url + '&template=info-window-max', cache ); 104 } else { 105 cache.info_window_options = {}; 106 GeoMashup.openMarkerInfoWindow( marker, node, cache.info_window_options ); 107 GeoMashup.doAction( 'loadedInfoWindow' ); 108 } 109 } // end readystate === 4 110 }; // end onreadystatechange function 111 info_window_request.send(null); 112 } // end object not loaded yet 113 }; 114 115 GeoMashup.addGlowMarker = function( marker ) { 116 var glow_icon; 117 118 if ( this.glow_marker ) { 119 this.map.removeOverlay( this.glow_marker ); 120 this.glow_marker.setLatLng( marker.getLatLng() ); 121 } else { 122 glow_icon = new google.maps.Icon( { 123 image : this.opts.url_path + '/images/mm_20_glow.png', 124 iconSize : new google.maps.Size( 22, 30 ), 125 iconAnchor : new google.maps.Point( 11, 27 ) 126 } ); 127 this.doAction( 'glowMarkerIcon', this.opts, glow_icon ); 128 this.glow_marker = new google.maps.Marker( marker.getLatLng(), { 129 clickable : false, 130 icon : glow_icon 131 } ); 132 } 133 this.map.addOverlay( this.glow_marker ); 134 }; 135 136 GeoMashup.removeGlowMarker = function() { 137 this.map.removeOverlay( this.glow_marker ); 138 }; 139 140 GeoMashup.hideAttachments = function() { 141 var i, j, obj; 142 143 for ( i = 0; i < this.open_attachments.length; i += 1 ) { 144 this.map.removeOverlay( this.open_attachments[i] ); 145 } 146 this.open_attachments = []; 147 }; 148 149 GeoMashup.showMarkerAttachments = function( marker ) { 150 var objects; 151 152 this.hideAttachments(); 153 objects = this.getObjectsAtLocation( marker.getLatLng() ); 154 this.forEach( objects, function( i, obj ) { 155 var ajax_params = {action: 'geo_mashup_kml_attachments'}; 156 if ( obj.attachments ) { 157 // Attachment overlays are available 158 this.forEach( obj.attachments, function( j, attachment ) { 159 this.open_attachments.push( attachment ); 160 this.map.addOverlay( attachment ); 161 } ); 162 } else { 163 // Look for attachments 164 obj.attachments = []; 165 ajax_params.post_ids = obj.object_id; 166 jQuery.getJSON( this.opts.ajaxurl + '?callback=?', ajax_params, function( data ) { 167 GeoMashup.forEach( data, function( j, url ) { 168 var geoxml = new google.maps.GeoXml( url ); 169 obj.attachments.push( geoxml ); 170 this.open_attachments.push( geoxml ); 171 this.map.addOverlay( geoxml ); 172 } ); 173 } ); 174 } 175 } ); 176 }; 177 178 GeoMashup.loadFullPost = function( point ) { 179 var i, url, cache, post_request, objects, object_ids, request_options; 180 181 objects = this.getObjectsAtLocation( point ); 182 object_ids = this.getOnObjectIDs( objects ); 183 cache = this.locationCache( point, 'full-post-' + object_ids.join(',') ); 184 if ( cache.post_html ) { 185 this.getShowPostElement().innerHTML = cache.post_html; 186 } else { 187 188 this.getShowPostElement().innerHTML = '<div align="center"><img src="' + 189 this.opts.url_path + '/images/busy_icon.gif" alt="Loading..." /></div>'; 190 request_options = { 191 url: this.geo_query_url + '&object_name=' + this.opts.object_name + 192 '&object_ids=' + object_ids.join( ',' ) + '&template=full-post' 193 }; 194 this.doAction( 'fullPostRequest', objects, request_options ); 195 post_request = new google.maps.XmlHttp.create(); 196 post_request.open('GET', request_options.url, true); 197 post_request.onreadystatechange = function() { 198 var filter; 199 if (post_request.readyState === 4 && post_request.status === 200) { 200 filter = {content: post_request.responseText}; 201 GeoMashup.doAction( 'fullPostLoad', objects, filter ); 202 GeoMashup.getShowPostElement().innerHTML = filter.content; 203 GeoMashup.doAction( 'fullPostChanged' ); 204 cache.post_html = filter.content; 205 } // end readystate === 4 206 }; // end onreadystatechange function 207 post_request.send(null); 208 } 209 }; 210 211 GeoMashup.addObjectIcon = function( obj ) { 212 213 // Back compat 214 if ( typeof customGeoMashupCategoryIcon === 'function' && obj.terms && obj.terms.hasOwnProperty( 'category' ) ) { 215 obj.icon = customGeoMashupCategoryIcon( GeoMashup.opts, obj.terms.category ); 216 } 217 218 if (!obj.icon) { 219 220 221 jQuery.each( obj.terms, function( taxonomy, terms ) { 222 var single_icon; 223 224 if ( terms.length > 1 ) { 225 226 obj.icon = new google.maps.Icon( GeoMashup.multiple_term_icon ); 227 return false; // continue 228 229 } else if ( terms.length === 1 ) { 230 231 single_icon = GeoMashup.term_manager.getTermData( taxonomy, terms[0], 'icon' ); 232 233 if ( obj.icon && obj.icon.image !== single_icon.image ) { 234 235 // We have two different icons in different taxonomies 236 obj.icon = new google.maps.Icon( GeoMashup.multiple_term_icon ); 237 return false; 238 239 } else { 240 241 obj.icon = GeoMashup.clone( single_icon ); 242 243 } 244 245 } 246 247 } ); 248 249 if ( !obj.icon ) { 250 obj.icon = GeoMashup.colorIcon( 'red' ); 251 } 252 253 this.doAction( 'objectIcon', this.opts, obj ); 254 255 } 256 }; 257 258 GeoMashup.createMarker = function( point, obj ) { 259 var marker, 260 // Apersand entities have been added for validity, but look bad in titles 261 marker_opts = {title: obj.title.replace( '&', '&' )}; 262 263 if ( !obj.icon ) { 264 this.addObjectIcon( obj ); 265 } 266 marker_opts.icon = this.clone( obj.icon ); 267 this.doAction( 'objectMarkerOptions', this.opts, marker_opts, obj ); 268 marker = new google.maps.Marker(point,marker_opts); 269 270 google.maps.Event.addListener(marker, 'click', function() { 271 GeoMashup.selectMarker( marker ); 272 }); 273 274 google.maps.Event.addListener( marker, 'remove', function() { 275 if ( GeoMashup.selected_marker && marker === GeoMashup.selected_marker ) { 276 GeoMashup.deselectMarker(); 277 } 278 } ); 279 280 google.maps.Event.addListener( marker, 'visibilitychanged', function( is_visible ) { 281 if ( GeoMashup.selected_marker && marker === GeoMashup.selected_marker && !is_visible ) { 282 GeoMashup.deselectMarker(); 283 } 284 } ); 285 286 this.doAction( 'marker', this.opts, marker ); 287 288 return marker; 289 }; 290 291 GeoMashup.checkDependencies = function () { 292 if (typeof google.maps.Map === 'undefined' || !google.maps.BrowserIsCompatible()) { 293 this.container.innerHTML = '<p class="errormessage">' + 294 'Sorry, the Google Maps script failed to load. Have you entered your ' + 295 '<a href="http://maps.google.com/apis/maps/signup.html">API key<\/a> ' + 296 'in the Geo Mashup Options?'; 297 throw "The Google Maps javascript didn't load."; 298 } 299 }; 300 301 GeoMashup.clickObjectMarker = function(object_id, try_count) { 302 if (typeof try_count === 'undefined') { 303 try_count = 1; 304 } 305 if (this.objects[object_id] && try_count < 4) { 306 if (GeoMashup.objects[object_id].marker.isHidden()) { 307 try_count += 1; 308 setTimeout(function () {GeoMashup.clickObjectMarker(object_id, try_count);}, 300); 309 } else { 310 google.maps.Event.trigger(GeoMashup.objects[object_id].marker,"click"); 311 } 312 } 313 }; 314 315 GeoMashup.colorIcon = function( color_name ) { 316 var icon = new google.maps.Icon(this.base_color_icon); 317 icon.image = this.opts.url_path + '/images/mm_20_' + color_name + '.png'; 318 return icon; 319 }; 320 321 GeoMashup.getMarkerLatLng = function( marker ) { 322 return marker.getLatLng(); 323 }; 324 325 GeoMashup.hideMarker = function( marker ) { 326 if ( marker === this.selected_marker ) { 327 this.deselectMarker(); 328 } 329 marker.hide(); 330 }; 331 332 GeoMashup.showMarker = function( marker ) { 333 marker.show(); 334 }; 335 336 GeoMashup.hideLine = function( line ) { 337 line.hide(); 338 }; 339 340 GeoMashup.showLine = function( line ) { 341 line.show(); 342 }; 343 344 GeoMashup.isLineVisible = function( line ) { 345 return line.isHidden(); 346 }; 347 348 GeoMashup.newLatLng = function( lat, lng ) { 349 return new google.maps.LatLng( lat, lng ); 350 }; 351 352 GeoMashup.extendLocationBounds = function( latlng ) { 353 this.location_bounds.extend( latlng ); 354 }; 355 356 GeoMashup.addMarkers = function( markers ) { 357 // No clustering, or ClusterMarker need the markers added to the map 358 this.forEach( markers, function( i, marker ) { 359 this.map.addOverlay( marker ); 360 } ); 361 if ( this.clusterer && markers.length > 0 ) { 362 this.clusterer.addMarkers( markers ); 363 this.recluster(); 364 } 365 }; 366 367 GeoMashup.makeMarkerMultiple = function( marker ) { 368 var plus_image; 369 if (typeof customGeoMashupMultiplePostImage === 'function') { 370 plus_image = customGeoMashupMultiplePostImage(this.opts, marker.getIcon().image); 371 } 372 if (!plus_image) { 373 plus_image = this.opts.url_path + '/images/mm_20_plus.png'; 374 } 375 if ( marker.getIcon().image !== plus_image ) { 376 // User testing gave best results when both methods of 377 // changing the marker image are used in this order 378 marker.setImage( plus_image ); 379 marker.getIcon().image = plus_image; 380 } 381 this.doAction( 'multiObjectMarker', this.opts, marker ); 382 this.doAction( 'multiObjectIcon', this.opts, marker.getIcon() ); 383 }; 384 385 GeoMashup.setMarkerImage = function( marker, image_url ) { 386 if ( marker.getIcon().image !== image_url ) { 387 marker.setImage( image_url ); 388 marker.getIcon().image = image_url; 389 } 390 }; 391 392 GeoMashup.setCenterUpToMaxZoom = function( latlng, zoom, callback ) { 393 var map_type = this.map.getCurrentMapType(); 394 if ( map_type === google.maps.SATELLITE_MAP || map_type === google.maps.HYBRID_MAP ) { 395 map_type.getMaxZoomAtLatLng( latlng, function( response ) { 396 if ( response && response.status === google.maps.GEO_SUCCESS ) { 397 if ( response.zoom < zoom ) { 398 zoom = response.zoom; 399 } 400 } 401 GeoMashup.map.setCenter( latlng, zoom ); 402 if ( typeof callback === 'function' ) { 403 callback( zoom ); 404 } 405 }, zoom ); 406 } else { 407 // Current map type doesn't have getMaxZoomAtLatLng 408 if ( map_type.getMaximumResolution() < zoom ) { 409 zoom = map_type.getMaximumResolution(); 410 } 411 this.map.setCenter( latlng, zoom ); 412 if ( typeof callback === 'function' ) { 413 callback( zoom ); 414 } 415 } 416 }; 417 418 GeoMashup.autoZoom = function() { 419 var zoom = this.map.getBoundsZoomLevel( this.location_bounds ); 420 var max_zoom = parseInt( this.opts.auto_zoom_max, 10 ); 421 if ( zoom > max_zoom ) { 422 zoom = max_zoom; 423 } 424 this.setCenterUpToMaxZoom( 425 this.location_bounds.getCenter(), 426 zoom, 427 function() {GeoMashup.updateVisibleList();} 428 ); 429 }; 430 431 GeoMashup.centerMarker = function( marker, zoom ) { 432 if ( typeof zoom === 'number' ) { 433 this.map.setCenter( marker.getLatLng(), zoom ); 434 } else { 435 this.map.setCenter( marker.getLatLng() ); 436 } 437 }; 438 439 GeoMashup.requestObjects = function( use_bounds ) { 440 var request, url, map_bounds, map_span; 441 if (this.opts.max_posts && this.object_count >= this.opts.max_posts) { 442 return; 443 } 444 request = google.maps.XmlHttp.create(); 445 url = this.geo_query_url; 446 if (use_bounds) { 447 map_bounds = this.map.getBounds(); 448 map_span = map_bounds.toSpan(); 449 url += '&minlat=' + (map_bounds.getSouthWest().lat() - map_span.lat()) + 450 '&minlon=' + (map_bounds.getSouthWest().lng() - map_span.lng()) + 451 '&maxlat=' + (map_bounds.getSouthWest().lat() + 3*map_span.lat()) + 452 '&maxlon=' + (map_bounds.getSouthWest().lng() + 3*map_span.lat()); 453 } 454 if (this.opts.map_cat) { 455 url += '&cat=' + GeoMashup.opts.map_cat; 456 } 457 if (this.opts.max_posts) { 458 url += '&limit=' + GeoMashup.opts.max_posts; 459 } 460 request.open("GET", url, true); 461 request.onreadystatechange = function() { 462 var objects; 463 464 if (request.readyState === 4 && request.status === 200) { 465 objects = window['eval']( '(' + request.responseText + ')' ); 466 GeoMashup.addObjects(objects,!use_bounds); 467 } // end readystate === 4 468 }; // end onreadystatechange function 469 request.send(null); 470 }; 471 472 GeoMashup.isMarkerVisible = function( marker ) { 473 var map_bounds = this.map.getBounds(); 474 return ( ! marker.isHidden() && map_bounds.containsLatLng( marker.getLatLng() ) ); 475 }; 476 477 GeoMashup.recluster = function( ) { 478 this.clusterer.refresh(); 479 }; 480 481 GeoMashup.createMap = function(container, opts) { 482 var i, type_num, center_latlng, map_opts, map_types, request, url, objects, point, marker_opts, 483 clusterer_opts, google_bar_opts, single_marker, ov, credit_div, initial_zoom = 1, filter = {}; 484 485 this.container = container; 486 this.checkDependencies(); 487 this.base_color_icon = new google.maps.Icon(); 488 this.base_color_icon.image = opts.url_path + '/images/mm_20_black.png'; 489 this.base_color_icon.shadow = opts.url_path + '/images/mm_20_shadow.png'; 490 this.base_color_icon.iconSize = new google.maps.Size(12, 20); 491 this.base_color_icon.shadowSize = new google.maps.Size(22, 20); 492 this.base_color_icon.iconAnchor = new google.maps.Point(6, 20); 493 this.base_color_icon.infoWindowAnchor = new google.maps.Point(5, 1); 494 this.multiple_term_icon = new google.maps.Icon( this.base_color_icon ); 495 this.multiple_term_icon.image = opts.url_path + '/images/mm_20_mixed.png'; 496 497 // Falsify options to make tests simpler 498 this.forEach( opts, function( key, value ) { 499 if ( 'false' === value || 'FALSE' === value ) { 500 opts[key] = false; 501 } 502 } ); 503 504 // See if we have access to a parent frame 505 this.have_parent_access = false; 506 try { 507 if ( typeof parent === 'object' ) { 508 // Try access, throws an exception if prohibited 509 parent.document.getElementById( 'bogus-test' ); 510 // Access worked 511 this.have_parent_access = true; 512 } 513 } catch ( parent_exception ) { } 514 515 // For now, siteurl is the home url 516 opts.home_url = opts.siteurl; 517 518 map_types = { 519 'G_NORMAL_MAP' : google.maps.NORMAL_MAP, 520 'G_SATELLITE_MAP' : google.maps.SATELLITE_MAP, 521 'G_HYBRID_MAP' : google.maps.HYBRID_MAP, 522 'G_PHYSICAL_MAP' : google.maps.PHYSICAL_MAP, 523 'G_SATELLITE_3D_MAP' : google.maps.SATELLITE_3D_MAP 524 }; 525 526 if (typeof opts.map_type === 'string') { 527 if ( map_types[opts.map_type] ) { 528 opts.map_type = map_types[opts.map_type] ; 529 } else { 530 type_num = parseInt(opts.map_type, 10); 531 if (isNaN(type_num)) { 532 opts.map_type = google.maps.NORMAL_MAP; 533 } else { 534 opts.map_type = this.map.getMapTypes()[type_num]; 535 } 536 } 537 } else if (typeof opts.map_type === 'undefined') { 538 opts.map_type = google.maps.NORMAL_MAP; 539 } 540 map_opts = { 541 mapTypes : [ opts.map_type ], 542 googleBarOptions : { 543 adsOptions : {client : opts.adsense_code || 'pub-5088093001880917'} 544 } 545 }; 546 if ( opts.background_color ) { 547 map_opts.backgroundColor = opts.background_color; 548 } 549 this.doAction( 'mapOptions', opts, map_opts ); 550 this.map = new google.maps.Map2( this.container, map_opts ); 551 this.map.setCenter(new google.maps.LatLng(0,0), 0); 552 553 this.doAction( 'newMap', opts, this.map ); 554 555 // Create the loading spinner icon and show it 556 this.spinner_div = document.createElement( 'div' ); 557 this.spinner_div.innerHTML = '<div id="gm-loading-icon" style="-moz-user-select: none; z-index: 100; position: absolute; left: ' + 558 ( this.map.getSize().width / 2 ) + 'px; top: ' + ( this.map.getSize().height / 2 ) + 'px;">' + 559 '<img style="border: 0px none ; margin: 0px; padding: 0px; width: 16px; height: 16px; -moz-user-select: none;" src="' + 560 opts.url_path + '/images/busy_icon.gif"/></a></div>'; 561 this.showLoadingIcon(); 562 google.maps.Event.bind( this.map, 'tilesloaded', this, this.hideLoadingIcon ); 563 564 if (!opts.object_name) { 565 opts.object_name = 'post'; 566 } 567 this.opts = opts; 568 filter.url = opts.siteurl + 569 ( opts.siteurl.indexOf( '?' ) > 0 ? '&' : '?' ) + 570 'geo_mashup_content=geo-query&map_name=' + encodeURIComponent( opts.name ); 571 if ( opts.lang && filter.url.indexOf( 'lang=' ) === -1 ) { 572 filter.url += '&lang=' + encodeURIComponent( opts.lang ); 573 } 574 this.doAction( 'geoQueryUrl', this.opts, filter ); 575 this.geo_query_url = filter.url; 576 577 google.maps.Event.bind(this.map, "zoomend", this, this.adjustZoom); 578 google.maps.Event.bind(this.map, "moveend", this, this.adjustViewport); 579 580 if (opts.cluster_max_zoom) { 581 clusterer_opts = { 582 'iconOptions' : {}, 583 'fitMapMaxZoom' : opts.cluster_max_zoom, 584 'clusterMarkerTitle' : '%count', 585 'intersectPadding' : 3 586 }; 587 /** 588 * <a href="http://googlemapsapi.martinpearman.co.uk/readarticle.php?article_id=4">ClusterMarker</a> 589 * options are being set on a Google v2 map. 590 * 591 * @see markerClustererOptions for Google v3. 592 * @name GeoMashup#clusterOptions 593 * @event 594 * @param {GeoMashupOptions} properties Geo Mashup configuration data 595 * @param {Object} clusterer_opts Modifiable clusterer options for 596 * <a href="http://googlemapsapi.martinpearman.co.uk/readarticle.php?article_id=4">ClusterMarker</a>. 597 */ 598 this.doAction( 'clusterOptions', this.opts, clusterer_opts ); 599 this.clusterer = new ClusterMarker( this.map, clusterer_opts ); 600 } 601 602 if ( opts.zoom !== 'auto' && typeof opts.zoom === 'string' ) { 603 initial_zoom = parseInt(opts.zoom, 10); 604 } else { 605 initial_zoom = opts.zoom; 606 } 607 608 if (opts.load_kml) { 609 this.kml = new google.maps.GeoXml(opts.load_kml); 610 this.map.addOverlay(this.kml); 611 if ( initial_zoom === 'auto' ) { 612 this.kml.gotoDefaultViewport( this.map ); 613 } 614 } 615 616 if ( this.term_manager ) { 617 this.term_manager.load(); 618 } 619 620 if ( initial_zoom !== 'auto' ) { 621 if (opts.center_lat && opts.center_lng) { 622 // Use the center from options 623 this.map.setCenter(new google.maps.LatLng(opts.center_lat, opts.center_lng), initial_zoom, opts.map_type); 624 } else if (this.kml) { 625 google.maps.Event.addListener( this.kml, 'load', function() { 626 GeoMashup.map.setCenter( GeoMashup.kml.getDefaultCenter(), initial_zoom, opts.map_type ); 627 } ); 628 } else if (opts.object_data && opts.object_data.objects[0]) { 629 center_latlng = new google.maps.LatLng(opts.object_data.objects[0].lat, opts.object_data.objects[0].lng); 630 this.map.setCenter(center_latlng, initial_zoom, opts.map_type); 631 } else { 632 // Center on the most recent located object 633 request = google.maps.XmlHttp.create(); 634 url = this.geo_query_url + '&limit=1'; 635 if (opts.map_cat) { 636 url += '&cat='+opts.map_cat; 637 } 638 request.open("GET", url, false); 639 request.send(null); 640 objects = window['eval']( '(' + request.responseText + ')' ); 641 if (objects.length>0) { 642 point = new google.maps.LatLng(objects[0].lat,objects[0].lng); 643 this.map.setCenter(point,initial_zoom,opts.map_type); 644 } else { 645 this.map.setCenter(new google.maps.LatLng(0,0),initial_zoom,opts.map_type); 646 } 647 } 648 } 649 650 this.location_bounds = new google.maps.LatLngBounds(); 651 652 if (opts.map_content === 'single') 653 { 654 if (opts.object_data && opts.object_data.objects.length && !this.kml) 655 { 656 marker_opts = {}; 657 if (typeof customGeoMashupSinglePostIcon === 'function') { 658 marker_opts.icon = customGeoMashupSinglePostIcon(this.opts); 659 } 660 if ( !marker_opts.icon ) { 661 marker_opts.icon = G_DEFAULT_ICON; 662 } 663 this.doAction( 'singleMarkerOptions', this.opts, marker_opts ); 664 single_marker = new google.maps.Marker( 665 new google.maps.LatLng( opts.object_data.objects[0].lat, opts.object_data.objects[0].lng ), marker_opts ); 666 this.map.addOverlay( single_marker ); 667 this.doAction( 'singleMarker', this.opts, single_marker ); 668 } 669 } else if (opts.object_data) { 670 this.addObjects(opts.object_data.objects,true); 671 } else { 672 // Request objects near visible range first 673 this.requestObjects(true); 674 675 // Request all objects 676 this.requestObjects(false); 677 } 678 679 if ('GSmallZoomControl' === opts.map_control) { 680 this.map.addControl(new google.maps.SmallZoomControl()); 681 } else if ('GSmallZoomControl3D' === opts.map_control) { 682 this.map.addControl(new google.maps.SmallZoomControl3D()); 683 } else if ('GSmallMapControl' === opts.map_control) { 684 this.map.addControl(new google.maps.SmallMapControl()); 685 } else if ('GLargeMapControl' === opts.map_control) { 686 this.map.addControl(new google.maps.LargeMapControl()); 687 } else if ('GLargeMapControl3D' === opts.map_control) { 688 this.map.addControl(new google.maps.LargeMapControl3D()); 689 } 690 691 if (opts.add_map_type_control ) { 692 if ( typeof opts.add_map_type_control === 'string' ) { 693 opts.add_map_type_control = opts.add_map_type_control.split(/\s*,\s*/); 694 if ( typeof map_types[opts.add_map_type_control[0]] === 'undefined' ) { 695 // Convert the old boolean value to a default array 696 opts.add_map_type_control = [ 'G_NORMAL_MAP', 'G_SATELLITE_MAP', 'G_PHYSICAL_MAP' ]; 697 } 698 } 699 for ( i = 0; i < opts.add_map_type_control.length; i += 1 ) { 700 this.map.addMapType( map_types[opts.add_map_type_control[i]] ); 701 } 702 this.map.addControl(new google.maps.MapTypeControl()); 703 } 704 705 if (opts.add_overview_control) { 706 this.overview_control = new google.maps.OverviewMapControl(); 707 this.overview_control.setMapType( opts.map_type ); 708 this.doAction( 'overviewControl', this.opts, this.overview_control ); 709 this.map.addControl( this.overview_control ); 710 ov = document.getElementById('gm-overview'); 711 if (ov) { 712 ov.style.position = 'absolute'; 713 this.container.appendChild(ov); 714 } 715 } 716 717 if ( opts.add_google_bar ) { 718 this.map.enableGoogleBar(); 719 } 720 721 if ( opts.enable_scroll_wheel_zoom ) { 722 this.map.enableScrollWheelZoom(); 723 } 724 725 google.maps.Event.addListener( this.map, 'click', function( overlay ) { 726 if ( GeoMashup.selected_marker && ( ! overlay ) ) { 727 GeoMashup.deselectMarker(); 728 } 729 } ); 730 731 if (typeof customizeGeoMashupMap === 'function') { 732 customizeGeoMashupMap(this.opts, this.map); 733 } 734 if (typeof customizeGeoMashup === 'function') { 735 customizeGeoMashup(this); 736 } 737 this.doAction( 'loadedMap', this.opts, this.map ); 738 739 }; 740