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