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