cordova.define("cordova-plugin-googlemaps.PluginMap", function(require, exports, module) {
var utils = require('cordova/utils'),
event = require('cordova-plugin-googlemaps.event'),
BaseClass = require('cordova-plugin-googlemaps.BaseClass'),
LatLng = require('cordova-plugin-googlemaps.LatLng'),
MapTypeId = require('cordova-plugin-googlemaps.MapTypeId');
var MAP_TYPES = {};
MAP_TYPES[MapTypeId.NORMAL] = 'roadmap';
MAP_TYPES[MapTypeId.ROADMAP] = 'roadmap';
MAP_TYPES[MapTypeId.SATELLITE] = 'satellite';
MAP_TYPES[MapTypeId.HYBRID] = 'hybrid';
MAP_TYPES[MapTypeId.TERRAIN] = 'terrain';
MAP_TYPES[MapTypeId.NONE] = 'none';
var LOCATION_ERROR = {};
LOCATION_ERROR[1] = 'service_denied';
LOCATION_ERROR[2] = 'not_available';
LOCATION_ERROR[3] = 'cannot_detect';
var LOCATION_ERROR_MSG = {};
LOCATION_ERROR_MSG[1] = 'Location service is rejected by user.';
LOCATION_ERROR_MSG[2] = 'Since this device does not have any location provider, this app can not detect your location.';
LOCATION_ERROR_MSG[3] = 'Can not detect your location. Try again.';
function displayGrayMap(container) {
var gmErrorContent = document.querySelector('.gm-err-container');
var gmnoprint = document.querySelector('.gmnoprint');
if (!gmErrorContent && !gmnoprint) {
container.innerHTML = [
'
',
'
',
'

',
'
Can not display map.
Check the developer console.
',
'
',
'
'
].join('\n');
}
}
function PluginMap(mapId, options) {
var self = this;
BaseClass.apply(this);
var mapDiv = document.querySelector('[__pluginMapId=\'' + mapId + '\']');
mapDiv.style.backgroundColor = 'rgb(229, 227, 223)';
var container = document.createElement('div');
container.style.userSelect='none';
container.style['-webkit-user-select']='none';
container.style['-moz-user-select']='none';
container.style['-ms-user-select']='none';
mapDiv.style.position = 'relative';
container.style.position = 'absolute';
container.style.top = 0;
container.style.bottom = 0;
container.style.right = 0;
container.style.left = 0;
mapDiv.insertBefore(container, mapDiv.firstElementChild);
self.set('isGoogleReady', false);
self.set('container', container);
self.PLUGINS = {};
Object.defineProperty(self, '__pgmId', {
value: mapId,
writable: false
});
Object.defineProperty(self, 'objects', {
value: {},
writable: false
});
Object.defineProperty(self, 'activeMarker', {
value: null,
writable: true
});
self.set('clickable', true);
self.one('googleready', function() {
self.set('isGoogleReady', true);
var mapTypeReg = new google.maps.MapTypeRegistry();
mapTypeReg.set('none', new google.maps.ImageMapType({
'getTileUrl': function() { return null; },
'name': 'none_type',
'tileSize': new google.maps.Size(256, 256),
'minZoom': 0,
'maxZoom': 25
}));
var mapInitOptions = {
mapTypes: mapTypeReg,
mapTypeId: google.maps.MapTypeId.ROADMAP,
noClear: true,
zoom: 2,
minZoom: 2,
disableDefaultUI: true,
zoomControl: true,
center: {lat: 0, lng: 0}
};
if (options) {
if (options.mapType) {
mapInitOptions.mapTypeId = MAP_TYPES[options.mapType];
}
if (options.styles) {
mapInitOptions.styles = JSON.parse(options.styles);
}
if (options.controls) {
if (options.controls.zoom !== undefined) {
mapInitOptions.zoomControl = options.controls.zoom == true;
}
}
if (options.preferences) {
if (options.preferences.zoom) {
mapInitOptions.minZoom = options.preferences.zoom.minZoom;
if (options.preferences.zoom.maxZoom) {
mapInitOptions.maxZoom = options.preferences.zoom.maxZoom;
}
}
}
}
var map = new google.maps.Map(container, mapInitOptions);
map.mapTypes = mapTypeReg;
self.set('map', map);
var boundsLimit = null;
if (options.preferences && options.preferences.gestureBounds &&
options.preferences.gestureBounds.length > 0) {
boundsLimit = new google.maps.LatLngBounds();
options.preferences.gestureBounds.forEach(function(pos) {
boundsLimit.extend(pos);
});
}
map.set('boundsLimit', boundsLimit);
var timeoutError = setTimeout(function() {
self.trigger('load_error');
displayGrayMap(mapDiv);
}, 3000);
map.addListener('bounds_changed', function() {
var boundsLimit = map.get('boundsLimit');
if (!boundsLimit) {
return;
}
var visibleBounds = map.getBounds();
if (boundsLimit.intersects(visibleBounds) ||
visibleBounds.contains(boundsLimit.getNorthEast()) && visibleBounds.contains(boundsLimit.getSouthWest()) ||
boundsLimit.contains(visibleBounds.getNorthEast()) && boundsLimit.contains(visibleBounds.getSouthWest())) {
return;
}
var center = map.getCenter();
var dummyLat = center.lat(),
dummyLng = center.lng();
var ne = boundsLimit.getNorthEast(),
sw = boundsLimit.getSouthWest();
if (dummyLat < sw.lat() ) {
dummyLat = sw.lat();
} else if (dummyLat > ne.lat()) {
dummyLat = ne.lat();
}
if (dummyLng < 0) {
// the Western Hemisphere
if (dummyLng > ne.lng()) {
dummyLng = ne.lng();
} else if (dummyLng < sw.lng()) {
dummyLng = sw.lng();
}
} else {
// the Eastern Hemisphere
if (dummyLng > ne.lng()) {
dummyLng = ne.lng();
} else if (dummyLng < sw.lng()) {
dummyLng = sw.lng();
}
}
var dummyLatLng = new google.maps.LatLng(dummyLat, dummyLng);
map.panTo(dummyLatLng);
});
google.maps.event.addListenerOnce(map, 'projection_changed', function() {
clearTimeout(timeoutError);
self.trigger(event.MAP_READY);
map.addListener('idle', self._onCameraEvent.bind(self, 'camera_move_end'));
//map.addListener("bounce_changed", self._onCameraEvent.bind(self, 'camera_move'));
map.addListener('drag', self._onCameraEvent.bind(self, event.CAMERA_MOVE));
map.addListener('dragend', self._onCameraEvent.bind(self, event.CAMERA_MOVE_END));
map.addListener('dragstart', self._onCameraEvent.bind(self, event.CAMERA_MOVE_START));
map.addListener('click', function(evt) {
self._onMapEvent.call(self, event.MAP_CLICK, evt);
});
map.addListener('mousedown', function() {
map.set('mousedown_time', Date.now());
});
map.addListener('mouseup', function(evt) {
if (Date.now() - (map.get('mousedown_time') || Date.now()) > 500) {
self._onMapEvent.call(self, event.MAP_LONG_CLICK, evt);
}
});
map.addListener('drag', function(evt) {
self._onMapEvent.call(self, event.MAP_DRAG, evt);
});
map.addListener('dragend', function(evt) {
self._onMapEvent.call(self, event.MAP_DRAG_END, evt);
});
map.addListener('dragstart', function(evt) {
map.set('mousedown_time', undefined);
self._onMapEvent.call(self, event.MAP_DRAG_START, evt);
});
});
if (options) {
if (options.camera) {
if (options.camera.target) {
if (Array.isArray(options.camera.target)) {
var bounds = new google.maps.LatLngBounds();
options.camera.target.forEach(function(pos) {
bounds.extend(pos);
});
map.fitBounds(bounds, 5);
} else {
map.setCenter(options.camera.target);
}
if (typeof options.camera.tilt === 'number') {
map.setTilt(options.camera.tilt);
}
if (typeof options.camera.bearing === 'number') {
map.setHeading(options.camera.bearing);
}
if (typeof options.camera.zoom === 'number') {
map.setZoom(options.camera.zoom);
}
}
} else {
map.setCenter({lat: 0, lng: 0});
}
} else {
map.setCenter({lat: 0, lng: 0});
}
});
}
utils.extend(PluginMap, BaseClass);
PluginMap.prototype.setOptions = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map'),
options = args[0];
var mapInitOptions = {};
if (options) {
if (options.mapType) {
mapInitOptions.mapTypeId = MAP_TYPES[options.mapType];
}
if (options.styles) {
mapInitOptions.styles = JSON.parse(options.styles);
}
if (options.controls) {
if (options.controls.zoom !== undefined) {
mapInitOptions.zoomControl = options.controls.zoom == true;
}
}
if (options.preferences) {
if (options.preferences.zoom) {
mapInitOptions.minZoom = Math.max(options.preferences.zoom || 2, 2);
if (options.preferences.zoom.maxZoom) {
mapInitOptions.maxZoom = options.preferences.zoom.maxZoom;
}
}
if ('gestureBounds' in options.preferences) {
var boundsLimit = null;
if (options.preferences.gestureBounds && options.preferences.gestureBounds.length > 0) {
boundsLimit = new google.maps.LatLngBounds();
options.preferences.gestureBounds.forEach(function(pos) {
boundsLimit.extend(pos);
});
}
map.set('boundsLimit', boundsLimit);
}
}
}
map.setOptions(mapInitOptions);
if (options) {
if (options.camera) {
if (options.camera.target) {
if (Array.isArray(options.camera.target)) {
var bounds = new google.maps.LatLngBounds();
options.camera.target.forEach(function(pos) {
bounds.extend(pos);
});
map.fitBounds(bounds, 5);
} else {
map.setCenter(options.camera.target);
}
if (typeof options.camera.tilt === 'number') {
map.setTilt(options.camera.tilt);
}
if (typeof options.camera.bearing === 'number') {
map.setHeading(options.camera.bearing);
}
if (typeof options.camera.zoom === 'number') {
map.setZoom(options.camera.zoom);
}
}
} else {
map.setCenter({lat: 0, lng: 0});
}
} else {
map.setCenter({lat: 0, lng: 0});
}
onSuccess();
};
PluginMap.prototype.setActiveMarkerId = function(onSuccess, onError, args) {
var self = this,
markerId = args[0];
self.activeMarker = self.objects[markerId];
onSuccess();
};
PluginMap.prototype.clear = function(onSuccess) {
this.activeMarker = null;
onSuccess();
};
PluginMap.prototype.getFocusedBuilding = function(onSuccess) {
// stub
onSuccess(-1);
};
PluginMap.prototype.setDiv = function(onSuccess, onError, args) {
var self = this,
map = self.get('map'),
container = self.get('container');
if (args.length === 0) {
if (container && container.parentNode) {
container.parentNode.removeAttribute('__pluginMapId');
container.parentNode.removeChild(container);
}
} else {
var domId = args[0];
var mapDiv = document.querySelector('[__pluginDomId=\'' + domId + '\']');
mapDiv.style.position = 'relative';
mapDiv.insertBefore(container, mapDiv.firstElementChild);
mapDiv.setAttribute('__pluginMapId', self.__pgmId);
}
google.maps.event.trigger(map, 'resize');
onSuccess();
};
PluginMap.prototype.resizeMap = function(onSuccess) {
var self = this;
var map = self.get('map');
google.maps.event.trigger(map, 'resize');
onSuccess();
};
PluginMap.prototype.panBy = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
map.panBy.apply(map, args);
onSuccess();
};
PluginMap.prototype.setCameraBearing = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
var heading = args[0];
map.setHeading(heading);
onSuccess();
};
PluginMap.prototype.setCameraZoom = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
var zoom = args[0];
map.setZoom(zoom);
onSuccess();
};
PluginMap.prototype.setCameraTarget = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
var lat = args[0],
lng = args[1];
map.setCenter(new google.maps.LatLng(lat, lng));
onSuccess();
};
PluginMap.prototype.setCameraTilt = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
var tilt = args[0];
map.setTilt(tilt);
onSuccess();
};
PluginMap.prototype.setMyLocationEnabled = function(onSuccess) {
// stub
onSuccess();
};
PluginMap.prototype.animateCamera = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
var options = args[0];
var padding = 'padding' in options ? options.padding : 5;
var bounds;
if (Array.isArray(options.target)) {
bounds = new google.maps.LatLngBounds();
options.target.forEach(function(pos) {
bounds.extend(pos);
});
map.fitBounds(bounds, padding);
} else {
var zoomFlag = typeof options.zoom === 'number';
var targetFlag = !!options.target;
if (zoomFlag && targetFlag) {
var projection = map.getProjection();
var centerLatLng = new google.maps.LatLng(options.target.lat, options.target.lng, true);
var centerPoint = projection.fromLatLngToPoint(centerLatLng);
var scale = Math.pow(2, options.zoom);
var div = map.getDiv();
var harfWidth = div.offsetWidth / 2;
var harfHeight = div.offsetHeight / 2;
var swPoint = new google.maps.Point((centerPoint.x * scale - harfWidth) / scale, (centerPoint.y * scale + harfHeight) / scale );
var nePoint = new google.maps.Point((centerPoint.x * scale + harfWidth) / scale, (centerPoint.y * scale - harfHeight) / scale);
var sw = projection.fromPointToLatLng(swPoint);
var ne = projection.fromPointToLatLng(nePoint);
bounds = new google.maps.LatLngBounds(sw, ne);
map.fitBounds(bounds, padding);
} else if (zoomFlag) {
map.setZoom(options.zoom);
} else if (targetFlag) {
map.panTo(options.target);
}
}
if (typeof options.tilt === 'number') {
map.setTilt(options.tilt);
}
if (typeof options.bearing === 'number') {
map.setHeading(options.bearing);
}
onSuccess();
};
PluginMap.prototype.moveCamera = function(onSuccess, onError, args) {
this.animateCamera.call(this, onSuccess, onError, args);
};
PluginMap.prototype.setMapTypeId = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
var mapTypeId = args[0];
map.setMapTypeId(MAP_TYPES[mapTypeId]);
onSuccess();
};
PluginMap.prototype.setClickable = function(onSuccess, onError, args) {
var self = this;
var clickable = args[0];
self.set('clickable', clickable);
onSuccess();
};
PluginMap.prototype.setVisible = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
var visibility = args[0];
var mapDiv = map.getDiv();
if (mapDiv) {
mapDiv.style.visibility = visibility === true ? 'visible' : 'hidden';
}
onSuccess();
};
PluginMap.prototype.setPadding = function(onSuccess) {
// stub
onSuccess();
};
PluginMap.prototype.setAllGesturesEnabled = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
var enabled = args[0];
map.setOptions({
gestureHandling: enabled === true ? 'auto': 'none'
});
onSuccess();
};
PluginMap.prototype.setCompassEnabled = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
var enabled = args[0];
map.setOptions({
rotateControl: enabled === true
});
var mapTypeId = map.getMapTypeId();
if (mapTypeId !== google.maps.MapTypeId.SATELLITE &&
mapTypeId !== google.maps.MapTypeId.HYBRID) {
console.warn('map.setCompassEnabled() works only HYBRID or SATELLITE for this platform.');
}
onSuccess();
};
PluginMap.prototype.setTrafficEnabled = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
var enabled = args[0];
var trafficLayer = map.get('trafficLayer');
if (!trafficLayer) {
trafficLayer = new google.maps.TrafficLayer();
map.set('trafficLayer', trafficLayer);
}
if (enabled) {
trafficLayer.setMap(map);
} else {
trafficLayer.setMap(null);
}
onSuccess();
};
PluginMap.prototype.fromLatLngToPoint = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
var lat = args[0],
lng = args[1];
var projection = map.getProjection(),
bounds = map.getBounds(),
ne = bounds.getNorthEast(),
sw = bounds.getSouthWest(),
zoom = map.getZoom(),
north = ne.lat(),
west = sw.lng();
var nowrapFlag = !bounds.contains(new google.maps.LatLng(north, 179));
var scale = Math.pow(2, zoom),
topLeft = projection.fromLatLngToPoint(new google.maps.LatLng(north, west + 360, nowrapFlag)),
worldPoint = projection.fromLatLngToPoint(new google.maps.LatLng(lat, lng + 360, true));
onSuccess([(worldPoint.x - topLeft.x) * scale, (worldPoint.y - topLeft.y) * scale]);
};
PluginMap.prototype.fromPointToLatLng = function(onSuccess, onError, args) {
var self = this;
var map = self.get('map');
var x = args[0],
y = args[1];
var projection = map.getProjection(),
bounds = map.getBounds(),
ne = bounds.getNorthEast(),
sw = bounds.getSouthWest(),
zoom = map.getZoom();
var topRight = projection.fromLatLngToPoint(ne);
var bottomLeft = projection.fromLatLngToPoint(sw);
var scale = Math.pow(2, zoom);
var worldPoint = new google.maps.Point(x / scale + bottomLeft.x, y / scale + topRight.y);
var latLng = map.getProjection().fromPointToLatLng(worldPoint);
onSuccess([latLng.lat(), latLng.lng()]);
};
PluginMap.prototype.setIndoorEnabled = function(onSuccess) {
// stub
onSuccess();
};
PluginMap.prototype.toDataURL = function(onSuccess) {
// stub
onSuccess();
};
PluginMap.prototype._syncInfoWndPosition = function() {
var self = this;
if (!self.activeMarker) {
return;
}
var latLng = self.activeMarker.getPosition();
self.fromLatLngToPoint(function(point) {
plugin.google.maps[self.__pgmId]({
'evtName': 'syncPosition',
'callback': '_onSyncInfoWndPosition',
'args': [{'x': point[0], 'y': point[1]}]
});
}, null, [latLng.lat(), latLng.lng()]);
};
PluginMap.prototype._onMapEvent = function(evtName, evt) {
var self = this;
if (self.get('clickable') === false &&
(evtName === event.MAP_CLICK || evtName === event.MAP_LONG_CLICK)) {
evt.stop();
return;
}
if (self.__pgmId in plugin.google.maps) {
if (evt) {
if (evtName === event.MAP_CLICK) {
if (evt.placeId) {
evt.stop();
plugin.google.maps[self.__pgmId]({
'evtName': event.POI_CLICK,
'callback': '_onMapEvent',
'args': [evt.placeId, undefined, new LatLng(evt.latLng.lat(), evt.latLng.lng())]
});
return;
}
}
plugin.google.maps[self.__pgmId]({
'evtName': evtName,
'callback': '_onMapEvent',
'args': [new LatLng(evt.latLng.lat(), evt.latLng.lng())]
});
} else {
plugin.google.maps[self.__pgmId]({
'evtName': evtName,
'callback': '_onMapEvent',
'args': []
});
}
}
};
PluginMap.prototype._onCameraEvent = function(evtName) {
var self = this,
map = self.get('map'),
center = map.getCenter(),
bounds = map.getBounds(),
ne = bounds.getNorthEast(),
sw = bounds.getSouthWest();
self._syncInfoWndPosition();
var cameraInfo = {
'target': {'lat': center.lat(), 'lng': center.lng()},
'zoom': map.getZoom(),
'tilt': map.getTilt() || 0,
'bearing': map.getHeading() || 0,
'northeast': {'lat': ne.lat(), 'lng': ne.lng()},
'southwest': {'lat': sw.lat(), 'lng': sw.lng()},
'farLeft': {'lat': ne.lat(), 'lng': sw.lng()},
'farRight': {'lat': ne.lat(), 'lng': ne.lng()}, // = northEast
'nearLeft': {'lat': sw.lat(), 'lng': sw.lng()}, // = southWest
'nearRight': {'lat': sw.lat(), 'lng': ne.lng()}
};
if (self.__pgmId in plugin.google.maps) {
plugin.google.maps[self.__pgmId]({
'evtName': evtName,
'callback': '_onCameraEvent',
'args': [cameraInfo]
});
}
};
PluginMap.prototype.loadPlugin = function(onSuccess, onError, args) {
var self = this;
var className = args[0];
var plugin;
if (className in self.PLUGINS) {
plugin = self.PLUGINS[className];
} else {
var OverlayClass = require('cordova-plugin-googlemaps.Plugin' + className);
plugin = new OverlayClass(this);
self.PLUGINS[className] = plugin;
// Since Cordova involes methods as Window,
// the `this` keyword of involved method is Window, not overlay itself.
// In order to keep indicate the `this` keyword as overlay itself,
// wrap the method.
var dummyObj = {};
for (var key in OverlayClass.prototype) {
if (typeof OverlayClass.prototype[key] === 'function') {
dummyObj[key] = plugin[key].bind(plugin);
} else {
dummyObj[key] = plugin[key];
}
}
require('cordova/exec/proxy').add(self.__pgmId + '-' + className.toLowerCase(), dummyObj);
}
plugin._create.call(plugin, onSuccess, onError, args);
};
module.exports = PluginMap;
});