Created
July 7, 2015 17:04
-
-
Save jmprado/f3f6e0eba1cc8c4ec8f4 to your computer and use it in GitHub Desktop.
GMaps.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function (root, factory) { | |
| if (typeof exports === 'object') { | |
| module.exports = factory(); | |
| } | |
| else if (typeof define === 'function' && define.amd) { | |
| define('GMaps', [], factory); | |
| } | |
| root.GMaps = factory(); | |
| }(this, function () { | |
| /*! | |
| * GMaps.js v0.4.9 | |
| * http://hpneo.github.com/gmaps/ | |
| * | |
| * Copyright 2013, Gustavo Leon | |
| * Released under the MIT License. | |
| */ | |
| if (!(typeof window.google === 'object' && window.google.maps)) { | |
| throw 'Google Maps API is required. Please register the following JavaScript library http://maps.google.com/maps/api/js?sensor=true.' | |
| } | |
| var extend_object = function (obj, new_obj) { | |
| var name; | |
| if (obj === new_obj) { | |
| return obj; | |
| } | |
| for (name in new_obj) { | |
| obj[name] = new_obj[name]; | |
| } | |
| return obj; | |
| }; | |
| var replace_object = function (obj, replace) { | |
| var name; | |
| if (obj === replace) { | |
| return obj; | |
| } | |
| for (name in replace) { | |
| if (obj[name] != undefined) { | |
| obj[name] = replace[name]; | |
| } | |
| } | |
| return obj; | |
| }; | |
| var array_map = function (array, callback) { | |
| var original_callback_params = Array.prototype.slice.call(arguments, 2), | |
| array_return = [], | |
| array_length = array.length, | |
| i; | |
| if (Array.prototype.map && array.map === Array.prototype.map) { | |
| array_return = Array.prototype.map.call(array, function (item) { | |
| callback_params = original_callback_params; | |
| callback_params.splice(0, 0, item); | |
| return callback.apply(this, callback_params); | |
| }); | |
| } | |
| else { | |
| for (i = 0; i < array_length; i++) { | |
| callback_params = original_callback_params; | |
| callback_params.splice(0, 0, array[i]); | |
| array_return.push(callback.apply(this, callback_params)); | |
| } | |
| } | |
| return array_return; | |
| }; | |
| var array_flat = function (array) { | |
| var new_array = [], | |
| i; | |
| for (i = 0; i < array.length; i++) { | |
| new_array = new_array.concat(array[i]); | |
| } | |
| return new_array; | |
| }; | |
| var coordsToLatLngs = function (coords, useGeoJSON) { | |
| var first_coord = coords[0], | |
| second_coord = coords[1]; | |
| if (useGeoJSON) { | |
| first_coord = coords[1]; | |
| second_coord = coords[0]; | |
| } | |
| return new google.maps.LatLng(first_coord, second_coord); | |
| }; | |
| var arrayToLatLng = function (coords, useGeoJSON) { | |
| var i; | |
| for (i = 0; i < coords.length; i++) { | |
| if (coords[i].length > 0 && typeof (coords[i][0]) == "object") { | |
| coords[i] = arrayToLatLng(coords[i], useGeoJSON); | |
| } | |
| else { | |
| coords[i] = coordsToLatLngs(coords[i], useGeoJSON); | |
| } | |
| } | |
| return coords; | |
| }; | |
| var getElementById = function (id, context) { | |
| var element, | |
| id = id.replace('#', ''); | |
| if ('jQuery' in this && context) { | |
| element = $("#" + id, context)[0]; | |
| } else { | |
| element = document.getElementById(id); | |
| }; | |
| return element; | |
| }; | |
| var findAbsolutePosition = function (obj) { | |
| var curleft = 0, | |
| curtop = 0; | |
| if (obj.offsetParent) { | |
| do { | |
| curleft += obj.offsetLeft; | |
| curtop += obj.offsetTop; | |
| } while (obj = obj.offsetParent); | |
| } | |
| return [curleft, curtop]; | |
| }; | |
| var GMaps = (function (global) { | |
| "use strict"; | |
| var doc = document; | |
| var GMaps = function (options) { | |
| if (!this) return new GMaps(options); | |
| options.zoom = options.zoom || 15; | |
| options.mapType = options.mapType || 'roadmap'; | |
| var self = this, | |
| i, | |
| events_that_hide_context_menu = ['bounds_changed', 'center_changed', 'click', 'dblclick', 'drag', 'dragend', 'dragstart', 'idle', 'maptypeid_changed', 'projection_changed', 'resize', 'tilesloaded', 'zoom_changed'], | |
| events_that_doesnt_hide_context_menu = ['mousemove', 'mouseout', 'mouseover'], | |
| options_to_be_deleted = ['el', 'lat', 'lng', 'mapType', 'width', 'height', 'markerClusterer', 'enableNewStyle'], | |
| container_id = options.el || options.div, | |
| markerClustererFunction = options.markerClusterer, | |
| mapType = google.maps.MapTypeId[options.mapType.toUpperCase()], | |
| map_center = new google.maps.LatLng(options.lat, options.lng), | |
| zoomControl = options.zoomControl || true, | |
| zoomControlOpt = options.zoomControlOpt || { | |
| style: 'DEFAULT', | |
| position: 'TOP_LEFT' | |
| }, | |
| zoomControlStyle = zoomControlOpt.style || 'DEFAULT', | |
| zoomControlPosition = zoomControlOpt.position || 'TOP_LEFT', | |
| panControl = options.panControl || true, | |
| mapTypeControl = options.mapTypeControl || true, | |
| scaleControl = options.scaleControl || true, | |
| streetViewControl = options.streetViewControl || true, | |
| overviewMapControl = overviewMapControl || true, | |
| map_options = {}, | |
| map_base_options = { | |
| zoom: this.zoom, | |
| center: map_center, | |
| mapTypeId: mapType | |
| }, | |
| map_controls_options = { | |
| panControl: panControl, | |
| zoomControl: zoomControl, | |
| zoomControlOptions: { | |
| style: google.maps.ZoomControlStyle[zoomControlStyle], | |
| position: google.maps.ControlPosition[zoomControlPosition] | |
| }, | |
| mapTypeControl: mapTypeControl, | |
| scaleControl: scaleControl, | |
| streetViewControl: streetViewControl, | |
| overviewMapControl: overviewMapControl | |
| }; | |
| if (typeof (options.el) === 'string' || typeof (options.div) === 'string') { | |
| this.el = getElementById(container_id, options.context); | |
| } else { | |
| this.el = container_id; | |
| } | |
| if (typeof (this.el) === 'undefined' || this.el === null) { | |
| throw 'No element defined.'; | |
| } | |
| window.context_menu = window.context_menu || {}; | |
| window.context_menu[self.el.id] = {}; | |
| this.controls = []; | |
| this.overlays = []; | |
| this.layers = []; // array with kml/georss and fusiontables layers, can be as many | |
| this.singleLayers = {}; // object with the other layers, only one per layer | |
| this.markers = []; | |
| this.polylines = []; | |
| this.routes = []; | |
| this.polygons = []; | |
| this.infoWindow = null; | |
| this.overlay_el = null; | |
| this.zoom = options.zoom; | |
| this.registered_events = {}; | |
| this.el.style.width = options.width || this.el.scrollWidth || this.el.offsetWidth; | |
| this.el.style.height = options.height || this.el.scrollHeight || this.el.offsetHeight; | |
| google.maps.visualRefresh = options.enableNewStyle; | |
| for (i = 0; i < options_to_be_deleted.length; i++) { | |
| delete options[options_to_be_deleted[i]]; | |
| } | |
| if (options.disableDefaultUI != true) { | |
| map_base_options = extend_object(map_base_options, map_controls_options); | |
| } | |
| map_options = extend_object(map_base_options, options); | |
| for (i = 0; i < events_that_hide_context_menu.length; i++) { | |
| delete map_options[events_that_hide_context_menu[i]]; | |
| } | |
| for (i = 0; i < events_that_doesnt_hide_context_menu.length; i++) { | |
| delete map_options[events_that_doesnt_hide_context_menu[i]]; | |
| } | |
| this.map = new google.maps.Map(this.el, map_options); | |
| if (markerClustererFunction) { | |
| this.markerClusterer = markerClustererFunction.apply(this, [this.map]); | |
| } | |
| var buildContextMenuHTML = function (control, e) { | |
| var html = '', | |
| options = window.context_menu[self.el.id][control]; | |
| for (var i in options) { | |
| if (options.hasOwnProperty(i)) { | |
| var option = options[i]; | |
| html += '<li><a id="' + control + '_' + i + '" href="#">' + option.title + '</a></li>'; | |
| } | |
| } | |
| if (!getElementById('gmaps_context_menu')) return; | |
| var context_menu_element = getElementById('gmaps_context_menu'); | |
| context_menu_element.innerHTML = html; | |
| var context_menu_items = context_menu_element.getElementsByTagName('a'), | |
| context_menu_items_count = context_menu_items.length | |
| i; | |
| for (i = 0; i < context_menu_items_count; i++) { | |
| var context_menu_item = context_menu_items[i]; | |
| var assign_menu_item_action = function (ev) { | |
| ev.preventDefault(); | |
| options[this.id.replace(control + '_', '')].action.apply(self, [e]); | |
| self.hideContextMenu(); | |
| }; | |
| google.maps.event.clearListeners(context_menu_item, 'click'); | |
| google.maps.event.addDomListenerOnce(context_menu_item, 'click', assign_menu_item_action, false); | |
| } | |
| var position = findAbsolutePosition.apply(this, [self.el]), | |
| left = position[0] + e.pixel.x - 15, | |
| top = position[1] + e.pixel.y - 15; | |
| context_menu_element.style.left = left + "px"; | |
| context_menu_element.style.top = top + "px"; | |
| context_menu_element.style.display = 'block'; | |
| }; | |
| this.buildContextMenu = function (control, e) { | |
| if (control === 'marker') { | |
| e.pixel = {}; | |
| var overlay = new google.maps.OverlayView(); | |
| overlay.setMap(self.map); | |
| overlay.draw = function () { | |
| var projection = overlay.getProjection(), | |
| position = e.marker.getPosition(); | |
| e.pixel = projection.fromLatLngToContainerPixel(position); | |
| buildContextMenuHTML(control, e); | |
| }; | |
| } | |
| else { | |
| buildContextMenuHTML(control, e); | |
| } | |
| }; | |
| this.setContextMenu = function (options) { | |
| window.context_menu[self.el.id][options.control] = {}; | |
| var i, | |
| ul = doc.createElement('ul'); | |
| for (i in options.options) { | |
| if (options.options.hasOwnProperty(i)) { | |
| var option = options.options[i]; | |
| window.context_menu[self.el.id][options.control][option.name] = { | |
| title: option.title, | |
| action: option.action | |
| }; | |
| } | |
| } | |
| ul.id = 'gmaps_context_menu'; | |
| ul.style.display = 'none'; | |
| ul.style.position = 'absolute'; | |
| ul.style.minWidth = '100px'; | |
| ul.style.background = 'white'; | |
| ul.style.listStyle = 'none'; | |
| ul.style.padding = '8px'; | |
| ul.style.boxShadow = '2px 2px 6px #ccc'; | |
| doc.body.appendChild(ul); | |
| var context_menu_element = getElementById('gmaps_context_menu') | |
| google.maps.event.addDomListener(context_menu_element, 'mouseout', function (ev) { | |
| if (!ev.relatedTarget || !this.contains(ev.relatedTarget)) { | |
| window.setTimeout(function () { | |
| context_menu_element.style.display = 'none'; | |
| }, 400); | |
| } | |
| }, false); | |
| }; | |
| this.hideContextMenu = function () { | |
| var context_menu_element = getElementById('gmaps_context_menu'); | |
| if (context_menu_element) { | |
| context_menu_element.style.display = 'none'; | |
| } | |
| }; | |
| var setupListener = function (object, name) { | |
| google.maps.event.addListener(object, name, function (e) { | |
| if (e == undefined) { | |
| e = this; | |
| } | |
| options[name].apply(this, [e]); | |
| self.hideContextMenu(); | |
| }); | |
| }; | |
| for (var ev = 0; ev < events_that_hide_context_menu.length; ev++) { | |
| var name = events_that_hide_context_menu[ev]; | |
| if (name in options) { | |
| setupListener(this.map, name); | |
| } | |
| } | |
| for (var ev = 0; ev < events_that_doesnt_hide_context_menu.length; ev++) { | |
| var name = events_that_doesnt_hide_context_menu[ev]; | |
| if (name in options) { | |
| setupListener(this.map, name); | |
| } | |
| } | |
| google.maps.event.addListener(this.map, 'rightclick', function (e) { | |
| if (options.rightclick) { | |
| options.rightclick.apply(this, [e]); | |
| } | |
| if (window.context_menu[self.el.id]['map'] != undefined) { | |
| self.buildContextMenu('map', e); | |
| } | |
| }); | |
| this.refresh = function () { | |
| google.maps.event.trigger(this.map, 'resize'); | |
| }; | |
| this.fitZoom = function () { | |
| var latLngs = [], | |
| markers_length = this.markers.length, | |
| i; | |
| for (i = 0; i < markers_length; i++) { | |
| if (typeof (this.markers[i].visible) === 'boolean' && this.markers[i].visible) { | |
| latLngs.push(this.markers[i].getPosition()); | |
| } | |
| } | |
| this.fitLatLngBounds(latLngs); | |
| }; | |
| this.fitLatLngBounds = function (latLngs) { | |
| var total = latLngs.length; | |
| var bounds = new google.maps.LatLngBounds(); | |
| for (var i = 0; i < total; i++) { | |
| bounds.extend(latLngs[i]); | |
| } | |
| this.map.fitBounds(bounds); | |
| }; | |
| this.setCenter = function (lat, lng, callback) { | |
| this.map.panTo(new google.maps.LatLng(lat, lng)); | |
| if (callback) { | |
| callback(); | |
| } | |
| }; | |
| this.getElement = function () { | |
| return this.el; | |
| }; | |
| this.zoomIn = function (value) { | |
| value = value || 1; | |
| this.zoom = this.map.getZoom() + value; | |
| this.map.setZoom(this.zoom); | |
| }; | |
| this.zoomOut = function (value) { | |
| value = value || 1; | |
| this.zoom = this.map.getZoom() - value; | |
| this.map.setZoom(this.zoom); | |
| }; | |
| var native_methods = [], | |
| method; | |
| for (method in this.map) { | |
| if (typeof (this.map[method]) == 'function' && !this[method]) { | |
| native_methods.push(method); | |
| } | |
| } | |
| for (i = 0; i < native_methods.length; i++) { | |
| (function (gmaps, scope, method_name) { | |
| gmaps[method_name] = function () { | |
| return scope[method_name].apply(scope, arguments); | |
| }; | |
| })(this, this.map, native_methods[i]); | |
| } | |
| }; | |
| return GMaps; | |
| })(this); | |
| GMaps.prototype.createControl = function (options) { | |
| var control = document.createElement('div'); | |
| control.style.cursor = 'pointer'; | |
| control.style.fontFamily = 'Arial, sans-serif'; | |
| control.style.fontSize = '13px'; | |
| control.style.boxShadow = 'rgba(0, 0, 0, 0.398438) 0px 2px 4px'; | |
| for (var option in options.style) { | |
| control.style[option] = options.style[option]; | |
| } | |
| if (options.id) { | |
| control.id = options.id; | |
| } | |
| if (options.classes) { | |
| control.className = options.classes; | |
| } | |
| if (options.content) { | |
| control.innerHTML = options.content; | |
| } | |
| for (var ev in options.events) { | |
| (function (object, name) { | |
| google.maps.event.addDomListener(object, name, function () { | |
| options.events[name].apply(this, [this]); | |
| }); | |
| })(control, ev); | |
| } | |
| control.index = 1; | |
| return control; | |
| }; | |
| GMaps.prototype.addControl = function (options) { | |
| var position = google.maps.ControlPosition[options.position.toUpperCase()]; | |
| delete options.position; | |
| var control = this.createControl(options); | |
| this.controls.push(control); | |
| this.map.controls[position].push(control); | |
| return control; | |
| }; | |
| GMaps.prototype.createMarker = function (options) { | |
| if (options.lat == undefined && options.lng == undefined && options.position == undefined) { | |
| throw 'No latitude or longitude defined.'; | |
| } | |
| var self = this, | |
| details = options.details, | |
| fences = options.fences, | |
| outside = options.outside, | |
| base_options = { | |
| position: new google.maps.LatLng(options.lat, options.lng), | |
| map: null | |
| }; | |
| delete options.lat; | |
| delete options.lng; | |
| delete options.fences; | |
| delete options.outside; | |
| var marker_options = extend_object(base_options, options), | |
| marker = new google.maps.Marker(marker_options); | |
| marker.fences = fences; | |
| if (options.infoWindow) { | |
| marker.infoWindow = new google.maps.InfoWindow(options.infoWindow); | |
| var info_window_events = ['closeclick', 'content_changed', 'domready', 'position_changed', 'zindex_changed']; | |
| for (var ev = 0; ev < info_window_events.length; ev++) { | |
| (function (object, name) { | |
| if (options.infoWindow[name]) { | |
| google.maps.event.addListener(object, name, function (e) { | |
| options.infoWindow[name].apply(this, [e]); | |
| }); | |
| } | |
| })(marker.infoWindow, info_window_events[ev]); | |
| } | |
| } | |
| 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']; | |
| var marker_events_with_mouse = ['dblclick', 'drag', 'dragend', 'dragstart', 'mousedown', 'mouseout', 'mouseover', 'mouseup']; | |
| for (var ev = 0; ev < marker_events.length; ev++) { | |
| (function (object, name) { | |
| if (options[name]) { | |
| google.maps.event.addListener(object, name, function () { | |
| options[name].apply(this, [this]); | |
| }); | |
| } | |
| })(marker, marker_events[ev]); | |
| } | |
| for (var ev = 0; ev < marker_events_with_mouse.length; ev++) { | |
| (function (map, object, name) { | |
| if (options[name]) { | |
| google.maps.event.addListener(object, name, function (me) { | |
| if (!me.pixel) { | |
| me.pixel = map.getProjection().fromLatLngToPoint(me.latLng) | |
| } | |
| options[name].apply(this, [me]); | |
| }); | |
| } | |
| })(this.map, marker, marker_events_with_mouse[ev]); | |
| } | |
| google.maps.event.addListener(marker, 'click', function () { | |
| this.details = details; | |
| if (options.click) { | |
| options.click.apply(this, [this]); | |
| } | |
| if (marker.infoWindow) { | |
| self.hideInfoWindows(); | |
| marker.infoWindow.open(self.map, marker); | |
| } | |
| }); | |
| google.maps.event.addListener(marker, 'rightclick', function (e) { | |
| e.marker = this; | |
| if (options.rightclick) { | |
| options.rightclick.apply(this, [e]); | |
| } | |
| if (window.context_menu[self.el.id]['marker'] != undefined) { | |
| self.buildContextMenu('marker', e); | |
| } | |
| }); | |
| if (marker.fences) { | |
| google.maps.event.addListener(marker, 'dragend', function () { | |
| self.checkMarkerGeofence(marker, function (m, f) { | |
| outside(m, f); | |
| }); | |
| }); | |
| } | |
| return marker; | |
| }; | |
| GMaps.prototype.addMarker = function (options) { | |
| var marker; | |
| if (options.hasOwnProperty('gm_accessors_')) { | |
| // Native google.maps.Marker object | |
| marker = options; | |
| } | |
| else { | |
| if ((options.hasOwnProperty('lat') && options.hasOwnProperty('lng')) || options.position) { | |
| marker = this.createMarker(options); | |
| } | |
| else { | |
| throw 'No latitude or longitude defined.'; | |
| } | |
| } | |
| marker.setMap(this.map); | |
| if (this.markerClusterer) { | |
| this.markerClusterer.addMarker(marker); | |
| } | |
| this.markers.push(marker); | |
| GMaps.fire('marker_added', marker, this); | |
| return marker; | |
| }; | |
| GMaps.prototype.addMarkers = function (array) { | |
| for (var i = 0, marker; marker = array[i]; i++) { | |
| this.addMarker(marker); | |
| } | |
| return this.markers; | |
| }; | |
| GMaps.prototype.hideInfoWindows = function () { | |
| for (var i = 0, marker; marker = this.markers[i]; i++) { | |
| if (marker.infoWindow) { | |
| marker.infoWindow.close(); | |
| } | |
| } | |
| }; | |
| GMaps.prototype.removeMarker = function (marker) { | |
| for (var i = 0; i < this.markers.length; i++) { | |
| if (this.markers[i] === marker) { | |
| this.markers[i].setMap(null); | |
| this.markers.splice(i, 1); | |
| if (this.markerClusterer) { | |
| this.markerClusterer.removeMarker(marker); | |
| } | |
| GMaps.fire('marker_removed', marker, this); | |
| break; | |
| } | |
| } | |
| return marker; | |
| }; | |
| GMaps.prototype.removeMarkers = function (collection) { | |
| var collection = (collection || this.markers); | |
| for (var i = 0; i < this.markers.length; i++) { | |
| if (this.markers[i] === collection[i]) { | |
| this.markers[i].setMap(null); | |
| } | |
| } | |
| var new_markers = []; | |
| for (var i = 0; i < this.markers.length; i++) { | |
| if (this.markers[i].getMap() != null) { | |
| new_markers.push(this.markers[i]); | |
| } | |
| } | |
| this.markers = new_markers; | |
| }; | |
| GMaps.prototype.drawOverlay = function (options) { | |
| var overlay = new google.maps.OverlayView(), | |
| auto_show = true; | |
| overlay.setMap(this.map); | |
| if (options.auto_show != null) { | |
| auto_show = options.auto_show; | |
| } | |
| overlay.onAdd = function () { | |
| var el = document.createElement('div'); | |
| el.style.borderStyle = "none"; | |
| el.style.borderWidth = "0px"; | |
| el.style.position = "absolute"; | |
| el.style.zIndex = 100; | |
| el.innerHTML = options.content; | |
| overlay.el = el; | |
| if (!options.layer) { | |
| options.layer = 'overlayLayer'; | |
| } | |
| var panes = this.getPanes(), | |
| overlayLayer = panes[options.layer], | |
| stop_overlay_events = ['contextmenu', 'DOMMouseScroll', 'dblclick', 'mousedown']; | |
| overlayLayer.appendChild(el); | |
| for (var ev = 0; ev < stop_overlay_events.length; ev++) { | |
| (function (object, name) { | |
| google.maps.event.addDomListener(object, name, function (e) { | |
| if (navigator.userAgent.toLowerCase().indexOf('msie') != -1 && document.all) { | |
| e.cancelBubble = true; | |
| e.returnValue = false; | |
| } | |
| else { | |
| e.stopPropagation(); | |
| } | |
| }); | |
| })(el, stop_overlay_events[ev]); | |
| } | |
| google.maps.event.trigger(this, 'ready'); | |
| }; | |
| overlay.draw = function () { | |
| var projection = this.getProjection(), | |
| pixel = projection.fromLatLngToDivPixel(new google.maps.LatLng(options.lat, options.lng)); | |
| options.horizontalOffset = options.horizontalOffset || 0; | |
| options.verticalOffset = options.verticalOffset || 0; | |
| var el = overlay.el, | |
| content = el.children[0], | |
| content_height = content.clientHeight, | |
| content_width = content.clientWidth; | |
| switch (options.verticalAlign) { | |
| case 'top': | |
| el.style.top = (pixel.y - content_height + options.verticalOffset) + 'px'; | |
| break; | |
| default: | |
| case 'middle': | |
| el.style.top = (pixel.y - (content_height / 2) + options.verticalOffset) + 'px'; | |
| break; | |
| case 'bottom': | |
| el.style.top = (pixel.y + options.verticalOffset) + 'px'; | |
| break; | |
| } | |
| switch (options.horizontalAlign) { | |
| case 'left': | |
| el.style.left = (pixel.x - content_width + options.horizontalOffset) + 'px'; | |
| break; | |
| default: | |
| case 'center': | |
| el.style.left = (pixel.x - (content_width / 2) + options.horizontalOffset) + 'px'; | |
| break; | |
| case 'right': | |
| el.style.left = (pixel.x + options.horizontalOffset) + 'px'; | |
| break; | |
| } | |
| el.style.display = auto_show ? 'block' : 'none'; | |
| if (!auto_show) { | |
| options.show.apply(this, [el]); | |
| } | |
| }; | |
| overlay.onRemove = function () { | |
| var el = overlay.el; | |
| if (options.remove) { | |
| options.remove.apply(this, [el]); | |
| } | |
| else { | |
| overlay.el.parentNode.removeChild(overlay.el); | |
| overlay.el = null; | |
| } | |
| }; | |
| this.overlays.push(overlay); | |
| return overlay; | |
| }; | |
| GMaps.prototype.removeOverlay = function (overlay) { | |
| for (var i = 0; i < this.overlays.length; i++) { | |
| if (this.overlays[i] === overlay) { | |
| this.overlays[i].setMap(null); | |
| this.overlays.splice(i, 1); | |
| break; | |
| } | |
| } | |
| }; | |
| GMaps.prototype.removeOverlays = function () { | |
| for (var i = 0, item; item = this.overlays[i]; i++) { | |
| item.setMap(null); | |
| } | |
| this.overlays = []; | |
| }; | |
| GMaps.prototype.drawPolyline = function (options) { | |
| var path = [], | |
| points = options.path; | |
| if (points.length) { | |
| if (points[0][0] === undefined) { | |
| path = points; | |
| } | |
| else { | |
| for (var i = 0, latlng; latlng = points[i]; i++) { | |
| path.push(new google.maps.LatLng(latlng[0], latlng[1])); | |
| } | |
| } | |
| } | |
| var polyline_options = { | |
| map: this.map, | |
| path: path, | |
| strokeColor: options.strokeColor, | |
| strokeOpacity: options.strokeOpacity, | |
| strokeWeight: options.strokeWeight, | |
| geodesic: options.geodesic, | |
| clickable: true, | |
| editable: false, | |
| visible: true | |
| }; | |
| if (options.hasOwnProperty("clickable")) { | |
| polyline_options.clickable = options.clickable; | |
| } | |
| if (options.hasOwnProperty("editable")) { | |
| polyline_options.editable = options.editable; | |
| } | |
| if (options.hasOwnProperty("icons")) { | |
| polyline_options.icons = options.icons; | |
| } | |
| if (options.hasOwnProperty("zIndex")) { | |
| polyline_options.zIndex = options.zIndex; | |
| } | |
| var polyline = new google.maps.Polyline(polyline_options); | |
| var polyline_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick']; | |
| for (var ev = 0; ev < polyline_events.length; ev++) { | |
| (function (object, name) { | |
| if (options[name]) { | |
| google.maps.event.addListener(object, name, function (e) { | |
| options[name].apply(this, [e]); | |
| }); | |
| } | |
| })(polyline, polyline_events[ev]); | |
| } | |
| this.polylines.push(polyline); | |
| GMaps.fire('polyline_added', polyline, this); | |
| return polyline; | |
| }; | |
| GMaps.prototype.removePolyline = function (polyline) { | |
| for (var i = 0; i < this.polylines.length; i++) { | |
| if (this.polylines[i] === polyline) { | |
| this.polylines[i].setMap(null); | |
| this.polylines.splice(i, 1); | |
| GMaps.fire('polyline_removed', polyline, this); | |
| break; | |
| } | |
| } | |
| }; | |
| GMaps.prototype.removePolylines = function () { | |
| for (var i = 0, item; item = this.polylines[i]; i++) { | |
| item.setMap(null); | |
| } | |
| this.polylines = []; | |
| }; | |
| GMaps.prototype.drawCircle = function (options) { | |
| options = extend_object({ | |
| map: this.map, | |
| center: new google.maps.LatLng(options.lat, options.lng) | |
| }, options); | |
| delete options.lat; | |
| delete options.lng; | |
| var polygon = new google.maps.Circle(options), | |
| polygon_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick']; | |
| for (var ev = 0; ev < polygon_events.length; ev++) { | |
| (function (object, name) { | |
| if (options[name]) { | |
| google.maps.event.addListener(object, name, function (e) { | |
| options[name].apply(this, [e]); | |
| }); | |
| } | |
| })(polygon, polygon_events[ev]); | |
| } | |
| this.polygons.push(polygon); | |
| return polygon; | |
| }; | |
| GMaps.prototype.drawRectangle = function (options) { | |
| options = extend_object({ | |
| map: this.map | |
| }, options); | |
| var latLngBounds = new google.maps.LatLngBounds( | |
| new google.maps.LatLng(options.bounds[0][0], options.bounds[0][1]), | |
| new google.maps.LatLng(options.bounds[1][0], options.bounds[1][1]) | |
| ); | |
| options.bounds = latLngBounds; | |
| var polygon = new google.maps.Rectangle(options), | |
| polygon_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick']; | |
| for (var ev = 0; ev < polygon_events.length; ev++) { | |
| (function (object, name) { | |
| if (options[name]) { | |
| google.maps.event.addListener(object, name, function (e) { | |
| options[name].apply(this, [e]); | |
| }); | |
| } | |
| })(polygon, polygon_events[ev]); | |
| } | |
| this.polygons.push(polygon); | |
| return polygon; | |
| }; | |
| GMaps.prototype.drawPolygon = function (options) { | |
| var useGeoJSON = false; | |
| if (options.hasOwnProperty("useGeoJSON")) { | |
| useGeoJSON = options.useGeoJSON; | |
| } | |
| delete options.useGeoJSON; | |
| options = extend_object({ | |
| map: this.map | |
| }, options); | |
| if (useGeoJSON == false) { | |
| options.paths = [options.paths.slice(0)]; | |
| } | |
| if (options.paths.length > 0) { | |
| if (options.paths[0].length > 0) { | |
| options.paths = array_flat(array_map(options.paths, arrayToLatLng, useGeoJSON)); | |
| } | |
| } | |
| var polygon = new google.maps.Polygon(options), | |
| polygon_events = ['click', 'dblclick', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'rightclick']; | |
| for (var ev = 0; ev < polygon_events.length; ev++) { | |
| (function (object, name) { | |
| if (options[name]) { | |
| google.maps.event.addListener(object, name, function (e) { | |
| options[name].apply(this, [e]); | |
| }); | |
| } | |
| })(polygon, polygon_events[ev]); | |
| } | |
| this.polygons.push(polygon); | |
| GMaps.fire('polygon_added', polygon, this); | |
| return polygon; | |
| }; | |
| GMaps.prototype.removePolygon = function (polygon) { | |
| for (var i = 0; i < this.polygons.length; i++) { | |
| if (this.polygons[i] === polygon) { | |
| this.polygons[i].setMap(null); | |
| this.polygons.splice(i, 1); | |
| GMaps.fire('polygon_removed', polygon, this); | |
| break; | |
| } | |
| } | |
| }; | |
| GMaps.prototype.removePolygons = function () { | |
| for (var i = 0, item; item = this.polygons[i]; i++) { | |
| item.setMap(null); | |
| } | |
| this.polygons = []; | |
| }; | |
| GMaps.prototype.getFromFusionTables = function (options) { | |
| var events = options.events; | |
| delete options.events; | |
| var fusion_tables_options = options, | |
| layer = new google.maps.FusionTablesLayer(fusion_tables_options); | |
| for (var ev in events) { | |
| (function (object, name) { | |
| google.maps.event.addListener(object, name, function (e) { | |
| events[name].apply(this, [e]); | |
| }); | |
| })(layer, ev); | |
| } | |
| this.layers.push(layer); | |
| return layer; | |
| }; | |
| GMaps.prototype.loadFromFusionTables = function (options) { | |
| var layer = this.getFromFusionTables(options); | |
| layer.setMap(this.map); | |
| return layer; | |
| }; | |
| GMaps.prototype.getFromKML = function (options) { | |
| var url = options.url, | |
| events = options.events; | |
| delete options.url; | |
| delete options.events; | |
| var kml_options = options, | |
| layer = new google.maps.KmlLayer(url, kml_options); | |
| for (var ev in events) { | |
| (function (object, name) { | |
| google.maps.event.addListener(object, name, function (e) { | |
| events[name].apply(this, [e]); | |
| }); | |
| })(layer, ev); | |
| } | |
| this.layers.push(layer); | |
| return layer; | |
| }; | |
| GMaps.prototype.loadFromKML = function (options) { | |
| var layer = this.getFromKML(options); | |
| layer.setMap(this.map); | |
| return layer; | |
| }; | |
| GMaps.prototype.addLayer = function (layerName, options) { | |
| //var default_layers = ['weather', 'clouds', 'traffic', 'transit', 'bicycling', 'panoramio', 'places']; | |
| options = options || {}; | |
| var layer; | |
| switch (layerName) { | |
| case 'weather': this.singleLayers.weather = layer = new google.maps.weather.WeatherLayer(); | |
| break; | |
| case 'clouds': this.singleLayers.clouds = layer = new google.maps.weather.CloudLayer(); | |
| break; | |
| case 'traffic': this.singleLayers.traffic = layer = new google.maps.TrafficLayer(); | |
| break; | |
| case 'transit': this.singleLayers.transit = layer = new google.maps.TransitLayer(); | |
| break; | |
| case 'bicycling': this.singleLayers.bicycling = layer = new google.maps.BicyclingLayer(); | |
| break; | |
| case 'panoramio': | |
| this.singleLayers.panoramio = layer = new google.maps.panoramio.PanoramioLayer(); | |
| layer.setTag(options.filter); | |
| delete options.filter; | |
| //click event | |
| if (options.click) { | |
| google.maps.event.addListener(layer, 'click', function (event) { | |
| options.click(event); | |
| delete options.click; | |
| }); | |
| } | |
| break; | |
| case 'places': | |
| this.singleLayers.places = layer = new google.maps.places.PlacesService(this.map); | |
| //search and nearbySearch callback, Both are the same | |
| if (options.search || options.nearbySearch) { | |
| var placeSearchRequest = { | |
| bounds: options.bounds || null, | |
| keyword: options.keyword || null, | |
| location: options.location || null, | |
| name: options.name || null, | |
| radius: options.radius || null, | |
| rankBy: options.rankBy || null, | |
| types: options.types || null | |
| }; | |
| if (options.search) { | |
| layer.search(placeSearchRequest, options.search); | |
| } | |
| if (options.nearbySearch) { | |
| layer.nearbySearch(placeSearchRequest, options.nearbySearch); | |
| } | |
| } | |
| //textSearch callback | |
| if (options.textSearch) { | |
| var textSearchRequest = { | |
| bounds: options.bounds || null, | |
| location: options.location || null, | |
| query: options.query || null, | |
| radius: options.radius || null | |
| }; | |
| layer.textSearch(textSearchRequest, options.textSearch); | |
| } | |
| break; | |
| } | |
| if (layer !== undefined) { | |
| if (typeof layer.setOptions == 'function') { | |
| layer.setOptions(options); | |
| } | |
| if (typeof layer.setMap == 'function') { | |
| layer.setMap(this.map); | |
| } | |
| return layer; | |
| } | |
| }; | |
| GMaps.prototype.removeLayer = function (layer) { | |
| if (typeof (layer) == "string" && this.singleLayers[layer] !== undefined) { | |
| this.singleLayers[layer].setMap(null); | |
| delete this.singleLayers[layer]; | |
| } | |
| else { | |
| for (var i = 0; i < this.layers.length; i++) { | |
| if (this.layers[i] === layer) { | |
| this.layers[i].setMap(null); | |
| this.layers.splice(i, 1); | |
| break; | |
| } | |
| } | |
| } | |
| }; | |
| var travelMode, unitSystem; | |
| GMaps.prototype.getRoutes = function (options) { | |
| switch (options.travelMode) { | |
| case 'bicycling': | |
| travelMode = google.maps.TravelMode.BICYCLING; | |
| break; | |
| case 'transit': | |
| travelMode = google.maps.TravelMode.TRANSIT; | |
| break; | |
| case 'driving': | |
| travelMode = google.maps.TravelMode.DRIVING; | |
| break; | |
| default: | |
| travelMode = google.maps.TravelMode.WALKING; | |
| break; | |
| } | |
| if (options.unitSystem === 'imperial') { | |
| unitSystem = google.maps.UnitSystem.IMPERIAL; | |
| } | |
| else { | |
| unitSystem = google.maps.UnitSystem.METRIC; | |
| } | |
| var base_options = { | |
| avoidHighways: false, | |
| avoidTolls: false, | |
| optimizeWaypoints: false, | |
| waypoints: [] | |
| }, | |
| request_options = extend_object(base_options, options); | |
| request_options.origin = /string/.test(typeof options.origin) ? options.origin : new google.maps.LatLng(options.origin[0], options.origin[1]); | |
| request_options.destination = /string/.test(typeof options.destination) ? options.destination : new google.maps.LatLng(options.destination[0], options.destination[1]); | |
| request_options.travelMode = travelMode; | |
| request_options.unitSystem = unitSystem; | |
| delete request_options.callback; | |
| delete request_options.error; | |
| var self = this, | |
| service = new google.maps.DirectionsService(); | |
| service.route(request_options, function (result, status) { | |
| if (status === google.maps.DirectionsStatus.OK) { | |
| for (var r in result.routes) { | |
| if (result.routes.hasOwnProperty(r)) { | |
| self.routes.push(result.routes[r]); | |
| } | |
| } | |
| if (options.callback) { | |
| options.callback(self.routes); | |
| } | |
| } | |
| else { | |
| if (options.error) { | |
| options.error(result, status); | |
| } | |
| } | |
| }); | |
| }; | |
| GMaps.prototype.removeRoutes = function () { | |
| this.routes = []; | |
| }; | |
| GMaps.prototype.getElevations = function (options) { | |
| options = extend_object({ | |
| locations: [], | |
| path: false, | |
| samples: 256 | |
| }, options); | |
| if (options.locations.length > 0) { | |
| if (options.locations[0].length > 0) { | |
| options.locations = array_flat(array_map([options.locations], arrayToLatLng, false)); | |
| } | |
| } | |
| var callback = options.callback; | |
| delete options.callback; | |
| var service = new google.maps.ElevationService(); | |
| //location request | |
| if (!options.path) { | |
| delete options.path; | |
| delete options.samples; | |
| service.getElevationForLocations(options, function (result, status) { | |
| if (callback && typeof (callback) === "function") { | |
| callback(result, status); | |
| } | |
| }); | |
| //path request | |
| } else { | |
| var pathRequest = { | |
| path: options.locations, | |
| samples: options.samples | |
| }; | |
| service.getElevationAlongPath(pathRequest, function (result, status) { | |
| if (callback && typeof (callback) === "function") { | |
| callback(result, status); | |
| } | |
| }); | |
| } | |
| }; | |
| GMaps.prototype.cleanRoute = GMaps.prototype.removePolylines; | |
| GMaps.prototype.drawRoute = function (options) { | |
| var self = this; | |
| this.getRoutes({ | |
| origin: options.origin, | |
| destination: options.destination, | |
| travelMode: options.travelMode, | |
| waypoints: options.waypoints, | |
| unitSystem: options.unitSystem, | |
| error: options.error, | |
| callback: function (e) { | |
| if (e.length > 0) { | |
| self.drawPolyline({ | |
| path: e[e.length - 1].overview_path, | |
| strokeColor: options.strokeColor, | |
| strokeOpacity: options.strokeOpacity, | |
| strokeWeight: options.strokeWeight | |
| }); | |
| if (options.callback) { | |
| options.callback(e[e.length - 1]); | |
| } | |
| } | |
| } | |
| }); | |
| }; | |
| GMaps.prototype.travelRoute = function (options) { | |
| if (options.origin && options.destination) { | |
| this.getRoutes({ | |
| origin: options.origin, | |
| destination: options.destination, | |
| travelMode: options.travelMode, | |
| waypoints: options.waypoints, | |
| error: options.error, | |
| callback: function (e) { | |
| //start callback | |
| if (e.length > 0 && options.start) { | |
| options.start(e[e.length - 1]); | |
| } | |
| //step callback | |
| if (e.length > 0 && options.step) { | |
| var route = e[e.length - 1]; | |
| if (route.legs.length > 0) { | |
| var steps = route.legs[0].steps; | |
| for (var i = 0, step; step = steps[i]; i++) { | |
| step.step_number = i; | |
| options.step(step, (route.legs[0].steps.length - 1)); | |
| } | |
| } | |
| } | |
| //end callback | |
| if (e.length > 0 && options.end) { | |
| options.end(e[e.length - 1]); | |
| } | |
| } | |
| }); | |
| } | |
| else if (options.route) { | |
| if (options.route.legs.length > 0) { | |
| var steps = options.route.legs[0].steps; | |
| for (var i = 0, step; step = steps[i]; i++) { | |
| step.step_number = i; | |
| options.step(step); | |
| } | |
| } | |
| } | |
| }; | |
| GMaps.prototype.drawSteppedRoute = function (options) { | |
| var self = this; | |
| if (options.origin && options.destination) { | |
| this.getRoutes({ | |
| origin: options.origin, | |
| destination: options.destination, | |
| travelMode: options.travelMode, | |
| waypoints: options.waypoints, | |
| error: options.error, | |
| callback: function (e) { | |
| //start callback | |
| if (e.length > 0 && options.start) { | |
| options.start(e[e.length - 1]); | |
| } | |
| //step callback | |
| if (e.length > 0 && options.step) { | |
| var route = e[e.length - 1]; | |
| if (route.legs.length > 0) { | |
| var steps = route.legs[0].steps; | |
| for (var i = 0, step; step = steps[i]; i++) { | |
| step.step_number = i; | |
| self.drawPolyline({ | |
| path: step.path, | |
| strokeColor: options.strokeColor, | |
| strokeOpacity: options.strokeOpacity, | |
| strokeWeight: options.strokeWeight | |
| }); | |
| options.step(step, (route.legs[0].steps.length - 1)); | |
| } | |
| } | |
| } | |
| //end callback | |
| if (e.length > 0 && options.end) { | |
| options.end(e[e.length - 1]); | |
| } | |
| } | |
| }); | |
| } | |
| else if (options.route) { | |
| if (options.route.legs.length > 0) { | |
| var steps = options.route.legs[0].steps; | |
| for (var i = 0, step; step = steps[i]; i++) { | |
| step.step_number = i; | |
| self.drawPolyline({ | |
| path: step.path, | |
| strokeColor: options.strokeColor, | |
| strokeOpacity: options.strokeOpacity, | |
| strokeWeight: options.strokeWeight | |
| }); | |
| options.step(step); | |
| } | |
| } | |
| } | |
| }; | |
| GMaps.Route = function (options) { | |
| this.origin = options.origin; | |
| this.destination = options.destination; | |
| this.waypoints = options.waypoints; | |
| this.map = options.map; | |
| this.route = options.route; | |
| this.step_count = 0; | |
| this.steps = this.route.legs[0].steps; | |
| this.steps_length = this.steps.length; | |
| this.polyline = this.map.drawPolyline({ | |
| path: new google.maps.MVCArray(), | |
| strokeColor: options.strokeColor, | |
| strokeOpacity: options.strokeOpacity, | |
| strokeWeight: options.strokeWeight | |
| }).getPath(); | |
| }; | |
| GMaps.Route.prototype.getRoute = function (options) { | |
| var self = this; | |
| this.map.getRoutes({ | |
| origin: this.origin, | |
| destination: this.destination, | |
| travelMode: options.travelMode, | |
| waypoints: this.waypoints || [], | |
| error: options.error, | |
| callback: function () { | |
| self.route = e[0]; | |
| if (options.callback) { | |
| options.callback.call(self); | |
| } | |
| } | |
| }); | |
| }; | |
| GMaps.Route.prototype.back = function () { | |
| if (this.step_count > 0) { | |
| this.step_count--; | |
| var path = this.route.legs[0].steps[this.step_count].path; | |
| for (var p in path) { | |
| if (path.hasOwnProperty(p)) { | |
| this.polyline.pop(); | |
| } | |
| } | |
| } | |
| }; | |
| GMaps.Route.prototype.forward = function () { | |
| if (this.step_count < this.steps_length) { | |
| var path = this.route.legs[0].steps[this.step_count].path; | |
| for (var p in path) { | |
| if (path.hasOwnProperty(p)) { | |
| this.polyline.push(path[p]); | |
| } | |
| } | |
| this.step_count++; | |
| } | |
| }; | |
| GMaps.prototype.checkGeofence = function (lat, lng, fence) { | |
| return fence.containsLatLng(new google.maps.LatLng(lat, lng)); | |
| }; | |
| GMaps.prototype.checkMarkerGeofence = function (marker, outside_callback) { | |
| if (marker.fences) { | |
| for (var i = 0, fence; fence = marker.fences[i]; i++) { | |
| var pos = marker.getPosition(); | |
| if (!this.checkGeofence(pos.lat(), pos.lng(), fence)) { | |
| outside_callback(marker, fence); | |
| } | |
| } | |
| } | |
| }; | |
| GMaps.prototype.toImage = function (options) { | |
| var options = options || {}, | |
| static_map_options = {}; | |
| static_map_options['size'] = options['size'] || [this.el.clientWidth, this.el.clientHeight]; | |
| static_map_options['lat'] = this.getCenter().lat(); | |
| static_map_options['lng'] = this.getCenter().lng(); | |
| if (this.markers.length > 0) { | |
| static_map_options['markers'] = []; | |
| for (var i = 0; i < this.markers.length; i++) { | |
| static_map_options['markers'].push({ | |
| lat: this.markers[i].getPosition().lat(), | |
| lng: this.markers[i].getPosition().lng() | |
| }); | |
| } | |
| } | |
| if (this.polylines.length > 0) { | |
| var polyline = this.polylines[0]; | |
| static_map_options['polyline'] = {}; | |
| static_map_options['polyline']['path'] = google.maps.geometry.encoding.encodePath(polyline.getPath()); | |
| static_map_options['polyline']['strokeColor'] = polyline.strokeColor | |
| static_map_options['polyline']['strokeOpacity'] = polyline.strokeOpacity | |
| static_map_options['polyline']['strokeWeight'] = polyline.strokeWeight | |
| } | |
| return GMaps.staticMapURL(static_map_options); | |
| }; | |
| GMaps.staticMapURL = function (options) { | |
| var parameters = [], | |
| data, | |
| static_root = 'http://maps.googleapis.com/maps/api/staticmap'; | |
| if (options.url) { | |
| static_root = options.url; | |
| delete options.url; | |
| } | |
| static_root += '?'; | |
| var markers = options.markers; | |
| delete options.markers; | |
| if (!markers && options.marker) { | |
| markers = [options.marker]; | |
| delete options.marker; | |
| } | |
| var styles = options.styles; | |
| delete options.styles; | |
| var polyline = options.polyline; | |
| delete options.polyline; | |
| /** Map options **/ | |
| if (options.center) { | |
| parameters.push('center=' + options.center); | |
| delete options.center; | |
| } | |
| else if (options.address) { | |
| parameters.push('center=' + options.address); | |
| delete options.address; | |
| } | |
| else if (options.lat) { | |
| parameters.push(['center=', options.lat, ',', options.lng].join('')); | |
| delete options.lat; | |
| delete options.lng; | |
| } | |
| else if (options.visible) { | |
| var visible = encodeURI(options.visible.join('|')); | |
| parameters.push('visible=' + visible); | |
| } | |
| var size = options.size; | |
| if (size) { | |
| if (size.join) { | |
| size = size.join('x'); | |
| } | |
| delete options.size; | |
| } | |
| else { | |
| size = '630x300'; | |
| } | |
| parameters.push('size=' + size); | |
| if (!options.zoom && options.zoom !== false) { | |
| options.zoom = 15; | |
| } | |
| var sensor = options.hasOwnProperty('sensor') ? !!options.sensor : true; | |
| delete options.sensor; | |
| parameters.push('sensor=' + sensor); | |
| for (var param in options) { | |
| if (options.hasOwnProperty(param)) { | |
| parameters.push(param + '=' + options[param]); | |
| } | |
| } | |
| /** Markers **/ | |
| if (markers) { | |
| var marker, loc; | |
| for (var i = 0; data = markers[i]; i++) { | |
| marker = []; | |
| if (data.size && data.size !== 'normal') { | |
| marker.push('size:' + data.size); | |
| delete data.size; | |
| } | |
| else if (data.icon) { | |
| marker.push('icon:' + encodeURI(data.icon)); | |
| delete data.icon; | |
| } | |
| if (data.color) { | |
| marker.push('color:' + data.color.replace('#', '0x')); | |
| delete data.color; | |
| } | |
| if (data.label) { | |
| marker.push('label:' + data.label[0].toUpperCase()); | |
| delete data.label; | |
| } | |
| loc = (data.address ? data.address : data.lat + ',' + data.lng); | |
| delete data.address; | |
| delete data.lat; | |
| delete data.lng; | |
| for (var param in data) { | |
| if (data.hasOwnProperty(param)) { | |
| marker.push(param + ':' + data[param]); | |
| } | |
| } | |
| if (marker.length || i === 0) { | |
| marker.push(loc); | |
| marker = marker.join('|'); | |
| parameters.push('markers=' + encodeURI(marker)); | |
| } | |
| // New marker without styles | |
| else { | |
| marker = parameters.pop() + encodeURI('|' + loc); | |
| parameters.push(marker); | |
| } | |
| } | |
| } | |
| /** Map Styles **/ | |
| if (styles) { | |
| for (var i = 0; i < styles.length; i++) { | |
| var styleRule = []; | |
| if (styles[i].featureType && styles[i].featureType != 'all') { | |
| styleRule.push('feature:' + styles[i].featureType); | |
| } | |
| if (styles[i].elementType && styles[i].elementType != 'all') { | |
| styleRule.push('element:' + styles[i].elementType); | |
| } | |
| for (var j = 0; j < styles[i].stylers.length; j++) { | |
| for (var p in styles[i].stylers[j]) { | |
| var ruleArg = styles[i].stylers[j][p]; | |
| if (p == 'hue' || p == 'color') { | |
| ruleArg = '0x' + ruleArg.substring(1); | |
| } | |
| styleRule.push(p + ':' + ruleArg); | |
| } | |
| } | |
| var rule = styleRule.join('|'); | |
| if (rule != '') { | |
| parameters.push('style=' + rule); | |
| } | |
| } | |
| } | |
| /** Polylines **/ | |
| function parseColor(color, opacity) { | |
| if (color[0] === '#') { | |
| color = color.replace('#', '0x'); | |
| if (opacity) { | |
| opacity = parseFloat(opacity); | |
| opacity = Math.min(1, Math.max(opacity, 0)); | |
| if (opacity === 0) { | |
| return '0x00000000'; | |
| } | |
| opacity = (opacity * 255).toString(16); | |
| if (opacity.length === 1) { | |
| opacity += opacity; | |
| } | |
| color = color.slice(0, 8) + opacity; | |
| } | |
| } | |
| return color; | |
| } | |
| if (polyline) { | |
| data = polyline; | |
| polyline = []; | |
| if (data.strokeWeight) { | |
| polyline.push('weight:' + parseInt(data.strokeWeight, 10)); | |
| } | |
| if (data.strokeColor) { | |
| var color = parseColor(data.strokeColor, data.strokeOpacity); | |
| polyline.push('color:' + color); | |
| } | |
| if (data.fillColor) { | |
| var fillcolor = parseColor(data.fillColor, data.fillOpacity); | |
| polyline.push('fillcolor:' + fillcolor); | |
| } | |
| var path = data.path; | |
| if (path.join) { | |
| for (var j = 0, pos; pos = path[j]; j++) { | |
| polyline.push(pos.join(',')); | |
| } | |
| } | |
| else { | |
| polyline.push('enc:' + path); | |
| } | |
| polyline = polyline.join('|'); | |
| parameters.push('path=' + encodeURI(polyline)); | |
| } | |
| /** Retina support **/ | |
| var dpi = window.devicePixelRatio || 1; | |
| parameters.push('scale=' + dpi); | |
| parameters = parameters.join('&'); | |
| return static_root + parameters; | |
| }; | |
| GMaps.prototype.addMapType = function (mapTypeId, options) { | |
| if (options.hasOwnProperty("getTileUrl") && typeof (options["getTileUrl"]) == "function") { | |
| options.tileSize = options.tileSize || new google.maps.Size(256, 256); | |
| var mapType = new google.maps.ImageMapType(options); | |
| this.map.mapTypes.set(mapTypeId, mapType); | |
| } | |
| else { | |
| throw "'getTileUrl' function required."; | |
| } | |
| }; | |
| GMaps.prototype.addOverlayMapType = function (options) { | |
| if (options.hasOwnProperty("getTile") && typeof (options["getTile"]) == "function") { | |
| var overlayMapTypeIndex = options.index; | |
| delete options.index; | |
| this.map.overlayMapTypes.insertAt(overlayMapTypeIndex, options); | |
| } | |
| else { | |
| throw "'getTile' function required."; | |
| } | |
| }; | |
| GMaps.prototype.removeOverlayMapType = function (overlayMapTypeIndex) { | |
| this.map.overlayMapTypes.removeAt(overlayMapTypeIndex); | |
| }; | |
| GMaps.prototype.addStyle = function (options) { | |
| var styledMapType = new google.maps.StyledMapType(options.styles, { name: options.styledMapName }); | |
| this.map.mapTypes.set(options.mapTypeId, styledMapType); | |
| }; | |
| GMaps.prototype.setStyle = function (mapTypeId) { | |
| this.map.setMapTypeId(mapTypeId); | |
| }; | |
| GMaps.prototype.createPanorama = function (streetview_options) { | |
| if (!streetview_options.hasOwnProperty('lat') || !streetview_options.hasOwnProperty('lng')) { | |
| streetview_options.lat = this.getCenter().lat(); | |
| streetview_options.lng = this.getCenter().lng(); | |
| } | |
| this.panorama = GMaps.createPanorama(streetview_options); | |
| this.map.setStreetView(this.panorama); | |
| return this.panorama; | |
| }; | |
| GMaps.createPanorama = function (options) { | |
| var el = getElementById(options.el, options.context); | |
| options.position = new google.maps.LatLng(options.lat, options.lng); | |
| delete options.el; | |
| delete options.context; | |
| delete options.lat; | |
| delete options.lng; | |
| var streetview_events = ['closeclick', 'links_changed', 'pano_changed', 'position_changed', 'pov_changed', 'resize', 'visible_changed'], | |
| streetview_options = extend_object({ visible: true }, options); | |
| for (var i = 0; i < streetview_events.length; i++) { | |
| delete streetview_options[streetview_events[i]]; | |
| } | |
| var panorama = new google.maps.StreetViewPanorama(el, streetview_options); | |
| for (var i = 0; i < streetview_events.length; i++) { | |
| (function (object, name) { | |
| if (options[name]) { | |
| google.maps.event.addListener(object, name, function () { | |
| options[name].apply(this); | |
| }); | |
| } | |
| })(panorama, streetview_events[i]); | |
| } | |
| return panorama; | |
| }; | |
| GMaps.prototype.on = function (event_name, handler) { | |
| return GMaps.on(event_name, this, handler); | |
| }; | |
| GMaps.prototype.off = function (event_name) { | |
| GMaps.off(event_name, this); | |
| }; | |
| GMaps.custom_events = ['marker_added', 'marker_removed', 'polyline_added', 'polyline_removed', 'polygon_added', 'polygon_removed', 'geolocated', 'geolocation_failed']; | |
| GMaps.on = function (event_name, object, handler) { | |
| if (GMaps.custom_events.indexOf(event_name) == -1) { | |
| return google.maps.event.addListener(object, event_name, handler); | |
| } | |
| else { | |
| var registered_event = { | |
| handler: handler, | |
| eventName: event_name | |
| }; | |
| object.registered_events[event_name] = object.registered_events[event_name] || []; | |
| object.registered_events[event_name].push(registered_event); | |
| return registered_event; | |
| } | |
| }; | |
| GMaps.off = function (event_name, object) { | |
| if (GMaps.custom_events.indexOf(event_name) == -1) { | |
| google.maps.event.clearListeners(object, event_name); | |
| } | |
| else { | |
| object.registered_events[event_name] = []; | |
| } | |
| }; | |
| GMaps.fire = function (event_name, object, scope) { | |
| if (GMaps.custom_events.indexOf(event_name) == -1) { | |
| google.maps.event.trigger(object, event_name, Array.prototype.slice.apply(arguments).slice(2)); | |
| } | |
| else { | |
| if (event_name in scope.registered_events) { | |
| var firing_events = scope.registered_events[event_name]; | |
| for (var i = 0; i < firing_events.length; i++) { | |
| (function (handler, scope, object) { | |
| handler.apply(scope, [object]); | |
| })(firing_events[i]['handler'], scope, object); | |
| } | |
| } | |
| } | |
| }; | |
| GMaps.geolocate = function (options) { | |
| var complete_callback = options.always || options.complete; | |
| if (navigator.geolocation) { | |
| navigator.geolocation.getCurrentPosition(function (position) { | |
| options.success(position); | |
| if (complete_callback) { | |
| complete_callback(); | |
| } | |
| }, function (error) { | |
| options.error(error); | |
| if (complete_callback) { | |
| complete_callback(); | |
| } | |
| }, options.options); | |
| } | |
| else { | |
| options.not_supported(); | |
| if (complete_callback) { | |
| complete_callback(); | |
| } | |
| } | |
| }; | |
| GMaps.geocode = function (options) { | |
| this.geocoder = new google.maps.Geocoder(); | |
| var callback = options.callback; | |
| if (options.hasOwnProperty('lat') && options.hasOwnProperty('lng')) { | |
| options.latLng = new google.maps.LatLng(options.lat, options.lng); | |
| } | |
| delete options.lat; | |
| delete options.lng; | |
| delete options.callback; | |
| this.geocoder.geocode(options, function (results, status) { | |
| callback(results, status); | |
| }); | |
| }; | |
| //========================== | |
| // Polygon containsLatLng | |
| // https://github.com/tparkin/Google-Maps-Point-in-Polygon | |
| // Poygon getBounds extension - google-maps-extensions | |
| // http://code.google.com/p/google-maps-extensions/source/browse/google.maps.Polygon.getBounds.js | |
| if (!google.maps.Polygon.prototype.getBounds) { | |
| google.maps.Polygon.prototype.getBounds = function (latLng) { | |
| var bounds = new google.maps.LatLngBounds(); | |
| var paths = this.getPaths(); | |
| var path; | |
| for (var p = 0; p < paths.getLength() ; p++) { | |
| path = paths.getAt(p); | |
| for (var i = 0; i < path.getLength() ; i++) { | |
| bounds.extend(path.getAt(i)); | |
| } | |
| } | |
| return bounds; | |
| }; | |
| } | |
| if (!google.maps.Polygon.prototype.containsLatLng) { | |
| // Polygon containsLatLng - method to determine if a latLng is within a polygon | |
| google.maps.Polygon.prototype.containsLatLng = function (latLng) { | |
| // Exclude points outside of bounds as there is no way they are in the poly | |
| var bounds = this.getBounds(); | |
| if (bounds !== null && !bounds.contains(latLng)) { | |
| return false; | |
| } | |
| // Raycast point in polygon method | |
| var inPoly = false; | |
| var numPaths = this.getPaths().getLength(); | |
| for (var p = 0; p < numPaths; p++) { | |
| var path = this.getPaths().getAt(p); | |
| var numPoints = path.getLength(); | |
| var j = numPoints - 1; | |
| for (var i = 0; i < numPoints; i++) { | |
| var vertex1 = path.getAt(i); | |
| var vertex2 = path.getAt(j); | |
| if (vertex1.lng() < latLng.lng() && vertex2.lng() >= latLng.lng() || vertex2.lng() < latLng.lng() && vertex1.lng() >= latLng.lng()) { | |
| if (vertex1.lat() + (latLng.lng() - vertex1.lng()) / (vertex2.lng() - vertex1.lng()) * (vertex2.lat() - vertex1.lat()) < latLng.lat()) { | |
| inPoly = !inPoly; | |
| } | |
| } | |
| j = i; | |
| } | |
| } | |
| return inPoly; | |
| }; | |
| } | |
| google.maps.LatLngBounds.prototype.containsLatLng = function (latLng) { | |
| return this.contains(latLng); | |
| }; | |
| google.maps.Marker.prototype.setFences = function (fences) { | |
| this.fences = fences; | |
| }; | |
| google.maps.Marker.prototype.addFence = function (fence) { | |
| this.fences.push(fence); | |
| }; | |
| google.maps.Marker.prototype.getId = function () { | |
| return this['__gm_id']; | |
| }; | |
| //========================== | |
| // Array indexOf | |
| // https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/indexOf | |
| if (!Array.prototype.indexOf) { | |
| Array.prototype.indexOf = function (searchElement /*, fromIndex */) { | |
| "use strict"; | |
| if (this == null) { | |
| throw new TypeError(); | |
| } | |
| var t = Object(this); | |
| var len = t.length >>> 0; | |
| if (len === 0) { | |
| return -1; | |
| } | |
| var n = 0; | |
| if (arguments.length > 1) { | |
| n = Number(arguments[1]); | |
| if (n != n) { // shortcut for verifying if it's NaN | |
| n = 0; | |
| } else if (n != 0 && n != Infinity && n != -Infinity) { | |
| n = (n > 0 || -1) * Math.floor(Math.abs(n)); | |
| } | |
| } | |
| if (n >= len) { | |
| return -1; | |
| } | |
| var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); | |
| for (; k < len; k++) { | |
| if (k in t && t[k] === searchElement) { | |
| return k; | |
| } | |
| } | |
| return -1; | |
| } | |
| } | |
| return GMaps; | |
| })); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment