cordova-plugin-googlemaps
Version:
Google Maps native SDK for Android and iOS
1,468 lines (1,318 loc) • 95.3 kB
JavaScript
/* 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