UNPKG

cordova-plugin-googlemaps

Version:
1,468 lines (1,318 loc) 95.3 kB
/* global cordova, plugin, CSSPrimitiveValue */ var PLUGIN_NAME = 'GoogleMaps'; var MARKERS = {}; var KML_LAYERS = {}; var OVERLAYS = {}; // Anti the .nav-decor class of ionic framework var navDecorBlocker = document.createElement("style"); navDecorBlocker.setAttribute("type", "text/css"); navDecorBlocker.innerText = [ "._gmaps_cdv_ .nav-decor {", " background-color: rgba(0,0,0,0) !important;", " background: rgba(0,0,0,0) !important;", " display:none !important;", "}" ].join(""); document.head.appendChild(navDecorBlocker); /** * Google Maps model. */ var BaseClass = function() { var self = this; var _vars = {}; var _listeners = {}; self.empty = function() { for (var key in Object.keys(_vars)) { _vars[key] = null; delete _vars[key]; } }; self.deleteFromObject = function(object, type) { if (object === null) return object; for(var index in Object.keys(object)) { var key = Object.keys(object)[index]; if (typeof object[key] === 'object') { object[key] = self.deleteFromObject(object[key], type); } else if (typeof object[key] === type) { delete object[key]; } } return object; }; self.get = function(key) { return key in _vars ? _vars[key] : null; }; self.set = function(key, value) { if (_vars[key] !== value) { self.trigger(key + "_changed", _vars[key], value); } _vars[key] = value; }; self.trigger = function(eventName) { var args = []; for (var i = 1; i < arguments.length; i++) { args.push(arguments[i]); } var event = document.createEvent('Event'); event.initEvent(eventName, false, false); event.mydata = args; event.myself = self; document.dispatchEvent(event); }; self.on = function(eventName, callback) { _listeners[eventName] = _listeners[eventName] || []; var listener = function(e) { if (!e.myself || e.myself !== self) { return; } callback.apply(self, e.mydata); }; document.addEventListener(eventName, listener, false); _listeners[eventName].push({ 'callback': callback, 'listener': listener }); }; self.addEventListener = self.on; self.off = function(eventName, callback) { var i; if (typeof eventName === "string") { if (eventName in _listeners) { if (typeof callback === "function") { for (i = 0; i < _listeners[eventName].length; i++) { if (_listeners[eventName][i].callback === callback) { document.removeEventListener(eventName, _listeners[eventName][i].listener); _listeners[eventName].splice(i, 1); break; } } } else { for (i = 0; i < _listeners[eventName].length; i++) { document.removeEventListener(eventName, _listeners[eventName][i].listener); } delete _listeners[eventName]; } } } else { //Remove all event listeners except 'keepWatching_changed' var eventNames = Object.keys(_listeners); for (i = 0; i < eventNames.length; i++) { eventName = eventNames[i]; if ( eventName !== 'keepWatching_changed' ) { for (var j = 0; j < _listeners[eventName].length; j++) { document.removeEventListener(eventName, _listeners[eventName][j].listener); } delete _listeners[eventName]; } } _listeners = {}; } }; self.removeEventListener = self.off; self.one = function(eventName, callback) { _listeners[eventName] = _listeners[eventName] || []; var listener = function(e) { if (!e.myself || e.myself !== self) { return; } callback.apply(self, e.mydata); self.off(eventName, callback); }; document.addEventListener(eventName, listener, false); _listeners[eventName].push({ 'callback': callback, 'listener': listener }); }; self.addEventListenerOnce = self.one; self.errorHandler = function(msg) { if (msg) { console.error(msg); self.trigger('error', msg); } return false; }; return self; }; var App = function() { BaseClass.apply(this); Object.defineProperty(this, "type", { value: "Map", writable: false }); }; App.prototype = new BaseClass(); //------------- // Cluster //------------- App.prototype.updateCluster = function(callback) { var self = this; cordova.exec(function(result) { if (callback) { callback(); }; }, self.errorHandler, PLUGIN_NAME, 'exec', ['GoogleMapsClusterViewController.updateCluster']); }; /* * Callback from Native */ App.prototype._onClusterEvent = function(eventName, obj) { if (isNaN(obj)) { this.trigger.apply(this, ['cluster_click', JSON.parse(obj)]); } }; App.prototype._onMarkerEvent = function(eventName, hashCode) { var marker = MARKERS[hashCode] || null; if (marker) { marker.trigger(eventName, marker); } }; App.prototype._onOverlayEvent = function(eventName, hashCode) { var overlay = OVERLAYS[hashCode] || null; if (overlay) { var args = [eventName, overlay]; for (var i = 2; i < arguments.length; i++) { args.push(arguments[i]); } overlay.trigger.apply(this, args); } }; /* * Callback from Native */ App.prototype._onKmlEvent = function(eventName, objectType, kmlLayerId, result, options) { var kmlLayer = KML_LAYERS[kmlLayerId] || null; if (kmlLayer) { var self = this; var args = [eventName]; if (eventName === "add") { var overlay = null; switch ((objectType + "").toLowerCase()) { case "marker": overlay = new Marker(self, result.id, options); MARKERS[result.id] = overlay; args.push({ "type": "Marker", "object": overlay }); overlay.on(plugin.google.maps.event.MARKER_CLICK, function() { kmlLayer.trigger(plugin.google.maps.event.OVERLAY_CLICK, overlay, overlay.getPosition()); }); break; case "polygon": overlay = new Polygon(self, result.id, options); args.push({ "type": "Polygon", "object": overlay }); overlay.on(plugin.google.maps.event.OVERLAY_CLICK, function(latLng) { kmlLayer.trigger(plugin.google.maps.event.OVERLAY_CLICK, overlay, latLng); }); break; case "polyline": overlay = new Polyline(self, result.id, options); args.push({ "type": "Polyline", "object": overlay }); overlay.on(plugin.google.maps.event.OVERLAY_CLICK, function(latLng) { kmlLayer.trigger(plugin.google.maps.event.OVERLAY_CLICK, overlay, latLng); }); break; } if (overlay) { OVERLAYS[result.id] = overlay; overlay.hashCode = result.hashCode; kmlLayer._overlays.push(overlay); kmlLayer.on("_REMOVE", function() { var idx = kmlLayer._overlays.indexOf(overlay); if (idx > -1) { kmlLayer._overlays.splice(idx, 1); } overlay.remove(); overlay.off(); }); } } else { for (var i = 2; i < arguments.length; i++) { args.push(arguments[i]); } } //kmlLayer.trigger.apply(kmlLayer, args); } }; /** * Callback from Native */ App.prototype._onMapEvent = function(eventName) { var args = [eventName]; for (var i = 1; i < arguments.length; i++) { if (typeof(arguments[i]) === "string") { if (["true", "false"].indexOf(arguments[i].toLowerCase()) > -1) { arguments[i] = parseBoolean(arguments[i]); } } args.push(arguments[i]); } args.push(this); this.trigger.apply(this, args); }; /** * Callback from Native */ App.prototype._onMyLocationChange = function(params) { var location = new Location(params); this.trigger('my_location_change', location, this); }; /** * Callback from Native */ App.prototype._onCameraEvent = function(eventName, params) { var cameraPosition = new CameraPosition(params); this.trigger(eventName, cameraPosition, this); }; App.prototype.getMap = function(div, params) { // Redraw the browser mandatory (especially for iOS) document.body.style.backgroundColor="rgba(0,0,0,0.1)"; var self = this, args = []; if (!isDom(div)) { params = div; params = params || {}; params.backgroundColor = params.backgroundColor || '#ffffff'; params.backgroundColor = HTMLColor2RGBA(params.backgroundColor); if (params.camera && params.camera.latLng) { params.camera.target = params.camera.latLng; delete params.camera.latLng; } args.push(params); } else { var currentDiv = self.get("div"); if (currentDiv !== div && currentDiv) { var children = getAllChildren(currentDiv); for (var i = 0; i < children.length; i++) { element = children[i]; elemId = element.getAttribute("__pluginDomId"); element.removeAttribute("__pluginDomId"); } currentDiv.removeEventListener("DOMNodeRemoved", _remove_child); while (currentDiv) { if (currentDiv.style) { currentDiv.style.backgroundColor = ''; } if (currentDiv.classList) { currentDiv.classList.remove('_gmaps_cdv_'); } else if (currentDiv.className) { currentDiv.className = currentDiv.className.replace(/_gmaps_cdv_/g, ""); currentDiv.className = currentDiv.className.replace(/\s+/g, " "); } currentDiv = currentDiv.parentNode; } self.set("div", null); self.set("keepWatching", false); } var children = getAllChildren(div); params = params || {}; params.backgroundColor = params.backgroundColor || '#ffffff'; params.backgroundColor = HTMLColor2RGBA(params.backgroundColor); if (params.camera && params.camera.latLng) { params.camera.target = params.camera.latLng; delete params.camera.latLng; } if (params.styles) { params.styles = JSON.stringify(params.styles); } args.push(params); self.set("div", div); args.push(getDivRect(div)); var elements = []; var elemId, clickable; for (var i = 0; i < children.length; i++) { element = children[i]; elemId = element.getAttribute("__pluginDomId"); if (!elemId) { elemId = "pgm" + Math.floor(Math.random() * Date.now()) + i; element.setAttribute("__pluginDomId", elemId); } elements.push({ id: elemId, size: getDivRect(element) }); i++; } args.push(elements); div.addEventListener("DOMNodeRemoved", _remove_child); div.addEventListener("DOMNodeInserted", _append_child); self.set("keepWatching", true); var className; while (div.parentNode) { div.style.backgroundColor = 'rgba(0,0,0,0)'; className = div.className; // prevent multiple readding the class if (div.classList && !div.classList.contains('_gmaps_cdv_')) { div.classList.add('_gmaps_cdv_'); } else if (div.className && !div.className.indexOf('_gmaps_cdv_') == -1) { div.className = div.className + ' _gmaps_cdv_'; } div = div.parentNode; } } cordova.exec(function() { setTimeout(function() { self.refreshLayout(); self.trigger(plugin.google.maps.event.MAP_READY, self); }, 100); }, self.errorHandler, PLUGIN_NAME, 'getMap', self.deleteFromObject(args,'function')); return self; }; App.prototype.getLicenseInfo = function(callback) { var self = this; cordova.exec(function(txt) { callback.call(self, txt); }, self.errorHandler, PLUGIN_NAME, 'getLicenseInfo', []); }; /** * @desc get watchDogTimer value for map positioning changes */ App.prototype.getWatchDogTimer = function() { var self = this; time = self.get('watchDogTimer') || 100; return time; }; /** * @desc Set watchDogTimer for map positioning changes */ App.prototype.setWatchDogTimer = function(time) { var self = this; time = time || 100; self.set('watchDogTimer', time); if (time < 50) { //console.log('Warning: watchdog values under 50ms will drain battery a lot. Just use for short operation times.'); } }; function onBackbutton() { _mapInstance.closeDialog(); } /** * @desc Open the map dialog */ App.prototype.showDialog = function() { document.addEventListener("backbutton", onBackbutton, false); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'showDialog', []); }; /** * @desc Close the map dialog */ App.prototype.closeDialog = function() { document.removeEventListener("backbutton", onBackbutton, false); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'closeDialog', []); }; App.prototype.setOptions = function(options) { options = options || {}; if (options.hasOwnProperty('backgroundColor')) { options.backgroundColor = HTMLColor2RGBA(options.backgroundColor); } if (options.camera && options.camera.latLng) { options.camera.target = options.camera.latLng; delete options.camera.latLng; } if (options.styles) { options.styles = JSON.stringify(options.styles); } cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Map.setOptions', this.deleteFromObject(options,'function')]); }; App.prototype.setCenter = function(latLng) { this.set('center', latLng); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Map.setCenter', latLng.lat, latLng.lng]); }; App.prototype.setZoom = function(zoom) { this.set('zoom', zoom); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Map.setZoom', zoom]); }; App.prototype.panBy = function(x, y) { x = parseInt(x, 10); y = parseInt(y, 10); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Map.panBy', x, y]); }; /** * @desc Change the map type * @param {String} mapTypeId Specifies the one of the follow strings: * MAP_TYPE_HYBRID * MAP_TYPE_SATELLITE * MAP_TYPE_TERRAIN * MAP_TYPE_NORMAL * MAP_TYPE_NONE */ App.prototype.setMapTypeId = function(mapTypeId) { if (mapTypeId !== plugin.google.maps.MapTypeId[mapTypeId.replace("MAP_TYPE_", '')]) { return this.errorHandler("Invalid MapTypeId was specified."); } this.set('mapTypeId', mapTypeId); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Map.setMapTypeId', mapTypeId]); }; /** * @desc Change the map view angle * @param {Number} tilt The angle */ App.prototype.setTilt = function(tilt) { this.set('tilt', tilt); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Map.setTilt', tilt]); }; /** * @desc Move the map camera with animation * @params {CameraPosition} cameraPosition New camera position * @params {Function} [callback] This callback is involved when the animation is completed. */ App.prototype.animateCamera = function(cameraPosition, callback) { var self = this; if (cameraPosition.target && cameraPosition.target.type === "LatLngBounds") { cameraPosition.target = [cameraPosition.target.southwest, cameraPosition.target.northeast]; } if (!cameraPosition.hasOwnProperty('zoom')) { self.getZoom(function(zoom) { cameraPosition.zoom = zoom; }); } if (!cameraPosition.hasOwnProperty('tilt')) { self.getTilt(function(tilt) { cameraPosition.tilt = tilt; }); } if (!cameraPosition.hasOwnProperty('bearing')) { self.getBearing(function(bearing) { cameraPosition.bearing = bearing; }); } var self = this; setTimeout(function() { cordova.exec(function() { if (typeof callback === "function") { callback.call(self); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.animateCamera', self.deleteFromObject(cameraPosition,'function')]); }.bind(self), 10); }; /** * @desc Move the map camera without animation * @params {CameraPosition} cameraPosition New camera position * @params {Function} [callback] This callback is involved when the animation is completed. */ App.prototype.moveCamera = function(cameraPosition, callback) { if (cameraPosition.target && cameraPosition.target.type === "LatLngBounds") { cameraPosition.target = [cameraPosition.target.southwest, cameraPosition.target.northeast]; } var self = this; if (!cameraPosition.hasOwnProperty('zoom')) { self.getZoom(function(zoom) { cameraPosition.zoom = zoom; }); } if (!cameraPosition.hasOwnProperty('tilt')) { self.getTilt(function(tilt) { cameraPosition.tilt = tilt; }); } if (!cameraPosition.hasOwnProperty('bearing')) { self.getBearing(function(bearing) { cameraPosition.bearing = bearing; }); } setTimeout(function() { cordova.exec(function() { if (typeof callback === "function") { callback.call(self); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.moveCamera', self.deleteFromObject(cameraPosition,'function')]); }.bind(self), 10); }; App.prototype.setMyLocationEnabled = function(enabled) { enabled = parseBoolean(enabled); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Map.setMyLocationEnabled', enabled]); }; App.prototype.setIndoorEnabled = function(enabled) { enabled = parseBoolean(enabled); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Map.setIndoorEnabled', enabled]); }; App.prototype.setTrafficEnabled = function(enabled) { enabled = parseBoolean(enabled); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Map.setTrafficEnabled', enabled]); }; App.prototype.setCompassEnabled = function(enabled) { var self = this; enabled = parseBoolean(enabled); cordova.exec(null, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.setCompassEnabled', enabled]); }; App.prototype.getMyLocation = function(params, success_callback, error_callback) { var args = [params || {}, success_callback || null, error_callback]; if (typeof args[0] === "function") { args.unshift({}); } params = args[0]; success_callback = args[1]; error_callback = args[2]; params.enableHighAccuracy = params.enableHighAccuracy === true; var self = this; var successHandler = function(location) { if (typeof success_callback === "function") { location.latLng = new LatLng(location.latLng.lat, location.latLng.lng); success_callback.call(self, location); } }; var errorHandler = function(result) { if (typeof error_callback === "function") { error_callback.call(self, result); } }; cordova.exec(successHandler, errorHandler, PLUGIN_NAME, 'getMyLocation', [self.deleteFromObject(params,'function')]); }; App.prototype.getFocusedBuilding = function(callback) { var self = this; cordova.exec(callback, this.errorHandler, PLUGIN_NAME, 'getFocusedBuilding', []); }; App.prototype.setVisible = function(isVisible) { var self = this; isVisible = parseBoolean(isVisible); cordova.exec(null, self.errorHandler, PLUGIN_NAME, 'setVisible', [isVisible]); }; App.prototype.setClickable = function(isClickable) { var self = this; isClickable = parseBoolean(isClickable); cordova.exec(null, self.errorHandler, PLUGIN_NAME, 'pluginLayer_setClickable', [isClickable]); }; App.prototype.setBackgroundColor = function(color) { this.set('strokeColor', color); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'pluginLayer_setBackGroundColor', [HTMLColor2RGBA(color)]); }; App.prototype.setDebuggable = function(debug) { var self = this; debug = parseBoolean(debug); cordova.exec(null, self.errorHandler, PLUGIN_NAME, 'pluginLayer_setDebuggable', [debug]); }; /** * Sets the preference for whether all gestures should be enabled or disabled. */ App.prototype.setAllGesturesEnabled = function(enabled) { var self = this; enabled = parseBoolean(enabled); cordova.exec(null, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.setAllGesturesEnabled', enabled]); }; /** * Return the current position of the camera * @return {CameraPosition} */ App.prototype.getCameraPosition = function(callback) { var self = this; cordova.exec(function(camera) { if (typeof callback === "function") { camera.target = new LatLng(camera.target.lat, camera.target.lng); callback.call(self, camera); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.getCameraPosition']); }; App.prototype.getZoom = function(callback) { var self = this; cordova.exec(function(camera) { if (typeof callback === "function") { callback.call(self, camera.zoom); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.getCameraPosition']); }; App.prototype.getTilt = function(callback) { var self = this; cordova.exec(function(camera) { if (typeof callback === "function") { callback.call(self, camera.tilt); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.getCameraPosition']); }; App.prototype.getBearing = function(callback) { var self = this; cordova.exec(function(camera) { if (typeof callback === "function") { callback.call(self, camera.bearing); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.getCameraPosition']); }; /** * Clears all markup that has been added to the map, * including markers, polylines and ground overlays. */ App.prototype.clear = function(callback) { var self = this; var clearObj = function (obj) { var ids = Object.keys(obj); var id; for (var i = 0; i < ids.length; i++) { id = ids[i]; obj[id].off(); delete obj[id]; } obj = {}; }; clearObj(OVERLAYS); clearObj(MARKERS); clearObj(KML_LAYERS); cordova.exec(function() { if (typeof callback === "function") { callback.call(self); } }, self.errorHandler, PLUGIN_NAME, 'clear', []); }; /** * Remove the map completely. */ App.prototype.remove = function(callback) { var self = this; var div = this.get('div'); if (div) { while (div) { if (div.style) { div.style.backgroundColor = ''; } if (div.classList) { div.classList.remove('_gmaps_cdv_'); } else if (div.className) { div.className = div.className.replace(/_gmaps_cdv_/g, ""); div.className = div.className.replace(/\s+/g, " "); } div = div.parentNode; } } this.set('div', undefined); self.set("keepWatching", false); this.clear(); this.empty(); this.off(); cordova.exec(function() { if (typeof callback === "function") { callback.call(self); } }, self.errorHandler, PLUGIN_NAME, 'remove', []); }; App.prototype.refreshLayout = function() { onMapResize(undefined, false); }; App.prototype.isAvailable = function(callback) { var self = this; /* var tmpmap = plugin.google.maps.Map.getMap(document.createElement("div"), {}); tmpmap.remove(); tmpmap = null; */ cordova.exec(function() { if (typeof callback === "function") { callback.call(self, true); } }, function(message) { if (typeof callback === "function") { callback.call(self, false, message); } }, PLUGIN_NAME, 'isAvailable', ['']); }; App.prototype.toDataURL = function(params, callback) { var args = [params || {}, callback]; if (typeof args[0] === "function") { args.unshift({}); } params = args[0]; callback = args[1]; params.uncompress = params.uncompress === true; var self = this; cordova.exec(function(image) { if (typeof callback === "function") { callback.call(self, image); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.toDataURL', self.deleteFromObject(params,'function')]); }; var _append_child = function(event) { event = event || window.event; event = event || {}; var target = event.srcElement; if (!target || "nodeType" in target == false) { return; } if (target.nodeType != 1) { return; } var size = getDivRect(target); var elemId = "pgm" + Math.floor(Math.random() * Date.now()); target.setAttribute("__pluginDomId", elemId); cordova.exec(null, null, PLUGIN_NAME, 'pluginLayer_pushHtmlElement', [elemId, size]); }; var _remove_child = function(event) { event = event || window.event; event = event || {}; var target = event.srcElement; if (!target || "nodeType" in target == false) { return; } if (target.nodeType != 1) { return; } var elemId = target.getAttribute("__pluginDomId"); if (!elemId) { return; } target.removeAttribute("__pluginDomId"); cordova.exec(null, null, PLUGIN_NAME, 'pluginLayer_removeHtmlElement', [elemId]); }; /** * Show the map into the specified div. */ App.prototype.setDiv = function(div) { var self = this, args = [], element; var currentDiv = self.get("div"); if (isDom(div) === false || currentDiv !== div) { if (currentDiv) { var children = getAllChildren(currentDiv); for (var i = 0; i < children.length; i++) { element = children[i]; elemId = element.getAttribute("__pluginDomId"); element.removeAttribute("__pluginDomId"); } currentDiv.removeEventListener("DOMNodeRemoved", _remove_child); while (currentDiv) { if (currentDiv.style) { currentDiv.style.backgroundColor = ''; } if (currentDiv.classList) { currentDiv.classList.remove('_gmaps_cdv_'); } else if (currentDiv.className) { currentDiv.className = currentDiv.className.replace(/_gmaps_cdv_/g, ""); currentDiv.className = currentDiv.className.replace(/\s+/g, " "); } currentDiv = currentDiv.parentNode; } } self.set("div", null); self.set("keepWatching", false); } if (isDom(div)) { var children = getAllChildren(div);; self.set("div", div); args.push(getDivRect(div)); var elements = []; var elemId; var clickable; for (var i = 0; i < children.length; i++) { element = children[i]; if (element.nodeType != 1) { continue; } clickable = element.getAttribute("data-clickable"); if (clickable && parseBoolean(clickable) == false) { continue; } elemId = element.getAttribute("__pluginDomId"); if (!elemId) { elemId = "pgm" + Math.floor(Math.random() * Date.now()) + i; element.setAttribute("__pluginDomId", elemId); } elements.push({ id: elemId, size: getDivRect(element) }); } args.push(elements); div.addEventListener("DOMNodeRemoved", _remove_child); div.addEventListener("DOMNodeInserted", _append_child); var className; while (div.parentNode) { div.style.backgroundColor = 'rgba(0,0,0,0)'; div.style.backgroundImage = ''; className = div.className; // prevent multiple reading the class if (div.classList && !div.classList.contains('_gmaps_cdv_')) { div.classList.add('_gmaps_cdv_'); } else if (div.className && !div.className.indexOf('_gmaps_cdv_') == -1) { div.className = div.className + ' _gmaps_cdv_'; } div = div.parentNode; } setTimeout(function() { self.refreshLayout(); self.set("keepWatching", true); }, 1000); } cordova.exec(null, self.errorHandler, PLUGIN_NAME, 'setDiv', self.deleteFromObject(args,'function')); }; /** * Return the visible region of the map. * Thanks @fschmidt */ App.prototype.getVisibleRegion = function(callback) { var self = this; cordova.exec(function(result) { if (typeof callback === "function") { var latLngBounds = new LatLngBounds(result.latLngArray); latLngBounds.northeast = new LatLng(result.northeast.lat, result.northeast.lng); latLngBounds.southwest = new LatLng(result.southwest.lat, result.southwest.lng); callback.call(self, latLngBounds); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.getVisibleRegion']); }; /** * Maps an Earth coordinate to a point coordinate in the map's view. */ App.prototype.fromLatLngToPoint = function(latLng, callback) { var self = this; if ("lat" in latLng && "lng" in latLng) { cordova.exec(function(result) { if (typeof callback === "function") { callback.call(self, result); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.fromLatLngToPoint', latLng.lat, latLng.lng]); } else { if (typeof callback === "function") { callback.call(self, [undefined, undefined]); } } }; /** * Maps a point coordinate in the map's view to an Earth coordinate. */ App.prototype.fromPointToLatLng = function(pixel, callback) { var self = this; if (pixel.length == 2 && Array.isArray(pixel)) { cordova.exec(function(result) { if (typeof callback === "function") { var latLng = new LatLng(result[0] || 0, result[1] || 0); callback.call(self, result); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.fromPointToLatLng', pixel[0], pixel[1]]); } else { if (typeof callback === "function") { callback.call(self, [undefined, undefined]); } } }; App.prototype.setPadding = function(p1, p2, p3, p4) { if (arguments.length === 0 || arguments.length > 4) { return; } var padding = {}; padding.top = parseInt(p1, 10); switch (arguments.length) { case 4: // top right bottom left padding.right = parseInt(p2, 10); padding.bottom = parseInt(p3, 10); padding.left = parseInt(p4, 10); break; case 3: // top right&left bottom padding.right = parseInt(p2, 10); padding.left = padding.right; padding.bottom = parseInt(p3, 10); break; case 2: // top & bottom right&left padding.bottom = parseInt(p1, 10); padding.right = parseInt(p2, 10); padding.left = padding.right; break; case 1: // top & bottom right & left padding.bottom = padding.top; padding.right = padding.top; padding.left = padding.top; break; } cordova.exec(function(result) { if (typeof callback === "function") { var latLng = new LatLng(result[0] || 0, result[1] || 0); callback.call(self, result); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Map.setPadding', padding]); }; //------------- // Marker //------------- App.prototype.addMarker = function(markerOptions, callback) { var self = this; markerOptions.animation = markerOptions.animation || undefined; markerOptions.position = markerOptions.position || {}; markerOptions.position.lat = markerOptions.position.lat || 0.0; markerOptions.position.lng = markerOptions.position.lng || 0.0; markerOptions.anchor = markerOptions.anchor || [0.5, 0.5]; markerOptions.draggable = markerOptions.draggable === true; markerOptions.icon = markerOptions.icon || undefined; markerOptions.snippet = markerOptions.snippet || undefined; markerOptions.title = markerOptions.title !== undefined ? String(markerOptions.title) : undefined; markerOptions.visible = markerOptions.visible === undefined ? true : markerOptions.visible; markerOptions.flat = markerOptions.flat === true; markerOptions.rotation = markerOptions.rotation || 0; markerOptions.opacity = parseFloat("" + markerOptions.opacity, 10) || 1; markerOptions.disableAutoPan = markerOptions.disableAutoPan === undefined ? false : markerOptions.disableAutoPan; markerOptions.params = markerOptions.params || {}; if ("styles" in markerOptions) { markerOptions.styles = typeof markerOptions.styles === "object" ? markerOptions.styles : {}; if ("color" in markerOptions.styles) { markerOptions.styles.color = HTMLColor2RGBA(markerOptions.styles.color || "#000000"); } } if (markerOptions.icon && isHTMLColorString(markerOptions.icon)) { markerOptions.icon = HTMLColor2RGBA(markerOptions.icon); } var markerClick = markerOptions.markerClick; var infoClick = markerOptions.infoClick; cordova.exec(function(result) { markerOptions.hashCode = result.hashCode; var marker = new Marker(self, result.id, markerOptions); MARKERS[result.id] = marker; OVERLAYS[result.id] = marker; if (typeof markerClick === "function") { marker.on(plugin.google.maps.event.MARKER_CLICK, markerClick); } if (typeof infoClick === "function") { marker.on(plugin.google.maps.event.INFO_CLICK, infoClick); } if (typeof callback === "function") { callback.call(self, marker, self); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Marker.createMarker', self.deleteFromObject(markerOptions,'function')]); }; //------------- // Circle //------------- App.prototype.addCircle = function(circleOptions, callback) { var self = this; circleOptions.center = circleOptions.center || {}; circleOptions.center.lat = circleOptions.center.lat || 0.0; circleOptions.center.lng = circleOptions.center.lng || 0.0; circleOptions.strokeColor = HTMLColor2RGBA(circleOptions.strokeColor || "#FF0000", 0.75); circleOptions.fillColor = HTMLColor2RGBA(circleOptions.fillColor || "#000000", 0.75); circleOptions.strokeWidth = circleOptions.strokeWidth || 10; circleOptions.visible = circleOptions.visible === undefined ? true : circleOptions.visible; circleOptions.zIndex = circleOptions.zIndex || 3; circleOptions.radius = circleOptions.radius || 1; cordova.exec(function(result) { var circle = new Circle(self, result.id, circleOptions); OVERLAYS[result.id] = circle; if (typeof circleOptions.onClick === "function") { circle.on(plugin.google.maps.event.OVERLAY_CLICK, circleOptions.onClick); } if (typeof callback === "function") { callback.call(self, circle, self); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Circle.createCircle', self.deleteFromObject(circleOptions,'function')]); }; //------------- // Polyline //------------- App.prototype.addPolyline = function(polylineOptions, callback) { var self = this; polylineOptions.points = polylineOptions.points || []; polylineOptions.color = HTMLColor2RGBA(polylineOptions.color || "#FF000080", 0.75); polylineOptions.width = polylineOptions.width || 10; polylineOptions.visible = polylineOptions.visible === undefined ? true : polylineOptions.visible; polylineOptions.zIndex = polylineOptions.zIndex || 4; polylineOptions.geodesic = polylineOptions.geodesic === true; cordova.exec(function(result) { var polyline = new Polyline(self, result.id, polylineOptions); OVERLAYS[result.id] = polyline; /*if (typeof polylineOptions.onClick === "function") { polyline.on(plugin.google.maps.event.OVERLAY_CLICK, polylineOptions.onClick); }*/ if (typeof callback === "function") { callback.call(self, polyline, self); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Polyline.createPolyline', self.deleteFromObject(polylineOptions,'function')]); }; //------------- // Polygon //------------- App.prototype.addPolygon = function(polygonOptions, callback) { var self = this; polygonOptions.points = polygonOptions.points || []; polygonOptions.holes = polygonOptions.holes || []; if (polygonOptions.holes.length > 0 && !Array.isArray(polygonOptions.holes[0])) { polygonOptions.holes = [polygonOptions.holes]; } polygonOptions.holes = polygonOptions.holes.map(function(hole) { if (!Array.isArray(hole)) { return []; } return hole.map(function(latLng) { return {lat: latLng.lat, lng: latLng.lng}; }); }); polygonOptions.strokeColor = HTMLColor2RGBA(polygonOptions.strokeColor || "#FF000080", 0.75); if (polygonOptions.fillColor) { polygonOptions.fillColor = HTMLColor2RGBA(polygonOptions.fillColor, 0.75); } polygonOptions.strokeWidth = polygonOptions.strokeWidth || 10; polygonOptions.visible = polygonOptions.visible === undefined ? true : polygonOptions.visible; polygonOptions.zIndex = polygonOptions.zIndex || 2; polygonOptions.geodesic = polygonOptions.geodesic === true; cordova.exec(function(result) { var polygon = new Polygon(self, result.id, polygonOptions); OVERLAYS[result.id] = polygon; if (typeof polygonOptions.onClick === "function") { polygon.on(plugin.google.maps.event.OVERLAY_CLICK, polygonOptions.onClick); } if (typeof callback === "function") { callback.call(self, polygon, self); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Polygon.createPolygon', self.deleteFromObject(polygonOptions,'function')]); }; //------------- // Tile overlay //------------- App.prototype.addTileOverlay = function(tilelayerOptions, callback) { var self = this; tilelayerOptions = tilelayerOptions || {}; tilelayerOptions.tileUrlFormat = tilelayerOptions.tileUrlFormat || null; if (typeof tilelayerOptions.tileUrlFormat !== "string") { throw new Error("tilelayerOptions.tileUrlFormat should set a string."); } tilelayerOptions.visible = tilelayerOptions.visible === undefined ? true : tilelayerOptions.visible; tilelayerOptions.zIndex = tilelayerOptions.zIndex || 0; tilelayerOptions.tileSize = tilelayerOptions.tileSize || 256; tilelayerOptions.opacity = tilelayerOptions.opacity || 1; cordova.exec(function(result) { var tileOverlay = new TileOverlay(self, result.id, tilelayerOptions); OVERLAYS[result.id] = tileOverlay; /* if (typeof tilelayerOptions.onClick === "function") { tileOverlay.on(plugin.google.maps.event.OVERLAY_CLICK, tilelayerOptions.onClick); } */ if (typeof callback === "function") { callback.call(self, tileOverlay, self); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['TileOverlay.createTileOverlay', self.deleteFromObject(tilelayerOptions,'function')]); }; //------------- // Ground overlay //------------- App.prototype.addGroundOverlay = function(groundOverlayOptions, callback) { var self = this; groundOverlayOptions = groundOverlayOptions || {}; groundOverlayOptions.url = groundOverlayOptions.url || null; groundOverlayOptions.visible = groundOverlayOptions.visible === undefined ? true : groundOverlayOptions.visible; groundOverlayOptions.zIndex = groundOverlayOptions.zIndex || 1; groundOverlayOptions.bounds = groundOverlayOptions.bounds || []; cordova.exec(function(result) { var groundOverlay = new GroundOverlay(self, result.id, groundOverlayOptions); OVERLAYS[result.id] = groundOverlay; if (typeof groundOverlayOptions.onClick === "function") { groundOverlay.on(plugin.google.maps.event.OVERLAY_CLICK, groundOverlayOptions.onClick); } if (typeof callback === "function") { callback.call(self, groundOverlay, self); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['GroundOverlay.createGroundOverlay', self.deleteFromObject(groundOverlayOptions,'function')]); }; //------------- // KML Layer //------------- App.prototype.addKmlOverlay = function(kmlOverlayOptions, callback) { var self = this; kmlOverlayOptions = kmlOverlayOptions || {}; kmlOverlayOptions.url = kmlOverlayOptions.url || null; kmlOverlayOptions.preserveViewport = kmlOverlayOptions.preserveViewport === true; kmlOverlayOptions.animation = kmlOverlayOptions.animation === undefined ? true : kmlOverlayOptions.animation; var kmlId = "kml" + (Math.random() * 9999999); kmlOverlayOptions.kmlId = kmlId; var kmlOverlay = new KmlOverlay(self, kmlId, kmlOverlayOptions); OVERLAYS[kmlId] = kmlOverlay; KML_LAYERS[kmlId] = kmlOverlay; cordova.exec(function(kmlId) { if (typeof callback === "function") { callback.call(self, kmlOverlay, self); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['KmlOverlay.createKmlOverlay', self.deleteFromObject(kmlOverlayOptions,'function')]); }; //------------- // Geocoding //------------- App.prototype.geocode = function(geocoderRequest, callback) { console.log("Map.geocode will be deprecated. Please use Geocoder.geocode instead."); Geocoder.geocode(geocoderRequest, callback); }; /******************************************************************************** * @name CameraPosition * @class This class represents new camera position * @property {LatLng} target The location where you want to show * @property {Number} [tilt] View angle * @property {Number} [zoom] Zoom level * @property {Number} [bearing] Map orientation * @property {Number} [duration] The duration of animation *******************************************************************************/ var CameraPosition = function(params) { var self = this; self.zoom = params.zoom; self.tilt = params.tilt; self.target = params.target; self.bearing = params.bearing; self.hashCode = params.hashCode; self.duration = params.duration; }; /***************************************************************************** * Location Class *****************************************************************************/ var Location = function(params) { var self = this; self.latLng = params.latLng || new LatLng(params.lat || 0, params.lng || 0); self.elapsedRealtimeNanos = params.elapsedRealtimeNanos; self.time = params.time; self.accuracy = params.accuracy || null; self.bearing = params.bearing || null; self.altitude = params.altitude || null; self.speed = params.speed || null; self.provider = params.provider; self.hashCode = params.hashCode; }; /******************************************************************************* * @name LatLng * @class This class represents new camera position * @param {Number} latitude * @param {Number} longitude ******************************************************************************/ var LatLng = function(latitude, longitude) { var self = this; /** * @property {Number} latitude */ self.lat = parseFloat(latitude || 0, 10); /** * @property {Number} longitude */ self.lng = parseFloat(longitude || 0, 10); /** * Comparison function. * @method * @return {Boolean} */ self.equals = function(other) { other = other || {}; return other.lat === self.lat && other.lng === self.lng; }; /** * @method * @return {String} latitude,lontitude */ self.toString = function() { return self.lat + "," + self.lng; }; /** * @method * @param {Number} * @return {String} latitude,lontitude */ self.toUrlValue = function(precision) { precision = precision || 6; return self.lat.toFixed(precision) + "," + self.lng.toFixed(precision); }; }; /***************************************************************************** * Marker Class *****************************************************************************/ var Marker = function(map, id, markerOptions) { BaseClass.apply(this); var self = this; Object.defineProperty(self, "map", { value: map, writable: false }); Object.defineProperty(self, "hashCode", { value: markerOptions.hashCode, writable: false }); Object.defineProperty(self, "id", { value: id, writable: false }); Object.defineProperty(self, "type", { value: "Marker", writable: false }); var ignores = ["hashCode", "id", "hashCode", "type"]; for (var key in markerOptions) { if (ignores.indexOf(key) === -1) { self.set(key, markerOptions[key]); } } }; Marker.prototype = new BaseClass(); Marker.prototype.isVisible = function() { return this.get('visible'); }; Marker.prototype.getPosition = function(callback) { var self = this; cordova.exec(function(latlng) { if (typeof callback === "function") { callback.call(self, new LatLng(latlng.lat, latlng.lng)); } }, self.errorHandler, PLUGIN_NAME, 'exec', ['Marker.getPosition', this.getId()]); }; Marker.prototype.getId = function() { return this.id; }; Marker.prototype.getMap = function() { return this.map; }; Marker.prototype.getHashCode = function() { return this.hashCode; }; Marker.prototype.setAnimation = function(animation, callback) { var self = this; animation = animation || null; if (!animation) { return; } this.set("animation", animation); cordova.exec(function() { if (typeof callback === "function") { callback.call(self); } }, this.errorHandler, PLUGIN_NAME, 'exec', ['Marker.setAnimation', this.getId(), self.deleteFromObject(animation,'function')]); }; Marker.prototype.remove = function(callback) { var self = this; self.set("keepWatching", false); delete MARKERS[this.id]; cordova.exec(function() { if (typeof callback === "function") { callback.call(self); } }, this.errorHandler, PLUGIN_NAME, 'exec', ['Marker.remove', this.getId()]); this.off(); }; Marker.prototype.setDisableAutoPan = function(disableAutoPan) { disableAutoPan = parseBoolean(disableAutoPan); this.set('disableAutoPan', disableAutoPan); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Marker.setDisableAutoPan', this.getId(), disableAutoPan]); }; Marker.prototype.getParams = function() { return this.get('params'); }; Marker.prototype.setOpacity = function(opacity) { if (!opacity && opacity !== 0) { console.log('opacity value must be int or double'); return false; } this.set('opacity', opacity); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Marker.setOpacity', this.getId(), opacity]); }; Marker.prototype.setZIndex = function(zIndex) { if (typeof zIndex === 'undefined') { return false; } this.set('zIndex', zIndex); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Marker.setZIndex', this.getId(), zIndex]); }; Marker.prototype.getOpacity = function() { return this.get('opacity'); }; Marker.prototype.setIconAnchor = function(anchorX, anchorY) { this.set('anchor', [anchorX, anchorY]); cordova.exec(null, this.errorHandler, PLUGIN_NAME, 'exec', ['Marker.setIconAnchor', this.getId(), anchorX, anchorY]); }; Marker.prototype.se