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