vendor: 57,629 bytes, lines 1-2152
1// IMPORTANT: This library is intentionally left out of the js.txt 2// file and is loaded dynamically by SHC.ui.Map 3 4(function(root, factory) { 5 if(typeof exports === 'object') { 6 module.exports = factory(); 7 } 8 else if(typeof define === 'function' && define.amd) { 9 define('GMaps', [], factory); 10 } 11 12 root.GMaps = factory(); 13 14}(this, function() { 15 16/*! 17 * GMaps.js v0.4.16 18 * http://hpneo.github.com/gmaps/ 19 * 20 * Copyright 2014, Gustavo Leon 21 * Released under the MIT License. 22 */ 23 24if (!(typeof window.google === 'object' && window.google.maps)) { 25 throw 'Google Maps API is required. Please register the following JavaScript library http://maps.google.com/maps/api/js?sensor=true.' 26} 27 28var extend_object = function(obj, new_obj) { 29 var name; 30 31 if (obj === new_obj) { 32 return obj; 33 } 34 35 for (name in new_obj) { 36 obj[name] = new_obj[name]; 37 } 38 39 return obj; 40}; 41 42var replace_object = function(obj, replace) { 43 var name; 44 45 if (obj === replace) { 46 return obj; 47 } 48 49 for (name in replace) { 50 if (obj[name] != undefined) { 51 obj[name] = replace[name]; 52 } 53 } 54 55 return obj; 56}; 57 58var array_map = function(array, callback) { 59 var original_callback_params = Array.prototype.slice.call(arguments, 2), 60 array_return = [], 61 array_length = array.length, 62 i; 63 64 if (Array.prototype.map && array.map === Array.prototype.map) { 65 array_return = Array.prototype.map.call(array, function(item) { 66 callback_params = original_callback_params; 67 callback_params.splice(0, 0, item); 68 69 return callback.apply(this, callback_params); 70 }); 71 } 72 else { 73 for (i = 0; i < array_length; i++) { 74 callback_params = original_callback_params; 75 callback_params.splice(0, 0, array[i]); 76 array_return.push(callback.apply(this, callback_params)); 77 } 78 } 79 80 return array_return; 81}; 82 83var array_flat = function(array) { 84 var new_array = [], 85 i; 86 87 for (i = 0; i < array.length; i++) { 88 new_array = new_array.concat(array[i]); 89 } 90 91 return new_array; 92}; 93 94var coordsToLatLngs = function(coords, useGeoJSON) { 95 var first_coord = coords[0], 96 second_coord = coords[1]; 97 98 if (useGeoJSON) { 99 first_coord = coords[1]; 100 second_coord = coords[0]; 101 } 102 103 return new google.maps.LatLng(first_coord, second_coord); 104}; 105 106var arrayToLatLng = function(coords, useGeoJSON) { 107 var i; 108 109 for (i = 0; i < coords.length; i++) { 110 if (!(coords[i] instanceof google.maps.LatLng)) { 111 if (coords[i].length > 0 && typeof(coords[i][0]) == "object") { 112 coords[i] = arrayToLatLng(coords[i], useGeoJSON); 113 } 114 else { 115 coords[i] = coordsToLatLngs(coords[i], useGeoJSON); 116 } 117 } 118 } 119 120 return coords; 121}; 122 123var getElementById = function(id, context) { 124 var element, 125 id = id.replace('#', ''); 126 127 if ('jQuery' in this && context) { 128 element = $("#" + id, context)[0]; 129 } else { 130 element = document.getElementById(id); 131 }; 132 133 return element; 134}; 135 136var findAbsolutePosition = function(obj) { 137 var curleft = 0, 138 curtop = 0; 139 140 if (obj.offsetParent) { 141 do { 142 curleft += obj.offsetLeft; 143 curtop += obj.offsetTop; 144 } while (obj = obj.offsetParent); 145 } 146 147 return [curleft, curtop]; 148}; 149 150var GMaps = (function(global) { 151 "use strict"; 152 153 var doc = document; 154 155 var GMaps = function(options) { 156 if (!this) return new GMaps(options); 157 158 options.zoom = options.zoom || 15; 159 options.mapType = options.mapType || 'roadmap'; 160 161 var self = this, 162 i, 163 events_that_hide_context_menu = ['bounds_changed', 'center_changed', 'click', 'dblclick', 'drag', 'dragend', 'dragstart', 'idle', 'maptypeid_changed', 'projection_changed', 'resize', 'tilesloaded', 'zoom_changed'], 164 events_that_doesnt_hide_context_menu = ['mousemove', 'mouseout', 'mouseover'], 165 options_to_be_deleted = ['el', 'lat', 'lng', 'mapType', 'width', 'height', 'markerClusterer', 'enableNewStyle'], 166 container_id = options.el || options.div, 167 markerClustererFunction = options.markerClusterer, 168 mapType = google.maps.MapTypeId[options.mapType.toUpperCase()], 169 map_center = new google.maps.LatLng(options.lat, options.lng), 170 zoomControl = options.zoomControl || true, 171 zoomControlOpt = options.zoomControlOpt || { 172 style: 'DEFAULT', 173 position: 'TOP_LEFT' 174 }, 175 zoomControlStyle = zoomControlOpt.style || 'DEFAULT', 176 zoomControlPosition = zoomControlOpt.position || 'TOP_LEFT', 177 panControl = options.panControl || true, 178 mapTypeControl = options.mapTypeControl || true, 179 scaleControl = options.scaleControl || true, 180 streetViewControl = options.streetViewControl || true, 181 overviewMapControl = overviewMapControl || true, 182 map_options = {}, 183 map_base_options = { 184 zoom: this.zoom, 185 center: map_center, 186 mapTypeId: mapType 187 }, 188 map_controls_options = { 189 panControl: panControl, 190 zoomControl: zoomControl, 191 zoomControlOptions: { 192 style: google.maps.ZoomControlStyle[zoomControlStyle], 193 position: google.maps.ControlPosition[zoomControlPosition] 194 }, 195 mapTypeControl: mapTypeControl, 196 scaleControl: scaleControl, 197 streetViewControl: streetViewControl, 198 overviewMapControl: overviewMapControl 199 }; 200 201 if (typeof(options.el) === 'string' || typeof(options.div) === 'string') { 202 this.el = getElementById(container_id, options.context); 203 } else { 204 this.el = container_id; 205 } 206 207 if (typeof(this.el) === 'undefined' || this.el === null) { 208 throw 'No element defined.'; 209 } 210 211 window.context_menu = window.context_menu || {}; 212 window.context_menu[self.el.id] = {}; 213 214 this.controls = []; 215 this.overlays = []; 216 this.layers = []; // array with kml/georss and fusiontables layers, can be as many 217 this.singleLayers = {}; // object with the other layers, only one per layer 218 this.markers = []; 219 this.polylines = []; 220 this.routes = []; 221 this.polygons = []; 222 this.infoWindow = null; 223 this.overlay_el = null; 224 this.zoom = options.zoom; 225 this.registered_events = {}; 226 227 this.el.style.width = options.width || this.el.scrollWidth || this.el.offsetWidth; 228 this.el.style.height = options.height || this.el.scrollHeight || this.el.offsetHeight; 229 230 google.maps.visualRefresh = options.enableNewStyle; 231 232 for (i = 0; i < options_to_be_deleted.length; i++) { 233 delete options[options_to_be_deleted[i]]; 234 } 235 236 if(options.disableDefaultUI != true) { 237 map_base_options = extend_object(map_base_options, map_controls_options); 238 } 239 240 map_options = extend_object(map_base_options, options); 241 242 for (i = 0; i < events_that_hide_context_menu.length; i++) { 243 delete map_options[events_that_hide_context_menu[i]]; 244 } 245 246 for (i = 0; i < events_that_doesnt_hide_context_menu.length; i++) { 247 delete map_options[events_that_doesnt_hide_context_menu[i]]; 248 } 249 250 this.map = new google.maps.Map(this.el, map_options); 251 252 if (markerClustererFunction) { 253 this.markerClusterer = markerClustererFunction.apply(this, [this.map]); 254 } 255 256 var buildContextMenuHTML = function(control, e) { 257 var html = '', 258 options = window.context_menu[self.el.id][control]; 259 260 for (var i in options){ 261 if (options.hasOwnProperty(i)) { 262 var option = options[i]; 263 264 html += '<li><a id="' + control + '_' + i + '" href="#">' + option.title + '</a></li>'; 265 } 266 } 267 268 if (!getElementById('gmaps_context_menu')) return; 269 270 var context_menu_element = getElementById('gmaps_context_menu'); 271 272 context_menu_element.innerHTML = html; 273 274 var context_menu_items = context_menu_element.getElementsByTagName('a'), 275 context_menu_items_count = context_menu_items.length, 276 i; 277 278 for (i = 0; i < context_menu_items_count; i++) { 279 var context_menu_item = context_menu_items[i]; 280 281 var assign_menu_item_action = function(ev){ 282 ev.preventDefault(); 283 284 options[this.id.replace(control + '_', '')].action.apply(self, [e]); 285 self.hideContextMenu(); 286 }; 287 288 google.maps.event.clearListeners(context_menu_item, 'click'); 289 google.maps.event.addDomListenerOnce(context_menu_item, 'click', assign_menu_item_action, false); 290 } 291 292 var position = findAbsolutePosition.apply(this, [self.el]), 293 left = position[0] + e.pixel.x - 15, 294 top = position[1] + e.pixel.y- 15; 295 296 context_menu_element.style.left = left + "px"; 297 context_menu_element.style.top = top + "px"; 298 299 context_menu_element.style.display = 'block'; 300 }; 301 302 this.buildContextMenu = function(control, e) { 303 if (control === 'marker') { 304 e.pixel = {}; 305 306 var overlay = new google.maps.OverlayView(); 307 overlay.setMap(self.map); 308 309 overlay.draw = function() { 310 var projection = overlay.getProjection(), 311 position = e.marker.getPosition(); 312 313 e.pixel = projection.fromLatLngToContainerPixel(position); 314 315 buildContextMenuHTML(control, e); 316 }; 317 } 318 else { 319 buildContextMenuHTML(control, e); 320 } 321 }; 322 323 this.setContextMenu = function(options) { 324 window.context_menu[self.el.id][options.control] = {}; 325 326 var i, 327 ul = doc.createElement('ul'); 328 329 for (i in options.options) { 330 if (options.options.hasOwnProperty(i)) { 331 var option = options.options[i]; 332 333 window.context_menu[self.el.id][options.control][option.name] = { 334 title: option.title, 335 action: option.action 336 }; 337 } 338 } 339 340 ul.id = 'gmaps_context_menu'; 341 ul.style.display = 'none'; 342 ul.style.position = 'absolute'; 343 ul.style.minWidth = '100px'; 344 ul.style.background = 'white'; 345 ul.style.listStyle = 'none'; 346 ul.style.padding = '8px'; 347 ul.style.boxShadow = '2px 2px 6px #ccc'; 348 349 doc.body.appendChild(ul); 350 351 var context_menu_element = getElementById('gmaps_context_menu') 352 353 google.maps.event.addDomListener(context_menu_element, 'mouseout', function(ev) { 354 if (!ev.relatedTarget || !this.contains(ev.relatedTarget)) { 355 window.setTimeout(function(){ 356 context_menu_element.style.display = 'none'; 357 }, 400); 358 } 359 }, false); 360 }; 361 362 this.hideContextMenu = function() { 363 var context_menu_element = getElementById('gmaps_context_menu'); 364 365 if (context_menu_element) { 366 context_menu_element.style.display = 'none'; 367 } 368 }; 369 370 var setupListener = function(object, name) { 371 google.maps.event.addListener(object, name, function(e){ 372 if (e == undefined) { 373 e = this; 374 } 375 376 options[name].apply(this, [e]); 377 378 self.hideContextMenu(); 379 }); 380 }; 381 382 //google.maps.event.addListener(this.map, 'idle', this.hideContextMenu); 383 google.maps.event.addListener(this.map, 'zoom_changed', this.hideContextMenu); 384 385 for (var ev = 0; ev < events_that_hide_context_menu.length; ev++) { 386 var name = events_that_hide_context_menu[ev]; 387 388 if (name in options) { 389 setupListener(this.map, name); 390 } 391 } 392 393 for (var ev = 0; ev < events_that_doesnt_hide_context_menu.length; ev++) { 394 var name = events_that_doesnt_hide_context_menu[ev]; 395 396 if (name in options) { 397 setupListener(this.map, name); 398 } 399 } 400 401 google.maps.event.addListener(this.map, 'rightclick', function(e) { 402 if (options.rightclick) { 403 options.rightclick.apply(this, [e]); 404 } 405 406 if(window.context_menu[self.el.id]['map'] != undefined) { 407 self.buildContextMenu('map', e); 408 } 409 }); 410 411 this.refresh = function() { 412 google.maps.event.trigger(this.map, 'resize'); 413 }; 414 415 this.fitZoom = function() { 416 var latLngs = [], 417 markers_length = this.markers.length, 418 i; 419 420 for (i = 0; i < markers_length; i++) { 421 if(typeof(this.markers[i].visible) === 'boolean' && this.markers[i].visible) { 422 latLngs.push(this.markers[i].getPosition()); 423 } 424 } 425 426 this.fitLatLngBounds(latLngs); 427 }; 428 429 this.fitLatLngBounds = function(latLngs) { 430 var total = latLngs.length; 431 var bounds = new google.maps.LatLngBounds(); 432 433 for(var i=0; i < total; i++) { 434 bounds.extend(latLngs[i]); 435 } 436 437 this.map.fitBounds(bounds); 438 }; 439 440 this.setCenter = function(lat, lng, callback) { 441 this.map.panTo(new google.maps.LatLng(lat, lng)); 442 443 if (callback) { 444 callback(); 445 } 446 }; 447 448 this.getElement = function() { 449 return this.el; 450 }; 451 452 this.zoomIn = function(value) { 453 value = value || 1; 454 455 this.zoom = this.map.getZoom() + value; 456 this.map.setZoom(this.zoom); 457 }; 458 459 this.zoomOut = function(value) { 460 value = value || 1; 461 462 this.zoom = this.map.getZoom() - value; 463 this.map.setZoom(this.zoom); 464 }; 465 466 var native_methods = [], 467 method; 468 469 for (method in this.map) { 470 if (typeof(this.map[method]) == 'function' && !this[method]) { 471 native_methods.push(method); 472 } 473 } 474 475 for (i=0; i < native_methods.length; i++) { 476 (function(gmaps, scope, method_name) { 477 gmaps[method_name] = function(){ 478 return scope[method_name].apply(scope, arguments); 479 }; 480 })(this, this.map, native_methods[i]); 481 } 482 }; 483 484 return GMaps; 485})(this); 486 487GMaps.prototype.createControl = function(options) { 488 var control = document.createElement('div'); 489 490 control.style.cursor = 'pointer'; 491 492 if (options.disableDefaultStyles !== true) { 493 control.style.fontFamily = 'Roboto, Arial, sans-serif'; 494 control.style.fontSize = '11px'; 495 control.style.boxShadow = 'rgba(0, 0, 0, 0.298039) 0px 1px 4px -1px'; 496 } 497 498 for (var option in options.style) { 499 control.style[option] = options.style[option]; 500 } 501 502 if (options.id) { 503 control.id = options.id; 504 } 505 506 if (options.classes) { 507 control.className = options.classes; 508 } 509 510 if (options.content) { 511 if (typeof options.content === 'string') { 512 control.innerHTML = options.content; 513 } 514 else if (options.content instanceof HTMLElement) { 515 control.appendChild(options.content); 516 } 517 } 518 519 if (options.position) { 520 control.position = google.maps.ControlPosition[options.position.toUpperCase()]; 521 } 522 523 for (var ev in options.events) { 524 (function(object, name) { 525 google.maps.event.addDomListener(object, name, function(){ 526 options.events[name].apply(this, [this]); 527 }); 528 })(control, ev); 529 } 530 531 control.index = 1; 532 533 return control; 534}; 535 536GMaps.prototype.addControl = function(options) { 537 var control = this.createControl(options); 538 this.controls.push(control); 539 this.map.controls[control.position].push(control); 540 541 return control; 542}; 543 544GMaps.prototype.removeControl = function(control) { 545 var position = null; 546 547 for (var i = 0; i < this.controls.length; i++) { 548 if (this.controls[i] == control) { 549 position = this.controls[i].position; 550 this.controls.splice(i, 1); 551 } 552 } 553 554 if (position) { 555 for (i = 0; i < this.map.controls.length; i++) { 556 var controlsForPosition = this.map.controls[control.position] 557 if (controlsForPosition.getAt(i) == control) { 558 controlsForPosition.removeAt(i); 559 break; 560 } 561 } 562 } 563 564 return control; 565}; 566 567GMaps.prototype.createMarker = function(options) { 568 if (options.lat == undefined && options.lng == undefined && options.position == undefined) { 569 throw 'No latitude or longitude defined.'; 570 } 571 572 var self = this, 573 details = options.details, 574 fences = options.fences, 575 outside = options.outside, 576 base_options = { 577 position: new google.maps.LatLng(options.lat, options.lng), 578 map: null 579 }, 580 marker_options = extend_object(base_options, options); 581 582 delete marker_options.lat; 583 delete marker_options.lng; 584 delete marker_options.fences; 585 delete marker_options.outside; 586 587 var marker = new google.maps.Marker(marker_options); 588 589 marker.fences = fences; 590 591 if (options.infoWindow) { 592 marker.infoWindow = new google.maps.InfoWindow(options.infoWindow); 593 594 var info_window_events = ['closeclick', 'content_changed', 'domready', 'position_changed', 'zindex_changed']; 595 596 for (var ev = 0; ev < info_window_events.length; ev++) { 597 (function(object, name) { 598 if (options.infoWindow[name]) { 599 google.maps.event.addListener(object, name, function(e){ 600 options.infoWindow[name].apply(this, [e]); 601 }); 602 } 603 })(marker.infoWindow, info_window_events[ev]); 604 } 605 } 606 607 var marker_events = ['animation_changed', 'clickable_changed', 'cursor_changed', 'draggable_changed', 'flat_changed', 'icon_changed', 'position_changed', 'shadow_changed', 'shape_changed', 'title_changed', 'visible_changed', 'zindex_changed']; 608 609 var marker_events_with_mouse = ['dblclick', 'drag', 'dragend', 'dragstart', 'mousedown', 'mouseout', 'mouseover', 'mouseup']; 610 611 for (var ev = 0; ev < marker_events.length; ev++) { 612 (function(object, name) { 613 if (options[name]) { 614 google.maps.event.addListener(object, name, function(){ 615 options[name].apply(this, [this]); 616 }); 617 } 618 })(marker, marker_events[ev]); 619 } 620 621 for (var ev = 0; ev < marker_events_with_mouse.length; ev++) { 622 (function(map, object, name) { 623 if (options[name]) { 624 google.maps.event.addListener(object, name, function(me){ 625 if(!me.pixel){ 626 me.pixel = map.getProjection().fromLatLngToPoint(me.latLng) 627 } 628 629 options[name].apply(this, [me]); 630 }); 631 } 632 })(this.map, marker, marker_events_with_mouse[ev]); 633 } 634 635 google.maps.event.addListener(marker, 'click', function() { 636 this.details = details; 637 638 if (options.click) { 639 options.click.apply(this, [this]); 640 } 641 642 if (marker.infoWindow) { 643 self.hideInfoWindows(); 644 marker.infoWindow.open(self.map, marker); 645 } 646 }); 647 648 google.maps.event.addListener(marker, 'rightclick', function(e) { 649 e.marker = this; 650 651 if (options.rightclick) { 652 options.rightclick.apply(this, [e]); 653 } 654 655 if (window.context_menu[self.el.id]['marker'] != undefined) { 656 self.buildContextMenu('marker', e); 657 } 658 }); 659 660 if (marker.fences) { 661 google.maps.event.addListener(marker, 'dragend', function() { 662 self.checkMarkerGeofence(marker, function(m, f) { 663 outside(m, f); 664 }); 665 }); 666 } 667 668 return marker; 669}; 670 671GMaps.prototype.addMarker = function(options) { 672 var marker; 673 if(options.hasOwnProperty('gm_accessors_')) { 674 // Native google.maps.Marker object 675 marker = options; 676 } 677 else { 678 if ((options.hasOwnProperty('lat') && options.hasOwnProperty('lng')) || options.position) { 679 marker = this.createMarker(options); 680 } 681 else { 682 throw 'No latitude or longitude defined.'; 683 } 684 } 685 686 marker.setMap(this.map); 687 688 if(this.markerClusterer) { 689 this.markerClusterer.addMarker(marker); 690 } 691 692 this.markers.push(marker); 693 694 GMaps.fire('marker_added', marker, this); 695 696 return marker; 697}; 698 699GMaps.prototype.addMarkers = function(array) { 700 for (var i = 0, marker; marker=array[i]; i++) { 701 this.addMarker(marker); 702 } 703 704 return this.markers; 705}; 706 707GMaps.prototype.hideInfoWindows = function() { 708 for (var i = 0, marker; marker = this.markers[i]; i++){ 709 if (marker.infoWindow) { 710 marker.infoWindow.close(); 711 } 712 } 713}; 714 715GMaps.prototype.removeMarker = function(marker) { 716 for (var i = 0; i < this.markers.length; i++) { 717 if (this.markers[i] === marker) { 718 this.markers[i].setMap(null); 719 this.markers.splice(i, 1); 720 721 if(this.markerClusterer) { 722 this.markerClusterer.removeMarker(marker); 723 } 724 725 GMaps.fire('marker_removed', marker, this); 726 727 break; 728 } 729 } 730 731 return marker; 732}; 733 734GMaps.prototype.removeMarkers = function (collection) { 735 var new_markers = []; 736 737 if (typeof collection == 'undefined') { 738 for (var i = 0; i < this.markers.length; i++) { 739 var marker = this.markers[i]; 740 marker.setMap(null); 741 742 if(this.markerClusterer) { 743 this.markerClusterer.removeMarker(marker); 744 } 745 746 GMaps.fire('marker_removed', marker, this); 747 } 748 749 this.markers = new_markers; 750 } 751 else { 752 for (var i = 0; i < collection.length; i++) { 753 var index = this.markers.indexOf(collection[i]); 754 755 if (index > -1) { 756 var marker = this.markers[index]; 757 marker.setMap(null); 758 759 if(this.markerClusterer) { 760 this.markerClusterer.removeMarker(marker); 761 } 762 763 GMaps.fire('marker_removed', marker, this); 764 } 765 } 766 767 for (var i = 0; i < this.markers.length; i++) { 768 var marker = this.markers[i]; 769 if (marker.getMap() != null) { 770 new_markers.push(marker); 771 } 772 } 773 774 this.markers = new_markers; 775 } 776}; 777 778GMaps.prototype.drawOverlay = function(options) { 779 var overlay = new google.maps.OverlayView(), 780 auto_show = true; 781 782 overlay.setMap(this.map); 783 784 if (options.auto_show != null) { 785 auto_show = options.auto_show; 786 } 787 788 overlay.onAdd = function() { 789 var el = document.createElement('div'); 790 791 el.style.borderStyle = "none"; 792 el.style.borderWidth = "0px"; 793 el.style.position = "absolute"; 794 el.style.zIndex = 100; 795 el.innerHTML = options.content; 796 797 overlay.el = el; 798 799 if (!options.layer) { 800 options.layer = 'overlayLayer'; 801 } 802 803 var panes = this.getPanes(), 804 overlayLayer = panes[options.layer], 805 stop_overlay_events = ['contextmenu', 'DOMMouseScroll', 'dblclick', 'mousedown']; 806 807 overlayLayer.appendChild(el); 808 809 for (var ev = 0; ev < stop_overlay_events.length; ev++) { 810 (function(object, name) { 811 google.maps.event.addDomListener(object, name, function(e){ 812 if (navigator.userAgent.toLowerCase().indexOf('msie') != -1 && document.all) { 813 e.cancelBubble = true; 814 e.returnValue = false; 815 } 816 else { 817 e.stopPropagation(); 818 } 819 }); 820 })(el, stop_overlay_events[ev]); 821 } 822 823 if (options.click) { 824 panes.overlayMouseTarget.appendChild(overlay.el); 825 google.maps.event.addDomListener(overlay.el, 'click', function() { 826 options.click.apply(overlay, [overlay]); 827 }); 828 } 829 830 google.maps.event.trigger(this, 'ready'); 831 }; 832 833 overlay.draw = function() { 834 var projection = this.getProjection(), 835 pixel = projection.fromLatLngToDivPixel(new google.maps.LatLng(options.lat, options.lng)); 836 837 options.horizontalOffset = options.horizontalOffset || 0; 838 options.verticalOffset = options.verticalOffset || 0; 839 840 var el = overlay.el, 841 content = el.children[0], 842 content_height = content.clientHeight, 843 content_width = content.clientWidth; 844 845 switch (options.verticalAlign) { 846 case 'top': 847 el.style.top = (pixel.y - content_height + options.verticalOffset) + 'px'; 848 break; 849 default: 850 case 'middle': 851 el.style.top = (pixel.y - (content_height / 2) + options.verticalOffset) + 'px'; 852 break; 853 case 'bottom': 854 el.style.top = (pixel.y + options.verticalOffset) + 'px'; 855 break; 856 } 857 858 switch (options.horizontalAlign) { 859 case 'left': 860 el.style.left = (pixel.x - content_width + options.horizontalOffset) + 'px'; 861 break; 862 default: 863 case 'center': 864 el.style.left = (pixel.x - (content_width / 2) + options.horizontalOffset) + 'px'; 865 break; 866 case 'right': 867 el.style.left = (pixel.x + options.horizontalOffset) + 'px'; 868 break; 869 } 870 871 el.style.display = auto_show ? 'block' : 'none'; 872 873 if (!auto_show) { 874 options.show.apply(this, [el]); 875 } 876 }; 877 878 overlay.onRemove = function() { 879 var el = overlay.el; 880 881 if (options.remove) { 882 options.remove.apply(this, [el]); 883 } 884 else { 885 overlay.el.parentNode.removeChild(overlay.el); 886 overlay.el = null; 887 } 888 }; 889 890 this.overlays.push(overlay); 891 return overlay; 892}; 893 894GMaps.prototype.removeOverlay = function(overlay) { 895 for (var i = 0; i < this.overlays.length; i++) { 896 if (this.overlays[i] === overlay) { 897 this.overlays[i].setMap(null); 898 this.overlays.splice(i, 1); 899 900 break; 901 } 902 } 903}; 904 905GMaps.prototype.removeOverlays = function() { 906 for (var i = 0, item; item = this.overlays[i]; i++) { 907 item.setMap(null); 908 } 909 910 this.overlays = []; 911}; 912 913GMaps.prototype.drawPolyline = function(options) { 914 var path = [], 915 points = options.path; 916 917 if (points.length) { 918 if (points[0][0] === undefined) { 919 path = points; 920 } 921 else { 922 for (var i=0, latlng; latlng=points[i]; i++) { 923 path.push(new google.maps.LatLng(latlng[0], latlng[1])); 924 } 925 } 926 } 927 928 var polyline_options = { 929 map: this.map, 930 path: path, 931 strokeColor: options.strokeColor, 932 strokeOpacity: options.strokeOpacity, 933 strokeWeight: options.strokeWeight, 934 geodesic: options.geodesic, 935 clickable: true, 936 editable: false, 937 visible: true 938 }; 939 940 if (options.hasOwnProperty("clickable")) { 941 polyline_options.clickable = options.clickable; 942 } 943 944 if (options.hasOwnProperty("editable")) { 945 polyline_options.editable = options.editable; 946 } 947 948 if (options.hasOwnProperty("icons")) { 949 polyline_options.icons = options.icons; 950 } 951 952 if (options.hasOwnProperty("zIndex")) { 953 polyline_options.zIndex = options.zIndex; 954 } 955 956 var polyline = new google.maps.Polyline(polyline_options); 957 958 var polyline_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick']; 959 960 for (var ev = 0; ev < polyline_events.length; ev++) { 961 (function(object, name) { 962 if (options[name]) { 963 google.maps.event.addListener(object, name, function(e){ 964 options[name].apply(this, [e]); 965 }); 966 } 967 })(polyline, polyline_events[ev]); 968 } 969 970 this.polylines.push(polyline); 971 972 GMaps.fire('polyline_added', polyline, this); 973 974 return polyline; 975}; 976 977GMaps.prototype.removePolyline = function(polyline) { 978 for (var i = 0; i < this.polylines.length; i++) { 979 if (this.polylines[i] === polyline) { 980 this.polylines[i].setMap(null); 981 this.polylines.splice(i, 1); 982 983 GMaps.fire('polyline_removed', polyline, this); 984 985 break; 986 } 987 } 988}; 989 990GMaps.prototype.removePolylines = function() { 991 for (var i = 0, item; item = this.polylines[i]; i++) { 992 item.setMap(null); 993 } 994 995 this.polylines = []; 996}; 997 998GMaps.prototype.drawCircle = function(options) { 999 options = extend_object({ 1000 map: this.map, 1001 center: new google.maps.LatLng(options.lat, options.lng) 1002 }, options); 1003 1004 delete options.lat; 1005 delete options.lng; 1006 1007 var polygon = new google.maps.Circle(options), 1008 polygon_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick']; 1009 1010 for (var ev = 0; ev < polygon_events.length; ev++) { 1011 (function(object, name) { 1012 if (options[name]) { 1013 google.maps.event.addListener(object, name, function(e){ 1014 options[name].apply(this, [e]); 1015 }); 1016 } 1017 })(polygon, polygon_events[ev]); 1018 } 1019 1020 this.polygons.push(polygon); 1021 1022 return polygon; 1023}; 1024 1025GMaps.prototype.drawRectangle = function(options) { 1026 options = extend_object({ 1027 map: this.map 1028 }, options); 1029 1030 var latLngBounds = new google.maps.LatLngBounds( 1031 new google.maps.LatLng(options.bounds[0][0], options.bounds[0][1]), 1032 new google.maps.LatLng(options.bounds[1][0], options.bounds[1][1]) 1033 ); 1034 1035 options.bounds = latLngBounds; 1036 1037 var polygon = new google.maps.Rectangle(options), 1038 polygon_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick']; 1039 1040 for (var ev = 0; ev < polygon_events.length; ev++) { 1041 (function(object, name) { 1042 if (options[name]) { 1043 google.maps.event.addListener(object, name, function(e){ 1044 options[name].apply(this, [e]); 1045 }); 1046 } 1047 })(polygon, polygon_events[ev]); 1048 } 1049 1050 this.polygons.push(polygon); 1051 1052 return polygon; 1053}; 1054 1055GMaps.prototype.drawPolygon = function(options) { 1056 var useGeoJSON = false; 1057 1058 if(options.hasOwnProperty("useGeoJSON")) { 1059 useGeoJSON = options.useGeoJSON; 1060 } 1061 1062 delete options.useGeoJSON; 1063 1064 options = extend_object({ 1065 map: this.map 1066 }, options); 1067 1068 if (useGeoJSON == false) { 1069 options.paths = [options.paths.slice(0)]; 1070 } 1071 1072 if (options.paths.length > 0) { 1073 if (options.paths[0].length > 0) { 1074 options.paths = array_flat(array_map(options.paths, arrayToLatLng, useGeoJSON)); 1075 } 1076 } 1077 1078 var polygon = new google.maps.Polygon(options), 1079 polygon_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick']; 1080 1081 for (var ev = 0; ev < polygon_events.length; ev++) { 1082 (function(object, name) { 1083 if (options[name]) { 1084 google.maps.event.addListener(object, name, function(e){ 1085 options[name].apply(this, [e]); 1086 }); 1087 } 1088 })(polygon, polygon_events[ev]); 1089 } 1090 1091 this.polygons.push(polygon); 1092 1093 GMaps.fire('polygon_added', polygon, this); 1094 1095 return polygon; 1096}; 1097 1098GMaps.prototype.removePolygon = function(polygon) { 1099 for (var i = 0; i < this.polygons.length; i++) { 1100 if (this.polygons[i] === polygon) { 1101 this.polygons[i].setMap(null); 1102 this.polygons.splice(i, 1); 1103 1104 GMaps.fire('polygon_removed', polygon, this); 1105 1106 break; 1107 } 1108 } 1109}; 1110 1111GMaps.prototype.removePolygons = function() { 1112 for (var i = 0, item; item = this.polygons[i]; i++) { 1113 item.setMap(null); 1114 } 1115 1116 this.polygons = []; 1117}; 1118 1119GMaps.prototype.getFromFusionTables = function(options) { 1120 var events = options.events; 1121 1122 delete options.events; 1123 1124 var fusion_tables_options = options, 1125 layer = new google.maps.FusionTablesLayer(fusion_tables_options); 1126 1127 for (var ev in events) { 1128 (function(object, name) { 1129 google.maps.event.addListener(object, name, function(e) { 1130 events[name].apply(this, [e]); 1131 }); 1132 })(layer, ev); 1133 } 1134 1135 this.layers.push(layer); 1136 1137 return layer; 1138}; 1139 1140GMaps.prototype.loadFromFusionTables = function(options) { 1141 var layer = this.getFromFusionTables(options); 1142 layer.setMap(this.map); 1143 1144 return layer; 1145}; 1146 1147GMaps.prototype.getFromKML = function(options) { 1148 var url = options.url, 1149 events = options.events; 1150 1151 delete options.url; 1152 delete options.events; 1153 1154 var kml_options = options, 1155 layer = new google.maps.KmlLayer(url, kml_options); 1156 1157 for (var ev in events) { 1158 (function(object, name) { 1159 google.maps.event.addListener(object, name, function(e) { 1160 events[name].apply(this, [e]); 1161 }); 1162 })(layer, ev); 1163 } 1164 1165 this.layers.push(layer); 1166 1167 return layer; 1168}; 1169 1170GMaps.prototype.loadFromKML = function(options) { 1171 var layer = this.getFromKML(options); 1172 layer.setMap(this.map); 1173 1174 return layer; 1175}; 1176 1177GMaps.prototype.addLayer = function(layerName, options) { 1178 //var default_layers = ['weather', 'clouds', 'traffic', 'transit', 'bicycling', 'panoramio', 'places']; 1179 options = options || {}; 1180 var layer; 1181 1182 switch(layerName) { 1183 case 'weather': this.singleLayers.weather = layer = new google.maps.weather.WeatherLayer(); 1184 break; 1185 case 'clouds': this.singleLayers.clouds = layer = new google.maps.weather.CloudLayer(); 1186 break; 1187 case 'traffic': this.singleLayers.traffic = layer = new google.maps.TrafficLayer(); 1188 break; 1189 case 'transit': this.singleLayers.transit = layer = new google.maps.TransitLayer(); 1190 break; 1191 case 'bicycling': this.singleLayers.bicycling = layer = new google.maps.BicyclingLayer(); 1192 break; 1193 case 'panoramio': 1194 this.singleLayers.panoramio = layer = new google.maps.panoramio.PanoramioLayer(); 1195 layer.setTag(options.filter); 1196 delete options.filter; 1197 1198 //click event 1199 if (options.click) { 1200 google.maps.event.addListener(layer, 'click', function(event) { 1201 options.click(event); 1202 delete options.click; 1203 }); 1204 } 1205 break; 1206 case 'places': 1207 this.singleLayers.places = layer = new google.maps.places.PlacesService(this.map); 1208 1209 //search, nearbySearch, radarSearch callback, Both are the same 1210 if (options.search || options.nearbySearch || options.radarSearch) { 1211 var placeSearchRequest = { 1212 bounds : options.bounds || null, 1213 keyword : options.keyword || null, 1214 location : options.location || null, 1215 name : options.name || null, 1216 radius : options.radius || null, 1217 rankBy : options.rankBy || null, 1218 types : options.types || null 1219 }; 1220 1221 if (options.radarSearch) { 1222 layer.radarSearch(placeSearchRequest, options.radarSearch); 1223 } 1224 1225 if (options.search) { 1226 layer.search(placeSearchRequest, options.search); 1227 } 1228 1229 if (options.nearbySearch) { 1230 layer.nearbySearch(placeSearchRequest, options.nearbySearch); 1231 } 1232 } 1233 1234 //textSearch callback 1235 if (options.textSearch) { 1236 var textSearchRequest = { 1237 bounds : options.bounds || null, 1238 location : options.location || null, 1239 query : options.query || null, 1240 radius : options.radius || null 1241 }; 1242 1243 layer.textSearch(textSearchRequest, options.textSearch); 1244 } 1245 break; 1246 } 1247 1248 if (layer !== undefined) { 1249 if (typeof layer.setOptions == 'function') { 1250 layer.setOptions(options); 1251 } 1252 if (typeof layer.setMap == 'function') { 1253 layer.setMap(this.map); 1254 } 1255 1256 return layer; 1257 } 1258}; 1259 1260GMaps.prototype.removeLayer = function(layer) { 1261 if (typeof(layer) == "string" && this.singleLayers[layer] !== undefined) { 1262 this.singleLayers[layer].setMap(null); 1263 1264 delete this.singleLayers[layer]; 1265 } 1266 else { 1267 for (var i = 0; i < this.layers.length; i++) { 1268 if (this.layers[i] === layer) { 1269 this.layers[i].setMap(null); 1270 this.layers.splice(i, 1); 1271 1272 break; 1273 } 1274 } 1275 } 1276}; 1277 1278var travelMode, unitSystem; 1279 1280GMaps.prototype.getRoutes = function(options) { 1281 switch (options.travelMode) { 1282 case 'bicycling': 1283 travelMode = google.maps.TravelMode.BICYCLING; 1284 break; 1285 case 'transit': 1286 travelMode = google.maps.TravelMode.TRANSIT; 1287 break; 1288 case 'driving': 1289 travelMode = google.maps.TravelMode.DRIVING; 1290 break; 1291 default: 1292 travelMode = google.maps.TravelMode.WALKING; 1293 break; 1294 } 1295 1296 if (options.unitSystem === 'imperial') { 1297 unitSystem = google.maps.UnitSystem.IMPERIAL; 1298 } 1299 else { 1300 unitSystem = google.maps.UnitSystem.METRIC; 1301 } 1302 1303 var base_options = { 1304 avoidHighways: false, 1305 avoidTolls: false, 1306 optimizeWaypoints: false, 1307 waypoints: [] 1308 }, 1309 request_options = extend_object(base_options, options); 1310 1311 request_options.origin = /string/.test(typeof options.origin) ? options.origin : new google.maps.LatLng(options.origin[0], options.origin[1]); 1312 request_options.destination = /string/.test(typeof options.destination) ? options.destination : new google.maps.LatLng(options.destination[0], options.destination[1]); 1313 request_options.travelMode = travelMode; 1314 request_options.unitSystem = unitSystem; 1315 1316 delete request_options.callback; 1317 delete request_options.error; 1318 1319 var self = this, 1320 service = new google.maps.DirectionsService(); 1321 1322 service.route(request_options, function(result, status) { 1323 if (status === google.maps.DirectionsStatus.OK) { 1324 for (var r in result.routes) { 1325 if (result.routes.hasOwnProperty(r)) { 1326 self.routes.push(result.routes[r]); 1327 } 1328 } 1329 1330 if (options.callback) { 1331 options.callback(self.routes); 1332 } 1333 } 1334 else { 1335 if (options.error) { 1336 options.error(result, status); 1337 } 1338 } 1339 }); 1340}; 1341 1342GMaps.prototype.removeRoutes = function() { 1343 this.routes = []; 1344}; 1345 1346GMaps.prototype.getElevations = function(options) { 1347 options = extend_object({ 1348 locations: [], 1349 path : false, 1350 samples : 256 1351 }, options); 1352 1353 if (options.locations.length > 0) { 1354 if (options.locations[0].length > 0) { 1355 options.locations = array_flat(array_map([options.locations], arrayToLatLng, false)); 1356 } 1357 } 1358 1359 var callback = options.callback; 1360 delete options.callback; 1361 1362 var service = new google.maps.ElevationService(); 1363 1364 //location request 1365 if (!options.path) { 1366 delete options.path; 1367 delete options.samples; 1368 1369 service.getElevationForLocations(options, function(result, status) { 1370 if (callback && typeof(callback) === "function") { 1371 callback(result, status); 1372 } 1373 }); 1374 //path request 1375 } else { 1376 var pathRequest = { 1377 path : options.locations, 1378 samples : options.samples 1379 }; 1380 1381 service.getElevationAlongPath(pathRequest, function(result, status) { 1382 if (callback && typeof(callback) === "function") { 1383 callback(result, status); 1384 } 1385 }); 1386 } 1387}; 1388 1389GMaps.prototype.cleanRoute = GMaps.prototype.removePolylines; 1390 1391GMaps.prototype.drawRoute = function(options) { 1392 var self = this; 1393 1394 this.getRoutes({ 1395 origin: options.origin, 1396 destination: options.destination, 1397 travelMode: options.travelMode, 1398 waypoints: options.waypoints, 1399 unitSystem: options.unitSystem, 1400 error: options.error, 1401 callback: function(e) { 1402 if (e.length > 0) { 1403 self.drawPolyline({ 1404 path: e[e.length - 1].overview_path, 1405 strokeColor: options.strokeColor, 1406 strokeOpacity: options.strokeOpacity, 1407 strokeWeight: options.strokeWeight 1408 }); 1409 1410 if (options.callback) { 1411 options.callback(e[e.length - 1]); 1412 } 1413 } 1414 } 1415 }); 1416}; 1417 1418GMaps.prototype.travelRoute = function(options) { 1419 if (options.origin && options.destination) { 1420 this.getRoutes({ 1421 origin: options.origin, 1422 destination: options.destination, 1423 travelMode: options.travelMode, 1424 waypoints : options.waypoints, 1425 unitSystem: options.unitSystem, 1426 error: options.error, 1427 callback: function(e) { 1428 //start callback 1429 if (e.length > 0 && options.start) { 1430 options.start(e[e.length - 1]); 1431 } 1432 1433 //step callback 1434 if (e.length > 0 && options.step) { 1435 var route = e[e.length - 1]; 1436 if (route.legs.length > 0) { 1437 var steps = route.legs[0].steps; 1438 for (var i=0, step; step=steps[i]; i++) { 1439 step.step_number = i; 1440 options.step(step, (route.legs[0].steps.length - 1)); 1441 } 1442 } 1443 } 1444 1445 //end callback 1446 if (e.length > 0 && options.end) { 1447 options.end(e[e.length - 1]); 1448 } 1449 } 1450 }); 1451 } 1452 else if (options.route) { 1453 if (options.route.legs.length > 0) { 1454 var steps = options.route.legs[0].steps; 1455 for (var i=0, step; step=steps[i]; i++) { 1456 step.step_number = i; 1457 options.step(step); 1458 } 1459 } 1460 } 1461}; 1462 1463GMaps.prototype.drawSteppedRoute = function(options) { 1464 var self = this; 1465 1466 if (options.origin && options.destination) { 1467 this.getRoutes({ 1468 origin: options.origin, 1469 destination: options.destination, 1470 travelMode: options.travelMode, 1471 waypoints : options.waypoints, 1472 error: options.error, 1473 callback: function(e) { 1474 //start callback 1475 if (e.length > 0 && options.start) { 1476 options.start(e[e.length - 1]); 1477 } 1478 1479 //step callback 1480 if (e.length > 0 && options.step) { 1481 var route = e[e.length - 1]; 1482 if (route.legs.length > 0) { 1483 var steps = route.legs[0].steps; 1484 for (var i=0, step; step=steps[i]; i++) { 1485 step.step_number = i; 1486 self.drawPolyline({ 1487 path: step.path, 1488 strokeColor: options.strokeColor, 1489 strokeOpacity: options.strokeOpacity, 1490 strokeWeight: options.strokeWeight 1491 }); 1492 options.step(step, (route.legs[0].steps.length - 1)); 1493 } 1494 } 1495 } 1496 1497 //end callback 1498 if (e.length > 0 && options.end) { 1499 options.end(e[e.length - 1]); 1500 } 1501 } 1502 }); 1503 } 1504 else if (options.route) { 1505 if (options.route.legs.length > 0) { 1506 var steps = options.route.legs[0].steps; 1507 for (var i=0, step; step=steps[i]; i++) { 1508 step.step_number = i; 1509 self.drawPolyline({ 1510 path: step.path, 1511 strokeColor: options.strokeColor, 1512 strokeOpacity: options.strokeOpacity, 1513 strokeWeight: options.strokeWeight 1514 }); 1515 options.step(step); 1516 } 1517 } 1518 } 1519}; 1520 1521GMaps.Route = function(options) { 1522 this.origin = options.origin; 1523 this.destination = options.destination; 1524 this.waypoints = options.waypoints; 1525 1526 this.map = options.map; 1527 this.route = options.route; 1528 this.step_count = 0; 1529 this.steps = this.route.legs[0].steps; 1530 this.steps_length = this.steps.length; 1531 1532 this.polyline = this.map.drawPolyline({ 1533 path: new google.maps.MVCArray(), 1534 strokeColor: options.strokeColor, 1535 strokeOpacity: options.strokeOpacity, 1536 strokeWeight: options.strokeWeight 1537 }).getPath(); 1538}; 1539 1540GMaps.Route.prototype.getRoute = function(options) { 1541 var self = this; 1542 1543 this.map.getRoutes({ 1544 origin : this.origin, 1545 destination : this.destination, 1546 travelMode : options.travelMode, 1547 waypoints : this.waypoints || [], 1548 error: options.error, 1549 callback : function() { 1550 self.route = e[0]; 1551 1552 if (options.callback) { 1553 options.callback.call(self); 1554 } 1555 } 1556 }); 1557}; 1558 1559GMaps.Route.prototype.back = function() { 1560 if (this.step_count > 0) { 1561 this.step_count--; 1562 var path = this.route.legs[0].steps[this.step_count].path; 1563 1564 for (var p in path){ 1565 if (path.hasOwnProperty(p)){ 1566 this.polyline.pop(); 1567 } 1568 } 1569 } 1570}; 1571 1572GMaps.Route.prototype.forward = function() { 1573 if (this.step_count < this.steps_length) { 1574 var path = this.route.legs[0].steps[this.step_count].path; 1575 1576 for (var p in path){ 1577 if (path.hasOwnProperty(p)){ 1578 this.polyline.push(path[p]); 1579 } 1580 } 1581 this.step_count++; 1582 } 1583}; 1584 1585GMaps.prototype.checkGeofence = function(lat, lng, fence) { 1586 return fence.containsLatLng(new google.maps.LatLng(lat, lng)); 1587}; 1588 1589GMaps.prototype.checkMarkerGeofence = function(marker, outside_callback) { 1590 if (marker.fences) { 1591 for (var i = 0, fence; fence = marker.fences[i]; i++) { 1592 var pos = marker.getPosition(); 1593 if (!this.checkGeofence(pos.lat(), pos.lng(), fence)) { 1594 outside_callback(marker, fence); 1595 } 1596 } 1597 } 1598}; 1599 1600GMaps.prototype.toImage = function(options) { 1601 var options = options || {}, 1602 static_map_options = {}; 1603 1604 static_map_options['size'] = options['size'] || [this.el.clientWidth, this.el.clientHeight]; 1605 static_map_options['lat'] = this.getCenter().lat(); 1606 static_map_options['lng'] = this.getCenter().lng(); 1607 1608 if (this.markers.length > 0) { 1609 static_map_options['markers'] = []; 1610 1611 for (var i = 0; i < this.markers.length; i++) { 1612 static_map_options['markers'].push({ 1613 lat: this.markers[i].getPosition().lat(), 1614 lng: this.markers[i].getPosition().lng() 1615 }); 1616 } 1617 } 1618 1619 if (this.polylines.length > 0) { 1620 var polyline = this.polylines[0]; 1621 1622 static_map_options['polyline'] = {}; 1623 static_map_options['polyline']['path'] = google.maps.geometry.encoding.encodePath(polyline.getPath()); 1624 static_map_options['polyline']['strokeColor'] = polyline.strokeColor 1625 static_map_options['polyline']['strokeOpacity'] = polyline.strokeOpacity 1626 static_map_options['polyline']['strokeWeight'] = polyline.strokeWeight 1627 } 1628 1629 return GMaps.staticMapURL(static_map_options); 1630}; 1631 1632GMaps.staticMapURL = function(options){ 1633 var parameters = [], 1634 data, 1635 static_root = 'http://maps.googleapis.com/maps/api/staticmap'; 1636 1637 if (options.url) { 1638 static_root = options.url; 1639 delete options.url; 1640 } 1641 1642 static_root += '?'; 1643 1644 var markers = options.markers; 1645 1646 delete options.markers; 1647 1648 if (!markers && options.marker) { 1649 markers = [options.marker]; 1650 delete options.marker; 1651 } 1652 1653 var styles = options.styles; 1654 1655 delete options.styles; 1656 1657 var polyline = options.polyline; 1658 delete options.polyline; 1659 1660 /** Map options **/ 1661 if (options.center) { 1662 parameters.push('center=' + options.center); 1663 delete options.center; 1664 } 1665 else if (options.address) { 1666 parameters.push('center=' + options.address); 1667 delete options.address; 1668 } 1669 else if (options.lat) { 1670 parameters.push(['center=', options.lat, ',', options.lng].join('')); 1671 delete options.lat; 1672 delete options.lng; 1673 } 1674 else if (options.visible) { 1675 var visible = encodeURI(options.visible.join('|')); 1676 parameters.push('visible=' + visible); 1677 } 1678 1679 var size = options.size; 1680 if (size) { 1681 if (size.join) { 1682 size = size.join('x'); 1683 } 1684 delete options.size; 1685 } 1686 else { 1687 size = '630x300'; 1688 } 1689 parameters.push('size=' + size); 1690 1691 if (!options.zoom && options.zoom !== false) { 1692 options.zoom = 15; 1693 } 1694 1695 var sensor = options.hasOwnProperty('sensor') ? !!options.sensor : true; 1696 delete options.sensor; 1697 parameters.push('sensor=' + sensor); 1698 1699 for (var param in options) { 1700 if (options.hasOwnProperty(param)) { 1701 parameters.push(param + '=' + options[param]); 1702 } 1703 } 1704 1705 /** Markers **/ 1706 if (markers) { 1707 var marker, loc; 1708 1709 for (var i=0; data=markers[i]; i++) { 1710 marker = []; 1711 1712 if (data.size && data.size !== 'normal') { 1713 marker.push('size:' + data.size); 1714 delete data.size; 1715 } 1716 else if (data.icon) { 1717 marker.push('icon:' + encodeURI(data.icon)); 1718 delete data.icon; 1719 } 1720 1721 if (data.color) { 1722 marker.push('color:' + data.color.replace('#', '0x')); 1723 delete data.color; 1724 } 1725 1726 if (data.label) { 1727 marker.push('label:' + data.label[0].toUpperCase()); 1728 delete data.label; 1729 } 1730 1731 loc = (data.address ? data.address : data.lat + ',' + data.lng); 1732 delete data.address; 1733 delete data.lat; 1734 delete data.lng; 1735 1736 for(var param in data){ 1737 if (data.hasOwnProperty(param)) { 1738 marker.push(param + ':' + data[param]); 1739 } 1740 } 1741 1742 if (marker.length || i === 0) { 1743 marker.push(loc); 1744 marker = marker.join('|'); 1745 parameters.push('markers=' + encodeURI(marker)); 1746 } 1747 // New marker without styles 1748 else { 1749 marker = parameters.pop() + encodeURI('|' + loc); 1750 parameters.push(marker); 1751 } 1752 } 1753 } 1754 1755 /** Map Styles **/ 1756 if (styles) { 1757 for (var i = 0; i < styles.length; i++) { 1758 var styleRule = []; 1759 if (styles[i].featureType){ 1760 styleRule.push('feature:' + styles[i].featureType.toLowerCase()); 1761 } 1762 1763 if (styles[i].elementType) { 1764 styleRule.push('element:' + styles[i].elementType.toLowerCase()); 1765 } 1766 1767 for (var j = 0; j < styles[i].stylers.length; j++) { 1768 for (var p in styles[i].stylers[j]) { 1769 var ruleArg = styles[i].stylers[j][p]; 1770 if (p == 'hue' || p == 'color') { 1771 ruleArg = '0x' + ruleArg.substring(1); 1772 } 1773 styleRule.push(p + ':' + ruleArg); 1774 } 1775 } 1776 1777 var rule = styleRule.join('|'); 1778 if (rule != '') { 1779 parameters.push('style=' + rule); 1780 } 1781 } 1782 } 1783 1784 /** Polylines **/ 1785 function parseColor(color, opacity) { 1786 if (color[0] === '#'){ 1787 color = color.replace('#', '0x'); 1788 1789 if (opacity) { 1790 opacity = parseFloat(opacity); 1791 opacity = Math.min(1, Math.max(opacity, 0)); 1792 if (opacity === 0) { 1793 return '0x00000000'; 1794 } 1795 opacity = (opacity * 255).toString(16); 1796 if (opacity.length === 1) { 1797 opacity += opacity; 1798 } 1799 1800 color = color.slice(0,8) + opacity; 1801 } 1802 } 1803 return color; 1804 } 1805 1806 if (polyline) { 1807 data = polyline; 1808 polyline = []; 1809 1810 if (data.strokeWeight) { 1811 polyline.push('weight:' + parseInt(data.strokeWeight, 10)); 1812 } 1813 1814 if (data.strokeColor) { 1815 var color = parseColor(data.strokeColor, data.strokeOpacity); 1816 polyline.push('color:' + color); 1817 } 1818 1819 if (data.fillColor) { 1820 var fillcolor = parseColor(data.fillColor, data.fillOpacity); 1821 polyline.push('fillcolor:' + fillcolor); 1822 } 1823 1824 var path = data.path; 1825 if (path.join) { 1826 for (var j=0, pos; pos=path[j]; j++) { 1827 polyline.push(pos.join(',')); 1828 } 1829 } 1830 else { 1831 polyline.push('enc:' + path); 1832 } 1833 1834 polyline = polyline.join('|'); 1835 parameters.push('path=' + encodeURI(polyline)); 1836 } 1837 1838 /** Retina support **/ 1839 var dpi = window.devicePixelRatio || 1; 1840 parameters.push('scale=' + dpi); 1841 1842 parameters = parameters.join('&'); 1843 return static_root + parameters; 1844}; 1845 1846GMaps.prototype.addMapType = function(mapTypeId, options) { 1847 if (options.hasOwnProperty("getTileUrl") && typeof(options["getTileUrl"]) == "function") { 1848 options.tileSize = options.tileSize || new google.maps.Size(256, 256); 1849 1850 var mapType = new google.maps.ImageMapType(options); 1851 1852 this.map.mapTypes.set(mapTypeId, mapType); 1853 } 1854 else { 1855 throw "'getTileUrl' function required."; 1856 } 1857}; 1858 1859GMaps.prototype.addOverlayMapType = function(options) { 1860 if (options.hasOwnProperty("getTile") && typeof(options["getTile"]) == "function") { 1861 var overlayMapTypeIndex = options.index; 1862 1863 delete options.index; 1864 1865 this.map.overlayMapTypes.insertAt(overlayMapTypeIndex, options); 1866 } 1867 else { 1868 throw "'getTile' function required."; 1869 } 1870}; 1871 1872GMaps.prototype.removeOverlayMapType = function(overlayMapTypeIndex) { 1873 this.map.overlayMapTypes.removeAt(overlayMapTypeIndex); 1874}; 1875 1876GMaps.prototype.addStyle = function(options) { 1877 var styledMapType = new google.maps.StyledMapType(options.styles, { name: options.styledMapName }); 1878 1879 this.map.mapTypes.set(options.mapTypeId, styledMapType); 1880}; 1881 1882GMaps.prototype.setStyle = function(mapTypeId) { 1883 this.map.setMapTypeId(mapTypeId); 1884}; 1885 1886GMaps.prototype.createPanorama = function(streetview_options) { 1887 if (!streetview_options.hasOwnProperty('lat') || !streetview_options.hasOwnProperty('lng')) { 1888 streetview_options.lat = this.getCenter().lat(); 1889 streetview_options.lng = this.getCenter().lng(); 1890 } 1891 1892 this.panorama = GMaps.createPanorama(streetview_options); 1893 1894 this.map.setStreetView(this.panorama); 1895 1896 return this.panorama; 1897}; 1898 1899GMaps.createPanorama = function(options) { 1900 var el = getElementById(options.el, options.context); 1901 1902 options.position = new google.maps.LatLng(options.lat, options.lng); 1903 1904 delete options.el; 1905 delete options.context; 1906 delete options.lat; 1907 delete options.lng; 1908 1909 var streetview_events = ['closeclick', 'links_changed', 'pano_changed', 'position_changed', 'pov_changed', 'resize', 'visible_changed'], 1910 streetview_options = extend_object({visible : true}, options); 1911 1912 for (var i = 0; i < streetview_events.length; i++) { 1913 delete streetview_options[streetview_events[i]]; 1914 } 1915 1916 var panorama = new google.maps.StreetViewPanorama(el, streetview_options); 1917 1918 for (var i = 0; i < streetview_events.length; i++) { 1919 (function(object, name) { 1920 if (options[name]) { 1921 google.maps.event.addListener(object, name, function(){ 1922 options[name].apply(this); 1923 }); 1924 } 1925 })(panorama, streetview_events[i]); 1926 } 1927 1928 return panorama; 1929}; 1930 1931GMaps.prototype.on = function(event_name, handler) { 1932 return GMaps.on(event_name, this, handler); 1933}; 1934 1935GMaps.prototype.off = function(event_name) { 1936 GMaps.off(event_name, this); 1937}; 1938 1939GMaps.custom_events = ['marker_added', 'marker_removed', 'polyline_added', 'polyline_removed', 'polygon_added', 'polygon_removed', 'geolocated', 'geolocation_failed']; 1940 1941GMaps.on = function(event_name, object, handler) { 1942 if (GMaps.custom_events.indexOf(event_name) == -1) { 1943 if(object instanceof GMaps) object = object.map; 1944 return google.maps.event.addListener(object, event_name, handler); 1945 } 1946 else { 1947 var registered_event = { 1948 handler : handler, 1949 eventName : event_name 1950 }; 1951 1952 object.registered_events[event_name] = object.registered_events[event_name] || []; 1953 object.registered_events[event_name].push(registered_event); 1954 1955 return registered_event; 1956 } 1957}; 1958 1959GMaps.off = function(event_name, object) { 1960 if (GMaps.custom_events.indexOf(event_name) == -1) { 1961 if(object instanceof GMaps) object = object.map; 1962 google.maps.event.clearListeners(object, event_name); 1963 } 1964 else { 1965 object.registered_events[event_name] = []; 1966 } 1967}; 1968 1969GMaps.fire = function(event_name, object, scope) { 1970 if (GMaps.custom_events.indexOf(event_name) == -1) { 1971 google.maps.event.trigger(object, event_name, Array.prototype.slice.apply(arguments).slice(2)); 1972 } 1973 else { 1974 if(event_name in scope.registered_events) { 1975 var firing_events = scope.registered_events[event_name]; 1976 1977 for(var i = 0; i < firing_events.length; i++) { 1978 (function(handler, scope, object) { 1979 handler.apply(scope, [object]); 1980 })(firing_events[i]['handler'], scope, object); 1981 } 1982 } 1983 } 1984}; 1985 1986GMaps.geolocate = function(options) { 1987 var complete_callback = options.always || options.complete; 1988 1989 if (navigator.geolocation) { 1990 navigator.geolocation.getCurrentPosition(function(position) { 1991 options.success(position); 1992 1993 if (complete_callback) { 1994 complete_callback(); 1995 } 1996 }, function(error) { 1997 options.error(error); 1998 1999 if (complete_callback) { 2000 complete_callback(); 2001 } 2002 }, options.options); 2003 } 2004 else { 2005 options.not_supported(); 2006 2007 if (complete_callback) { 2008 complete_callback(); 2009 } 2010 } 2011}; 2012 2013GMaps.geocode = function(options) { 2014 this.geocoder = new google.maps.Geocoder(); 2015 var callback = options.callback; 2016 if (options.hasOwnProperty('lat') && options.hasOwnProperty('lng')) { 2017 options.latLng = new google.maps.LatLng(options.lat, options.lng); 2018 } 2019 2020 delete options.lat; 2021 delete options.lng; 2022 delete options.callback; 2023 2024 this.geocoder.geocode(options, function(results, status) { 2025 callback(results, status); 2026 }); 2027}; 2028 2029//========================== 2030// Polygon containsLatLng 2031// https://github.com/tparkin/Google-Maps-Point-in-Polygon 2032// Poygon getBounds extension - google-maps-extensions 2033// http://code.google.com/p/google-maps-extensions/source/browse/google.maps.Polygon.getBounds.js 2034if (!google.maps.Polygon.prototype.getBounds) { 2035 google.maps.Polygon.prototype.getBounds = function(latLng) { 2036 var bounds = new google.maps.LatLngBounds(); 2037 var paths = this.getPaths(); 2038 var path; 2039 2040 for (var p = 0; p < paths.getLength(); p++) { 2041 path = paths.getAt(p); 2042 for (var i = 0; i < path.getLength(); i++) { 2043 bounds.extend(path.getAt(i)); 2044 } 2045 } 2046 2047 return bounds; 2048 }; 2049} 2050 2051if (!google.maps.Polygon.prototype.containsLatLng) { 2052 // Polygon containsLatLng - method to determine if a latLng is within a polygon 2053 google.maps.Polygon.prototype.containsLatLng = function(latLng) { 2054 // Exclude points outside of bounds as there is no way they are in the poly 2055 var bounds = this.getBounds(); 2056 2057 if (bounds !== null && !bounds.contains(latLng)) { 2058 return false; 2059 } 2060 2061 // Raycast point in polygon method 2062 var inPoly = false; 2063 2064 var numPaths = this.getPaths().getLength(); 2065 for (var p = 0; p < numPaths; p++) { 2066 var path = this.getPaths().getAt(p); 2067 var numPoints = path.getLength(); 2068 var j = numPoints - 1; 2069 2070 for (var i = 0; i < numPoints; i++) { 2071 var vertex1 = path.getAt(i); 2072 var vertex2 = path.getAt(j); 2073 2074 if (vertex1.lng() < latLng.lng() && vertex2.lng() >= latLng.lng() || vertex2.lng() < latLng.lng() && vertex1.lng() >= latLng.lng()) { 2075 if (vertex1.lat() + (latLng.lng() - vertex1.lng()) / (vertex2.lng() - vertex1.lng()) * (vertex2.lat() - vertex1.lat()) < latLng.lat()) { 2076 inPoly = !inPoly; 2077 } 2078 } 2079 2080 j = i; 2081 } 2082 } 2083 2084 return inPoly; 2085 }; 2086} 2087 2088if (!google.maps.Circle.prototype.containsLatLng) { 2089 google.maps.Circle.prototype.containsLatLng = function(latLng) { 2090 if (google.maps.geometry) { 2091 return google.maps.geometry.spherical.computeDistanceBetween(this.getCenter(), latLng) <= this.getRadius(); 2092 } 2093 else { 2094 return true; 2095 } 2096 }; 2097} 2098 2099google.maps.LatLngBounds.prototype.containsLatLng = function(latLng) { 2100 return this.contains(latLng); 2101}; 2102 2103google.maps.Marker.prototype.setFences = function(fences) { 2104 this.fences = fences; 2105}; 2106 2107google.maps.Marker.prototype.addFence = function(fence) { 2108 this.fences.push(fence); 2109}; 2110 2111google.maps.Marker.prototype.getId = function() { 2112 return this['__gm_id']; 2113}; 2114 2115//========================== 2116// Array indexOf 2117// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf 2118if (!Array.prototype.indexOf) { 2119 Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) { 2120 "use strict"; 2121 if (this == null) { 2122 throw new TypeError(); 2123 } 2124 var t = Object(this); 2125 var len = t.length >>> 0; 2126 if (len === 0) { 2127 return -1; 2128 } 2129 var n = 0; 2130 if (arguments.length > 1) { 2131 n = Number(arguments[1]); 2132 if (n != n) { // shortcut for verifying if it's NaN 2133 n = 0; 2134 } else if (n != 0 && n != Infinity && n != -Infinity) { 2135 n = (n > 0 || -1) * Math.floor(Math.abs(n)); 2136 } 2137 } 2138 if (n >= len) { 2139 return -1; 2140 } 2141 var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); 2142 for (; k < len; k++) { 2143 if (k in t && t[k] === searchElement) { 2144 return k; 2145 } 2146 } 2147 return -1; 2148 } 2149} 2150 2151return GMaps; 2152}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.