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