依赖文件

This commit is contained in:
浅念
2025-03-20 17:35:53 +08:00
parent 634fe57349
commit 021ffc6052
1134 changed files with 137518 additions and 132 deletions
+181
View File
@@ -0,0 +1,181 @@
var PluginMap = require('cordova-plugin-googlemaps.PluginMap'),
PluginStreetViewPanorama = require('cordova-plugin-googlemaps.PluginStreetViewPanorama'),
event = require('cordova-plugin-googlemaps.event'),
Environment = require('cordova-plugin-googlemaps.PluginEnvironment');
var MAPS = {};
var API_LOADED_STATUS = 0; // 0: not loaded, 1: loading, 2: completed
document.addEventListener('load_googlemaps', function() {
var envOptions = Environment._getEnv();
var API_KEY_FOR_BROWSER;
if (envOptions) {
if (location.protocol === 'https:') {
API_KEY_FOR_BROWSER = envOptions.API_KEY_FOR_BROWSER_RELEASE;
} else {
API_KEY_FOR_BROWSER = envOptions.API_KEY_FOR_BROWSER_DEBUG;
}
}
API_LOADED_STATUS = 1;
var secureStripeScript = document.createElement('script');
if (API_KEY_FOR_BROWSER && API_KEY_FOR_BROWSER.length > 35) {
secureStripeScript.setAttribute('src','https://maps.googleapis.com/maps/api/js?key=' + API_KEY_FOR_BROWSER);
} else {
// for development only
secureStripeScript.setAttribute('src','https://maps.googleapis.com/maps/api/js');
}
secureStripeScript.addEventListener('load', function() {
API_LOADED_STATUS = 2;
var mKeys = Object.keys(MAPS);
mKeys.forEach(function(mkey) {
var map = MAPS[mkey];
if (!map.get('isGoogleReady')) {
map.trigger('googleready');
}
});
});
secureStripeScript.addEventListener('error', function(error) {
console.log('Can not load the Google Maps JavaScript API v3');
console.log(error);
var mKeys = Object.keys(MAPS);
mKeys.forEach(function(mkey) {
var map = MAPS[mkey];
if (map) {
map.trigger('load_error');
}
});
});
document.getElementsByTagName('head')[0].appendChild(secureStripeScript);
}, {
once: true
});
var stub = function(onSuccess) {
onSuccess();
};
var CordovaGoogleMaps = {
resume: stub,
pause: stub,
getMap: function(onSuccess, onError, args) {
// memory cleanup
var mapIDs = Object.keys(MAPS);
mapIDs.forEach(function(mapId) {
var mapDivId = document.querySelector('[__pluginmapid=\'' + mapId + '\']');
if (!mapDivId) {
if (MAPS[mapDivId]) {
MAPS[mapDivId].destroy();
}
MAPS[mapDivId] = undefined;
delete MAPS[mapDivId];
}
});
var meta = args[0],
mapId = meta.__pgmId;
args[0] = mapId;
args.unshift(this);
var pluginMap = new (PluginMap.bind.apply(PluginMap, args));
MAPS[mapId] = pluginMap;
var dummyObj = {};
var keys = Object.getOwnPropertyNames(PluginMap.prototype).filter(function (p) {
return typeof PluginMap.prototype[p] === 'function';
});
keys.forEach(function(key) {
dummyObj[key] = pluginMap[key].bind(pluginMap);
});
require('cordova/exec/proxy').add(mapId, dummyObj);
pluginMap.one(event.MAP_READY, onSuccess);
pluginMap.one('load_error', onError);
// Does this app already load the google maps library?
API_LOADED_STATUS = (window.google && window.google.maps) ? 2 : API_LOADED_STATUS;
switch(API_LOADED_STATUS) {
case 0:
cordova.fireDocumentEvent('load_googlemaps', []);
break;
case 2:
pluginMap.trigger('googleready');
break;
}
},
removeMap: function(onSuccess, onError, args) {
var mapId = args[0];
var pluginMap = MAPS[mapId];
if (pluginMap) {
var map = pluginMap.get('map');
google.maps.event.clearInstanceListeners(map);
var mapDiv = map.getDiv();
if (mapDiv) {
mapDiv.parentNode.removeChild(mapDiv);
pluginMap.set('map', undefined);
}
}
pluginMap.destroy();
pluginMap = null;
MAPS[mapId] = undefined;
delete MAPS[mapId];
onSuccess();
},
getPanorama: function(onSuccess, onError, args) {
// memory cleanup
var mapIDs = Object.keys(MAPS);
mapIDs.forEach(function(mapId) {
var mapDivId = document.querySelector('[__pluginmapid=\'' + mapId + '\']');
if (!mapDivId) {
if (MAPS[mapDivId]) {
MAPS[mapDivId].destroy();
}
MAPS[mapDivId] = undefined;
delete MAPS[mapDivId];
}
});
var meta = args[0],
mapId = meta.__pgmId;
args[0] = mapId;
args.unshift(this);
var pluginStreetView = new (PluginStreetViewPanorama.bind.apply(PluginStreetViewPanorama, args));
MAPS[mapId] = pluginStreetView;
var dummyObj = {};
var keys = Object.getOwnPropertyNames(PluginStreetViewPanorama.prototype).filter(function (p) {
return typeof PluginStreetViewPanorama.prototype[p] === 'function';
});
keys.forEach(function(key) {
dummyObj[key] = pluginStreetView[key].bind(pluginStreetView);
});
require('cordova/exec/proxy').add(mapId, dummyObj);
pluginStreetView.one(event.PANORAMA_READY, onSuccess);
pluginStreetView.one('load_error', onError);
// Does this app already load the google maps library?
API_LOADED_STATUS = (window.google && window.google.maps) ? 2 : API_LOADED_STATUS;
switch(API_LOADED_STATUS) {
case 0:
cordova.fireDocumentEvent('load_googlemaps', []);
break;
case 2:
pluginStreetView.trigger('googleready');
break;
}
},
};
require('cordova/exec/proxy').add('CordovaGoogleMaps', CordovaGoogleMaps);
+199
View File
@@ -0,0 +1,199 @@
var utils = require('cordova/utils'),
event = require('cordova-plugin-googlemaps.event'),
BaseClass = require('cordova-plugin-googlemaps.BaseClass');
function PluginCircle(pluginMap) {
var self = this;
BaseClass.apply(self);
Object.defineProperty(self, 'pluginMap', {
value: pluginMap,
writable: false
});
}
utils.extend(PluginCircle, BaseClass);
PluginCircle.prototype._create = function(onSuccess, onError, args) {
var self = this,
map = self.pluginMap.get('map'),
circleId = 'circle_' + args[2],
pluginOptions = args[1];
var circleOpts = {
'overlayId': circleId,
'map': map
};
circleOpts.center = pluginOptions.center;
circleOpts.radius = pluginOptions.radius;
if (Array.isArray(pluginOptions.strokeColor)) {
circleOpts.strokeColor = 'rgb(' + pluginOptions.strokeColor[0] + ',' + pluginOptions.strokeColor[1] + ',' + pluginOptions.strokeColor[2] + ')';
circleOpts.strokeOpacity = pluginOptions.strokeColor[3] / 256;
}
if (Array.isArray(pluginOptions.fillColor)) {
circleOpts.fillColor = 'rgb(' + pluginOptions.fillColor[0] + ',' + pluginOptions.fillColor[1] + ',' + pluginOptions.fillColor[2] + ')';
circleOpts.fillOpacity = pluginOptions.fillColor[3] / 256;
}
if ('width' in pluginOptions) {
circleOpts.strokeWeight = pluginOptions.width;
}
if ('zIndex' in pluginOptions) {
circleOpts.zIndex = pluginOptions.zIndex;
}
if ('visible' in pluginOptions) {
circleOpts.visible = pluginOptions.visible;
}
if ('clickable' in pluginOptions) {
circleOpts.clickable = pluginOptions.clickable;
}
var circle = new google.maps.Circle(circleOpts);
circle.addListener('click', function(polyMouseEvt) {
self._onCircleEvent.call(self, circle, polyMouseEvt);
});
self.pluginMap.objects[circleId] = circle;
onSuccess({
'__pgmId': circleId
});
};
PluginCircle.prototype.setCenter = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var lat = args[1];
var lng = args[2];
var circle = self.pluginMap.objects[overlayId];
if (circle) {
circle.setCenter(new google.maps.LatLng(lat, lng));
}
onSuccess();
};
PluginCircle.prototype.setFillColor = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var fillColor = args[1];
var circle = self.pluginMap.objects[overlayId];
if (circle) {
if (Array.isArray(fillColor)) {
circle.setOptions({
'fillColor': 'rgb(' + fillColor[0] + ',' + fillColor[1] + ',' + fillColor[2] + ')',
'fillOpacity': fillColor[3] / 256
});
}
}
onSuccess();
};
PluginCircle.prototype.setStrokeColor = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var strokeColor = args[1];
var circle = self.pluginMap.objects[overlayId];
if (circle) {
if (Array.isArray(strokeColor)) {
circle.setOptions({
'strokeColor': 'rgb(' + strokeColor[0] + ',' + strokeColor[1] + ',' + strokeColor[2] + ')',
'strokeOpacity': strokeColor[3] / 256
});
}
}
onSuccess();
};
PluginCircle.prototype.setStrokeWidth = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var width = args[1];
var circle = self.pluginMap.objects[overlayId];
if (circle) {
circle.setOptions({
'strokeWeight': width
});
}
onSuccess();
};
PluginCircle.prototype.setRadius = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var radius = args[1];
var circle = self.pluginMap.objects[overlayId];
if (circle) {
circle.setRadius(radius);
}
onSuccess();
};
PluginCircle.prototype.setZIndex = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var zIndex = args[1];
var circle = self.pluginMap.objects[overlayId];
if (circle) {
circle.setOptions({
'zIndex': zIndex
});
}
onSuccess();
};
PluginCircle.prototype.setVisible = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var visible = args[1];
var circle = self.pluginMap.objects[overlayId];
if (circle) {
circle.setVisible(visible === true);
}
onSuccess();
};
PluginCircle.prototype.setClickable = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var clickable = args[1];
var circle = self.pluginMap.objects[overlayId];
if (circle) {
circle.setOptions({
'clickable': clickable === true
});
}
onSuccess();
};
PluginCircle.prototype.remove = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var circle = self.pluginMap.objects[overlayId];
if (circle) {
google.maps.event.clearInstanceListeners(circle);
circle.setMap(null);
circle = undefined;
self.pluginMap.objects[overlayId] = undefined;
delete self.pluginMap.objects[overlayId];
}
onSuccess();
};
PluginCircle.prototype._onCircleEvent = function(circle, polyMouseEvt) {
var self = this,
mapId = self.pluginMap.__pgmId;
if (mapId in plugin.google.maps) {
plugin.google.maps[mapId]({
'evtName': event.CIRCLE_CLICK,
'callback': '_onOverlayEvent',
'args': [circle.overlayId, new plugin.google.maps.LatLng(polyMouseEvt.latLng.lat(), polyMouseEvt.latLng.lng())]
});
}
};
module.exports = PluginCircle;
@@ -0,0 +1,31 @@
var envOptions = {};
module.exports = {
'isAvailable': function(onSuccess) {
onSuccess();
},
'setBackGroundColor': function(onSuccess) {
// stub
onSuccess();
},
'getLicenseInfo': function(onSuccess) {
// stub
onSuccess('cordova-plugin-googlemaps for browser does not need to display any open source lincenses. But for iOS, you still need to display the lincense.');
},
'setEnv': function(onSuccess, onError, args) {
var options = args[0];
var keys = Object.keys(options);
keys.forEach(function(key) {
envOptions[key] = options[key];
});
onSuccess();
},
'_getEnv': function() {
// internal method
return envOptions;
}
};
require('cordova/exec/proxy').add('PluginEnvironment', module.exports);
+176
View File
@@ -0,0 +1,176 @@
var BaseArrayClass = require('cordova-plugin-googlemaps.BaseArrayClass');
var geocoder = null;
var lastRequestTime = 0;
var QUEUE = new BaseArrayClass();
QUEUE.on('insert_at', function() {
if (QUEUE.getLength() === 1) {
this.trigger('next');
}
});
QUEUE.one('insert_at', function() {
geocoder = new google.maps.Geocoder();
this.trigger('next');
});
QUEUE.on('next', function() {
var self = QUEUE;
if (!geocoder || self._executing || QUEUE.getLength() === 0) {
return;
}
if (Date.now() - lastRequestTime < 300) {
setTimeout(function() {
self.trigger('next');
}, 300 + Math.floor(Math.random() * 200));
return;
}
lastRequestTime = Date.now();
self._executing = true;
var cmd = QUEUE.removeAt(0, true);
geocoder.geocode(cmd.geocoderRequest, function(results, status) {
switch(status) {
case google.maps.GeocoderStatus.ERROR:
cmd.onError('[geocoding] Cannot connect to Google servers');
return;
case google.maps.GeocoderStatus.INVALID_REQUEST:
cmd.onError('[geocoding] Invalid request for geocoder');
return;
case google.maps.GeocoderStatus.OVER_QUERY_LIMIT:
QUEUE.insertAt(0, cmd);
console.warn('[geocoding] Due to the OVER_QUERY_LIMIT error, wait 3 sec, then try again.');
setTimeout(function() {
self._executing = false;
self.trigger('next');
}, 3000 + Math.floor(Math.random() * 200));
return;
case google.maps.GeocoderStatus.REQUEST_DENIED:
cmd.onError('[geocoding] Google denited your geocoding request.');
return;
case google.maps.GeocoderStatus.UNKNOWN_ERROR:
cmd.onError('[geocoding] There was an unknown error. Please try again.');
return;
}
var pluginResults = results.map(function(geocoderResult) {
var result = {
'position': {
'lat': geocoderResult.geometry.location.lat(),
'lng': geocoderResult.geometry.location.lng()
},
extra: {
lines: []
}
};
if (geocoderResult.place_id) {
result.extra.place_id = geocoderResult.place_id;
}
if (geocoderResult.plus_code) {
result.extra.plus_code = geocoderResult.plus_code;
}
if (geocoderResult.types) {
result.extra.types = geocoderResult.types;
}
var administrative_area = [];
var sublocality_area = [];
geocoderResult.address_components.forEach(function(addrComp) {
result.extra.lines.push(addrComp.long_name);
if (!result.locality && addrComp.types.indexOf('locality') > -1) {
result.locality = addrComp.short_name;
}
if (addrComp.types.indexOf('administrative_area_level_1') > -1 ||
addrComp.types.indexOf('administrative_area_level_2') > -1 ||
addrComp.types.indexOf('administrative_area_level_3') > -1 ||
addrComp.types.indexOf('administrative_area_level_4') > -1) {
addrComp.types.forEach(function(type) {
if (type.indexOf('administrative_area_level_') === 0) {
var idx = parseInt(type.replace('administrative_area_level_', ''), 10);
administrative_area[idx - 1] = addrComp.long_name;
}
});
}
if (addrComp.types.indexOf('sublocality_level_1') > -1 ||
addrComp.types.indexOf('sublocality_level_2') > -1 ||
addrComp.types.indexOf('sublocality_level_3') > -1 ||
addrComp.types.indexOf('sublocality_level_4') > -1 ||
addrComp.types.indexOf('sublocality_level_5') > -1) {
addrComp.types.forEach(function(type) {
if (type.indexOf('sublocality_level_') === 0) {
var idx = parseInt(type.replace('sublocality_level_', ''), 10);
sublocality_area[idx - 1] = addrComp.long_name;
}
});
}
if (!result.country && addrComp.types.indexOf('country') > -1) {
result.country = addrComp.long_name;
result.countryCode = addrComp.short_name;
}
if (!result.postalCode && addrComp.types.indexOf('postal_code') > -1) {
result.postalCode = addrComp.long_name;
}
if (!result.thoroughfare && addrComp.types.indexOf('street_address') > -1) {
result.thoroughfare = addrComp.long_name;
}
});
if (administrative_area.length > 0) {
result.adminArea = administrative_area.shift();
result.subAdminArea = administrative_area.join(',');
}
if (sublocality_area.length > 0) {
result.subLocality = sublocality_area.join(',');
}
//result.extra = geocoderResult.address_components; // for debug
return result;
});
self._executing = false;
cmd.onSuccess({
'idx': cmd.pluginRequest.idx,
'results': pluginResults
});
// Insert delay to prevent the OVER_QUERY_LIMIT error.
var delay = 300 + Math.floor(Math.random() * 200);
setTimeout(function() {
self._executing = false;
self.trigger('next');
}, delay);
});
});
module.exports = {
'geocode': function(onSuccess, onError, args) {
var request = args[0];
var geocoderRequest = {};
if (!request.position && request.address) {
//---------------------
// Geocoding
//---------------------
if (request.bounds && Array.isArray(request.bounds)) {
var bounds = new google.maps.LatLngBounds();
request.bounds.forEach(function(position) {
bounds.extend(position);
});
geocoderRequest.bounds = bounds;
}
geocoderRequest.address = request.address;
}
if (request.position && !request.address) {
geocoderRequest.location = request.position;
}
QUEUE.push({
'geocoderRequest': geocoderRequest,
'pluginRequest': request,
'onSuccess': onSuccess,
'onError': onError
});
}
};
require('cordova/exec/proxy').add('PluginGeocoder', module.exports);
@@ -0,0 +1,412 @@
var utils = require('cordova/utils'),
event = require('cordova-plugin-googlemaps.event'),
BaseClass = require('cordova-plugin-googlemaps.BaseClass'),
Spherical = require('cordova-plugin-googlemaps.spherical'),
LatLng = require('cordova-plugin-googlemaps.LatLng');
function PluginGroundOverlay(pluginMap) {
var self = this;
BaseClass.apply(self);
Object.defineProperty(self, 'pluginMap', {
value: pluginMap,
writable: false
});
}
utils.extend(PluginGroundOverlay, BaseClass);
PluginGroundOverlay.prototype._create = function(onSuccess, onError, args) {
var self = this,
map = self.pluginMap.get('map'),
groundoverlayId = 'groundoverlay_' + args[2],
pluginOptions = args[1];
var groundoverlayOpts = {
'overlayId': groundoverlayId,
'map': map
};
var bounds = new google.maps.LatLngBounds();
pluginOptions.bounds.forEach(function(latLng) {
bounds.extend(latLng);
});
if ('bearing' in pluginOptions) {
groundoverlayOpts.bearing = pluginOptions.bearing;
}
if ('zIndex' in pluginOptions) {
groundoverlayOpts.zIndex = pluginOptions.zIndex;
}
if ('opacity' in pluginOptions) {
groundoverlayOpts.opacity = pluginOptions.opacity;
}
if ('visible' in pluginOptions) {
groundoverlayOpts.visible = pluginOptions.visible;
}
if ('clickable' in pluginOptions) {
groundoverlayOpts.clickable = pluginOptions.clickable;
}
var groundoverlay = newGroundOverlay(pluginOptions.url, bounds, groundoverlayOpts);
groundoverlay.addListener('click', function(polyMouseEvt) {
self._onGroundOverlayEvent.call(self, groundoverlay, polyMouseEvt);
});
self.pluginMap.objects[groundoverlayId] = groundoverlay;
self.pluginMap.objects['groundoverlay_property_' + groundoverlayId] = pluginOptions;
onSuccess({
'__pgmId': groundoverlayId
});
};
PluginGroundOverlay.prototype.setImage = function(onSuccess, onError, args) {
var self = this,
overlayId = args[0],
url = args[1],
groundoverlay = self.pluginMap.objects[overlayId];
if (groundoverlay) {
groundoverlay.setImage(url);
}
onSuccess();
};
PluginGroundOverlay.prototype.setBearing = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var groundOverlay = self.pluginMap.objects[overlayId];
if (groundOverlay) {
groundOverlay.setBearing(args[1]);
}
onSuccess();
};
PluginGroundOverlay.prototype.setOpacity = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var groundOverlay = self.pluginMap.objects[overlayId];
if (groundOverlay) {
groundOverlay.setOpacity(args[1]);
}
onSuccess();
};
PluginGroundOverlay.prototype.setBounds = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var groundOverlay = self.pluginMap.objects[overlayId];
if (groundOverlay) {
var points = args[1];
var bounds = new google.maps.LatLngBounds();
points.forEach(function(latLng) {
bounds.extend(latLng);
});
groundOverlay.setBounds(bounds);
}
onSuccess();
};
PluginGroundOverlay.prototype.setZIndex = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var zIndex = args[1];
var groundOverlay = self.pluginMap.objects[overlayId];
if (groundOverlay) {
groundOverlay.setZIndex(zIndex);
}
onSuccess();
};
PluginGroundOverlay.prototype.setClickable = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var groundOverlay = self.pluginMap.objects[overlayId];
if (groundOverlay) {
groundOverlay.setClickable(args[1]);
}
onSuccess();
};
PluginGroundOverlay.prototype.setVisible = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var groundOverlay = self.pluginMap.objects[overlayId];
if (groundOverlay) {
groundOverlay.setVisible(args[1]);
}
onSuccess();
};
PluginGroundOverlay.prototype.remove = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var groundOverlay = self.pluginMap.objects[overlayId];
if (groundOverlay) {
google.maps.event.clearInstanceListeners(groundOverlay);
groundOverlay.setMap(null);
groundOverlay.remove();
groundOverlay = undefined;
self.pluginMap.objects[overlayId] = undefined;
delete self.pluginMap.objects[overlayId];
delete self.pluginMap.objects['groundoverlay_property_' + overlayId];
}
onSuccess();
};
PluginGroundOverlay.prototype._onGroundOverlayEvent = function(groundoverlay, mouseEvt) {
var self = this,
mapId = self.pluginMap.__pgmId;
if (mapId in plugin.google.maps) {
plugin.google.maps[mapId]({
'evtName': event.GROUND_OVERLAY_CLICK,
'callback': '_onOverlayEvent',
'args': [groundoverlay.overlayId, new LatLng(mouseEvt.latLng.lat(), mouseEvt.latLng.lng())]
});
}
};
module.exports = PluginGroundOverlay;
function newGroundOverlay(url, bounds, options) {
// https://github.com/apache/cordova-js/blob/c75e8059114255d1dbae1ede398e6626708ee9f3/src/common/utils.js#L167
if (CustomGroundOverlay.__super__ !== google.maps.OverlayView.prototype) {
var key, defined = {};
for (key in CustomGroundOverlay.prototype) {
defined[key] = CustomGroundOverlay.prototype[key];
}
utils.extend(CustomGroundOverlay, google.maps.OverlayView);
for (key in defined) {
CustomGroundOverlay.prototype[key] = defined[key];
}
}
return new CustomGroundOverlay(url, bounds, options);
}
function CustomGroundOverlay(url, bounds, options) {
google.maps.OverlayView.apply(this);
var self = this;
//------------------------------------------------------------
// Create an img element, then put it on map as GroundOverlay
//------------------------------------------------------------
var img = new Image();
img.src = url;
img.style.position = 'absolute';
img.style.WebkitTransformOrigin = '50% 50%';
img.style.MozTransformOrigin = '50% 50%';
img.style.transformOrigin = '50% 50%';
self.set('img', img);
self.set('url', url);
self.addListener('url_changed', function() {
img.src = self.get('url');
});
var path = new google.maps.MVCArray([
new google.maps.LatLng(0, 0),
new google.maps.LatLng(0, 0),
new google.maps.LatLng(0, 0),
new google.maps.LatLng(0, 0)
]);
self.set('path', path);
self.addListener('bearing_changed', self.updateVertixes);
self.addListener('bounds_changed', self.updateVertixes);
self.addListener('opacity_changed', function() {
img.style.opacity = self.get('opacity');
});
//---------------------------------------------------------
// Create a transparent rectangle above the groundOverlay,
// then catch click event
//---------------------------------------------------------
var touchPolygon = new google.maps.Polygon({
'map': options.map,
'paths': path,
'clickable': true,
'fillColor': 'red',
'fillOpacity': 0,
'strokeOpacity': 0,
'zIndex': options.zIndex || 0
});
self.addListener('visible_changed', function() {
img.style.visibility = self.get('visible') ? 'visible' : 'hidden';
touchPolygon.setVisible(self.get('visible'));
});
self.addListener('zIndex_changed', function() {
touchPolygon.setOptions({
'zIndex': self.get('zIndex')
});
img.style.zIndex = self.get('zIndex');
});
touchPolygon.addListener('click', function(evt) {
if (self.get('clickable')) {
google.maps.event.trigger(self, 'click', {
'latLng': evt. latLng
});
}
});
self.set('touchPolygon', touchPolygon);
var markers = [];
for (var i = 0; i < 4; i++) {
markers.push(new google.maps.Marker({
'position': {'lat': 0, 'lng': 0},
'map': options.map
}));
}
self.set('markers', markers);
//---------------------------------------------------------
// Apply option values
//---------------------------------------------------------
for (var key in options) {
self.set(key, options[key]);
}
self.set('bounds', bounds);
}
CustomGroundOverlay.prototype.updateVertixes = function() {
var self = this;
var degree = self.get('bearing') || 0;
// Get center
var bounds = self.get('bounds');
if (!bounds) {
return;
}
var center = bounds.getCenter(),
centerPos = {
'lat': center.lat(),
'lng': center.lng()
};
// original NorthEast
var orgNE = bounds.getNorthEast(),
orgSW = bounds.getSouthWest(),
orgNEpos = {
'lat': orgNE.lat(),
'lng': orgNE.lng()
};
var orgDrgreeNE = Spherical.computeHeading(centerPos, orgNEpos);
var orgDrgreeSE = Spherical.computeHeading(centerPos, {
'lat': orgSW.lat(),
'lng': orgNE.lng()
});
var distanceCenter2NE = Spherical.computeDistanceBetween(orgNEpos, centerPos);
// new NorthEast
var newNE = Spherical.computeOffsetOrigin(centerPos, distanceCenter2NE, degree + orgDrgreeNE);
// new SourthEast
var newSE = Spherical.computeOffsetOrigin(centerPos, distanceCenter2NE, degree + orgDrgreeSE);
// new SourthWest
var newSW = Spherical.computeOffsetOrigin(centerPos, distanceCenter2NE, degree + orgDrgreeNE + 180);
// new SouthEast
var newNW = Spherical.computeOffsetOrigin(centerPos, distanceCenter2NE, degree + orgDrgreeSE + 180);
// Caclulate bounds
var path = self.get('path');
path.setAt(0, new google.maps.LatLng(newNE.lat, newNE.lng));
path.setAt(1, new google.maps.LatLng(newSE.lat, newSE.lng));
path.setAt(2, new google.maps.LatLng(newSW.lat, newSW.lng));
path.setAt(3, new google.maps.LatLng(newNW.lat, newNW.lng));
self.draw();
};
CustomGroundOverlay.prototype.remove = function() {
var self = this;
self.set('img', undefined);
google.maps.event.clearInstanceListeners(self);
google.maps.event.clearInstanceListeners(self.get('touchPolygon'));
};
CustomGroundOverlay.prototype.setClickable = function(clickable) {
var self = this;
self.set('clickable', clickable);
};
CustomGroundOverlay.prototype.setOpacity = function(opacity) {
var self = this;
self.get('img').style.opacity = opacity;
};
CustomGroundOverlay.prototype.setBearing = function(bearing) {
var self = this;
self.set('bearing', bearing);
};
CustomGroundOverlay.prototype.setBounds = function(bounds) {
var self = this;
self.set('bounds', bounds);
};
CustomGroundOverlay.prototype.setOpacity = function(opacity) {
var self = this;
self.set('opacity', opacity);
};
CustomGroundOverlay.prototype.setZIndex = function(zIndex) {
var self = this;
self.set('zIndex', zIndex);
};
CustomGroundOverlay.prototype.setVisible = function(visible) {
var self = this;
self.set('visible', visible);
};
CustomGroundOverlay.prototype.setImage = function(url) {
var self = this;
self.set('url', url);
};
CustomGroundOverlay.prototype.getBounds = function() {
var self = this;
return new google.maps.LatLngBounds(
self.get('sw'), self.get('ne')
);
};
CustomGroundOverlay.prototype.draw = function() {
var self = this,
projection = self.getProjection();
if (!projection) {
return;
}
var bounds = self.get('bounds'),
img = self.get('img');
// Calculate positions
var swPx = projection.fromLatLngToDivPixel(bounds.getSouthWest()),
nePx = projection.fromLatLngToDivPixel(bounds.getNorthEast());
img.style.left = swPx.x + 'px';
img.style.top = nePx.y + 'px';
img.style.width = (nePx.x - swPx.x) + 'px';
img.style.height = (swPx.y - nePx.y) + 'px';
img.style.transform = 'rotate(' + self.get('bearing') + 'deg)';
img.style.WebkitTransform = 'rotate(' + self.get('bearing') + 'deg)';
img.style.MozTransform = 'rotate(' + self.get('bearing') + 'deg)';
};
CustomGroundOverlay.prototype.onAdd = function() {
var self = this;
self.set('mapPane', self.getPanes().mapPane);
self.getPanes().mapPane.appendChild(self.get('img'));
};
CustomGroundOverlay.prototype.onRemove = function() {
var self = this;
self.get('mapPane').removeChild(self.get('img'));
google.maps.event.clearInstanceListeners(self.get('img'));
};
+545
View File
@@ -0,0 +1,545 @@
/* eslint no-useless-escape: off */
var InlineWorker = require('cordova-plugin-googlemaps.InlineWorker');
function PluginKmlOverlay() {
// stub
}
PluginKmlOverlay.prototype._create = function(onSuccess, onError, args) {
var pluginOptions = args[1];
if (!/^https?:/.test(location.protocol)) {
return onError('KmlOverlay is only available on http: or https: protocols.');
}
//-------------------------------------
// Parse the xml file using WebWorker
//-------------------------------------
var worker = new InlineWorker(loadKml);
worker.onmessage = function(evt) {
//console.log('host message', evt.data);
worker.terminate();
onSuccess(evt.data);
};
worker.onerror = onError;
var link = document.createElement('a');
link.href = pluginOptions.url;
var url = link.protocol+'//'+link.host+link.pathname+link.search;
worker.postMessage({
'url': url
});
};
module.exports = PluginKmlOverlay;
function loadKml(self) {
// code: https://stackoverflow.com/q/32912732/697856
var createCORSRequest = function(method, url, asynch) {
var xhr = new XMLHttpRequest();
if ('withCredentials' in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, asynch);
// xhr.setRequestHeader('MEDIBOX', 'login');
xhr.setRequestHeader('Content-Type', 'application/xml; charset=UTF-8');
} else if (typeof window.XDomainRequest != 'undefined') {
// XDomainRequest for IE.
xhr = new window.XDomainRequest();
xhr.open(method, url, asynch);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
};
//---------------------------------------
// modified fromXML (xml parser)
//---------------------------------------
var fromXML = (function() {
// fromXML
// https://github.com/kawanet/from-xml
//
// The MIT License (MIT)
//
// Copyright (c) 2016 Yusuke Kawasaki
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
/**
* The fromXML() method parses an XML string, constructing the JavaScript
* value or object described by the string.
*
* @function fromXML
* @param text {String} The string to parse as XML
* @param [reviver] {Function} If a function, prescribes how the value
* originally produced by parsing is transformed, before being returned.
* @returns {Object}
*/
var UNESCAPE = {
'&amp;': '&',
'&lt;': '<',
'&gt;': '>',
'&apos;': '\'',
'&quot;': '"'
};
var CHILD_NODE_KEY = '#';
function parseXML(text) {
var list = String.prototype.split.call(text, /<([^!<>?](?:'[\S\s]*?'|"[\S\s]*?"|[^'"<>])*|!(?:--[\S\s]*?--|\[[^\[\]'"<>]+\[[\S\s]*?]]|DOCTYPE[^\[<>]*?\[[\S\s]*?]|(?:ENTITY[^"<>]*?"[\S\s]*?")?[\S\s]*?)|\?[\S\s]*?\?)>/);
var length = list.length;
// root element
var root = {f: []};
var elem = root;
// dom tree stack
var stack = [];
for (var i = 0; i < length;) {
// text node
var str = list[i++];
if (str) appendText(str);
// child node
var tag = list[i++];
if (tag) parseNode(tag);
}
return root;
function parseNode(tag) {
var tagLength = tag.length;
var firstChar = tag[0];
if (firstChar === '/') {
// close tag
var closed = tag.replace(/^\/|[\s\/].*$/g, '').toLowerCase();
while (stack.length) {
var tagName = elem.n && elem.n.toLowerCase();
elem = stack.pop();
if (tagName === closed) break;
}
// } else if (firstChar === "?") {
// // XML declaration
// appendChild({n: "?", r: tag.substr(1, tagLength - 2)});
} else if (firstChar === '!') {
if (tag.substr(1, 7) === '[CDATA[' && tag.substr(-2) === ']]') {
// CDATA section
appendText(tag.substr(8, tagLength - 10));
} else {
// comment
appendChild({n: '!', r: tag.substr(1)});
}
} else {
var child = openTag(tag);
appendChild(child);
if (tag[tagLength - 1] === '/') {
child.c = 1; // emptyTag
} else {
stack.push(elem); // openTag
elem = child;
}
}
}
function appendChild(child) {
elem.f.push(child);
}
function appendText(str) {
str = removeSpaces(str);
if (str) appendChild(unescapeXML(str));
}
}
function openTag(tag) {
var elem = {f: []};
tag = tag.replace(/\s*\/?$/, '');
var pos = tag.search(/[\s='"\/]/);
if (pos < 0) {
elem.n = tag;
} else {
elem.n = tag.substr(0, pos);
elem.t = tag.substr(pos);
}
return elem;
}
function parseAttribute(elem, reviver) {
if (!elem.t) return;
var list = elem.t.split(/([^\s='"]+(?:\s*=\s*(?:'[\S\s]*?'|"[\S\s]*?"|[^\s'"]*))?)/);
var attributes = {};
list.forEach(function(str) {
var val;
str = removeSpaces(str);
if (!str) return;
var pos = str.indexOf('=');
if (pos < 0) {
// bare attribute
val = null;
} else {
// attribute key/value pair
val = str.substr(pos + 1).replace(/^\s+/, '');
str = str.substr(0, pos).replace(/\s+$/, '');
// quote: foo="FOO" bar='BAR'
var firstChar = val[0];
var lastChar = val[val.length - 1];
if (firstChar === lastChar && (firstChar === '\'' || firstChar === '"')) {
val = val.substr(1, val.length - 2);
}
val = unescapeXML(val);
}
if (reviver) {
val = reviver(str, val);
}
addAttribute(attributes, str, val);
});
return attributes;
}
function removeSpaces(str) {
return str && str.replace(/^\s+|\s+$/g, '');
}
function unescapeXML(str) {
return str.replace(/(&(?:lt|gt|amp|apos|quot|#(?:\d{1,6}|x[0-9a-fA-F]{1,5}));)/g, function(str) {
if (str[1] === '#') {
var code = (str[2] === 'x') ? parseInt(str.substr(3), 16) : parseInt(str.substr(2), 10);
if (code > -1) return String.fromCharCode(code);
}
return UNESCAPE[str] || str;
});
}
function toObject(elem, reviver) {
//
// var raw = elem.r;
// if (raw) return raw;
var attributes = parseAttribute(elem, reviver);
var object;
var childList = elem.f;
var childLength = childList && childList.length || 0;
if (attributes || childLength > 1) {
// merge attributes and child nodes
if (typeof attributes === 'object') {
object = attributes;
object.line=198;
} else {
object = {};
}
object.tagName = elem.n;
childList.forEach(function(child) {
if ('string' === typeof child) {
addObject(object, CHILD_NODE_KEY, child);
} else {
addObject(object, child.n, toObject(child, reviver));
}
});
} else if (childLength) {
// the node has single child node but no attribute
var child = childList[0];
if ('string' === typeof child) {
object = {
'tagName': elem.n,
'value': child,
'line': 215
};
} else {
object = toObject(child, reviver);
if (child.n) {
object = {
'tagName': elem.n,
'value': {
'children': [object]
},
'line': 227
};
}
}
} else {
// the node has no attribute nor child node
object = {
'tagName': elem.n,
'value': '',
'line': 233
};
}
if (reviver) {
object = reviver(elem.n || '', object);
}
return object;
}
function addAttribute(object, key, val) {
if ('undefined' === typeof val) return;
object.attributes = object.attributes || {};
object.attributes[key] = val;
}
function addObject(object, key, val) {
if ('undefined' === typeof val) return;
object.value = object.value || {};
object.value.children = object.value.children || [];
if (typeof val === 'object' && val.tagName) {
object.value.children.push(val);
} else {
object.value.children.push({
'tagName': key,
'value': val,
'line': 258
});
}
}
return function(text, reviver) {
text = text.replace(/<\?xml[^>]+>/i, '');
var xmlTree = parseXML(text);
var result = toObject(xmlTree, reviver);
result.tagName = 'document';
return result;
};
})();
//---------------------------------------
// KmlParserClass
//---------------------------------------
function KmlParserClass() {
var _parser = this;
_parser.styleHolder = {};
_parser.schemaHolder = {};
_parser.tagSwitchTables = {
'styleurl': _parser._styleurl,
'stylemap': _parser._style,
'style': _parser._style,
'schema': _parser._schema,
'coordinates': _parser._coordinates
};
}
KmlParserClass.prototype.parseXml = function(rootElement) {
var _parser = this,
tagName = rootElement.tagName.toLowerCase();
var _proc = _parser.tagSwitchTables[tagName] || _parser._default;
//console.log("--->tagName = " + tagName, tagName in _parser.tagSwitchTables ? tagName : '_default');
var result = _proc.call(_parser, rootElement);
if (!result) {
return null;
}
result.tagName = tagName;
if (rootElement.attributes) {
var attrNames = Object.keys(rootElement.attributes);
attrNames.forEach(function(attrName) {
result[attrName] = rootElement.attributes[attrName];
});
}
return result;
};
KmlParserClass.prototype._styleurl = function(rootElement) {
return {
'styleId': rootElement.value
};
};
KmlParserClass.prototype._style = function(rootElement) {
var _parser = this;
// Generate a style id for the tag
var styleId = rootElement.attributes ? rootElement.attributes.id : null;
if (!styleId) {
styleId = '__' + Math.floor(Date.now() * Math.random()) + '__';
}
var result = {
'styleId': styleId
};
// Store style information into the styleHolder
var styles = {};
var children = [];
if (rootElement.value.children) {
rootElement.value.children.forEach(function(childNode) {
var node = _parser.parseXml(childNode);
if (node.value) {
styles[node.tagName] = node.value;
} else {
children.push(node);
}
});
if (children.length > 0) {
styles.children = children;
}
}
_parser.styleHolder[styleId] = styles;
return result;
};
KmlParserClass.prototype._schema = function(rootElement) {
var _parser = this;
var result = {};
// Generate a schema id for the tag
var schemaId = rootElement.attributes ? rootElement.attributes.id : null;
if (!schemaId) {
schemaId = '__' + Math.floor(Date.now() * Math.random()) + '__';
}
// Store schema information into the schemaHolder.
var schema = {};
schema.name = rootElement.attributes ? rootElement.attributes.id : '__' + Math.floor(Date.now() * Math.random()) + '__';
if (rootElement.value.children) {
var children = [];
rootElement.value.children.forEach(function(childNode) {
var node = _parser.parseXml(childNode);
if (node) {
children.push(node);
}
});
if (children.length > 0) {
schema.children = children;
}
}
_parser.schemaHolder[schemaId] = schema;
return result;
};
KmlParserClass.prototype._coordinates = function(rootElement) {
var result = {};
var latLngList = [];
var txt = rootElement.value;
txt = txt.replace(/\s+/g, '\n');
txt = txt.replace(/\n+/g, '\n');
var lines = txt.split(/\n/);
lines.forEach(function(line) {
line = line.replace(/[^0-9,.\\-]/g, '');
if (line !== '') {
var tmpArry = line.split(',');
latLngList.push({
'lat': parseFloat(tmpArry[1]),
'lng': parseFloat(tmpArry[0])
});
}
});
result.coordinates = latLngList;
return result;
};
KmlParserClass.prototype._default = function(rootElement) {
var _parser = this,
result = {};
if (!rootElement.value) {
return null;
}
if (rootElement.value.children) {
var children = [];
rootElement.value.children.forEach(function(childNode) {
var node = _parser.parseXml.call(_parser, childNode);
if (node) {
if ('styleId' in node) {
result.styleIDs = result.styleIDs || [];
result.styleIDs.push(node.styleId);
} else if (node.tagName !== 'schema') {
children.push(node);
}
}
});
result.children = children;
} else {
var value = rootElement.value;
if (/^-?[0-9]+$/.test(value)) {
result.value = parseInt(value, 10);
} else if (/^-?[0-9\.]+$/.test(value)) {
result.value = parseFloat(value, 10);
} else {
result.value = value;
}
}
return result;
};
self.onmessage = function(evt) {
var params = evt.data;
//------------------------------------------
// Load & parse kml file in WebWorker
//------------------------------------------
(new Promise(function(resolve, reject) {
//-----------------
// Read XML file
//-----------------
var xhr = createCORSRequest('GET', params.url, true);
if (xhr) {
xhr.onreadystatechange = function() {
try {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
resolve(xhr.responseText);
} else {
reject(xhr);
}
}
} catch (e) {
reject(e.description);
}
};
xhr.send();
}
}))
.then(function(xmlTxt) {
//-----------------
// Parse it
//-----------------
var doc = fromXML(xmlTxt);
var parser = new KmlParserClass();
var root = parser.parseXml(doc);
var result = {
'schemas': parser.schemaHolder,
'styles': parser.styleHolder,
'root': root
};
postMessage(result);
});
};
}
@@ -0,0 +1,59 @@
var LOCATION_ERROR = {
'1': 'service_denied',
'2': 'not_available',
'3': 'timeout'
};
module.exports = {
'hasPermission': function(onSuccess, onError) {
if (navigator.permissions) {
navigator.permissions.query({'name': 'geolocation'})
.then(function(permission) {
onSuccess(permission.state === 'granted' ? 1 : 0);
})
.catch(onError);
} else {
onError('Browser does not support this feature.');
}
},
'getMyLocation': function(onSuccess, onError) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
onSuccess({
'latLng': {
'lat': position.coords.latitude,
'lng': position.coords.longitude
},
'elapsedRealtimeNanos': 0,
'time': position.timestamp,
'accuracy': position.coords.accuracy,
'altitude': position.coords.altitude,
'speed': position.coords.speed,
'bearing': position.coords.heading,
'provider': 'geolocationapi',
'hashCode': 'dummy',
'status': true
});
}, function(error) {
onError({
'status': false,
'error_code': LOCATION_ERROR[error.code],
'error_message': error.message
});
}, {
'enableHighAccuracy': true
});
} else {
onError({
'status': false,
'error_code': 'not_available',
'error_message': 'Since this device does not have any location provider, this app can not detect your location.'
});
}
}
};
require('cordova/exec/proxy').add('PluginLocationService', module.exports);
+726
View File
@@ -0,0 +1,726 @@
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 = [
'<div style="position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-color:rgb(229, 227, 223)">',
'<div style="text-align: center; position: absolute; left: 0; top: 0; bottom: 0; right: 0; width: 80%; height: 100px; margin: auto; color: #616161">',
'<img src="https://maps.gstatic.com/mapfiles/api-3/images/icon_error.png"><br>',
'<h3>Can not display map.<br>Check the developer console.</h3>',
'</div>',
'</div>'
].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.stopAnimation = 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;
+489
View File
@@ -0,0 +1,489 @@
var utils = require('cordova/utils'),
event = require('cordova-plugin-googlemaps.event'),
BaseClass = require('cordova-plugin-googlemaps.BaseClass'),
LatLng = require('cordova-plugin-googlemaps.LatLng');
function PluginMarker(pluginMap) {
var self = this;
BaseClass.apply(self);
Object.defineProperty(self, 'pluginMap', {
value: pluginMap,
writable: false
});
Object.defineProperty(self, 'infoWnd', {
value: null,
writable: true
});
}
utils.extend(PluginMarker, BaseClass);
PluginMarker.prototype._create = function(onSuccess, onError, args) {
var self = this,
markerId = 'marker_' + args[2],
pluginOptions = args[1];
self.__create.call(self, markerId, pluginOptions, function(marker, properties) {
onSuccess(properties);
}, onError);
};
/*eslint-disable no-unused-vars*/
PluginMarker.prototype.__create = function(markerId, pluginOptions, onSuccess, onError) {
/*eslint-enable no-unused-vars*/
var self = this,
map = self.pluginMap.get('map');
var markerOpts = {
'overlayId': markerId,
'position': pluginOptions.position,
'disableAutoPan': pluginOptions.disableAutoPan,
'draggable': pluginOptions.draggable,
'visible': pluginOptions.visible
};
var iconSize = null;
if (pluginOptions.animation) {
markerOpts.animation = google.maps.Animation[pluginOptions.animation.toUpperCase()];
}
if (pluginOptions.icon) {
var icon = pluginOptions.icon;
markerOpts.icon = {};
if (Array.isArray(pluginOptions.icon) && pluginOptions.icon.length === 4) {
pluginOptions.icon = {
'url': pluginOptions.icon
};
}
if (typeof pluginOptions.icon === 'string') {
// Specifies path or url to icon image
markerOpts.icon.url = pluginOptions.icon;
} else if (typeof pluginOptions.icon === 'object') {
if (Array.isArray(pluginOptions.icon.url)) {
// Specifies color name or rule
markerOpts.icon = {
'path': 'm12 0c-4.4183 2.3685e-15 -8 3.5817-8 8 0 1.421 0.3816 2.75 1.0312 3.906 0.1079 0.192 0.221 0.381 0.3438 0.563l6.625 11.531 6.625-11.531c0.102-0.151 0.19-0.311 0.281-0.469l0.063-0.094c0.649-1.156 1.031-2.485 1.031-3.906 0-4.4183-3.582-8-8-8zm0 4c2.209 0 4 1.7909 4 4 0 2.209-1.791 4-4 4-2.2091 0-4-1.791-4-4 0-2.2091 1.7909-4 4-4z',
'fillColor': 'rgb(' + pluginOptions.icon.url[0] + ',' + pluginOptions.icon.url[1] + ',' + pluginOptions.icon.url[2] + ')',
'fillOpacity': pluginOptions.icon.url[3] / 255,
'scale': 1.3,
'strokeWeight': 1,
'strokeColor': 'rgb(255, 255, 255)',
'strokeOpacity': 0.65,
'anchor': new google.maps.Point(12, 27)
};
iconSize = {
'width': 22,
'height': 28
};
} else {
markerOpts.icon.url = pluginOptions.icon.url;
if (pluginOptions.icon.size) {
markerOpts.icon.scaledSize = new google.maps.Size(icon.size.width, icon.size.height);
iconSize = icon.size;
}
}
if ('anchor' in icon && Array.isArray(icon.anchor)) {
markerOpts.icon.anchor = new google.maps.Point(icon.anchor[0], icon.anchor[1]);
}
}
}
if (!markerOpts.icon ||
!markerOpts.icon.url && !markerOpts.icon.path) {
// default marker
markerOpts.icon = {
'path': 'm12 0c-4.4183 2.3685e-15 -8 3.5817-8 8 0 1.421 0.3816 2.75 1.0312 3.906 0.1079 0.192 0.221 0.381 0.3438 0.563l6.625 11.531 6.625-11.531c0.102-0.151 0.19-0.311 0.281-0.469l0.063-0.094c0.649-1.156 1.031-2.485 1.031-3.906 0-4.4183-3.582-8-8-8zm0 4c2.209 0 4 1.7909 4 4 0 2.209-1.791 4-4 4-2.2091 0-4-1.791-4-4 0-2.2091 1.7909-4 4-4z',
'fillColor': 'rgb(255, 0, 0)',
'fillOpacity': 1,
'scale': 1.3,
'strokeWeight': 1,
'strokeColor': 'rgb(255, 255, 255)',
'strokeOpacity': 0.65,
'anchor': new google.maps.Point(12, 27)
};
iconSize = {
'width': 22,
'height': 28
};
}
if ('zIndex' in pluginOptions) {
markerOpts.zIndex = pluginOptions.zIndex;
}
markerOpts.map = map;
var marker = new google.maps.Marker(markerOpts);
marker.addListener('click', self.onMarkerClickEvent.bind(self, event.MARKER_CLICK, marker), {passive: true});
marker.addListener('dragstart', self.onMarkerEvent.bind(self, event.MARKER_DRAG_START, marker));
marker.addListener('drag', self.onMarkerEvent.bind(self, event.MARKER_DRAG, marker));
marker.addListener('dragend', self.onMarkerEvent.bind(self, event.MARKER_DRAG_END, marker));
if (pluginOptions.title) {
marker.set('title', pluginOptions.title);
}
if (pluginOptions.snippet) {
marker.set('snippet', pluginOptions.snippet);
}
self.pluginMap.objects[markerId] = marker;
self.pluginMap.objects['marker_property_' + markerId] = markerOpts;
if (iconSize) {
onSuccess(marker, {
'__pgmId': markerId,
'width': iconSize.width,
'height': iconSize.height
});
} else {
var markerIcon = marker.getIcon();
if (markerIcon && markerIcon.size) {
onSuccess({
'__pgmId': markerId,
'width': markerIcon.size.width,
'height': markerIcon.size.height
});
} else {
var img = new Image();
img.onload = function() {
onSuccess(marker, {
'__pgmId': markerId,
'width': img.width,
'height': img.height
});
};
img.onerror = function(error) {
console.warn(error.getMessage());
onSuccess(marker, {
'__pgmId': markerId,
'width': 20,
'height': 42
});
};
if (typeof markerOpts.icon === 'string') {
img.src = markerOpts.icon;
} else {
img.src = markerOpts.icon.url;
}
}
}
setTimeout(function() {
marker.setAnimation(null);
}, 500);
};
PluginMarker.prototype._removeMarker = function(marker) {
marker.setMap(null);
marker = undefined;
};
PluginMarker.prototype.setDisableAutoPan = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var disableAutoPan = args[1];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
marker.set('disableAutoPan', disableAutoPan);
}
onSuccess();
};
PluginMarker.prototype.setFlat = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var flat = args[1];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
marker.set('flat', flat);
}
onSuccess();
};
PluginMarker.prototype.setVisible = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var visible = args[1];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
marker.setVisible(visible);
}
onSuccess();
};
PluginMarker.prototype.setAnimation = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var animation = args[1];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
marker.setAnimation(google.maps.Animation[animation]);
setTimeout(function() {
marker.setAnimation(null);
}, 500);
}
onSuccess();
};
PluginMarker.prototype.setRotation = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var rotation = args[1];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
var icon = marker.getIcon();
if (icon && icon.path) {
icon.rotation = rotation;
marker.setIcon(icon);
}
}
onSuccess();
};
PluginMarker.prototype.setDraggable = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
marker.setDraggable(args[1]);
}
onSuccess();
};
PluginMarker.prototype.setInfoWindowAnchor = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
var icon = marker.getIcon();
var anchorX = args[1];
anchorX = anchorX - icon.size.width / 2;
var anchorY = args[2];
anchorY = anchorY - icon.size.height / 2;
marker.setOptions({
'anchorPoint': new google.maps.Point(anchorX, anchorY)
});
if (self.infoWnd) {
self._showInfoWindow.call(self, marker);
}
}
onSuccess();
};
PluginMarker.prototype.setTitle = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var title = args[1];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
marker.set('title', title);
}
onSuccess();
};
PluginMarker.prototype.setSnippet = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var snippet = args[1];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
marker.set('snippet', snippet);
}
onSuccess();
};
PluginMarker.prototype.setOpacity = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var opacity = args[1];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
marker.setOpacity(opacity);
}
onSuccess();
};
PluginMarker.prototype.setIconAnchor = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var anchorX = args[1],
anchorY = args[2];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
var icon = marker.getIcon();
if (typeof icon === 'string') {
icon = {
'url': icon
};
}
icon.anchor = new google.maps.Point(anchorX, anchorY);
marker.setIcon(icon);
}
onSuccess();
};
PluginMarker.prototype.setZIndex = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var zIndex = args[1];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
marker.setZIndex(zIndex);
}
onSuccess();
};
PluginMarker.prototype.showInfoWindow = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
if (self.pluginMap.activeMarker && self.pluginMap.activeMarker !== marker) {
self.onMarkerClickEvent(event.INFO_CLICK, self.pluginMap.activeMarker);
}
self.pluginMap.activeMarker = marker;
self._showInfoWindow.call(self, marker);
}
onSuccess();
};
PluginMarker.prototype.hideInfoWindow = function(onSuccess) {
var self = this;
if (self.infoWnd) {
google.maps.event.trigger(self.infoWnd, 'closeclick');
self.infoWnd.close();
self.infoWnd = null;
}
onSuccess();
};
PluginMarker.prototype.setIcon = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var marker = self.pluginMap.objects[overlayId];
self.setIcon_(marker, args[1])
.then(onSuccess)
.catch(onError);
};
PluginMarker.prototype.setIcon_ = function(marker, iconOpts) {
return new Promise(function(resolve) {
if (marker) {
if (Array.isArray(iconOpts)) {
// Specifies color name or rule
iconOpts = {
'path': 'm12 0c-4.4183 2.3685e-15 -8 3.5817-8 8 0 1.421 0.3816 2.75 1.0312 3.906 0.1079 0.192 0.221 0.381 0.3438 0.563l6.625 11.531 6.625-11.531c0.102-0.151 0.19-0.311 0.281-0.469l0.063-0.094c0.649-1.156 1.031-2.485 1.031-3.906 0-4.4183-3.582-8-8-8zm0 4c2.209 0 4 1.7909 4 4 0 2.209-1.791 4-4 4-2.2091 0-4-1.791-4-4 0-2.2091 1.7909-4 4-4z',
'fillColor': 'rgb(' + iconOpts[0] + ',' + iconOpts[1] + ',' + iconOpts[2] + ')',
'fillOpacity': iconOpts[3] / 256,
'scale': 1.3,
'strokeWeight': 0,
'anchor': new google.maps.Point(12, 27)
};
} else if (typeof iconOpts === 'object') {
if (typeof iconOpts.size === 'object') {
iconOpts.size = new google.maps.Size(iconOpts.size.width, iconOpts.size.height, 'px', 'px');
iconOpts.scaledSize = iconOpts.size;
}
if (Array.isArray(iconOpts.anchor)) {
iconOpts.anchor = new google.maps.Point(iconOpts.anchor[0], iconOpts.anchor[1]);
}
}
marker.setIcon(iconOpts);
}
resolve();
});
};
PluginMarker.prototype.setPosition = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
marker.setPosition({'lat': args[1], 'lng': args[2]});
}
onSuccess();
};
PluginMarker.prototype.remove = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var marker = self.pluginMap.objects[overlayId];
if (marker) {
google.maps.event.clearInstanceListeners(marker);
marker.setMap(null);
marker = undefined;
self.pluginMap.objects[overlayId] = undefined;
delete self.pluginMap.objects[overlayId];
delete self.pluginMap.objects['marker_property_' + overlayId];
}
onSuccess();
};
PluginMarker.prototype.onMarkerEvent = function(evtName, marker) {
var self = this,
mapId = self.pluginMap.__pgmId;
if (mapId in plugin.google.maps) {
var latLng = marker.getPosition();
plugin.google.maps[mapId]({
'evtName': evtName,
'callback': '_onMarkerEvent',
'args': [marker.overlayId, new LatLng(latLng.lat(), latLng.lng())]
});
}
};
PluginMarker.prototype._showInfoWindow = function(marker) {
var self = this;
if (!self.infoWnd) {
self.infoWnd = new google.maps.InfoWindow({
'pixelOffset': new google.maps.Size(0, 0)
});
}
var container = document.createElement('div');
if (self.pluginMap.activeMarker && self.pluginMap.activeMarker !== marker) {
self.onMarkerClickEvent(event.INFO_CLICK, self.pluginMap.activeMarker);
}
self.pluginMap.activeMarker = marker;
self.pluginMap._syncInfoWndPosition.call(self);
var maxWidth = marker.getMap().getDiv().offsetWidth * 0.7;
var html = [];
if (marker.get('title')) {
html.push(marker.get('title'));
}
if (marker.get('snippet')) {
html.push('<small>' + marker.get('snippet') + '</small>');
}
if (html.length > 0) {
container.innerHTML = html.join('<br>');
google.maps.event.addListenerOnce(self.infoWnd, 'domready', function() {
self.onMarkerClickEvent(event.INFO_OPEN, marker);
if (container.parentNode) {
google.maps.event.addDomListener(container.parentNode.parentNode.parentNode, 'click', function() {
self.onMarkerClickEvent(event.INFO_CLICK, marker);
}, true);
}
});
self.infoWnd.setOptions({
content: container,
disableAutoPan: marker.disableAutoPan,
maxWidth: maxWidth
});
google.maps.event.addListener(self.infoWnd, 'closeclick', function() {
google.maps.event.clearInstanceListeners(self.infoWnd);
self.onMarkerClickEvent(event.INFO_CLOSE, marker);
});
self.infoWnd.open(marker.getMap(), marker);
}
};
PluginMarker.prototype.onMarkerClickEvent = function(evtName, marker) {
var self = this;
var overlayId = marker.get('overlayId');
if (self.pluginMap.activeMarker && self.pluginMap.activeMarker !== marker) {
self.onMarkerEvent(event.INFO_CLOSE, self.pluginMap.activeMarker);
}
self.pluginMap.activeMarker = marker;
if (marker.get('disableAutoPan') === false) {
self.pluginMap.get('map').panTo(marker.getPosition());
}
if (overlayId.indexOf('markercluster_') > -1) {
self.onClusterEvent(evtName, marker);
} else {
self.onMarkerEvent(evtName, marker);
}
};
module.exports = PluginMarker;
@@ -0,0 +1,714 @@
var utils = require('cordova/utils'),
event = require('cordova-plugin-googlemaps.event'),
PluginMarker = require('cordova-plugin-googlemaps.PluginMarker'),
Thread = require('cordova-plugin-googlemaps.Thread'),
LatLng = require('cordova-plugin-googlemaps.LatLng'),
BaseArrayClass = require('cordova-plugin-googlemaps.BaseArrayClass');
var STATUS = {
'WORKING': 0,
'CREATED': 1,
'DELETED': 2
};
function PluginMarkerCluster(pluginMap) {
var self = this;
PluginMarker.call(self, pluginMap);
Object.defineProperty(self, 'pluginMarkers', {
value: {},
writable: false
});
Object.defineProperty(self, 'debugFlags', {
value: {},
writable: false
});
var deleteMarkers = new BaseArrayClass();
Object.defineProperty(self, 'deleteMarkers', {
value: deleteMarkers,
writable: false
});
deleteMarkers.on('insert_at', function() {
var key = deleteMarkers.removeAt(0);
var marker = self.pluginMap.objects[key];
if (marker) {
self._removeMarker(marker);
}
self.pluginMap.objects[key] = undefined;
self.pluginMap.objects['marker_property_' + key] = undefined;
self.pluginMarkers[key] = undefined;
delete self.pluginMap.objects[key];
delete self.pluginMap.objects['marker_property_' + key];
delete self.pluginMarkers[key];
self.pluginMarkers[key] = STATUS.DELETED;
});
}
utils.extend(PluginMarkerCluster, PluginMarker);
PluginMarkerCluster.prototype._create = function(onSuccess, onError, args) {
var self = this,
params = args[1],
hashCode = args[2],
positionList = params.positionList;
//---------------------------------------------
// Calculate geocell hashCode on multi thread
//---------------------------------------------
var tasks = [];
while(positionList.length > 0) {
var list = positionList.splice(0, 10);
tasks.push(new Promise(function(resolve, reject) {
var thread = new Thread(function(params) {
var GEOCELL_GRID_SIZE = 4;
var GEOCELL_ALPHABET = '0123456789abcdef';
function getGeocell(lat, lng, resolution) {
var north = 90.0,
south = -90.0,
east = 180.0,
west = -180.0,
subcell_lng_span, subcell_lat_span,
x, y, cell = [];
while(cell.length < resolution + 1) {
subcell_lng_span = (east - west) / GEOCELL_GRID_SIZE;
subcell_lat_span = (north - south) / GEOCELL_GRID_SIZE;
x = Math.min(Math.floor(GEOCELL_GRID_SIZE * (lng - west) / (east - west)), GEOCELL_GRID_SIZE - 1);
y = Math.min(Math.floor(GEOCELL_GRID_SIZE * (lat - south) / (north - south)), GEOCELL_GRID_SIZE - 1);
cell.push(_subdiv_char(x, y));
south += subcell_lat_span * y;
north = south + subcell_lat_span;
west += subcell_lng_span * x;
east = west + subcell_lng_span;
}
return cell.join('');
}
function _subdiv_char(posX, posY) {
return GEOCELL_ALPHABET.charAt(
(posY & 2) << 2 |
(posX & 2) << 1 |
(posY & 1) << 1 |
(posX & 1) << 0);
}
return params.positionList.map(function(position) {
return getGeocell(position.lat, position.lng, params.resolution);
});
});
thread
.once({
'positionList': list,
'resolution': 12
})
.done(resolve)
.fail(reject);
}));
}
Promise.all(tasks)
.then(function(results) {
var id = 'markerclister_' + hashCode;
self.debugFlags[id] = params.debug;
var result = {
'geocellList': Array.prototype.concat.apply([], results),
'hashCode': hashCode,
'__pgmId': id
};
onSuccess(result);
})
.catch(onError);
};
PluginMarkerCluster.prototype.redrawClusters = function(onSuccess, onError, args) {
var self = this;
var updateClusterIDs = [],
changeProperties = {},
clusterId = args[0],
isDebug = self.debugFlags[clusterId],
params = args[1],
map = self.pluginMap.get('map');
if ('new_or_update' in params) {
//---------------------------
// Determine new or update
//---------------------------
params.new_or_update.forEach(function(clusterData) {
var positionJSON = clusterData.position,
markerId = clusterData.__pgmId,
clusterId_markerId = clusterId + '-' + markerId;
// Save the marker properties
self.pluginMap.objects['marker_property_' + clusterId_markerId] = clusterData;
// Set the WORKING status flag
self.pluginMarkers[clusterId_markerId] = STATUS.WORKING;
updateClusterIDs.push(clusterId_markerId);
// Prepare the marker properties for addMarker()
var properties = {
'lat': positionJSON.lat,
'lng': positionJSON.lng,
'__pgmId': clusterId_markerId
};
if ('title' in clusterData) {
properties.title = clusterData.title;
}
if ('icon' in clusterData) {
var iconObj = clusterData.icon,
iconProperties = {},
label;
if (typeof iconObj === 'string') {
iconProperties.url = iconObj;
properties.icon = iconProperties;
} else if (typeof iconObj === 'object') {
iconProperties = iconObj;
if (clusterData.isClusterIcon) {
if (iconObj.label) {
label = iconObj.label;
if (isDebug) {
label.text = markerId;
} else {
label.text = clusterData.count;
}
} else {
label = {};
if (isDebug) {
label.text = markerId;
} else {
label.fontSize = 15;
label.bold = true;
label.text = clusterData.count;
}
}
iconProperties.label = label;
}
if ('anchor' in iconObj) {
iconProperties.anchor = iconObj.anchor;
}
if ('infoWindowAnchor' in iconObj) {
iconProperties.anchor = iconObj.infoWindowAnchor;
}
properties.icon = iconProperties;
}
}
changeProperties[clusterId_markerId] = JSON.parse(JSON.stringify(properties));
});
if (updateClusterIDs.length === 0) {
self.deleteProcess(clusterId, params);
onSuccess({});
return;
}
//---------------------------
// mapping markers on the map
//---------------------------
var allResults = {};
//---------------
// new or update
//---------------
var tasks = [];
updateClusterIDs.forEach(function(clusterId_markerId) {
self.pluginMarkers[clusterId_markerId] = STATUS.WORKING;
var isNew = !(clusterId_markerId in self.pluginMap.objects);
// Get the marker properties
var markerProperties = changeProperties[clusterId_markerId],
properties, marker;
if (clusterId_markerId.indexOf('-marker_') > -1) {
//-------------------
// regular marker
//-------------------
if (isNew) {
properties = self.pluginMap.objects['marker_property_' + clusterId_markerId];
tasks.push(new Promise(function(resolve) {
self.__create.call(self, clusterId_markerId, {
'position': properties.position,
'icon': properties.icon,
'disableAutoPan': properties.disableAutoPan
}, function(marker, properties) {
if (markerProperties.title) {
marker.set('title', markerProperties.title);
}
if (markerProperties.snippet) {
marker.set('snippet', markerProperties.snippet);
}
if (self.pluginMarkers[clusterId_markerId] === STATUS.DELETED) {
self._removeMarker.call(self, marker);
delete self.pluginMarkers[clusterId_markerId];
resolve();
} else {
self.pluginMarkers[clusterId_markerId] = STATUS.CREATED;
allResults[clusterId_markerId.split('-')[1]] = {
'width': properties.width,
'height': properties.height
};
resolve();
}
});
}));
} else {
marker = self.pluginMap.objects[clusterId_markerId];
//----------------------------------------
// Set the title and snippet properties
//----------------------------------------
if (markerProperties.title) {
marker.set('title', markerProperties.title);
}
if (markerProperties.snippet) {
marker.set('snippet', markerProperties.snippet);
}
if (self.pluginMarkers[clusterId_markerId] === STATUS.DELETED) {
self._removeMarker.call(self, marker);
delete self.pluginMarkers[clusterId_markerId];
} else {
self.pluginMarkers[clusterId_markerId] = STATUS.CREATED;
}
}
} else {
//--------------------------
// cluster icon
//--------------------------
if (isNew) {
// If the requested id is new location, create a marker
marker = newClusterIcon({
'map': map,
'position': {
'lat': markerProperties.lat,
'lng': markerProperties.lng
},
'overlayId': clusterId_markerId,
'opacity': 0
});
marker.addListener('click', self.onClusterEvent.bind(self, 'cluster_click', marker));
// Store the marker instance with markerId
self.pluginMap.objects[clusterId_markerId] = marker;
} else {
marker = self.pluginMap.objects[clusterId_markerId];
}
//----------------------------------------
// Set the title and snippet properties
//----------------------------------------
if (markerProperties.title) {
marker.set('title', markerProperties.title);
}
if (markerProperties.snippet) {
marker.set('snippet', markerProperties.snippet);
}
if (markerProperties.icon) {
var icon = markerProperties.icon;
tasks.push(new Promise(function(resolve) {
self.setIconToClusterMarker.call(self, clusterId_markerId, marker, icon)
.then(function() {
//--------------------------------------
// Marker was updated
//--------------------------------------
marker.setVisible(true);
self.pluginMarkers[clusterId_markerId] = STATUS.CREATED;
resolve();
})
.catch(function(error) {
//--------------------------------------
// Could not read icon for some reason
//--------------------------------------
if (marker.get('overlayId')) {
self._removeMarker.call(self, marker);
}
self.pluginMarkers[clusterId_markerId] = STATUS.DELETED;
console.warn(error.getMessage());
self.deleteMarkers.push(clusterId_markerId);
resolve();
});
}));
} else {
//--------------------
// No icon for marker
//--------------------
self.pluginMarkers[clusterId_markerId] = STATUS.CREATED;
}
}
});
Promise.all(tasks).then(function() {
self.deleteProcess(clusterId, params);
onSuccess(allResults);
}).catch(onError);
}
};
PluginMarkerCluster.prototype.deleteProcess = function(clusterId, params) {
var self = this;
if (!params.delete || params.delete.length === 0) {
return;
}
params.delete.forEach(function(key) {
self.deleteMarkers.push(clusterId + '-' + key);
});
};
PluginMarkerCluster.prototype.setIconToClusterMarker = function(markerId, marker, iconProperty) {
var self = this;
return new Promise(function(resolve, reject) {
if (self.pluginMarkers[markerId] === STATUS.DELETED) {
self._removeMarker.call(self, marker);
delete self.pluginMap.objects[markerId];
delete self.pluginMap.objects['marker_property_' + markerId];
delete self.pluginMarkers[markerId];
reject('marker has been removed');
return;
}
self.setIcon_.call(self, marker, iconProperty)
.then(function() {
if (self.pluginMarkers[markerId] === STATUS.DELETED) {
self._removeMarker.call(self, marker);
delete self.pluginMap.objects[markerId];
delete self.pluginMap.objects['marker_property_' + markerId];
self.pluginMarkers.remove(markerId);
resolve();
return;
}
marker.setVisible(true);
self.pluginMarkers[markerId] = STATUS.CREATED;
resolve();
});
});
};
PluginMarkerCluster.prototype.remove = function(onSuccess, onError, args) {
var self = this,
clusterId = args[0],
keys = Object.keys(self.pluginMarkers);
keys.forEach(function(key) {
if (key.indexOf(clusterId) === 0) {
if (self.pluginMap.objects[key]) {
self.pluginMap.objects[key].setMap(null);
}
self.pluginMarkers[key] = STATUS.DELETED;
delete self.pluginMap.objects[key];
delete self.pluginMap.objects['marker_property_' + key];
}
});
onSuccess();
};
PluginMarkerCluster.prototype.onClusterEvent = function(evtName, marker) {
var self = this,
mapId = self.pluginMap.__pgmId;
var overlayId = marker.get('overlayId');
var tmp = overlayId.split('-');
var clusterId = tmp[0];
var markerId = tmp[1];
var latLng = marker.getPosition();
if (mapId in plugin.google.maps) {
if (self.pluginMap.activeMarker) {
self.onMarkerEvent(event.INFO_CLOSE, self.pluginMap.activeMarker);
}
plugin.google.maps[mapId]({
'evtName': evtName,
'callback': '_onClusterEvent',
'args': [clusterId, markerId, new LatLng(latLng.lat(), latLng.lng())]
});
}
};
module.exports = PluginMarkerCluster;
function newClusterIcon(options) {
// https://github.com/apache/cordova-js/blob/c75e8059114255d1dbae1ede398e6626708ee9f3/src/common/utils.js#L167
if (ClusterIconClass.__super__ !== google.maps.OverlayView.prototype) {
var key, defined = {};
for (key in ClusterIconClass.prototype) {
defined[key] = ClusterIconClass.prototype[key];
}
utils.extend(ClusterIconClass, google.maps.OverlayView);
for (key in defined) {
ClusterIconClass.prototype[key] = defined[key];
}
}
return new ClusterIconClass(options);
}
function ClusterIconClass(options) {
google.maps.OverlayView.apply(this);
var self = this;
//-----------------------------------------
// Create a canvas to draw label
//-----------------------------------------
var canvas = document.createElement('canvas');
canvas.width = 50;
canvas.height = 50;
canvas.style.visibility = 'hidden';
canvas.style.position = 'absolute';
canvas.style.zIndex = -100;
canvas.setAttribute('id', 'canvas_' + options.overlayId);
self.set('canvas', canvas);
//-----------------------------------------
// Create two markers for icon and label
//-----------------------------------------
var iconMarker = new google.maps.Marker({
'clickable': false,
'icon': options.icon,
'zIndex': 0,
'opacity': 0
});
var labelMarker = new google.maps.Marker({
'clickable': true,
'zIndex': 1,
'icon': self.get('label'),
'opacity': 0
});
labelMarker.addListener('click', function() {
google.maps.event.trigger(self, 'click');
});
self.set('iconMarker', iconMarker);
self.set('labelMarker', labelMarker);
self.set('opacity', 0);
iconMarker.bindTo('opacity', labelMarker);
iconMarker.bindTo('visible', labelMarker);
iconMarker.bindTo('position', labelMarker);
iconMarker.bindTo('map', labelMarker);
self.bindTo('opacity', iconMarker);
self.bindTo('visible', iconMarker);
self.bindTo('map', iconMarker);
self.bindTo('position', iconMarker);
self.set('labelMarkerAnchor', new google.maps.Point(canvas.width / 2, canvas.height / 2));
self.addListener('icon_changed', function() {
var icon = self.get('icon');
if (typeof icon === 'string') {
icon = {
'url': icon
};
}
var iconUrl = icon.url;
if (typeof icon === 'object') {
if (typeof icon.size === 'object' &&
icon.size.width && icon.size.height) {
icon.anchor = new google.maps.Point(icon.size.width / 2, icon.size.height / 2);
iconMarker.setIcon(icon);
return;
}
}
var img = new Image();
img.onload = function() {
icon.size = new google.maps.Size(img.width, img.height);
icon.scaledSize = new google.maps.Size(img.width, img.height);
icon.anchor = new google.maps.Point(img.width / 2, img.height / 2);
self.set('labelMarkerAnchor', new google.maps.Point(img.width / 2, img.height / 2));
iconMarker.setIcon(icon);
};
img.onerror = function(e) {
console.error(e);
};
img.src = iconUrl;
});
//debug
//var positionConfirmMarker = new google.maps.Marker();
//labelMarker.bindTo('position', positionConfirmMarker);
//labelMarker.bindTo('map', positionConfirmMarker);
for (var key in options) {
self.set(key, options[key]);
}
}
ClusterIconClass.prototype.onAdd = function() {
var self = this;
var canvas = self.get('canvas');
self.get('map').getDiv().appendChild(canvas);
};
ClusterIconClass.prototype.onRemove = function() {
var self = this;
var canvas = self.get('canvas');
self.set('map', null);
google.maps.event.clearInstanceListeners(self.get('iconMarker'));
google.maps.event.clearInstanceListeners(self.get('labelMarker'));
var parent = canvas.parentNode;
if (parent) {
parent.removeChild(canvas);
}
canvas = undefined;
};
ClusterIconClass.prototype.draw = function() {
var self = this,
icon = self.get('icon');
if (typeof icon === 'string') {
icon = {
'url': icon
};
}
icon.label = icon.label || {};
if (self.get('prevText') === icon.label.text) {
return;
}
self.set('prevText', icon.label.text);
self.get('labelMarker').set('opacity', 0);
(new Promise(function(resolve) {
var iconUrl = icon.url;
if (typeof icon === 'object') {
if (typeof icon.size === 'object' &&
icon.size.width && icon.size.height) {
return resolve(icon.size);
}
}
var img = new Image();
img.onload = function() {
var newIconInfo = {
width: img.width,
height: img.height
};
icon.size = newIconInfo;
self.set('labelMarkerAnchor', new google.maps.Point(newIconInfo.width / 2, newIconInfo.height / 2));
self.set('icon', icon, true);
resolve(newIconInfo);
};
img.onerror = function() {
var newIconInfo = {
width: img.width,
height: img.height
};
icon.size = newIconInfo;
self.set('icon', icon, true);
resolve(newIconInfo);
};
img.src = iconUrl;
}))
.then(function(iconSize) {
var canvas = self.get('canvas'),
ctx = canvas.getContext('2d');
canvas.width = iconSize.width;
canvas.height = iconSize.height;
var labelOptions = icon.label || {
fontSize: 10,
bold: false,
italic: false
};
ctx.clearRect(0, 0, canvas.width, canvas.height);
// debug
//ctx.fillStyle="#FF000077";
//ctx.fillRect(0, 0, canvas.width, canvas.height);
if (labelOptions.text) {
var fontStyles = [];
if ('color' in labelOptions) {
ctx.fillStyle = [
'rgba(',
labelOptions.color[0],
',',
labelOptions.color[1],
',',
labelOptions.color[2],
',',
labelOptions.color[3] / 255,
')'].join('');
} else {
ctx.fillStyle = 'black';
}
if (labelOptions.italic === true) {
fontStyles.push('italic');
}
if (labelOptions.bold === true) {
fontStyles.push('bold');
}
fontStyles.push(parseInt(labelOptions.fontSize || '10', 10) + 'px');
fontStyles.push('Arial');
ctx.font = fontStyles.join(' ');
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.fillText(labelOptions.text, iconSize.width / 2, iconSize.height / 2);
// debug
//ctx.fillText(selfId.split("-")[1], iconSize.width / 2, iconSize.height / 2);
}
self.get('labelMarker').set('icon', {
'url': canvas.toDataURL(),
'anchor': self.get('labelMarkerAnchor')
});
setTimeout(function() {
self.set('opacity', 1);
}, 10);
});
};
ClusterIconClass.prototype.setIcon = function(icon) {
var self = this;
self.set('icon', icon);
};
ClusterIconClass.prototype.setVisible = function(visible) {
var self = this;
self.set('visible', visible);
};
ClusterIconClass.prototype.setPosition = function(position) {
var self = this;
self.set('position', position);
};
ClusterIconClass.prototype.getPosition = function() {
var self = this;
return self.get('position');
};
ClusterIconClass.prototype.setMap = function(map) {
var self = this;
self.set('map', map);
};
+371
View File
@@ -0,0 +1,371 @@
var utils = require('cordova/utils'),
event = require('cordova-plugin-googlemaps.event'),
BaseClass = require('cordova-plugin-googlemaps.BaseClass');
function PluginPolygon(pluginMap) {
var self = this;
BaseClass.apply(self);
Object.defineProperty(self, 'pluginMap', {
value: pluginMap,
writable: false
});
}
utils.extend(PluginPolygon, BaseClass);
PluginPolygon.prototype._create = function(onSuccess, onError, args) {
var self = this,
map = self.pluginMap.get('map'),
polygonId = 'polygon_' + args[2],
pluginOptions = args[1];
var polygonOpts = {
'overlayId': polygonId,
'map': map,
'paths': new google.maps.MVCArray()
};
if (pluginOptions.points) {
var strokePath = new google.maps.MVCArray();
pluginOptions.points.forEach(function(point) {
strokePath.push(new google.maps.LatLng(point.lat, point.lng));
});
polygonOpts.paths.push(strokePath);
if (Array.isArray(pluginOptions.holes)) {
pluginOptions.holes.forEach(function(hole) {
var holeMvc = new google.maps.MVCArray();
hole.forEach(function(vertix) {
holeMvc.push(new google.maps.LatLng(vertix.lat, vertix.lng));
});
polygonOpts.paths.push(holeMvc);
});
}
}
if (Array.isArray(pluginOptions.strokeColor)) {
polygonOpts.strokeColor = 'rgb(' + pluginOptions.strokeColor[0] + ',' + pluginOptions.strokeColor[1] + ',' + pluginOptions.strokeColor[2] + ')';
polygonOpts.strokeOpacity = pluginOptions.strokeColor[3] / 256;
}
if (Array.isArray(pluginOptions.fillColor)) {
polygonOpts.fillColor = 'rgb(' + pluginOptions.fillColor[0] + ',' + pluginOptions.fillColor[1] + ',' + pluginOptions.fillColor[2] + ')';
polygonOpts.fillOpacity = pluginOptions.fillColor[3] / 256;
}
if ('width' in pluginOptions) {
polygonOpts.strokeWeight = pluginOptions.width;
}
if ('zIndex' in pluginOptions) {
polygonOpts.zIndex = pluginOptions.zIndex;
}
if ('visible' in pluginOptions) {
polygonOpts.visible = pluginOptions.visible;
}
if ('geodesic' in pluginOptions) {
polygonOpts.geodesic = pluginOptions.geodesic;
}
if ('clickable' in pluginOptions) {
polygonOpts.clickable = pluginOptions.clickable;
}
var polygon = new google.maps.Polygon(polygonOpts);
polygon.addListener('click', function(polyMouseEvt) {
self._onPolygonEvent.call(self, polygon, polyMouseEvt);
});
self.pluginMap.objects[polygonId] = polygon;
onSuccess({
'__pgmId': polygonId
});
};
PluginPolygon.prototype.setFillColor = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var fillColor = args[1];
var polygon = self.pluginMap.objects[overlayId];
if (polygon) {
if (Array.isArray(fillColor)) {
polygon.setOptions({
'fillColor': 'rgb(' + fillColor[0] + ',' + fillColor[1] + ',' + fillColor[2] + ')',
'fillOpacity': fillColor[3] / 256
});
}
}
onSuccess();
};
PluginPolygon.prototype.setStrokeColor = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polygon = self.pluginMap.objects[overlayId];
var strokeColor = args[1];
if (polygon) {
if (Array.isArray(strokeColor)) {
polygon.setOptions({
'strokeColor': 'rgb(' + strokeColor[0] + ',' + strokeColor[1] + ',' + strokeColor[2] + ')',
'strokeOpacity': strokeColor[3] / 256
});
}
}
onSuccess();
};
PluginPolygon.prototype.setStrokeWidth = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var width = args[1];
var polygon = self.pluginMap.objects[overlayId];
if (polygon) {
polygon.setOptions({
'strokeWeight': width
});
}
onSuccess();
};
PluginPolygon.prototype.setZIndex = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var zIndex = args[1];
var polygon = self.pluginMap.objects[overlayId];
if (polygon) {
polygon.setOptions({
'zIndex': zIndex
});
}
onSuccess();
};
PluginPolygon.prototype.setPoints = function(onSuccess, onError, args) {
var self = this,
polygonId = args[0],
positionList = args[1],
polygon = self.pluginMap.objects[polygonId];
if (polygon) {
//------------------------
// Update the points list
//------------------------
polygon.setPath(positionList);
}
onSuccess();
};
PluginPolygon.prototype.setClickable = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var clickable = args[1];
var polygon = self.pluginMap.objects[overlayId];
if (polygon) {
polygon.setOptions({
'clickable': clickable === true
});
}
onSuccess();
};
PluginPolygon.prototype.setVisible = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polygon = self.pluginMap.objects[overlayId];
if (polygon) {
polygon.setVisible(args[1]);
}
onSuccess();
};
PluginPolygon.prototype.setGeodesic = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polygon = self.pluginMap.objects[overlayId];
if (polygon) {
polygon.setOptions({
'geodesic': args[1] === true
});
}
onSuccess();
};
PluginPolygon.prototype.insertPointAt = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polygon = self.pluginMap.objects[overlayId];
if (polygon) {
var index = args[1];
var latLng = new google.maps.LatLng(args[2].lat, args[2].lng);
polygon.getPath().insertAt(index, latLng);
}
onSuccess();
};
PluginPolygon.prototype.setPointAt = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polygon = self.pluginMap.objects[overlayId];
if (polygon) {
var index = args[1];
var latLng = new google.maps.LatLng(args[2].lat, args[2].lng);
polygon.getPath().setAt(index, latLng);
}
onSuccess();
};
PluginPolygon.prototype.removePointAt = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polygon = self.pluginMap.objects[overlayId];
if (polygon) {
var index = args[1];
polygon.getPath().removeAt(index);
}
onSuccess();
};
PluginPolygon.prototype.setHoles = function(onSuccess, onError, args) {
var self = this,
overlayId = args[0],
polygon = self.pluginMap.objects[overlayId];
if (polygon) {
var paths = polygon.getPaths(),
holeList = args[1],
newPaths = new google.maps.MVCArray([paths.getAt(0)]);
holeList.forEach(function(holeVertixes) {
var hole = new google.maps.MVCArray();
holeVertixes.forEach(function(vertix) {
hole.push(new google.maps.LatLng(vertix.lat, vertix.lng));
});
newPaths.push(hole);
});
polygon.setPaths(newPaths);
}
onSuccess();
};
PluginPolygon.prototype.insertPointOfHoleAt = function(onSuccess, onError, args) {
var self = this,
overlayId = args[0],
holeIndex = args[1] + 1, // idx=0 is for outter vertixes
pointIndex = args[2],
position = args[3],
polygon = self.pluginMap.objects[overlayId];
if (polygon) {
var latLng = new google.maps.LatLng(position.lat, position.lng);
var paths = polygon.getPaths();
var hole = null;
if (holeIndex < paths.getLength()) {
hole = paths.getAt(holeIndex);
}
if (!hole) {
hole = new google.maps.MVCArray();
paths.push(hole);
}
hole.insertAt(pointIndex, latLng);
}
onSuccess();
};
PluginPolygon.prototype.setPointOfHoleAt = function(onSuccess, onError, args) {
var self = this,
overlayId = args[0],
holeIndex = args[1] + 1,
pointIndex = args[2],
position = args[3],
polygon = self.pluginMap.objects[overlayId];
if (polygon) {
var latLng = new google.maps.LatLng(position.lat, position.lng);
polygon.getPaths().getAt(holeIndex).setAt(pointIndex, latLng);
}
onSuccess();
};
PluginPolygon.prototype.removePointOfHoleAt = function(onSuccess, onError, args) {
var self = this,
overlayId = args[0],
holeIndex = args[1] + 1,
pointIndex = args[2],
polygon = self.pluginMap.objects[overlayId];
if (polygon) {
polygon.getPaths().getAt(holeIndex).removeAt(pointIndex);
}
onSuccess();
};
PluginPolygon.prototype.insertHoleAt = function(onSuccess, onError, args) {
var self = this,
overlayId = args[0],
holeIndex = args[1] + 1,
vertixes = args[2],
polygon = self.pluginMap.objects[overlayId];
if (polygon) {
var hole = new google.maps.MVCArray();
vertixes.forEach(function(vertix) {
hole.push(new google.maps.LatLng(vertix.lat, vertix.lng));
});
polygon.getPaths().insertAt(holeIndex, hole);
}
onSuccess();
};
PluginPolygon.prototype.setHoleAt = function(onSuccess, onError, args) {
var self = this,
overlayId = args[0],
holeIndex = args[1] + 1,
vertixes = args[2],
polygon = self.pluginMap.objects[overlayId];
if (polygon) {
var hole = new google.maps.MVCArray();
vertixes.forEach(function(vertix) {
hole.push(new google.maps.LatLng(vertix.lat, vertix.lng));
});
polygon.getPaths().setAt(holeIndex, hole);
}
onSuccess();
};
PluginPolygon.prototype.removeHoleAt = function(onSuccess, onError, args) {
var self = this,
overlayId = args[0],
holeIndex = args[1] + 1,
polygon = self.pluginMap.objects[overlayId];
if (polygon) {
polygon.getPaths().removeAt(holeIndex);
}
onSuccess();
};
PluginPolygon.prototype.remove = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polygon = self.pluginMap.objects[overlayId];
if (polygon) {
google.maps.event.clearInstanceListeners(polygon);
polygon.setMap(null);
polygon = undefined;
self.pluginMap.objects[overlayId] = undefined;
delete self.pluginMap.objects[overlayId];
}
onSuccess();
};
PluginPolygon.prototype._onPolygonEvent = function(polygon, polyMouseEvt) {
var self = this,
mapId = self.pluginMap.__pgmId;
if (mapId in plugin.google.maps) {
plugin.google.maps[mapId]({
'evtName': event.POLYGON_CLICK,
'callback': '_onOverlayEvent',
'args': [polygon.overlayId, new plugin.google.maps.LatLng(polyMouseEvt.latLng.lat(), polyMouseEvt.latLng.lng())]
});
}
};
module.exports = PluginPolygon;
+216
View File
@@ -0,0 +1,216 @@
var utils = require('cordova/utils'),
event = require('cordova-plugin-googlemaps.event'),
BaseClass = require('cordova-plugin-googlemaps.BaseClass');
function PluginPolyline(pluginMap) {
var self = this;
BaseClass.apply(self);
Object.defineProperty(self, 'pluginMap', {
value: pluginMap,
writable: false
});
}
utils.extend(PluginPolyline, BaseClass);
PluginPolyline.prototype._create = function(onSuccess, onError, args) {
var self = this,
map = self.pluginMap.get('map'),
polylineId = 'polyline_' + args[2],
pluginOptions = args[1];
var polylineOpts = {
'overlayId': polylineId,
'map': map,
'path': new google.maps.MVCArray()
};
if (pluginOptions.points) {
pluginOptions.points.forEach(function(point) {
polylineOpts.path.push(new google.maps.LatLng(point.lat, point.lng));
});
}
if (Array.isArray(pluginOptions.color)) {
polylineOpts.strokeColor = 'rgb(' + pluginOptions.color[0] + ',' + pluginOptions.color[1] + ',' + pluginOptions.color[2] + ')';
polylineOpts.strokeOpacity = pluginOptions.color[3] / 256;
}
if ('width' in pluginOptions) {
polylineOpts.strokeWeight = pluginOptions.width;
}
if ('zIndex' in pluginOptions) {
polylineOpts.zIndex = pluginOptions.zIndex;
}
if ('visible' in pluginOptions) {
polylineOpts.visible = pluginOptions.visible;
}
if ('geodesic' in pluginOptions) {
polylineOpts.geodesic = pluginOptions.geodesic;
}
if ('clickable' in pluginOptions) {
polylineOpts.clickable = pluginOptions.clickable;
}
var polyline = new google.maps.Polyline(polylineOpts);
polyline.addListener('click', function(polyMouseEvt) {
self._onPolylineEvent.call(self, polyline, polyMouseEvt);
});
self.pluginMap.objects[polylineId] = polyline;
onSuccess({
'__pgmId': polylineId
});
};
PluginPolyline.prototype.remove = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polyline = self.pluginMap.objects[overlayId];
if (polyline) {
google.maps.event.clearInstanceListeners(polyline);
polyline.setMap(null);
polyline = undefined;
self.pluginMap.objects[overlayId] = undefined;
delete self.pluginMap.objects[overlayId];
}
onSuccess();
};
PluginPolyline.prototype.setStrokeColor = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polyline = self.pluginMap.objects[overlayId];
var strokeColor = args[1];
if (polyline) {
if (Array.isArray(strokeColor)) {
polyline.setOptions({
'strokeColor': 'rgb(' + strokeColor[0] + ',' + strokeColor[1] + ',' + strokeColor[2] + ')',
'strokeOpacity': strokeColor[3] / 256
});
}
}
onSuccess();
};
PluginPolyline.prototype.setStrokeWidth = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var width = args[1];
var polyline = self.pluginMap.objects[overlayId];
if (polyline) {
polyline.setOptions({
'strokeWeight': width
});
}
onSuccess();
};
PluginPolyline.prototype.setZIndex = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var zIndex = args[1];
var polyline = self.pluginMap.objects[overlayId];
if (polyline) {
polyline.setOptions({
'zIndex': zIndex
});
}
onSuccess();
};
PluginPolyline.prototype.setPoints = function(onSuccess, onError, args) {
var self = this,
polylineId = args[0],
positionList = args[1],
polyline = self.pluginMap.objects[polylineId];
if (polyline) {
//------------------------
// Update the points list
//------------------------
polyline.setPath(positionList);
}
onSuccess();
};
PluginPolyline.prototype.setClickable = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var clickable = args[1];
var polyline = self.pluginMap.objects[overlayId];
if (polyline) {
polyline.setOptions({
'clickable': clickable === true
});
}
onSuccess();
};
PluginPolyline.prototype.setVisible = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polyline = self.pluginMap.objects[overlayId];
if (polyline) {
polyline.setVisible(args[1]);
}
onSuccess();
};
PluginPolyline.prototype.setGeodesic = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polyline = self.pluginMap.objects[overlayId];
if (polyline) {
polyline.setOptions({
'geodesic': args[1] === true
});
}
onSuccess();
};
PluginPolyline.prototype.insertPointAt = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polyline = self.pluginMap.objects[overlayId];
if (polyline) {
var index = args[1];
var latLng = new google.maps.LatLng(args[2].lat, args[2].lng);
polyline.getPath().insertAt(index, latLng);
}
onSuccess();
};
PluginPolyline.prototype.setPointAt = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polyline = self.pluginMap.objects[overlayId];
if (polyline) {
var index = args[1];
var latLng = new google.maps.LatLng(args[2].lat, args[2].lng);
polyline.getPath().setAt(index, latLng);
}
onSuccess();
};
PluginPolyline.prototype.removePointAt = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var polyline = self.pluginMap.objects[overlayId];
if (polyline) {
var index = args[1];
polyline.getPath().removeAt(index);
}
onSuccess();
};
PluginPolyline.prototype._onPolylineEvent = function(polyline, polyMouseEvt) {
var self = this,
mapId = self.pluginMap.__pgmId;
if (mapId in plugin.google.maps) {
plugin.google.maps[mapId]({
'evtName': event.POLYLINE_CLICK,
'callback': '_onOverlayEvent',
'args': [polyline.overlayId, new plugin.google.maps.LatLng(polyMouseEvt.latLng.lat(), polyMouseEvt.latLng.lng())]
});
}
};
module.exports = PluginPolyline;
@@ -0,0 +1,346 @@
var utils = require('cordova/utils'),
event = require('cordova-plugin-googlemaps.event'),
BaseClass = require('cordova-plugin-googlemaps.BaseClass');
function displayGrayMap(container) {
var gmErrorContent = document.querySelector('.gm-err-container');
var gmnoprint = document.querySelector('.gmnoprint');
if (!gmErrorContent && !gmnoprint) {
container.innerHTML = [
'<div style="position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-color:rgb(229, 227, 223)">',
'<div style="text-align: center; position: absolute; left: 0; top: 0; bottom: 0; right: 0; width: 80%; height: 100px; margin: auto; color: #616161">',
'<img src="https://maps.gstatic.com/mapfiles/api-3/images/icon_error.png"><br>',
'<h3>Can not display panorama.<br>Check the developer console.</h3>',
'</div>',
'</div>'
].join('\n');
}
}
function PluginStreetViewPanorama(panoramaId, options) {
var self = this;
BaseClass.apply(this);
var panoramaDiv = document.querySelector('[__pluginMapId=\'' + panoramaId + '\']');
panoramaDiv.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';
panoramaDiv.style.position = 'relative';
container.style.position = 'absolute';
container.style.top = 0;
container.style.bottom = 0;
container.style.right = 0;
container.style.left = 0;
container.style.zIndex = 0;
panoramaDiv.insertBefore(container, panoramaDiv.firstElementChild);
self.set('isGoogleReady', false);
self.set('container', container);
self.PLUGINS = {};
Object.defineProperty(self, '__pgmId', {
value: panoramaId,
writable: false
});
self.one('googleready', function() {
self.set('isGoogleReady', true);
var service = new google.maps.StreetViewService();
self.set('service', service);
new Promise(function(resolve, reject) {
if (options.camera) {
var request = {};
if (typeof options.camera.target === 'string') {
request.pano = options.camera.target;
} else {
request.location = options.camera.target;
request.radius = options.camera.radius | 50;
request.source = options.camera.source === 'OUTDOOR' ?
google.maps.StreetViewSource.OUTDOOR : google.maps.StreetViewSource.DEFAULT;
}
var timeoutError = setTimeout(function() {
self.trigger('load_error');
displayGrayMap(panoramaDiv);
reject();
}, 3000);
service.getPanorama(request, function(data, status) {
clearTimeout(timeoutError);
if (status === google.maps.StreetViewStatus.OK) {
resolve(data.location.pano);
} else {
resolve(null);
}
});
} else {
resolve(null);
}
})
.then(function(panoId) {
var stOptions = {
'addressControl': options.controls.streetNames,
'showRoadLabels': options.controls.streetNames,
'linksControl': options.controls.navigation,
'panControl': options.gestures.panning,
'zoomControl': options.gestures.zoom,
'scrollwheel': options.gestures.zoom,
'pano': panoId
};
if (options.camera) {
if ('zoom' in options.camera) {
stOptions.zoom = options.camera.zoom;
}
var pov;
if ('tilt' in options.camera) {
pov = {};
pov.pitch = options.camera.tilt;
}
if ('bearing' in options.camera) {
pov = pov || {};
pov.heading = options.camera.bearing;
}
if (pov) {
stOptions.pov = pov;
}
}
google.maps.event.addDomListener(container, 'click', function(evt) {
var pov = panorama.getPov();
var clickInfo = {
'orientation': {
'bearing': pov.heading,
'tilt': pov.pitch
},
'point': [evt.clientX, evt.clientY]
};
if (self.__pgmId in plugin.google.maps) {
plugin.google.maps[self.__pgmId]({
'evtName': event.PANORAMA_CLICK,
'callback': '_onPanoramaEvent',
'args': [clickInfo]
});
}
});
var panorama = new google.maps.StreetViewPanorama(container, stOptions);
self.set('panorama', panorama);
self.trigger(event.PANORAMA_READY);
panorama.addListener('position_changed', self._onPanoChangedEvent.bind(self, panorama));
panorama.addListener('pov_changed', self._onCameraEvent.bind(self, panorama));
panorama.addListener('zoom_changed', self._onCameraEvent.bind(self, panorama));
if (!panoId) {
self._onPanoChangedEvent(null);
}
});
});
}
utils.extend(PluginStreetViewPanorama, BaseClass);
PluginStreetViewPanorama.prototype.setPanningGesturesEnabled = function(onSuccess, onError, args) {
var self = this;
var panorama = self.get('panorama');
var boolValue = args[0] === true;
if (panorama) {
panorama.setOptions({
'panControl': boolValue
});
}
onSuccess();
};
PluginStreetViewPanorama.prototype.setZoomGesturesEnabled = function(onSuccess, onError, args) {
var self = this;
var panorama = self.get('panorama');
var boolValue = args[0] === true;
if (panorama) {
panorama.setOptions({
'zoomControl': boolValue,
'scrollwheel': boolValue,
});
}
onSuccess();
};
PluginStreetViewPanorama.prototype.setNavigationEnabled = function(onSuccess, onError, args) {
var self = this;
var panorama = self.get('panorama');
var boolValue = args[0] === true;
if (panorama) {
panorama.setOptions({
'linksControl': boolValue
});
}
onSuccess();
};
PluginStreetViewPanorama.prototype.setStreetNamesEnabled = function(onSuccess, onError, args) {
var self = this;
var panorama = self.get('panorama');
var boolValue = args[0] === true;
if (panorama) {
panorama.setOptions({
'addressControl': boolValue,
'showRoadLabels': boolValue
});
}
onSuccess();
};
PluginStreetViewPanorama.prototype.setStreetNamesEnabled = function(onSuccess, onError, args) {
var self = this;
var panorama = self.get('panorama');
var boolValue = args[0] === true;
if (panorama) {
panorama.setOptions({
'visible': boolValue
});
}
onSuccess();
};
PluginStreetViewPanorama.prototype.setPosition = function(onSuccess, onError, args) {
var self = this;
var panorama = self.get('panorama');
var camera = args[0];
if (panorama) {
var service = self.get('service');
new Promise(function(resolve, reject) {
var request = {};
if (typeof camera.target === 'string') {
request.pano = camera.target;
} else {
request.location = camera.target;
request.radius = camera.radius | 50;
request.source = camera.source === 'OUTDOOR' ?
google.maps.StreetViewSource.OUTDOOR : google.maps.StreetViewSource.DEFAULT;
}
var timeoutError = setTimeout(function() {
reject('timeout error');
}, 3000);
service.getPanorama(request, function(data, status) {
clearTimeout(timeoutError);
if (status === google.maps.StreetViewStatus.OK) {
resolve(data.location.pano);
} else {
resolve(null);
}
});
})
.then(function(panoId) {
panorama.setPano(panoId);
if (!panoId) {
self._onPanoChangedEvent(null);
}
onSuccess();
})
.catch(onError);
} else {
onError('panorama has been already removed.');
}
};
PluginStreetViewPanorama.prototype.setPov = function(onSuccess, onError, args) {
var self = this;
var panorama = self.get('panorama');
var povRequest = args[0];
if (panorama) {
var options = {
pov: panorama.getPov()
};
options.pov = options.pov || {
heading: 0,
pitch: 0
};
if ('bearing' in povRequest) {
options.pov.heading = povRequest.bearing;
}
if ('tilt' in povRequest) {
options.pov.pitch = povRequest.tilt;
}
if ('zoom' in povRequest) {
options.zoom = povRequest.zoom;
}
panorama.setOptions(options);
}
onSuccess();
};
PluginStreetViewPanorama.prototype._onCameraEvent = function(panorama) {
var self = this;
var pov = panorama.getPov();
var camera = {
'bearing': pov.heading,
'tilt': pov.pitch,
'zoom': panorama.getZoom()
};
if (self.__pgmId in plugin.google.maps) {
plugin.google.maps[self.__pgmId]({
'evtName': event.PANORAMA_CAMERA_CHANGE,
'callback': '_onPanoramaCameraChange',
'args': [camera]
});
}
};
PluginStreetViewPanorama.prototype._onPanoChangedEvent = function(panorama) {
var self = this;
var locationInfo = null;
if (panorama) {
var location = panorama.getLocation();
locationInfo = {
'panoId': location.pano,
'latLng': {
'lat': location.latLng.lat(),
'lng': location.latLng.lng()
}
};
var links = panorama.getLinks() || [];
if (links) {
locationInfo.links = links.map(function(link) {
return {
'panoId': link.pano,
'bearing': link.heading
};
});
}
}
if (self.__pgmId in plugin.google.maps) {
plugin.google.maps[self.__pgmId]({
'evtName': event.PANORAMA_LOCATION_CHANGE,
'callback': '_onPanoramaLocationChange',
'args': [locationInfo]
});
}
};
module.exports = PluginStreetViewPanorama;
+299
View File
@@ -0,0 +1,299 @@
var utils = require('cordova/utils'),
BaseClass = require('cordova-plugin-googlemaps.BaseClass');
function TileOverlay(mapId, hashCode, options) {
var tileSize = 256,
tileCaches = {},
_opacity = 'opacity' in options ? options.opacity : 1;
var mapType = {
zIndex: options.zIndex || 0,
name: options.name || hashCode,
mapTypeId: hashCode,
fadeIn: options.fadeIn === false ? false : true,
visible: true,
setOpacity: function(opacity) {
_opacity = opacity;
var keys = Object.keys(tileCaches);
keys.forEach(function(key) {
tileCaches[key].style.opacity = _opacity;
});
},
getTileFromCache: function(cacheId) {
return tileCaches[cacheId];
},
getZIndex: function() {
return this.zIndex;
},
setZIndex: function(zIndexVal) {
this.zIndex = parseInt(zIndexVal, 10);
},
getOpacity: function() {
return _opacity;
},
tileSize: new google.maps.Size(tileSize, tileSize),
setVisible: function(visible) {
this.visible = visible;
var visibility = visible ? 'visible': 'hidden';
var keys = Object.keys(tileCaches);
keys.forEach(function(key) {
tileCaches[key].style.visibility = visibility;
});
},
getTile: function(coord, zoom) {
var cacheId = [mapId, hashCode, coord.x, coord.y, zoom].join('-');
if (cacheId in tileCaches) {
return tileCaches[cacheId];
} else {
var div = document.createElement('div');
div.style.width = tileSize + 'px';
div.style.height = tileSize + 'px';
div.style.opacity = 0;
div.style.visibility = 'hidden';
if (options.debug) {
div.style.borderLeft = '1px solid red';
div.style.borderTop = '1px solid red';
div.style.color = 'red';
div.style.fontSize = '12px';
div.style.padding = '1em';
div.innerHTML = 'x = ' + coord.x + ', y = ' + coord.y + ', zoom = ' + zoom;
}
div.setAttribute('cacheId', cacheId);
tileCaches[cacheId] = div;
options.getTile(coord.x, coord.y, zoom, cacheId);
return div;
}
},
releaseTile: function(div) {
var cacheId = div.getAttribute('cacheId');
delete tileCaches[cacheId];
},
remove: function() {
var keys = Object.keys(tileCaches);
keys.forEach(function(key) {
if (tileCaches[key].parentNode) {
tileCaches[key].parentNode.removeChild(tileCaches[key]);
}
tileCaches[key] = undefined;
delete tileCaches[key];
});
}
};
return mapType;
}
function PluginTileOverlay(pluginMap) {
var self = this;
BaseClass.apply(self);
Object.defineProperty(self, 'pluginMap', {
value: pluginMap,
enumerable: false,
writable: false
});
}
utils.extend(PluginTileOverlay, BaseClass);
PluginTileOverlay.prototype._create = function(onSuccess, onError, args) {
var self = this,
map = self.pluginMap.get('map'),
hashCode = args[2],
tileoverlayId = 'tileoverlay_' + hashCode,
pluginOptions = args[1],
mapId = self.pluginMap.__pgmId,
getTileEventName = mapId + '-' + hashCode + '-tileoverlay';
pluginOptions.getTile = function(x, y, zoom, urlCallbackId) {
cordova.fireDocumentEvent(getTileEventName, {
key: urlCallbackId,
x: x,
y: y,
zoom: zoom
});
};
var tileoverlay = new TileOverlay(self.pluginMap.__pgmId, hashCode, pluginOptions);
var layers = map.overlayMapTypes.getArray();
layers = layers.filter(function(layer) {
return !!layer;
});
layers.forEach(function(layer, idx) {
if (!layer) {
return;
}
if (layer.zIndex === undefined) {
layer.zIndex = idx;
}
if (!layer.getZIndex) {
layer.getZIndex = function() {
return layer.zIndex;
};
}
if (!layer.setZIndex) {
layer.setZIndex = function(zIndexVal) {
layer.zIndex = zIndexVal;
};
}
});
layers.push(tileoverlay);
layers = layers.sort(function(a, b) {
return a.getZIndex() - b.getZIndex();
});
layers.forEach(function(layer, idx) {
if (idx < map.overlayMapTypes.getLength()) {
layer.zIndex = idx;
map.overlayMapTypes.setAt(idx, layer);
} else {
layer.zIndex = idx;
map.overlayMapTypes.push(layer);
}
});
self.pluginMap.objects[tileoverlayId] = tileoverlay;
onSuccess({
'__pgmId': tileoverlayId
});
};
PluginTileOverlay.prototype.onGetTileUrlFromJS = function(onSuccess, onError, args) {
var self = this,
cacheId = args[1],
tileUrl = args[2];
var tmp = cacheId.split(/-/),
hashCode = tmp[1],
tileoverlayId = 'tileoverlay_' + hashCode;
var tileLayer = self.pluginMap.objects[tileoverlayId];
if (tileLayer && tileLayer.getTileFromCache(cacheId)) {
var tile = tileLayer.getTileFromCache(cacheId);
tile.style.backgroundImage = 'url(\'' + tileUrl + '\')';
tile.style.visibility = tileLayer.visible ? 'visible': 'hidden';
if (tileLayer.fadeIn) {
fadeInAnimation(tile, 500, tileLayer.getOpacity());
} else {
tile.style.opacity = tileLayer.getOpacity();
}
}
onSuccess();
};
PluginTileOverlay.prototype.setVisible = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var tileoverlay = self.pluginMap.objects[overlayId];
if (tileoverlay) {
tileoverlay.setVisible(args[1]);
}
onSuccess();
};
PluginTileOverlay.prototype.setOpacity = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var opacity = args[1];
var tileoverlay = self.pluginMap.objects[overlayId];
if (tileoverlay) {
tileoverlay.setOpacity(opacity);
}
onSuccess();
};
PluginTileOverlay.prototype.setFadeIn = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var tileoverlay = self.pluginMap.objects[overlayId];
if (tileoverlay) {
tileoverlay.fadeIn = args[1] === false ? false : true;
}
onSuccess();
};
PluginTileOverlay.prototype.setZIndex = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var map = self.pluginMap.get('map');
var tileoverlay = self.pluginMap.objects[overlayId];
if (tileoverlay) {
tileoverlay.setZIndex(args[1]);
var layers = map.overlayMapTypes.getArray();
layers = layers.sort(function(a, b) {
return a.getZIndex() - b.getZIndex();
});
layers.forEach(function(layer, idx) {
if (idx < map.overlayMapTypes.getLength()) {
map.overlayMapTypes.setAt(idx, layer);
} else {
map.overlayMapTypes.push(layer);
}
});
}
onSuccess();
};
PluginTileOverlay.prototype.remove = function(onSuccess, onError, args) {
var self = this;
var overlayId = args[0];
var tileoverlay = self.pluginMap.objects[overlayId];
if (tileoverlay) {
google.maps.event.clearInstanceListeners(tileoverlay);
tileoverlay.remove();
var layers = self.pluginMap.get('map').overlayMapTypes.getArray();
layers.forEach(function(layer, idx) {
if (layer === tileoverlay) {
layers.splice(idx, 1);
}
});
tileoverlay = undefined;
self.pluginMap.objects[overlayId] = undefined;
delete self.pluginMap.objects[overlayId];
}
onSuccess();
};
module.exports = PluginTileOverlay;
function fadeInAnimation(el, time, maxOpacity) {
el.style.opacity = 0;
var timeFunc = typeof window.requestAnimationFrame === 'function' ? requestAnimationFrame : setTimeout;
var last = Date.now();
var tick = function() {
var now = Date.now();
el.style.opacity = +el.style.opacity + (now - last) / time;
last = now;
if (+el.style.opacity < maxOpacity) {
timeFunc.call(window, tick, 16);
}
};
tick();
}
@@ -0,0 +1,19 @@
const PluginMap = require('../PluginMap');
describe('PluginMap', () => {
it('should exist', () => {
expect(PluginMap).toBeDefined();
});
describe('toDataURL', () => {
afterEach(() => {
document.body.innerHTML = '';
});
it('should exist', () => {
var mapId = 'map';
document.body.innerHTML = '<div __pluginMapId="' + mapId + '"></div>';
expect(new PluginMap(mapId, {}).toDataURL).toBeDefined();
});
});
});