diff --git a/.gitignore b/.gitignore index 0286574..1d87d49 100644 --- a/.gitignore +++ b/.gitignore @@ -19,12 +19,12 @@ npm-debug.log* .tmp/ .versions/ coverage/ -www/ +/www/ node_modules/ tmp/ temp/ platforms/ -plugins/ +/plugins/ plugins/android.json plugins/ios.json $RECYCLE.BIN/ diff --git a/docs/plugins/cordova-plugin-device/src/browser/DeviceProxy.js b/docs/plugins/cordova-plugin-device/src/browser/DeviceProxy.js new file mode 100644 index 0000000..a4998fe --- /dev/null +++ b/docs/plugins/cordova-plugin-device/src/browser/DeviceProxy.js @@ -0,0 +1,86 @@ +cordova.define("cordova-plugin-device.DeviceProxy", function(require, exports, module) { /* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +var browser = require('cordova/platform'); + +function getPlatform () { + return 'browser'; +} + +function getModel () { + return getBrowserInfo(true); +} + +function getVersion () { + return getBrowserInfo(false); +} + +function getBrowserInfo (getModel) { + var userAgent = navigator.userAgent; + var returnVal = ''; + var offset; + + if ((offset = userAgent.indexOf('Edge')) !== -1) { + returnVal = (getModel) ? 'Edge' : userAgent.substring(offset + 5); + } else if ((offset = userAgent.indexOf('Chrome')) !== -1) { + returnVal = (getModel) ? 'Chrome' : userAgent.substring(offset + 7); + } else if ((offset = userAgent.indexOf('Safari')) !== -1) { + if (getModel) { + returnVal = 'Safari'; + } else { + returnVal = userAgent.substring(offset + 7); + + if ((offset = userAgent.indexOf('Version')) !== -1) { + returnVal = userAgent.substring(offset + 8); + } + } + } else if ((offset = userAgent.indexOf('Firefox')) !== -1) { + returnVal = (getModel) ? 'Firefox' : userAgent.substring(offset + 8); + } else if ((offset = userAgent.indexOf('MSIE')) !== -1) { + returnVal = (getModel) ? 'MSIE' : userAgent.substring(offset + 5); + } else if ((offset = userAgent.indexOf('Trident')) !== -1) { + returnVal = (getModel) ? 'MSIE' : '11'; + } + + if ((offset = returnVal.indexOf(';')) !== -1 || (offset = returnVal.indexOf(' ')) !== -1) { + returnVal = returnVal.substring(0, offset); + } + + return returnVal; +} + +module.exports = { + getDeviceInfo: function (success, error) { + setTimeout(function () { + success({ + cordova: browser.cordovaVersion, + platform: getPlatform(), + model: getModel(), + version: getVersion(), + uuid: null, + isVirtual: false + }); + }, 0); + } +}; + +require('cordova/exec/proxy').add('Device', module.exports); + +}); diff --git a/docs/plugins/cordova-plugin-device/www/device.js b/docs/plugins/cordova-plugin-device/www/device.js new file mode 100644 index 0000000..059351d --- /dev/null +++ b/docs/plugins/cordova-plugin-device/www/device.js @@ -0,0 +1,85 @@ +cordova.define("cordova-plugin-device.device", function(require, exports, module) { /* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +var argscheck = require('cordova/argscheck'); +var channel = require('cordova/channel'); +var utils = require('cordova/utils'); +var exec = require('cordova/exec'); +var cordova = require('cordova'); + +channel.createSticky('onCordovaInfoReady'); +// Tell cordova channel to wait on the CordovaInfoReady event +channel.waitForInitialization('onCordovaInfoReady'); + +/** + * This represents the mobile device, and provides properties for inspecting the model, version, UUID of the + * phone, etc. + * @constructor + */ +function Device () { + this.available = false; + this.platform = null; + this.version = null; + this.uuid = null; + this.cordova = null; + this.model = null; + this.manufacturer = null; + this.isVirtual = null; + this.serial = null; + + var me = this; + + channel.onCordovaReady.subscribe(function () { + me.getInfo(function (info) { + // ignoring info.cordova returning from native, we should use value from cordova.version defined in cordova.js + // TODO: CB-5105 native implementations should not return info.cordova + var buildLabel = cordova.version; + me.available = true; + me.platform = info.platform; + me.version = info.version; + me.uuid = info.uuid; + me.cordova = buildLabel; + me.model = info.model; + me.isVirtual = info.isVirtual; + me.manufacturer = info.manufacturer || 'unknown'; + me.serial = info.serial || 'unknown'; + channel.onCordovaInfoReady.fire(); + }, function (e) { + me.available = false; + utils.alert('[ERROR] Error initializing Cordova: ' + e); + }); + }); +} + +/** + * Get device info + * + * @param {Function} successCallback The function to call when the heading data is available + * @param {Function} errorCallback The function to call when there is an error getting the heading data. (OPTIONAL) + */ +Device.prototype.getInfo = function (successCallback, errorCallback) { + argscheck.checkArgs('fF', 'Device.getInfo', arguments); + exec(successCallback, errorCallback, 'Device', 'getDeviceInfo', []); +}; + +module.exports = new Device(); + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/src/browser/CordovaGoogleMaps.js b/docs/plugins/cordova-plugin-googlemaps/src/browser/CordovaGoogleMaps.js new file mode 100644 index 0000000..da9823d --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/src/browser/CordovaGoogleMaps.js @@ -0,0 +1,183 @@ +cordova.define("cordova-plugin-googlemaps.CordovaGoogleMaps", function(require, exports, module) { + + +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) { + 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); + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginCircle.js b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginCircle.js new file mode 100644 index 0000000..70e6138 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginCircle.js @@ -0,0 +1,201 @@ +cordova.define("cordova-plugin-googlemaps.PluginCircle", function(require, exports, module) { + + +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; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginEnvironment.js b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginEnvironment.js new file mode 100644 index 0000000..53919bf --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginEnvironment.js @@ -0,0 +1,33 @@ +cordova.define("cordova-plugin-googlemaps.PluginEnvironment", function(require, exports, module) { +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); + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginGeocoder.js b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginGeocoder.js new file mode 100644 index 0000000..a8c7953 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginGeocoder.js @@ -0,0 +1,181 @@ +cordova.define("cordova-plugin-googlemaps.PluginGeocoder", function(require, exports, module) { + +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.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); + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginGroundOverlay.js b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginGroundOverlay.js new file mode 100644 index 0000000..74f885f --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginGroundOverlay.js @@ -0,0 +1,414 @@ +cordova.define("cordova-plugin-googlemaps.PluginGroundOverlay", function(require, exports, module) { + + +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')); +}; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginKmlOverlay.js b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginKmlOverlay.js new file mode 100644 index 0000000..9a1e762 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginKmlOverlay.js @@ -0,0 +1,542 @@ +cordova.define("cordova-plugin-googlemaps.PluginKmlOverlay", function(require, exports, module) { + +/* 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 = { + '&': '&', + '<': '<', + '>': '>', + ''': '\'', + '"': '"' + }; + + 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); + 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.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); + }); + + }; +} + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginLocationService.js b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginLocationService.js new file mode 100644 index 0000000..09f8ba1 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginLocationService.js @@ -0,0 +1,61 @@ +cordova.define("cordova-plugin-googlemaps.PluginLocationService", function(require, exports, module) { +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); + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginMap.js b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginMap.js new file mode 100644 index 0000000..b24d5de --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginMap.js @@ -0,0 +1,724 @@ +cordova.define("cordova-plugin-googlemaps.PluginMap", function(require, exports, module) { + + +var utils = require('cordova/utils'), + event = require('cordova-plugin-googlemaps.event'), + BaseClass = require('cordova-plugin-googlemaps.BaseClass'), + LatLng = require('cordova-plugin-googlemaps.LatLng'), + MapTypeId = require('cordova-plugin-googlemaps.MapTypeId'); + +var MAP_TYPES = {}; +MAP_TYPES[MapTypeId.NORMAL] = 'roadmap'; +MAP_TYPES[MapTypeId.ROADMAP] = 'roadmap'; +MAP_TYPES[MapTypeId.SATELLITE] = 'satellite'; +MAP_TYPES[MapTypeId.HYBRID] = 'hybrid'; +MAP_TYPES[MapTypeId.TERRAIN] = 'terrain'; +MAP_TYPES[MapTypeId.NONE] = 'none'; + +var LOCATION_ERROR = {}; +LOCATION_ERROR[1] = 'service_denied'; +LOCATION_ERROR[2] = 'not_available'; +LOCATION_ERROR[3] = 'cannot_detect'; +var LOCATION_ERROR_MSG = {}; +LOCATION_ERROR_MSG[1] = 'Location service is rejected by user.'; +LOCATION_ERROR_MSG[2] = 'Since this device does not have any location provider, this app can not detect your location.'; +LOCATION_ERROR_MSG[3] = 'Can not detect your location. Try again.'; + +function displayGrayMap(container) { + var gmErrorContent = document.querySelector('.gm-err-container'); + var gmnoprint = document.querySelector('.gmnoprint'); + if (!gmErrorContent && !gmnoprint) { + container.innerHTML = [ + '
', + '
', + '
', + '

Can not display map.
Check the developer console.

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

Can not display panorama.
Check the developer console.

', + '
', + '
' + ].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; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginTileOverlay.js b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginTileOverlay.js new file mode 100644 index 0000000..8b88740 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/src/browser/PluginTileOverlay.js @@ -0,0 +1,301 @@ +cordova.define("cordova-plugin-googlemaps.PluginTileOverlay", function(require, exports, module) { +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(); +} + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/BaseArrayClass.js b/docs/plugins/cordova-plugin-googlemaps/www/BaseArrayClass.js new file mode 100644 index 0000000..aa72301 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/BaseArrayClass.js @@ -0,0 +1,615 @@ +cordova.define("cordova-plugin-googlemaps.BaseArrayClass", function(require, exports, module) { var utils = require('cordova/utils'), + BaseClass = require('./BaseClass'); + +var ARRAY_FIELD = typeof Symbol === 'undefined' ? '__array' + Date.now() : Symbol('array'); + +var nextTick = function(fn) { Promise.resolve().then(fn); }; +/** + * Create a BaseArrayClass. + * @class + */ +function BaseArrayClass(array) { + BaseClass.apply(this); + var self = this; + self[ARRAY_FIELD] = []; + + if (array && (array instanceof Array || Array.isArray(array))) { + for (var i = 0; i < array.length; i++) { + self[ARRAY_FIELD].push(array[i]); + } + } +} + +utils.extend(BaseArrayClass, BaseClass); + +/** + * The same as `Array.map` but runs a single async operation at a time. + * + * @name mapSeries + * @param {Function} iteratee - An async function to apply to each item in array. + * @param {Function} [callback] - A callback which is called when all `iteratee` functions + * have finished. Results is an array of the transformed items from holding array. + * Invoked with (results); + * @return {Promise} a promise, if no calback if passed. + */ +BaseArrayClass.prototype.mapSeries = function(iteratee, callback) { + if (typeof iteratee !== 'function') { + var error = new Error('iteratee must be a function'); + if (typeof callback === 'function') { + throw error; + } else { + return Promise.reject(error); + } + } + + var self = this; + + var results = []; + var _arrayLength = self[ARRAY_FIELD].length; + var currentCnt = 0; + if (_arrayLength === 0) { + if (typeof callback === 'function') { + callback.call(self, []); + return; + } else { + return Promise.resolve([]); + } + } + var _looper = function(currentIdx, resolve) { + + iteratee.call(self, self[ARRAY_FIELD][currentIdx], function(value) { + results[currentIdx] = value; + currentCnt++; + if (_arrayLength === currentCnt) { + resolve(results); + } else { + nextTick(function() { + _looper(currentIdx + 1, resolve); + }); + } + }); + }; + + return new Promise(function(resolve) { + nextTick(function() { + _looper(0, resolve); + }); + }).then(function(results) { + if (typeof callback === 'function') { + return callback.call(self, results); + } else { + return Promise.resolve(results); + } + }); +}; + + +/** + * The same as `Array.map` but runs async all `iteratee` function at the same time. + * + * ``` + * baseArray.mapAsync(function(item, idx, callback) { + * ... + * callback(value); + * }).then(function(values) { + * + * }); + * ``` + * + * @name mapAsync + * @param {Function} iteratee - An async function to apply to each item in array. + * @param {Function} [callback] - A callback which is called when all `iteratee` functions + * have finished. Results is an array of the transformed items from holding array. + * Invoked with (results); + * @return {Promise} a promise, if no calback if passed. + */ +BaseArrayClass.prototype.mapAsync = function(iteratee, callback) { + if (typeof iteratee !== 'function') { + var error = new Error('iteratee must be a function'); + if (typeof callback === 'function') { + throw error; + } else { + return Promise.reject(error); + } + } + var self = this; + var results = []; + for (var i = 0; i < self[ARRAY_FIELD].length; i++) { + results.push(null); + } + var _arrayLength = self[ARRAY_FIELD].length; + var finishCnt = 0; + if (_arrayLength === 0) { + if (typeof callback === 'function') { + callback.call(self, []); + return; + } else { + return Promise.resolve([]); + } + } + + return new Promise(function(resolve) { + for (i = 0; i < self[ARRAY_FIELD].length; i++) { + (function(item, idx) { + nextTick(function() { + iteratee.call(self, item, function(value) { + results[idx] = value; + finishCnt++; + if (finishCnt === _arrayLength) { + resolve(results); + } + }); + }); + })(self[ARRAY_FIELD][i], i); + } + }).then(function(results) { + if (typeof callback === 'function') { + return callback.call(self, results); + } else { + return Promise.resolve(results); + } + }); + +}; + + +/** + * If you provide `iteratee` and `callback`, work as `mapAsync()`. + * If you provide `iteratee`, but omit `callback`, work as `Array.map()`. + * + * @deprecated + * @name map + * @param {Function} iteratee - An async function to apply to each item in array. + * @param {Function} [callback] - A callback which is called when all `iteratee` functions + * have finished. Results is an array of the transformed items from holding array. + * Invoked with (results); + * @return {Promise|any[]} a promise, if no calback if passed. If you omit `callback`, return transformed items. + */ +BaseArrayClass.prototype.map = function(iteratee, callback) { + var self = this; + + if (typeof iteratee !== 'function') { + var error = new Error('iteratee must be a function'); + if (typeof callback === 'function') { + throw error; + } else { + return Promise.reject(error); + } + } + if (typeof callback !== 'function') { + //------------------------ + // example: + // var values = baseArray.map(function(item, idx) { + // ... + // return someValue; + // }); + //------------------------ + return self[ARRAY_FIELD].map(iteratee.bind(self)); + } + return self.mapAsync(iteratee, callback); +}; + +/** + * The same as `Array.forEach` but runs async all `iteratee` function at the same time. + * + * @name forEachAsync + * @param {Function} iteratee - An async function to apply to each item in array. + * @param {Function} [callback] - A callback which is called when all `iteratee` functions + * have finished. + * @return {Promise} a promise, if no calback if passed. + */ +BaseArrayClass.prototype.forEachAsync = function(iteratee, callback) { + if (typeof iteratee !== 'function') { + var error = new Error('iteratee must be a function'); + if (typeof callback === 'function') { + throw error; + } else { + return Promise.reject(error); + } + } + var self = this; + //------------------------ + // example: + // baseArray.forEach(function(item, callback) { + // ... + // callback(); + // }, function() { + // + // }); + //------------------------ + var finishCnt = 0; + var _arrayLength = self[ARRAY_FIELD].length; + if (_arrayLength === 0) { + if (typeof callback === 'function') { + callback.call(self); + return; + } else { + return Promise.resolve(); + } + } + + return new Promise(function(resolve) { + + self[ARRAY_FIELD].forEach(function(item) { + iteratee.call(self, item, function() { + finishCnt++; + if (finishCnt === _arrayLength) { + resolve(self); + } + }); + }); + + }) + .then(function() { + if (typeof callback === 'function') { + callback.call(self); + return; + } else { + return Promise.resolve(); + } + }); +}; + +/** + * If you provide `iteratee` and `callback`, work as `forEachAsync()`. + * If you provide `iteratee`, but you omit `callback`, work as `Array.forEach()` + * + * @deprecated + * @name forEach + * @param {Function} iteratee - An async function to apply to each item in array. + * @param {Function} [callback] - A callback which is called when all `iteratee` functions + * have finished. + * Invoked with (results); + * @return {Promise} a promise, if no calback if passed. + */ +BaseArrayClass.prototype.forEach = function(iteratee, callback) { + var self = this; + if (typeof iteratee !== 'function') { + var error = new Error('iteratee must be a function'); + if (typeof callback === 'function') { + throw error; + } else { + return Promise.reject(error); + } + } + + if (typeof callback !== 'function') { + //------------------------ + // example: + // baseArray.forEach(function(item, idx) { + // ... + // }); + //------------------------ + self[ARRAY_FIELD].forEach(iteratee.bind(self)); + return Promise.resolve(); + } + return self.forEachAsync(iteratee, callback); +}; + + +/** + * The same as `Array.filter` but runs async all `iteratee` function at the same time. + * + * @name filterAsync + * @param {Function} iteratee - An async function to apply to each item in array. + * @param {Function} [callback] - A callback which is called when all `iteratee` functions + * have finished. Results is an array of the filtered items from holding array. + * Invoked with (results); + * @return {Promise} a promise, if no calback if passed. + */ +BaseArrayClass.prototype.filterAsync = function(iteratee, callback) { + var self = this; + if (typeof iteratee !== 'function') { + var error = new Error('iteratee must be a function'); + if (typeof callback === 'function') { + throw error; + } else { + return Promise.reject(error); + } + } + //------------------------ + // example: + // baseArray.filter(function(item, callback) { + // ... + // callback(true or false); + // }, function(filteredItems) { + // + // }); + //------------------------ + var finishCnt = 0; + var _arrayLength = self[ARRAY_FIELD].length; + if (_arrayLength === 0) { + if (typeof callback === 'function') { + callback.call(self, []); + return; + } else { + return Promise.resolve([]); + } + } + return (new Promise(function(resolve) { + var results = []; + self[ARRAY_FIELD].forEach(function(item, idx) { + iteratee.call(self, item, function(isOk) { + results[idx] = isOk; + finishCnt++; + if (finishCnt === _arrayLength) { + resolve(self[ARRAY_FIELD].filter(function(item, j) { + return results[j]; + })); + } + }); + }); + })) + .then(function(results) { + if (typeof callback === 'function') { + callback.call(self, results); + return; + } else { + return Promise.resolve(results); + } + }); +}; + +/** + * If you provide `iteratee` and `callback`, work as `filterAsync()`. + * If you provide `iteratee`, but you omit `callback`, work as `Array.filter()` + * + * @deprecated + * @name filter + * @param {Function} iteratee - An async function to apply to each item in array. + * @param {Function} [callback] - A callback which is called when all `iteratee` functions + * have finished. + * @return {Promise} a promise, if no calback if passed. + */ +BaseArrayClass.prototype.filter = function(iteratee, callback) { + var self = this; + if (typeof iteratee !== 'function') { + var error = new Error('iteratee must be a function'); + if (typeof callback === 'function') { + throw error; + } else { + return Promise.reject(error); + } + } + if (typeof callback !== 'function') { + //------------------------ + // example: + // baseArray.filter(function(item, idx) { + // ... + // return true or false + // }); + //------------------------ + return self[ARRAY_FIELD].filter(iteratee); + } + return self.filterAsync(iteratee, callback); +}; + +/** + * Returns the first index at which a given element can be found in the array, or -1 if it is not present. + * + * @name indexOf + * @param {any} searchElement - Element to locate in the array. + * @param {number} [searchElement] - The index to start the search at. + * If the index is greater than or equal to the array's length, -1 is returned, + * which means the array will not be searched. + * If the provided index value is a negative number, + * it is taken as the offset from the end of the array. + * Note: if the provided index is negative, the array is still searched from front to back. + * If the provided index is 0, then the whole array will be searched. Default: 0 (entire array is searched). + * @return The first index of the element in the array; -1 if not found. + */ +BaseArrayClass.prototype.indexOf = function(item, searchElement) { + searchElement = searchElement === undefined || searchElement === null ? 0 : searchElement; + if (typeof searchElement !== 'number') { + throw new Error('searchElement must be a number'); + } + if (searchElement < 0) { + throw new Error('searchElement must be over number than 0'); + } + + return this[ARRAY_FIELD].indexOf(item, searchElement); +}; + +/** + * Removes all elements. Fire `remove_at` event for each element. + * + * @name empty + * @param {boolean} [noNotify] - Sets `true` if you don't want to fire `remove_at` event. + */ +BaseArrayClass.prototype.empty = function(noNotify) { + var self = this; + var cnt = self[ARRAY_FIELD].length; + for (var i = cnt - 1; i >= 0; i--) { + self.removeAt(i, noNotify); + } +}; + +/** + * Adds one element to the end of an array and returns the new length of the array. + * Fire `insert_at` event if `noNotify` is `false`. + * + * @name push + * @param {any} value - The element to add to the end of the array. + * @param {boolean} [noNotify] - Sets `true` if you don't want to fire `insert_at` event. + * @return {number} The new length property of the object upon which the method was called. + */ +BaseArrayClass.prototype.push = function(value, noNotify) { + var self = this; + self[ARRAY_FIELD].push(value); + if (noNotify !== true) { + self.trigger('insert_at', self[ARRAY_FIELD].length - 1); + } + return self[ARRAY_FIELD].length; +}; + +/** + * Adds one element to the end of an array and returns the new length of the array. + * Fire `insert_at` event if `noNotify` is `false`. + * + * @name insertAt + * @param {number} index - The position of the array you want to insert new element. + * @param {any} value - The element to add to the end of the array. + * @param {boolean} [noNotify] - Sets `true` if you don't want to fire `insert_at` event. + * @return {number} The new length property of the object upon which the method was called. + */ +BaseArrayClass.prototype.insertAt = function(index, value, noNotify) { + var self = this; + if (typeof index !== 'number') { + throw new Error('index must be a number'); + } + if (index < 0) { + throw new Error('index must be over number than 0'); + } + self[ARRAY_FIELD].splice(index, 0, value); + if (noNotify !== true) { + self.trigger('insert_at', index); + } + return self[ARRAY_FIELD].length; +}; + +/** + * Returns a new array that is the clone of internal array. + * + * @name getArray + * @return {Array} New array + */ +BaseArrayClass.prototype.getArray = function() { + //return _array.slice(0); <-- Android browser keeps the same instance of original array + return JSON.parse(JSON.stringify(this[ARRAY_FIELD])); +}; + +/** + * Returns item of specified position. + * + * @name getAt + * @param {number} index - The position of the array you want to get. + * @return {any} item + */ +BaseArrayClass.prototype.getAt = function(index) { + var self = this; + if (typeof index !== 'number') { + throw new Error('index must be a number'); + } + if (index < 0) { + throw new Error('index must be over number than 0'); + } + if (index >= self[ARRAY_FIELD].length) { + throw new Error('index must be lower number than ' + self[ARRAY_FIELD].length); + } + return this[ARRAY_FIELD][index]; +}; + +/** + * Replaces item of specified position. + * + * @name setAt + * @param {number} index - The position of the array you want to get. + * @param {any} value - New element + * @param {boolean} [noNotify] - Sets `true` if you don't want to fire `set_at` event. + * @return {any} previous item + */ +BaseArrayClass.prototype.setAt = function(index, value, noNotify) { + var self = this; + if (typeof index !== 'number') { + throw new Error('index must be a number'); + } + if (index < 0) { + throw new Error('index must be over number than 0'); + } + if (index > self[ARRAY_FIELD].length) { + for (var i = self[ARRAY_FIELD].length; i <= index; i++) { + self[ARRAY_FIELD][i] = undefined; + } + } + var prev = self[ARRAY_FIELD][index]; + self[ARRAY_FIELD][index] = value; + if (noNotify !== true) { + self.trigger('set_at', index, prev); + } + return prev; +}; + +/** + * Removes item of specified position. + * + * @name removeAt + * @param {number} index - The position of the array you want to get. + * @param {boolean} [noNotify] - Sets `true` if you don't want to fire `remove_at` event. + * @return {any} removed item + */ +BaseArrayClass.prototype.removeAt = function(index, noNotify) { + var self = this; + if (typeof index !== 'number') { + throw new Error('index must be a number'); + } + if (index < 0) { + throw new Error('index must be over number than 0'); + } + if (index >= self[ARRAY_FIELD].length) { + throw new Error('index must be lower number than ' + self[ARRAY_FIELD].length); + } + var value = self[ARRAY_FIELD][index]; + self[ARRAY_FIELD].splice(index, 1); + if (noNotify !== true) { + self.trigger('remove_at', index, value); + } + return value; +}; + +/** + * Removes item of the last array item. + * + * @name pop + * @param {boolean} [noNotify] - Sets `true` if you don't want to fire `remove_at` event. + * @return {any} removed item + */ +BaseArrayClass.prototype.pop = function(noNotify) { + var self = this; + var index = self[ARRAY_FIELD].length - 1; + var value = self[ARRAY_FIELD].pop(); + if (noNotify !== true) { + self.trigger('remove_at', index, value); + } + return value; +}; + +/** + * Returns the length of array. + * + * @name getLength + * @return {any} Number of items + */ +BaseArrayClass.prototype.getLength = function() { + return parseInt(this[ARRAY_FIELD].length, 10); // In order to prevent manupulating through `length` property, conver to number mandatory using `parseInt`. +}; + +/** + * Reverses an array in place. The first array element becomes the last, and the last array element becomes the first. + * + * @name reverse + */ +BaseArrayClass.prototype.reverse = function() { + this[ARRAY_FIELD].reverse(); +}; + +/** + * The `sort()` method sorts the elements of an array in place and returns the array. + * The same as `array.sort()`. + * + * @name sort + * @param {Function} [compareFunction] - Specifies a function that defines the sort order. + * If omitted, the array is sorted according to each character's Unicode code point value, + * according to the string conversion of each element. + */ +BaseArrayClass.prototype.sort = function(compareFunction) { + if (typeof compareFunction === 'function') { + this[ARRAY_FIELD].sort(compareFunction); + } else { + this[ARRAY_FIELD].sort(); + } +}; + + +module.exports = BaseArrayClass; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/BaseClass.js b/docs/plugins/cordova-plugin-googlemaps/www/BaseClass.js new file mode 100644 index 0000000..75329a5 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/BaseClass.js @@ -0,0 +1,225 @@ +cordova.define("cordova-plugin-googlemaps.BaseClass", function(require, exports, module) { var VARS_FIELD = typeof Symbol === 'undefined' ? '__vars' + Date.now() : Symbol('vars'); +var SUBSCRIPTIONS_FIELD = typeof Symbol === 'undefined' ? '__subs' + Date.now() : Symbol('subscriptions'); + +function BaseClass() { + this[VARS_FIELD] = {}; + this[SUBSCRIPTIONS_FIELD] = {}; + this.errorHandler = this.errorHandler.bind(this); + + Object.defineProperty(this, 'hashCode', { + value: Math.floor(Date.now() * Math.random()) + }); +} + +BaseClass.prototype = { + empty: function () { + var vars = this[VARS_FIELD]; + + Object.keys(vars).forEach(function (name) { + vars[name] = null; + delete vars[name]; + }); + }, + + get: function (key) { + return this[VARS_FIELD].hasOwnProperty(key) ? this[VARS_FIELD][key] : undefined; + }, + + set: function (key, value, noNotify) { + var prev = this.get(key); + + this[VARS_FIELD][key] = value; + + if (!noNotify && prev !== value) { + this.trigger(key + '_changed', prev, value, key); + } + + return this; + }, + + bindTo: function (key, target, targetKey, noNotify) { + targetKey = targetKey || key; + + // If `noNotify` is true, prevent `(targetKey)_changed` event occurrs, + // when bind the value for the first time only. + // (Same behaviour as Google Maps JavaScript v3) + target.set(targetKey, this[VARS_FIELD][key], noNotify); + + this.on(key + '_changed', function (oldValue, value) { + target.set(targetKey, value); + }); + }, + + trigger: function (eventName) { + if (!eventName) { + return this; + } + + if (!this[SUBSCRIPTIONS_FIELD][eventName]) { + return this; + } + + var listenerHashMap = this[SUBSCRIPTIONS_FIELD][eventName]; + var keys = Object.keys(listenerHashMap); + var args = Array.prototype.slice.call(arguments, 1); + var self = this; + + keys.forEach(function (_hashCode) { + if (self[SUBSCRIPTIONS_FIELD] && + self[SUBSCRIPTIONS_FIELD][eventName] && + _hashCode in self[SUBSCRIPTIONS_FIELD][eventName]) { + var info = self[SUBSCRIPTIONS_FIELD][eventName][_hashCode]; + + switch (info.kind) { + case 'on': + info.listener.apply(self, args); + break; + case 'onThrottled': + info.args = args; + if (!info.timer) { + info.timer = setTimeout(function () { + info.listener.apply(this, info.args); + info.timer = null; + }.bind(self), info.interval); + } + break; + } + } + }); + + return this; + }, + + on: function (eventName, listener) { + if (!listener || typeof listener !== 'function') { + throw Error('Listener for on()/addEventListener() method is not a function'); + } + if (!listener._hashCode) { + Object.defineProperty(listener, '_hashCode', { + value: Math.floor(Date.now() * Math.random()), + writable: false, + enumerable: false + }); + } + this[SUBSCRIPTIONS_FIELD][eventName] = this[SUBSCRIPTIONS_FIELD][eventName] || {}; + this[SUBSCRIPTIONS_FIELD][eventName][listener._hashCode] = { + 'kind': 'on', + 'listener': listener + }; + return this; + }, + + onThrottled: function (eventName, listener, interval) { + if (!listener || typeof listener !== 'function') { + throw Error('Listener for on()/addEventListener() method is not a function'); + } + if (typeof interval !== 'number' || interval < 1) { + throw Error('interval argument must be bigger number than 0'); + } + if (!listener._hashCode) { + Object.defineProperty(listener, '_hashCode', { + value: Math.floor(Date.now() * Math.random()), + writable: false, + enumerable: false + }); + } + this[SUBSCRIPTIONS_FIELD][eventName] = this[SUBSCRIPTIONS_FIELD][eventName] || {}; + this[SUBSCRIPTIONS_FIELD][eventName][listener._hashCode] = { + 'kind': 'onThrottled', + 'interval': interval, + 'timer': null, + 'listener': listener + }; + return this; + }, + + off: function (eventName, listener) { + if (!eventName && !listener) { + this[SUBSCRIPTIONS_FIELD] = {}; + return this; + } + + if (eventName && !listener) { + this[SUBSCRIPTIONS_FIELD][eventName] = null; + delete this[SUBSCRIPTIONS_FIELD][eventName]; + } else if (this[SUBSCRIPTIONS_FIELD][eventName] && listener._hashCode) { + delete this[SUBSCRIPTIONS_FIELD][eventName][listener._hashCode]; + } + + return this; + }, + + one: function (eventName, listener) { + if (!listener || typeof listener !== 'function') { + throw Error('Listener for one()/addEventListenerOnce() method is not a function'); + } + + var self = this; + + var callback = function () { + self.off(eventName, arguments.callee); + listener.apply(self, arguments); + callback = undefined; + }; + this.on(eventName, callback); + + return this; + }, + + hasEventListener: function (eventName) { + return (eventName in this[SUBSCRIPTIONS_FIELD] && Object.keys(this[SUBSCRIPTIONS_FIELD][eventName]).length > 0); + }, + + destroy: function () { + this.off(); + this.empty(); + }, + + errorHandler: function (error) { + if (error) { + if (typeof console.error === 'function') { + if (this.__pgmId) { + console.error(this.__pgmId, error); + } else { + console.error(error); + } + } else { + if (this.__pgmId) { + console.log(this.__pgmId, error); + } else { + console.log(error); + } + } + this.trigger('error', error instanceof Error ? error : createError(error)); + } + + return false; + } +}; + +BaseClass.prototype.addEventListener = BaseClass.prototype.on; +BaseClass.prototype.addThrottledEventListener = BaseClass.prototype.onThrottled; +BaseClass.prototype.addEventListenerOnce = BaseClass.prototype.one; +BaseClass.prototype.removeEventListener = BaseClass.prototype.off; + +function createError(message, methodName, args) { + var error = new Error(methodName ? [ + 'Got error with message: "', message, '" ', + 'after calling "', methodName, '"' + ].join('') : message); + + Object.defineProperties(error, { + methodName: { + value: methodName + }, + args: { + value: args + } + }); + + return error; +} + +module.exports = BaseClass; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/CameraPosition.js b/docs/plugins/cordova-plugin-googlemaps/www/CameraPosition.js new file mode 100644 index 0000000..b27b364 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/CameraPosition.js @@ -0,0 +1,22 @@ +cordova.define("cordova-plugin-googlemaps.CameraPosition", function(require, exports, module) { /******************************************************************************** + * @name CameraPosition + * @class This class represents new camera position + * @property {LatLng} target The location where you want to show + * @property {Number} [tilt] View angle + * @property {Number} [zoom] Zoom level + * @property {Number} [bearing] Map orientation + * @property {Number} [duration] The duration of animation + *******************************************************************************/ +var CameraPosition = function(params) { + var self = this; + self.zoom = params.zoom; + self.tilt = params.tilt; + self.target = params.target; + self.bearing = params.bearing; + self.hashCode = params.hashCode; + self.duration = params.duration; +}; + +module.exports = CameraPosition; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Circle.js b/docs/plugins/cordova-plugin-googlemaps/www/Circle.js new file mode 100644 index 0000000..c5f78c6 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Circle.js @@ -0,0 +1,176 @@ +cordova.define("cordova-plugin-googlemaps.Circle", function(require, exports, module) { var utils = require('cordova/utils'), + common = require('./Common'), + LatLngBounds = require('./LatLngBounds'), + Overlay = require('./Overlay'); + +/***************************************************************************** + * Circle Class + *****************************************************************************/ +var Circle = function (map, circleOptions, _exec) { + Overlay.call(this, map, circleOptions, 'Circle', _exec); + + var self = this; + + //----------------------------------------------- + // Sets event listeners + //----------------------------------------------- + self.on('center_changed', function () { + var center = self.get('center'); + center.lat = parseFloat(center.lat, 10); + center.lng = parseFloat(center.lng, 10); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setCenter', [self.getId(), center.lat, center.lng]); + }); + self.on('fillColor_changed', function () { + var color = self.get('fillColor'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setFillColor', [self.getId(), common.HTMLColor2RGBA(color, 0.75)]); + }); + self.on('strokeColor_changed', function () { + var color = self.get('strokeColor'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setStrokeColor', [self.getId(), common.HTMLColor2RGBA(color, 0.75)]); + }); + self.on('strokeWidth_changed', function () { + var width = self.get('strokeWidth'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setStrokeWidth', [self.getId(), width]); + }); + self.on('clickable_changed', function () { + var clickable = self.get('clickable'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setClickable', [self.getId(), clickable]); + }); + self.on('radius_changed', function () { + var radius = self.get('radius'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setRadius', [self.getId(), radius]); + }); + self.on('zIndex_changed', function () { + var zIndex = self.get('zIndex'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setZIndex', [self.getId(), zIndex]); + }); + self.on('visible_changed', function () { + var visible = self.get('visible'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setVisible', [self.getId(), visible]); + }); + +}; + +utils.extend(Circle, Overlay); + +Circle.prototype.getCenter = function () { + return this.get('center'); +}; +Circle.prototype.getRadius = function () { + return this.get('radius'); +}; +Circle.prototype.getStrokeColor = function () { + return this.get('strokeColor'); +}; +Circle.prototype.getStrokeWidth = function () { + return this.get('strokeWidth'); +}; +Circle.prototype.getZIndex = function () { + return this.get('zIndex'); +}; +Circle.prototype.getVisible = function () { + return this.get('visible'); +}; +Circle.prototype.getClickable = function () { + return this.get('clickable'); +}; +Circle.prototype.setCenter = function (center) { + center.lat = parseFloat(center.lat, 10); + center.lng = parseFloat(center.lng, 10); + this.set('center', center); + return this; +}; +Circle.prototype.setFillColor = function (color) { + this.set('fillColor', color); + return this; +}; +Circle.prototype.setStrokeColor = function (color) { + this.set('strokeColor', color); + return this; +}; +Circle.prototype.setStrokeWidth = function (width) { + this.set('strokeWidth', width); + return this; +}; +Circle.prototype.setVisible = function (visible) { + visible = common.parseBoolean(visible); + this.set('visible', visible); + return this; +}; +Circle.prototype.setClickable = function (clickable) { + clickable = common.parseBoolean(clickable); + this.set('clickable', clickable); + return this; +}; +Circle.prototype.setZIndex = function (zIndex) { + this.set('zIndex', zIndex); + return this; +}; +Circle.prototype.setRadius = function (radius) { + this.set('radius', radius); + return this; +}; + +Circle.prototype.remove = function (callback) { + var self = this; + if (self._isRemoved) { + if (typeof callback === 'function') { + return; + } else { + return Promise.resolve(); + } + } + Object.defineProperty(self, '_isRemoved', { + value: true, + writable: false + }); + self.trigger(self.__pgmId + '_remove'); + + var resolver = function(resolve, reject) { + self.exec.call(self, + function() { + self.destroy(); + resolve.call(self); + }, + reject.bind(self), + self.getPluginName(), 'remove', [self.getId()], { + remove: true + }); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } + +}; + +Circle.prototype.getBounds = function () { + var d2r = Math.PI / 180; // degrees to radians + var r2d = 180 / Math.PI; // radians to degrees + var earthsradius = 3963.189; // 3963 is the radius of the earth in miles + var radius = this.get('radius'); + var center = this.get('center'); + radius *= 0.000621371192; + + // find the raidus in lat/lon + var rlat = (radius / earthsradius) * r2d; + var rlng = rlat / Math.cos(center.lat * d2r); + + var bounds = new LatLngBounds(); + var ex, ey; + for (var i = 0; i < 360; i += 90) { + ey = center.lng + (rlng * Math.cos(i * d2r)); // center a + radius x * cos(theta) + ex = center.lat + (rlat * Math.sin(i * d2r)); // center b + radius y * sin(theta) + bounds.extend({ + lat: ex, + lng: ey + }); + } + return bounds; +}; + +module.exports = Circle; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Cluster.js b/docs/plugins/cordova-plugin-googlemaps/www/Cluster.js new file mode 100644 index 0000000..094a7de --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Cluster.js @@ -0,0 +1,114 @@ +cordova.define("cordova-plugin-googlemaps.Cluster", function(require, exports, module) { var LatLngBounds = require('./LatLngBounds'); + +/***************************************************************************** + * Cluster Class + *****************************************************************************/ +var Cluster = function(__pgmId, geocell) { + var obj = {}; + + var self = this; + Object.defineProperty(self, '__pgmId', { + value: __pgmId, + writable: false + }); + Object.defineProperty(self, 'geocell', { + value: geocell, + writable: false + }); + + Object.defineProperty(self, 'type', { + value: 'Cluster', + writable: false + }); + Object.defineProperty(self, '_markerArray', { + value: [], + writable: false + }); + + + Object.defineProperty(self, 'set', { + value: function(key, value) { + obj[key] = value; + }, + writable: false + }); + + Object.defineProperty(self, 'get', { + value: function(key) { + return obj[key]; + }, + writable: false + }); +}; + +Cluster.prototype.NO_CLUSTER_MODE = 1; +Cluster.prototype.CLUSTER_MODE = 2; + +Cluster.prototype.getPluginName = function() { + return this.map.getId() + '-cluster'; +}; +Cluster.prototype.getBounds = function() { + return this.get('bounds'); +}; +/* +Cluster.prototype.getBounds = function() { + var bounds = this.get('bounds'); + if (!bounds) { + bounds = geomodel.computeBox(this.geocell); + this.set('bounds', bounds); + } + return bounds; +}; +*/ +Cluster.prototype.getCenter = function() { + return this.getBounds().getCenter(); +}; + +Cluster.prototype.getMarkers = function() { + return this._markerArray; +}; + +Cluster.prototype.addMarkers = function(markerRefs) { + var self = this; + var bounds = this.get('bounds') || new LatLngBounds(markerRefs[0].get('position'), markerRefs[0].get('position')); + + markerRefs.forEach(function(marker) { + if (self._markerArray.indexOf(marker) === -1) { + marker.get('_cluster').isAdded = true; + self._markerArray.push(marker); + bounds.extend(marker.get('position')); + } + }); + + this.set('bounds', bounds); +}; +Cluster.prototype.getId = function() { + return this.__pgmId; +}; +Cluster.prototype.setMode = function(mode) { + this.set('mode', mode); +}; +Cluster.prototype.getMode = function() { + return this.get('mode'); +}; +Cluster.prototype.removeMarker = function(marker) { + + var idx = this._markerArray.indexOf(marker); + if (idx !== -1) { + this._markerArray.splice(idx, 1); + } +}; + +Cluster.prototype.remove = function() { + this.set('isRemoved', true); + this._markerArray.forEach(function(marker) { + marker.get('_cluster').isAdded = false; + }); +}; +Cluster.prototype.getItemLength = function() { + return this._markerArray.length; +}; + +module.exports = Cluster; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Common.js b/docs/plugins/cordova-plugin-googlemaps/www/Common.js new file mode 100644 index 0000000..d92f5a7 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Common.js @@ -0,0 +1,796 @@ +cordova.define("cordova-plugin-googlemaps.Common", function(require, exports, module) { +var BaseArrayClass = require('./BaseArrayClass'); +var utils = require('cordova/utils'); + +var resolvedPromise = typeof Promise == 'undefined' ? null : Promise.resolve(); +var nextTick = resolvedPromise ? function (fn) { + resolvedPromise.then(fn); +} : function (fn) { + setTimeout(fn); +}; + +//--------------------------- +// Convert HTML color to RGB +//--------------------------- +function isHTMLColorString(inputValue) { + if (!inputValue || typeof inputValue !== 'string') { + return false; + } + if (inputValue.match(/^#[0-9A-F]{3}$/i) || + inputValue.match(/^#[0-9A-F]{4}$/i) || + inputValue.match(/^#[0-9A-F]{6}$/i) || + inputValue.match(/^#[0-9A-F]{8}$/i) || + inputValue.match(/^rgba?\([\d,.\s]+\)$/) || + inputValue.match(/^hsla?\([\d%,.\s]+\)$/)) { + return true; + } + + inputValue = inputValue.toLowerCase(); + return inputValue in HTML_COLORS; +} + +function HTMLColor2RGBA(colorValue, defaultOpacity) { + defaultOpacity = !defaultOpacity ? 1.0 : defaultOpacity; + if (colorValue instanceof Array) { + return colorValue; + } + if (colorValue === 'transparent' || !colorValue) { + return [0, 0, 0, 0]; + } + var alpha = Math.floor(255 * defaultOpacity), + matches; + var colorStr = colorValue.toLowerCase(); + if (colorStr in HTML_COLORS) { + colorStr = HTML_COLORS[colorStr]; + } + if (colorStr.match(/^#([0-9A-F]){3}$/i)) { + matches = colorStr.match(/([0-9A-F])/ig); + + return [ + parseInt(matches[0], 16), + parseInt(matches[1], 16), + parseInt(matches[2], 16), + alpha + ]; + } + + if (colorStr.match(/^#[0-9A-F]{4}$/i)) { + alpha = colorStr.substr(4, 1); + alpha = parseInt(alpha + alpha, 16); + + matches = colorStr.match(/([0-9A-F])/ig); + return [ + parseInt(matches[0], 16), + parseInt(matches[1], 16), + parseInt(matches[2], 16), + alpha + ]; + } + + if (colorStr.match(/^#[0-9A-F]{6}$/i)) { + matches = colorStr.match(/([0-9A-F]{2})/ig); + return [ + parseInt(matches[0], 16), + parseInt(matches[1], 16), + parseInt(matches[2], 16), + alpha + ]; + } + if (colorStr.match(/^#[0-9A-F]{8}$/i)) { + matches = colorStr.match(/([0-9A-F]{2})/ig); + + return [ + parseInt(matches[0], 16), + parseInt(matches[1], 16), + parseInt(matches[2], 16), + parseInt(matches[3], 16) + ]; + } + // convert rgb(), rgba() + if (colorStr.match(/^rgba?\([\d,.\s]+\)$/)) { + matches = colorStr.match(/([\d.]+)/g); + alpha = matches.length == 4 ? Math.floor(parseFloat(matches[3]) * 256) : alpha; + return [ + parseInt(matches[0], 10), + parseInt(matches[1], 10), + parseInt(matches[2], 10), + alpha + ]; + } + + // convert hsl(), hsla() + if (colorStr.match(/^hsla?\([\d%,.\s]+\)$/)) { + matches = colorStr.match(/([\d%.]+)/g); + alpha = matches.length == 4 ? Math.floor(parseFloat(matches[3]) * 256) : alpha; + var rgb = HLStoRGB(matches[0], matches[1], matches[2]); + rgb.push(alpha); + return rgb; + } + + console.warn('Warning: "' + colorValue + '" is not available. The overlay is drew by black.'); + return [0, 0, 0, alpha]; +} + +/** + * http://d.hatena.ne.jp/ja9/20100907/1283840213 + */ +function HLStoRGB(h, l, s) { + var r, g, b; // 0..255 + + while (h < 0) { + h += 360; + } + h = h % 360; + + // In case of saturation = 0 + if (s === 0) { + // RGB are the same as V + l = Math.round(l * 255); + return [l, l, l]; + } + + var m2 = (l < 0.5) ? l * (1 + s) : l + s - l * s, + m1 = l * 2 - m2, + tmp; + + tmp = h + 120; + if (tmp > 360) { + tmp = tmp - 360; + } + + if (tmp < 60) { + r = (m1 + (m2 - m1) * tmp / 60); + } else if (tmp < 180) { + r = m2; + } else if (tmp < 240) { + r = m1 + (m2 - m1) * (240 - tmp) / 60; + } else { + r = m1; + } + + tmp = h; + if (tmp < 60) { + g = m1 + (m2 - m1) * tmp / 60; + } else if (tmp < 180) { + g = m2; + } else if (tmp < 240) { + g = m1 + (m2 - m1) * (240 - tmp) / 60; + } else { + g = m1; + } + + tmp = h - 120; + if (tmp < 0) { + tmp = tmp + 360; + } + if (tmp < 60) { + b = m1 + (m2 - m1) * tmp / 60; + } else if (tmp < 180) { + b = m2; + } else if (tmp < 240) { + b = m1 + (m2 - m1) * (240 - tmp) / 60; + } else { + b = m1; + } + return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; +} + +function parseBoolean(boolValue) { + return typeof (boolValue) === 'string' && boolValue.toLowerCase() === 'true' || + boolValue === true || + boolValue === 1; +} + +function isDom(element) { + return element && + element.nodeType === Node.ELEMENT_NODE && + element instanceof SVGElement === false && + typeof element.getBoundingClientRect === 'function'; +} + +function getDivRect(div) { + if (!div) { + return; + } + var rect; + if (div === document.body) { + rect = div.getBoundingClientRect(); + rect.left = Math.max(rect.left, window.pageOffsetX); + rect.top = Math.max(rect.top, window.pageOffsetY); + rect.width = Math.max(rect.width, window.innerWidth); + rect.height = Math.max(rect.height, window.innerHeight); + rect.right = rect.left + rect.width; + rect.bottom = rect.top + rect.height; + } else { + rect = div.getBoundingClientRect(); + if ('right' in rect === false) { + rect.right = rect.left + rect.width; + } + if ('bottom' in rect === false) { + rect.bottom = rect.top + rect.height; + } + } + return { + left: rect.left, + top: rect.top, + width: rect.width, + height: rect.height, + right: rect.right, + bottom: rect.bottom + }; +} + +var ignoreTags = [ + 'pre', 'textarea', 'p', 'form', 'input', 'caption', 'canvas', 'svg' +]; + +function shouldWatchByNative(node) { + if (!node || node.nodeType !== Node.ELEMENT_NODE || !node.parentNode || node instanceof SVGElement) { + if (node === document.body) { + return true; + } + return false; + } + + var tagName = node.tagName.toLowerCase(); + if (ignoreTags.indexOf(tagName) > -1) { + return false; + } + + var classNames = (node.className || '').split(' '); + if (classNames.indexOf('_gmaps_cdv_') > -1) { + return true; + } + + var visibilityCSS = getStyle(node, 'visibility'); + var displayCSS = getStyle(node, 'display'); + + // Do not check this at here. + //var pointerEventsCSS = getStyle(node, 'pointer-events'); + + //----------------------------------------- + // no longer check the opacity property, + // because the app might start changing the opacity later. + //----------------------------------------- + //var opacityCSS = getStyle(node, 'opacity'); + //opacityCSS = /^[\d.]+$/.test(opacityCSS + '') ? opacityCSS : 1; + + //----------------------------------------- + // no longer check the clickable size, + // because HTML still can display larger element inside one small element. + //----------------------------------------- + // var clickableSize = ( + // node.offsetHeight > 0 && node.offsetWidth > 0 || + // node.clientHeight > 0 && node.clientWidth > 0); + return displayCSS !== 'none' && + visibilityCSS !== 'hidden'; +} + +// Get z-index order +// http://stackoverflow.com/a/24136505 +var internalCache = {}; + +function _clearInternalCache() { + internalCache = undefined; + internalCache = {}; +} + +function _removeCacheById(elemId) { + delete internalCache[elemId]; +} + +function getZIndex(dom) { + if (dom === document.body) { + internalCache = undefined; + internalCache = {}; + } + if (!dom) { + return 0; + } + + var z = 0; + if (window.getComputedStyle) { + z = document.defaultView.getComputedStyle(dom, null).getPropertyValue('z-index'); + } + if (dom.currentStyle) { + z = dom.currentStyle['z-index']; + } + var elemId = dom.getAttribute('__pluginDomId'); + var parentNode = dom.parentNode; + var parentZIndex = 0; + if (parentNode && parentNode.nodeType === Node.ELEMENT_NODE) { + var parentElemId = parentNode.getAttribute('__pluginDomId'); + if (parentElemId in internalCache) { + parentZIndex = internalCache[parentElemId]; + } else { + parentZIndex = getZIndex(dom.parentNode); + internalCache[parentElemId] = parentZIndex; + } + } + + var isInherit = false; + if (z === 'unset' || z === 'initial') { + z = 0; + } else if (z === 'auto' || z === 'inherit') { + z = 0; + isInherit = true; + } else { + z = parseInt(z); + } + //dom.setAttribute('__ZIndex', z); + internalCache[elemId] = z + parentZIndex; + return { + isInherit: isInherit, + z: z + }; +} + +// Get CSS value of an element +// http://stackoverflow.com/a/1388022 +function getStyle(element, styleProperty) { + if (window.getComputedStyle) { + return document.defaultView.getComputedStyle(element, null).getPropertyValue(styleProperty); + } else if (element.currentStyle) { + return element.currentStyle[styleProperty]; + } + return; +} + +var HTML_COLORS = { + 'aliceblue': '#f0f8ff', + 'antiquewhite': '#faebd7', + 'aqua': '#00ffff', + 'aquamarine': '#7fffd4', + 'azure': '#f0ffff', + 'beige': '#f5f5dc', + 'bisque': '#ffe4c4', + 'black': '#000000', + 'blanchedalmond': '#ffebcd', + 'blue': '#0000ff', + 'blueviolet': '#8a2be2', + 'brown': '#a52a2a', + 'burlywood': '#deb887', + 'cadetblue': '#5f9ea0', + 'chartreuse': '#7fff00', + 'chocolate': '#d2691e', + 'coral': '#ff7f50', + 'cornflowerblue': '#6495ed', + 'cornsilk': '#fff8dc', + 'crimson': '#dc143c', + 'cyan': '#00ffff', + 'darkblue': '#00008b', + 'darkcyan': '#008b8b', + 'darkgoldenrod': '#b8860b', + 'darkgray': '#a9a9a9', + 'darkgrey': '#a9a9a9', + 'darkgreen': '#006400', + 'darkkhaki': '#bdb76b', + 'darkmagenta': '#8b008b', + 'darkolivegreen': '#556b2f', + 'darkorange': '#ff8c00', + 'darkorchid': '#9932cc', + 'darkred': '#8b0000', + 'darksalmon': '#e9967a', + 'darkseagreen': '#8fbc8f', + 'darkslateblue': '#483d8b', + 'darkslategray': '#2f4f4f', + 'darkslategrey': '#2f4f4f', + 'darkturquoise': '#00ced1', + 'darkviolet': '#9400d3', + 'deeppink': '#ff1493', + 'deepskyblue': '#00bfff', + 'dimgray': '#696969', + 'dimgrey': '#696969', + 'dodgerblue': '#1e90ff', + 'firebrick': '#b22222', + 'floralwhite': '#fffaf0', + 'forestgreen': '#228b22', + 'fuchsia': '#ff00ff', + 'gainsboro': '#dcdcdc', + 'ghostwhite': '#f8f8ff', + 'gold': '#ffd700', + 'goldenrod': '#daa520', + 'gray': '#808080', + 'grey': '#808080', + 'green': '#008000', + 'greenyellow': '#adff2f', + 'honeydew': '#f0fff0', + 'hotpink': '#ff69b4', + 'indianred ': '#cd5c5c', + 'indigo ': '#4b0082', + 'ivory': '#fffff0', + 'khaki': '#f0e68c', + 'lavender': '#e6e6fa', + 'lavenderblush': '#fff0f5', + 'lawngreen': '#7cfc00', + 'lemonchiffon': '#fffacd', + 'lightblue': '#add8e6', + 'lightcoral': '#f08080', + 'lightcyan': '#e0ffff', + 'lightgoldenrodyellow': '#fafad2', + 'lightgray': '#d3d3d3', + 'lightgrey': '#d3d3d3', + 'lightgreen': '#90ee90', + 'lightpink': '#ffb6c1', + 'lightsalmon': '#ffa07a', + 'lightseagreen': '#20b2aa', + 'lightskyblue': '#87cefa', + 'lightslategray': '#778899', + 'lightslategrey': '#778899', + 'lightsteelblue': '#b0c4de', + 'lightyellow': '#ffffe0', + 'lime': '#00ff00', + 'limegreen': '#32cd32', + 'linen': '#faf0e6', + 'magenta': '#ff00ff', + 'maroon': '#800000', + 'mediumaquamarine': '#66cdaa', + 'mediumblue': '#0000cd', + 'mediumorchid': '#ba55d3', + 'mediumpurple': '#9370db', + 'mediumseagreen': '#3cb371', + 'mediumslateblue': '#7b68ee', + 'mediumspringgreen': '#00fa9a', + 'mediumturquoise': '#48d1cc', + 'mediumvioletred': '#c71585', + 'midnightblue': '#191970', + 'mintcream': '#f5fffa', + 'mistyrose': '#ffe4e1', + 'moccasin': '#ffe4b5', + 'navajowhite': '#ffdead', + 'navy': '#000080', + 'oldlace': '#fdf5e6', + 'olive': '#808000', + 'olivedrab': '#6b8e23', + 'orange': '#ffa500', + 'orangered': '#ff4500', + 'orchid': '#da70d6', + 'palegoldenrod': '#eee8aa', + 'palegreen': '#98fb98', + 'paleturquoise': '#afeeee', + 'palevioletred': '#db7093', + 'papayawhip': '#ffefd5', + 'peachpuff': '#ffdab9', + 'peru': '#cd853f', + 'pink': '#ffc0cb', + 'plum': '#dda0dd', + 'powderblue': '#b0e0e6', + 'purple': '#800080', + 'rebeccapurple': '#663399', + 'red': '#ff0000', + 'rosybrown': '#bc8f8f', + 'royalblue': '#4169e1', + 'saddlebrown': '#8b4513', + 'salmon': '#fa8072', + 'sandybrown': '#f4a460', + 'seagreen': '#2e8b57', + 'seashell': '#fff5ee', + 'sienna': '#a0522d', + 'silver': '#c0c0c0', + 'skyblue': '#87ceeb', + 'slateblue': '#6a5acd', + 'slategray': '#708090', + 'slategrey': '#708090', + 'snow': '#fffafa', + 'springgreen': '#00ff7f', + 'steelblue': '#4682b4', + 'tan': '#d2b48c', + 'teal': '#008080', + 'thistle': '#d8bfd8', + 'tomato': '#ff6347', + 'turquoise': '#40e0d0', + 'violet': '#ee82ee', + 'wheat': '#f5deb3', + 'white': '#ffffff', + 'whitesmoke': '#f5f5f5', + 'yellow': '#ffff00', + 'yellowgreen': '#9acd32' +}; + +function defaultTrueOption(value) { + return value === undefined ? true : value === true; +} + +function createMvcArray(array) { + if (!array) { + return new BaseArrayClass(); + } + if (array.type === 'BaseArrayClass') { + return array; + } + + var mvcArray; + if (array.type === 'LatLngBounds') { + array = [ + array.southwest, + { + lat: array.northeast.lat, + lng: array.southwest.lng + }, + array.northeast, + { + lat: array.southwest.lat, + lng: array.northeast.lng + }, + array.southwest + ]; + array = array.map(getLatLng); + } + + if (array && typeof array.getArray === 'function') { + mvcArray = new BaseArrayClass(array.getArray()); + array.on('set_at', function (index) { + var value = array.getAt(index); + value = 'position' in value ? value.getPosition() : value; + mvcArray.setAt(index, value); + }); + array.on('insert_at', function (index) { + var value = array.getAt(index); + value = 'position' in value ? value.getPosition() : value; + mvcArray.insertAt(index, value); + }); + array.on('remove_at', function (index) { + mvcArray.removeAt(index); + }); + + } else { + mvcArray = new BaseArrayClass(array ? array.slice(0) : undefined); + } + return mvcArray; +} + +function getLatLng(target) { + return 'getPosition' in target ? target.getPosition() : { + 'lat': parseFloat(target.lat, 10), + 'lng': parseFloat(target.lng, 10) + }; +} + +function convertToPositionArray(array) { + array = array || []; + + if (!utils.isArray(array)) { + if (array.type === 'LatLngBounds') { + array = [ + array.southwest, + { + lat: array.northeast.lat, + lng: array.southwest.lng + }, + array.northeast, + { + lat: array.southwest.lat, + lng: array.northeast.lng + }, + array.southwest + ]; + } else if (array && typeof array.getArray === 'function') { + array = array.getArray(); + } else { + array = [array]; + } + } + + array = array.map(getLatLng); + + return array; +} + +function markerOptionsFilter(markerOptions) { + markerOptions = markerOptions || {}; + + markerOptions.animation = markerOptions.animation || undefined; + markerOptions.position = markerOptions.position || {}; + markerOptions.position.lat = markerOptions.position.lat || 0.0; + markerOptions.position.lng = markerOptions.position.lng || 0.0; + markerOptions.draggable = markerOptions.draggable === true; + markerOptions.icon = markerOptions.icon || undefined; + markerOptions.zIndex = markerOptions.zIndex || 0; + markerOptions.snippet = typeof (markerOptions.snippet) === 'string' ? markerOptions.snippet : undefined; + markerOptions.title = typeof (markerOptions.title) === 'string' ? markerOptions.title : undefined; + markerOptions.visible = defaultTrueOption(markerOptions.visible); + markerOptions.flat = markerOptions.flat === true; + markerOptions.rotation = markerOptions.rotation || 0; + markerOptions.opacity = markerOptions.opacity === 0 ? 0 : (parseFloat('' + markerOptions.opacity, 10) || 1); + markerOptions.disableAutoPan = markerOptions.disableAutoPan === true; + markerOptions.noCache = markerOptions.noCache === true; //experimental + if (typeof markerOptions.icon === 'object') { + if ('anchor' in markerOptions.icon && + !Array.isArray(markerOptions.icon.anchor) && + 'x' in markerOptions.icon.anchor && + 'y' in markerOptions.icon.anchor) { + markerOptions.icon.anchor = [markerOptions.icon.anchor.x, markerOptions.icon.anchor.y]; + } + } + + if ('infoWindowAnchor' in markerOptions && + !Array.isArray(markerOptions.infoWindowAnchor) && + 'x' in markerOptions.infoWindowAnchor && + 'y' in markerOptions.infoWindowAnchor) { + markerOptions.infoWindowAnchor = [markerOptions.infoWindowAnchor.x, markerOptions.infoWindowAnchor.anchor.y]; + } + + if ('style' in markerOptions && !('styles' in markerOptions)) { + markerOptions.styles = markerOptions.style; + delete markerOptions.style; + } + if ('styles' in markerOptions) { + markerOptions.styles = typeof markerOptions.styles === 'object' ? markerOptions.styles : {}; + + if ('color' in markerOptions.styles) { + markerOptions.styles.color = HTMLColor2RGBA(markerOptions.styles.color || '#000000'); + } + } + if (markerOptions.icon && isHTMLColorString(markerOptions.icon)) { + markerOptions.icon = HTMLColor2RGBA(markerOptions.icon); + } + if (markerOptions.icon && markerOptions.icon.label && + isHTMLColorString(markerOptions.icon.label.color)) { + markerOptions.icon.label.color = HTMLColor2RGBA(markerOptions.icon.label.color); + } + return markerOptions; +} + +function quickfilter(domPositions, mapElemIDs) { + //console.log('before', JSON.parse(JSON.stringify(domPositions))); + var keys = Object.keys(domPositions); + + var tree = {}; + mapElemIDs.forEach(function (mapElemId) { + var size = domPositions[mapElemId].size; + var mapRect = { + left: size.left, + top: size.top, + right: size.left + size.width, + bottom: size.top + size.height + }; + + tree[mapElemId] = domPositions[mapElemId]; + + keys.forEach(function (elemId) { + if (domPositions[elemId].ignore) { + return; + } + var domSize = { + left: domPositions[elemId].size.left, + top: domPositions[elemId].size.top, + right: domPositions[elemId].size.left + domPositions[elemId].size.width, + bottom: domPositions[elemId].size.bottom + domPositions[elemId].size.height + }; + if ( + (domSize.left >= mapRect.left && domSize.left <= mapRect.right) || + (domSize.right >= mapRect.left && domSize.right <= mapRect.right) || + (domSize.top >= mapRect.top && domSize.top <= mapRect.bottom) || + (domSize.bottom >= mapRect.top && domSize.bottom <= mapRect.bottom) + ) { + tree[elemId] = domPositions[elemId]; + } + }); + }); + + //console.log('after', JSON.parse(JSON.stringify(tree))); + return tree; +} + +function getPluginDomId(element) { + // Generates a __pluginDomId + if (!element || !shouldWatchByNative(element)) { + return; + } + var elemId = element.getAttribute('__pluginDomId'); + if (!elemId) { + if (element === document.body) { + elemId = 'root'; + } else { + elemId = 'pgm' + Math.floor(Math.random() * Date.now()); + } + element.setAttribute('__pluginDomId', elemId); + } + return elemId; +} + +// Add hashCode() method +// https://stackoverflow.com/a/7616484/697856 +function hashCode(text) { + var hash = 0, + i, chr; + if (text.length === 0) return hash; + for (i = 0; i < text.length; i++) { + chr = text.charCodeAt(i); + hash = ((hash << 5) - hash) + chr; + hash |= 0; // Convert to 32bit integer + } + return hash; +} + +function createEvent(eventName, properties) { + var evt; + if (typeof CustomEvent === 'function') { + evt = new CustomEvent(eventName, { + bubbles: true, + detail: properties || null + }); + } else { + evt = document.createEvent('Event'); + evt.initEvent(eventName, true, false); + Object.keys(properties).forEach(function (key) { + if (!(key in properties)) { + evt[key] = properties[key]; + } + }); + } + return evt; +} + +function attachTransparentClass(div) { + + if (div.classList && !div.classList.contains('_gmaps_cdv_')) { + div.classList.add('_gmaps_cdv_'); + } else if (div.className && div.className.indexOf('_gmaps_cdv_') === -1) { + div.className = div.className + ' _gmaps_cdv_'; + } + + if (div.shadowRoot) { + var styleAttr = div.getAttribute('style') || ''; + if (styleAttr && styleAttr.indexOf('--ion-background-color') === -1) { + styleAttr = styleAttr + ' --ion-background-color: transparent;'; + } + div.setAttribute('style', styleAttr); + } +} +// function dettachTransparentClass(root) { +// +// if (div.classList && div.classList.contains('_gmaps_cdv_')) { +// div.classList.remove('_gmaps_cdv_'); +// } else if (div.className && div.className.indexOf('_gmaps_cdv_') === -1) { +// div.className = div.className.replace('_gmaps_cdv_', ''); +// } +// +// var visibilityCSS = getStyle(node, 'visibility'); +// if (getStyle(div, 'background-color') === 'transparent !important') { +// div.style.backgroundColor = undefined; +// } +// if (getStyle(div, 'background') === 'transparent !important') { +// div.style.backgroundColor = undefined; +// } +// if (getStyle(div, 'background-image') === 'transparent !important') { +// div.style.backgroundImage = undefined; +// } +// if (div.shadowRoot) { +// var hiddenChildren = div.querySelectorAll('*'); +// hiddenChildren = Array.prototype.splice(hiddenChildren, 0); +// hiddenChildren.forEach(dettachTransparentClass); +// } +// } + +module.exports = { + _clearInternalCache: _clearInternalCache, + _removeCacheById: _removeCacheById, + getZIndex: getZIndex, + getDivRect: getDivRect, + isDom: isDom, + parseBoolean: parseBoolean, + HLStoRGB: HLStoRGB, + HTMLColor2RGBA: HTMLColor2RGBA, + isHTMLColorString: isHTMLColorString, + defaultTrueOption: defaultTrueOption, + createMvcArray: createMvcArray, + getStyle: getStyle, + convertToPositionArray: convertToPositionArray, + getLatLng: getLatLng, + shouldWatchByNative: shouldWatchByNative, + markerOptionsFilter: markerOptionsFilter, + quickfilter: quickfilter, + nextTick: nextTick, + getPluginDomId: getPluginDomId, + hashCode: hashCode, + createEvent: createEvent, + //dettachTransparentClass: dettachTransparentClass, + attachTransparentClass: attachTransparentClass +}; + +if (cordova && cordova.platformId === 'browser') { + require('cordova/exec/proxy').add('common', module.exports); +} + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Environment.js b/docs/plugins/cordova-plugin-googlemaps/www/Environment.js new file mode 100644 index 0000000..fe66f9f --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Environment.js @@ -0,0 +1,38 @@ +cordova.define("cordova-plugin-googlemaps.Environment", function(require, exports, module) { var common = require('./Common'); + +/***************************************************************************** + * Config Class + *****************************************************************************/ +var Environment = {}; + +Environment.setBackgroundColor = function (color) { + cordova.exec(null, null, 'PluginEnvironment', 'setBackGroundColor', [common.HTMLColor2RGBA(color)]); +}; + +Environment.isAvailable = function (callback) { + cordova.exec(function () { + if (typeof callback === 'function') { + callback(true); + } + }, function (message) { + if (typeof callback === 'function') { + callback(false, message); + } + }, 'PluginEnvironment', 'isAvailable', ['']); +}; + +Environment.getLicenseInfo = function (callback) { + cordova.exec(function (txt) { + callback(txt); + }, null, 'PluginEnvironment', 'getLicenseInfo', []); +}; + +Environment.setEnv = function (options) { + if (options) { + cordova.exec(null, null, 'PluginEnvironment', 'setEnv', [options]); + } +}; + +module.exports = Environment; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Geocoder.js b/docs/plugins/cordova-plugin-googlemaps/www/Geocoder.js new file mode 100644 index 0000000..3eb9ebe --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Geocoder.js @@ -0,0 +1,126 @@ +cordova.define("cordova-plugin-googlemaps.Geocoder", function(require, exports, module) { + +/***************************************************************************** + * Geocoder class + *****************************************************************************/ +var common = require('./Common'), + utils = require('cordova/utils'); + +var Geocoder = function (exec) { + + return { + geocode: function (geocoderRequest, callback) { + + geocoderRequest = geocoderRequest || {}; + var requestProperty = null; + if ('position' in geocoderRequest && !('address' in geocoderRequest)) { + requestProperty = 'position'; + } else if ('address' in geocoderRequest && !('position' in geocoderRequest)) { + requestProperty = 'address'; + } + if (!requestProperty) { + var error = new Error('Invalid request'); + if (typeof callback === 'function') { + callback([], error); + } else { + return Promise.reject(error); + } + } + + if (geocoderRequest[requestProperty] instanceof Array || Array.isArray(geocoderRequest[requestProperty])) { + //------------------------- + // Geocoder.geocode({ + // address: [ + // 'Kyoto, Japan', + // 'Tokyo, Japan' + // ] + // }) + //------------------------- + + var mvcResults = common.createMvcArray(); + for (var i = 0; i < requestCnt; i++) { + mvcResults.push(-1, true); + } + + // Execute geocoder.geocode() when a new request is instearted. + var requestCnt = geocoderRequest[requestProperty].length; + var requests = common.createMvcArray(); + requests.on('insert_at', function (idx) { + var request = requests.getAt(idx); + request.idx = idx; + exec.call({ + _isReady: true + }, function (result) { + + mvcResults.insertAt(result.idx, result.results); + if (mvcResults.getLength() === requestCnt) { + var tmp = mvcResults.getArray(); + var tmp2 = tmp.filter(function (ele) { + return ele === -1; + }); + if (tmp2.length === 0) { + // Notifies `finish` event when all results are received. + mvcResults.trigger('finish'); + } + } + + }, function (error) { + mvcResults.trigger('error', error); + }, 'PluginGeocoder', 'geocode', [request]); + }); + + var request; + var baseRequest = utils.clone(geocoderRequest); + delete baseRequest[requestProperty]; + for (i = 0; i < requestCnt; i++) { + request = utils.clone(baseRequest); + request[requestProperty] = geocoderRequest[requestProperty][i]; + request.idx = i; + if (requestProperty === 'position') { + request.position.lat = request.position.lat || 0.0; + request.position.lng = request.position.lng || 0.0; + } + requests.push(request); + } + if (typeof callback === 'function') { + callback(mvcResults); + } else { + return Promise.resolve(mvcResults); + } + } else { + //------------------------- + // Geocoder.geocode({ + // address: 'Kyoto, Japan' + // }) + //------------------------- + if (requestProperty === 'position') { + geocoderRequest.position.lat = geocoderRequest.position.lat || 0.0; + geocoderRequest.position.lng = geocoderRequest.position.lng || 0.0; + } + geocoderRequest.idx = -1; + + var resolver1 = function (resolve, reject) { + exec.call({ + _isReady: true + }, function (_results) { + resolve(_results.results); + }, reject, 'PluginGeocoder', 'geocode', [geocoderRequest]); + }; + + if (typeof callback === 'function') { + resolver1(callback, function (error) { + callback([], error); + }); + } else { + return new Promise(resolver1); + } + + } + } + + }; +}; + +module.exports = Geocoder; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/GroundOverlay.js b/docs/plugins/cordova-plugin-googlemaps/www/GroundOverlay.js new file mode 100644 index 0000000..d4c6dd4 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/GroundOverlay.js @@ -0,0 +1,154 @@ +cordova.define("cordova-plugin-googlemaps.GroundOverlay", function(require, exports, module) { var utils = require('cordova/utils'), + common = require('./Common'), + Overlay = require('./Overlay'); + +/***************************************************************************** + * GroundOverlay Class + *****************************************************************************/ +var GroundOverlay = function (map, groundOverlayOptions, _exec) { + Overlay.call(this, map, groundOverlayOptions, 'GroundOverlay', _exec); + + var self = this; + groundOverlayOptions.visible = groundOverlayOptions.visible === undefined ? true : groundOverlayOptions.visible; + groundOverlayOptions.zIndex = groundOverlayOptions.zIndex || 1; + groundOverlayOptions.opacity = groundOverlayOptions.opacity || 1; + groundOverlayOptions.bounds = groundOverlayOptions.bounds || []; + groundOverlayOptions.anchor = groundOverlayOptions.anchor || [0, 0]; + groundOverlayOptions.bearing = groundOverlayOptions.bearing || 0; + + //----------------------------------------------- + // Sets event listeners + //----------------------------------------------- + self.on('visible_changed', function () { + var visible = self.get('visible'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setVisible', [self.getId(), visible]); + }); + self.on('image_changed', function () { + var image = self.get('image'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setImage', [self.getId(), image]); + }); + self.on('bounds_changed', function () { + var bounds = self.get('bounds'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setBounds', [self.getId(), bounds]); + }); + self.on('opacity_changed', function () { + var opacity = self.get('opacity'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setOpacity', [self.getId(), opacity]); + }); + self.on('clickable_changed', function () { + var clickable = self.get('clickable'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setClickable', [self.getId(), clickable]); + }); + self.on('bearing_changed', function () { + var bearing = self.get('bearing'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setBearing', [self.getId(), bearing]); + }); + self.on('zIndex_changed', function () { + var zIndex = self.get('zIndex'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setZIndex', [self.getId(), zIndex]); + }); + +}; + +utils.extend(GroundOverlay, Overlay); + +GroundOverlay.prototype.setVisible = function (visible) { + this.set('visible', visible); +}; + +GroundOverlay.prototype.getVisible = function () { + return this.get('visible'); +}; + +GroundOverlay.prototype.setImage = function (url) { + this.set('image', url); +}; + +GroundOverlay.prototype.setBounds = function (points) { + var i, + bounds = []; + for (i = 0; i < points.length; i++) { + bounds.push({ + 'lat': parseFloat(points[i].lat, 10), + 'lng': parseFloat(points[i].lng, 10) + }); + } + this.set('bounds', bounds); +}; + +GroundOverlay.prototype.getOpacity = function () { + return this.get('opacity'); +}; + +GroundOverlay.prototype.getBearing = function () { + return this.get('bearing'); +}; + +GroundOverlay.prototype.setOpacity = function (opacity) { + if (!opacity && opacity !== 0) { + console.log('opacity value must be int or double'); + return false; + } + this.set('opacity', opacity); +}; +GroundOverlay.prototype.setBearing = function (bearing) { + if (bearing > 360) { + bearing = bearing - Math.floor(bearing / 360) * 360; + } + this.set('bearing', bearing); +}; + +GroundOverlay.prototype.getZIndex = function () { + return this.get('zIndex'); +}; + +GroundOverlay.prototype.setZIndex = function (zIndex) { + this.set('zIndex', zIndex); +}; +GroundOverlay.prototype.setClickable = function (clickable) { + clickable = common.parseBoolean(clickable); + this.set('clickable', clickable); + return this; +}; +GroundOverlay.prototype.getClickable = function () { + return this.get('clickable'); +}; + +GroundOverlay.prototype.remove = function (callback) { + var self = this; + if (self._isRemoved) { + if (typeof callback === 'function') { + return; + } else { + return Promise.resolve(); + } + } + Object.defineProperty(self, '_isRemoved', { + value: true, + writable: false + }); + self.trigger(self.__pgmId + '_remove'); + + var resolver = function(resolve, reject) { + self.exec.call(self, + function() { + self.destroy(); + resolve.call(self); + }, + reject.bind(self), + self.getPluginName(), 'remove', [self.getId()], { + remove: true + }); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } + +}; + +module.exports = GroundOverlay; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/HtmlInfoWindow.js b/docs/plugins/cordova-plugin-googlemaps/www/HtmlInfoWindow.js new file mode 100644 index 0000000..dfdad82 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/HtmlInfoWindow.js @@ -0,0 +1,475 @@ +cordova.define("cordova-plugin-googlemaps.HtmlInfoWindow", function(require, exports, module) { +var utils = require('cordova/utils'), + event = require('./event'), + BaseClass = require('./BaseClass'); + +/***************************************************************************** + * HTMLInfoWindow Class + *****************************************************************************/ +var HTMLInfoWindow = function () { + var self = this; + BaseClass.apply(self); + var callbackTable = {}; + var listenerMgr = { + one: function (target, eventName, callback) { + callbackTable[target.hashCode] = callbackTable[target.hashCode] || {}; + callbackTable[target.hashCode][eventName] = callbackTable[target.hashCode][eventName] || []; + callbackTable[target.hashCode][eventName].push(callback); + target.one.call(target, eventName, callback); + }, + on: function (target, eventName, callback) { + callbackTable[target.hashCode] = callbackTable[target.hashCode] || {}; + callbackTable[target.hashCode][eventName] = callbackTable[target.hashCode][eventName] || []; + callbackTable[target.hashCode][eventName].push(callback); + target.on.call(target, eventName, callback); + }, + bindTo: function (srcObj, srcField, dstObj, dstField, noNotify) { + var eventName = srcField + '_changed'; + dstField = dstField || srcField; + var callback = function (oldValue, newValue) { + dstObj.set(dstField, newValue, noNotify); + }; + callbackTable[dstObj.hashCode] = callbackTable[dstObj.hashCode] || {}; + callbackTable[dstObj.hashCode][eventName] = callbackTable[dstObj.hashCode][eventName] || []; + callbackTable[dstObj.hashCode][eventName].push(callback); + srcObj.on.call(srcObj, eventName, callback); + }, + off: function (target, eventName) { + if (!target || !eventName || + !(target.hashCode in callbackTable) || + !(eventName in callbackTable[target.hashCode])) { + return; + } + callbackTable[target.hashCode][eventName].forEach(function (listener) { + target.off.call(target, eventName, listener); + }); + delete callbackTable[target.hashCode][eventName]; + } + }; + + Object.defineProperty(self, '_hook', { + value: listenerMgr, + writable: false + }); + + var frame = document.createElement('div'); + frame.style.overflow = 'visible'; + frame.style.position = 'absolute'; + frame.style.display = 'inline-block'; + frame.classList.add('pgm-html-info-frame'); + self.set('frame', frame); + + var anchorDiv = document.createElement('div'); + anchorDiv.setAttribute('class', 'pgm-anchor'); + anchorDiv.style.overflow = 'visible'; + anchorDiv.style.position = 'absolute'; + anchorDiv.style['z-index'] = 0; + anchorDiv.style.width = '0 !important'; + anchorDiv.style.height = '0 !important'; + //anchorDiv.style.border = '1px solid green'; + //anchorDiv.style.backgroundColor = 'rgba(125, 125, 255, 0.5)'; + + anchorDiv.style.transition = 'transform 0s ease'; + anchorDiv.style['will-change'] = 'transform'; + + anchorDiv.style['-webkit-backface-visibility'] = 'hidden'; + anchorDiv.style['-webkit-perspective'] = 1000; + anchorDiv.style['-webkit-transition'] = '-webkit-transform 0s ease'; + + anchorDiv.appendChild(frame); + self.set('anchor', anchorDiv); + + var contentBox = document.createElement('div'); + contentBox.style.display = 'inline-block'; + contentBox.style.padding = '5px'; + contentBox.style.boxSizing = 'content-box'; + contentBox.classList.add('pgm-html-info-content-box'); + + var contentFrame = document.createElement('div'); + contentFrame.style.display = 'block'; + contentFrame.style.position = 'relative'; + contentFrame.style.backgroundColor = 'white'; + contentFrame.style.border = '1px solid rgb(204, 204, 204)'; + contentFrame.style.left = '0px'; + contentFrame.style.right = '0px'; + contentFrame.style.zIndex = '1'; // In order to set higher depth than the map div certainly + contentFrame.style.overflow = 'hidden'; + contentFrame.classList.add('pgm-html-info-content-frame'); + frame.appendChild(contentFrame); + contentFrame.appendChild(contentBox); + + var tailFrame = document.createElement('div'); + tailFrame.style.position = 'relative'; + tailFrame.style.top = '-1px'; + tailFrame.style.zIndex = 100; + tailFrame.classList.add('pgm-html-info-tail-frame'); + frame.appendChild(tailFrame); + + var tailLeft = document.createElement('div'); + /* + tailLeft.style.position = 'absolute'; + tailLeft.style.marginLeft = '-15px'; + tailLeft.style.left = '50%'; + tailLeft.style.top = '0px'; + tailLeft.style.height = '15px'; + tailLeft.style.width = '16px'; + tailLeft.style.overflow = 'hidden'; + tailLeft.style.borderWidth = '0px'; + */ + tailLeft.classList.add('pgm-html-info-tail-left'); + + tailLeft.style.position = 'absolute'; + tailLeft.style.left = '50%'; + tailLeft.style.height = '0px'; + tailLeft.style.width = '0px'; + tailLeft.style.marginLeft = '-15px'; + tailLeft.style.borderWidth = '15px 15px 0px'; + tailLeft.style.borderColor = 'rgb(204, 204, 204) transparent transparent'; + tailLeft.style.borderStyle = 'solid'; + tailFrame.appendChild(tailLeft); + + /* + var tailLeftCover = document.createElement('div'); + tailLeftCover.style.position = 'absolute'; + tailLeftCover.style.backgroundColor = 'white'; + tailLeftCover.style.transform = 'skewX(45deg)'; + tailLeftCover.style.transformOrigin = '0px 0px 0px'; + tailLeftCover.style.left = '0px'; + tailLeftCover.style.height = '15px'; + tailLeftCover.style.width = '15px'; + tailLeftCover.style.top = '0px'; + tailLeftCover.style.zIndex = 1; + tailLeftCover.style.borderLeft = '1px solid rgb(204, 204, 204)'; + tailLeft.classList.add('pgm-html-info-tail-left-cover'); + tailLeft.appendChild(tailLeftCover); + */ + + var tailRight = document.createElement('div'); + /* + tailRight.style.position = 'absolute'; + tailRight.style.left = '50%'; + tailRight.style.top = '0px'; + tailRight.style.height = '15px'; + tailRight.style.width = '16px'; + tailRight.style.overflow = 'hidden'; + tailRight.style.borderWidth = '0px'; + */ + tailRight.style.position = 'absolute'; + tailRight.style.left = '50%'; + tailRight.style.height = '0px'; + tailRight.style.width = '0px'; + tailRight.style.marginLeft = '-14px'; + tailRight.style.borderTopWidth = '14px'; + tailRight.style.borderLeftWidth = '14px'; + tailRight.style.borderRightWidth = '14px'; + tailRight.style.borderColor = 'rgb(255, 255, 255) transparent transparent'; + tailRight.style.borderStyle = 'solid'; + tailRight.classList.add('pgm-html-info-tail-right'); + tailFrame.appendChild(tailRight); + /* + var tailRightCover = document.createElement('div'); + tailRightCover.style.position = 'absolute'; + tailRightCover.style.backgroundColor = 'white'; + tailRightCover.style.transform = 'skewX(-45deg)'; + tailRightCover.style.transformOrigin = '0px 0px 0px'; + tailRightCover.style.left = '0px'; + tailRightCover.style.height = '15px'; + tailRightCover.style.width = '15px'; + tailRightCover.style.top = '0px'; + tailRightCover.style.zIndex = 2; + tailRightCover.style.borderRight = '1px solid rgb(204, 204, 204)'; + tailRightCover.classList.add('pgm-html-info-tail-right-cover'); + tailRight.appendChild(tailRightCover); + */ + var eraseBorder = document.createElement('div'); + eraseBorder.style.position = 'absolute'; + eraseBorder.style.zIndex = 3; + eraseBorder.style.backgroundColor = 'white'; + eraseBorder.style.width = '27px'; + eraseBorder.style.height = '2px'; + eraseBorder.style.top = '-1px'; + eraseBorder.style.left = '50%'; + eraseBorder.style.marginLeft = '-13px'; + eraseBorder.classList.add('pgm-html-info-tail-erase-border'); + tailFrame.appendChild(eraseBorder); + + var calculate = function (marker) { + + //var marker = self.get('marker'); + var map = marker.getMap(); + + var div = map.getDiv(); + + var frame = self.get('frame'); + var contentFrame = frame.firstChild; + var contentBox = contentFrame.firstChild; + contentBox.style.minHeight = '50px'; + contentBox.style.width = 'auto'; + contentBox.style.height = 'auto'; + contentBox.style.padding = '5px'; + + var content = self.get('content'); + if (typeof content === 'string') { + contentBox.style.whiteSpace = 'pre-wrap'; + contentBox.innerHTML = content; + } else { + if (!content) { + contentBox.innerText = ''; + } else if (content.nodeType === 1) { + contentBox.innerHTML = ''; + contentBox.appendChild(content); + } else { + contentBox.innerText = content; + } + } + + var cssOptions = self.get('cssOptions'); + if (cssOptions && typeof cssOptions === 'object') { + var keys = Object.keys(cssOptions); + keys.forEach(function (key) { + contentBox.style.setProperty(key, cssOptions[key]); + }); + } + // Insert the contents to this HTMLInfoWindow + if (!anchorDiv.parentNode) { + map._layers.info.appendChild(anchorDiv); + } + + // Adjust the HTMLInfoWindow size + var contentsWidth = contentBox.offsetWidth + 10; // padding 5px x 2 + var contentsHeight = contentBox.offsetHeight; + self.set('contentsHeight', contentsHeight); + contentFrame.style.width = contentsWidth + 'px'; + contentFrame.style.height = contentsHeight + 'px'; + frame.style.width = contentsWidth + 'px'; + frame.style.height = (contentsHeight + 15) + 'px'; + + if (contentBox.offsetWidth > div.offsetWidth * 0.9) { + contentBox.style.width = (div.offsetWidth * 0.9) + 'px'; + } + contentBox.style.width = '100%'; + contentBox.style.height = '100%'; + contentBox.style.padding = '5px 17px 17px 5px'; + self.set('contentsWidth', contentsWidth); + + var infoOffset = { + x: 31, + y: 31 + }; + var iconSize = { + width: 62, + height: 110 + }; + + // If there is no specification with `anchor` property, + // the values {x: 0.5, y: 1} are specified by native APIs. + // For the case, anchor values are {x: 0} in JS. + var anchor = { + x: 15, + y: 15 + }; + + var icon = marker.get('icon'); + + if (typeof icon === 'object') { + if (typeof icon.url === 'string' && icon.url.indexOf('data:image/') === 0) { + var img = document.createElement('img'); + img.src = icon.url; + iconSize.width = img.width; + iconSize.height = img.height; + } + if (typeof icon.size === 'object') { + iconSize.width = icon.size.width; + iconSize.height = icon.size.height; + } + + if (Array.isArray(icon.anchor)) { + anchor.x = icon.anchor[0]; + anchor.y = icon.anchor[1]; + } + } + + var infoWindowAnchor = marker.get('infoWindowAnchor'); + if (utils.isArray(infoWindowAnchor)) { + infoOffset.x = infoWindowAnchor[0]; + infoOffset.y = infoWindowAnchor[1]; + } + infoOffset.x = infoOffset.x / iconSize.width; + infoOffset.x = infoOffset.x > 1 ? 1 : infoOffset.x; + infoOffset.x = infoOffset.x < 0 ? 0 : infoOffset.x; + infoOffset.y = infoOffset.y / iconSize.height; + infoOffset.y = infoOffset.y > 1 ? 1 : infoOffset.y; + infoOffset.y = infoOffset.y < 0 ? 0 : infoOffset.y; + infoOffset.y *= iconSize.height; + infoOffset.x *= iconSize.width; + + anchor.x = anchor.x / iconSize.width; + anchor.x = anchor.x > 1 ? 1 : anchor.x; + anchor.x = anchor.x < 0 ? 0 : anchor.x; + anchor.y = anchor.y / iconSize.height; + anchor.y = anchor.y > 1 ? 1 : anchor.y; + anchor.y = anchor.y < 0 ? 0 : anchor.y; + anchor.y *= iconSize.height; + anchor.x *= iconSize.width; + + //console.log('contentsSize = ' + contentsWidth + ', ' + contentsHeight); + //console.log('iconSize = ' + iconSize.width + ', ' + iconSize.height); + //console.log('infoOffset = ' + infoOffset.x + ', ' + infoOffset.y); + + //var frameBorder = parseInt(common.getStyle(contentFrame, 'border-left-width').replace(/[^\d]/g, ''), 10); + //var offsetX = (contentsWidth + frameBorder + anchor.x ) * 0.5 + (iconSize.width / 2 - infoOffset.x); + //var offsetY = contentsHeight + anchor.y - (frameBorder * 2) - infoOffset.y + 15; + var offsetX = -(iconSize.width / 2) - (cordova.platformId === 'android' ? 1 : 0); + var offsetY = -iconSize.height - (cordova.platformId === 'android' ? 1 : 0); + anchorDiv.style.width = iconSize.width + 'px'; + anchorDiv.style.height = iconSize.height + 'px'; + + self.set('offsetX', offsetX); + self.set('offsetY', offsetY); + + frame.style.bottom = (iconSize.height - infoOffset.y) + 'px'; + frame.style.left = ((-contentsWidth) / 2 + infoOffset.x) + 'px'; + + //console.log('frameLeft = ' + frame.style.left ); + var point = map.get('infoPosition'); + anchorDiv.style.visibility = 'hidden'; + var x = point.x + self.get('offsetX'); + var y = point.y + self.get('offsetY'); + anchorDiv.style['-webkit-transform'] = 'translate3d(' + x + 'px, ' + y + 'px, 0px)'; + anchorDiv.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0px)'; + anchorDiv.style.visibility = 'visible'; + self.trigger('infoPosition_changed', '', point); + self.trigger(event.INFO_OPEN); + }; + + self._hook.on(self, 'infoPosition_changed', function (ignore, point) { + if (!point) return; + var x = point.x + self.get('offsetX'); + var y = point.y + self.get('offsetY'); + anchorDiv.style['-webkit-transform'] = 'translate3d(' + x + 'px, ' + y + 'px, 0px)'; + anchorDiv.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0px)'; + }); + + self._hook.on(self, 'infoWindowAnchor_changed', calculate); + + self.set('isInfoWindowVisible', false); + +}; + +utils.extend(HTMLInfoWindow, BaseClass); + +HTMLInfoWindow.prototype.isInfoWindowShown = function () { + return this.get('isInfoWindowVisible') === true; +}; + +HTMLInfoWindow.prototype.close = function () { + var self = this; + + var marker = self.get('marker'); + if (marker) { + self._hook.off(marker, 'isInfoWindowVisible_changed'); + } + if (!self.isInfoWindowShown() || !marker) { + return; + } + self.set('isInfoWindowVisible', false); + marker.set('isInfoWindowVisible', false); + marker.set('infoWindow', undefined); + this.set('marker', undefined); + + var map = marker.getMap(); + self._hook.off(marker.getMap(), 'map_clear'); + self._hook.off(marker, 'infoPosition_changed'); + self._hook.off(marker, 'icon_changed'); + //self._hook.off(self, 'infoWindowAnchor_changed'); + self._hook.off(marker, event.INFO_CLOSE); //This event listener is assigned in the open method. So detach it. + self.trigger(event.INFO_CLOSE); + map.set('active_marker', null); + + //var div = map.getDiv(); + var anchorDiv = self.get('anchor'); + if (anchorDiv && anchorDiv.parentNode) { + anchorDiv.parentNode.removeChild(anchorDiv); + + // Remove the contents from this HTMLInfoWindow + var contentFrame = anchorDiv.firstChild.firstChild; + var contentBox = contentFrame.firstChild; + contentBox.innerHTML = ''; + } +}; + +HTMLInfoWindow.prototype.setContent = function (content, cssOptions) { + var self = this; + var prevContent = self.get('content'); + self.set('content', content); + self.set('cssOptions', cssOptions); + var marker = self.get('marker'); + if (content !== prevContent && marker && marker.isInfoWindowShown()) { + var anchorDiv = self.get('anchor'); + if (anchorDiv) { + anchorDiv.style.width = '0 !important'; + anchorDiv.style.height = '0 !important'; + if (anchorDiv.parentNode) { + anchorDiv.parentNode.removeChild(anchorDiv); + + // Remove the contents from this HTMLInfoWindow + var contentFrame = anchorDiv.firstChild.firstChild; + var contentBox = contentFrame.firstChild; + contentBox.innerHTML = ''; + } + } + self.trigger('infoWindowAnchor_changed', marker); + } +}; + +HTMLInfoWindow.prototype.open = function (marker) { + if (!marker) { + return; + } + if (marker._objectInstance) { + // marker is an instance of the ionic-native wrapper plugin. + marker = marker._objectInstance; + } + + var self = this, + map = marker.getMap(); + + marker.set('infoWindow', self); + marker.set('isInfoWindowVisible', true); + self._hook.on(marker, 'icon_changed', function () { + self.trigger.call(self, 'infoWindowAnchor_changed', marker); + }); + self.set('isInfoWindowVisible', true); + self._hook.on(marker, 'isInfoWindowVisible_changed', function (prevValue, newValue) { + if (newValue === false) { + self.close.call(self); + } + }); + + map.fromLatLngToPoint(marker.getPosition(), function (point) { + map.set('infoPosition', { + x: point[0], + y: point[1] + }); + + self._hook.bindTo(map, 'infoPosition', self); + self._hook.bindTo(marker, 'infoWindowAnchor', self); + self._hook.bindTo(marker, 'icon', self); + self._hook.one(marker.getMap(), 'map_clear', self.close.bind(self)); + self._hook.one(marker, event.INFO_CLOSE, self.close.bind(self)); + self.set('marker', marker); + map.set('active_marker', marker); + self.trigger.call(self, 'infoWindowAnchor_changed', marker); + }); +}; + +HTMLInfoWindow.prototype.setBackgroundColor = function (backgroundColor) { + this.get('frame').children[0].style.backgroundColor = backgroundColor; + this.get('frame').children[1].children[0].style.borderColor = backgroundColor + ' rgba(0,0,0,0) rgba(0,0,0,0)'; + this.get('frame').children[1].children[1].style.borderColor = backgroundColor + ' rgba(0,0,0,0) rgba(0,0,0,0)'; + this.get('frame').children[1].children[2].style.backgroundColor = backgroundColor; +}; + +module.exports = HTMLInfoWindow; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/InlineWorker.js b/docs/plugins/cordova-plugin-googlemaps/www/InlineWorker.js new file mode 100644 index 0000000..5bb4ff3 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/InlineWorker.js @@ -0,0 +1,55 @@ +cordova.define("cordova-plugin-googlemaps.InlineWorker", function(require, exports, module) { // InlineWorker +// https://github.com/mohayonao/inline-worker +// +// The MIT License (MIT) +// Copyright © 2018 Nao Yonamine +// +// 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. + + +var WORKER_ENABLED = !!window.Worker; +var global = window; + +function InlineWorker(func, self) { + var _this = this; + var functionBody; + + self = self || {}; + + if (WORKER_ENABLED) { + functionBody = func.toString().trim().match( + /^function\s*\w*\s*\([\w\s,]*\)\s*{([\w\W]*?)}$/ + )[1]; + + return new global.Worker(global.URL.createObjectURL( + new global.Blob([ functionBody ], { type: 'text/javascript' }) + )); + } + + function postMessage(data) { + setTimeout(function() { + _this.onmessage({ data: data }); + }, 0); + } + + this.self = self; + this.self.postMessage = postMessage; + + setTimeout(func.bind(self, self), 0); +} + +InlineWorker.prototype.postMessage = function postMessage(data) { + var _this = this; + + setTimeout(function() { + _this.self.onmessage({ data: data }); + }, 0); +}; + +module.exports = InlineWorker; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/KmlLoader.js b/docs/plugins/cordova-plugin-googlemaps/www/KmlLoader.js new file mode 100644 index 0000000..1a97c0e --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/KmlLoader.js @@ -0,0 +1,1116 @@ +cordova.define("cordova-plugin-googlemaps.KmlLoader", function(require, exports, module) { + + +var utils = require('cordova/utils'), + event = require('./event'), + BaseClass = require('./BaseClass'), + BaseArrayClass = require('./BaseArrayClass'), + VisibleRegion = require('./VisibleRegion'); + +/***************************************************************************** + * KmlLoader Class + *****************************************************************************/ +var KmlLoader = function(map, exec, options) { + BaseClass.apply(this); + + var self = this; + //self.set("visible", KmlLoaderOptions.visible === undefined ? true : KmlLoaderOptions.visible); + //self.set("zIndex", KmlLoaderOptions.zIndex || 0); + Object.defineProperty(self, '_overlays', { + value: new BaseArrayClass(), + writable: false + }); + Object.defineProperty(self, '_isReady', { + value: true, + writable: false + }); + Object.defineProperty(self, 'type', { + value: 'KmlLoader', + writable: false + }); + Object.defineProperty(self, 'map', { + value: map, + writable: false + }); + Object.defineProperty(self, 'exec', { + value: exec, + writable: false + }); + Object.defineProperty(self, 'options', { + value: options, + writable: false + }); + Object.defineProperty(self, 'kmlUrl', { + value: options.url, + writable: false + }); + Object.defineProperty(self, 'camera', { + value: { + target: [] + }, + writable: false + }); +}; + +utils.extend(KmlLoader, BaseClass); + +KmlLoader.prototype.parseKmlFile = function(callback) { + var self = this; + + self.exec.call(self.map, function(kmlData) { + //var rawKmlData = JSON.parse(JSON.stringify(kmlData)); + //console.log(rawKmlData); + Object.defineProperty(self, 'kmlStyles', { + value: kmlData.styles, + writable: false + }); + Object.defineProperty(self, 'kmlSchemas', { + value: kmlData.schemas, + writable: false + }); + + var placeMarks = new BaseArrayClass(kmlData.root.children); + placeMarks.mapAsync(function(placeMark, cb) { + self.kmlTagProcess.call(self, { + child: placeMark, + attrHolder: {}, + styles: { + children: [] + } + }, cb); + }, function(placeMarkOverlays) { + placeMarkOverlays = placeMarkOverlays.filter(function(overlay) { + return !!overlay; + }); + var result = placeMarkOverlays.shift(); + //result.set('kmlData', rawKmlData); + callback.call(self, self.camera, result); + }); + }, self.map.errorHandler, self.map.__pgmId, 'loadPlugin', ['KmlOverlay', { + url: self.options.url + }], {sync: true}); +}; + +KmlLoader.prototype.kmlTagProcess = function(params, callback) { + var self = this; + + if (params.child.styleIDs) { + //--------------------------- + // Read styles if specified + //--------------------------- + var styleIDs = new BaseArrayClass(params.child.styleIDs); + styleIDs.mapAsync(function(styleId, cb) { + self.getStyleById.call(self, styleId, cb); + }, function(styleSets) { + + //----------------------------------- + // Merge styles with parent styles, + //----------------------------------- + var merged = {}; + styleSets.unshift(params.styles); + styleSets.forEach(function(styleSet) { + styleSet.children.forEach(function(style) { + merged[style.tagName] = merged[style.tagName] || {}; + style.children.forEach(function(styleEle) { + merged[style.tagName][styleEle.tagName] = styleEle; + }); + }); + }); + + params.styles = {}; + var keys = Object.keys(merged); + params.styles.children = keys.map(function(tagName) { + var properties = Object.keys(merged[tagName]); + var children = properties.map(function(propName) { + return merged[tagName][propName]; + }); + return { + tagName: tagName, + children: children + }; + }); + //------------------------ + // then process the tag. + //------------------------ + self.parseKmlTag.call(self, params, callback); + + }); + } else { + //------------------------------------------------- + // No styleID is specified, just process the tag + //------------------------------------------------- + self.parseKmlTag.call(self, params, callback); + } +}; + +KmlLoader.prototype.getObjectById = function(requestId, targetProp, callback) { + var self = this; + + if (!requestId) { + return callback.call(self, {children: []}); + } + var i, child, + results = {}; + if (requestId.indexOf('http://') === 0 || + requestId.indexOf('https://') === 0 || + requestId.indexOf('.kml') !== -1) { + + if (requestId.indexOf('://') === -1) { + requestId = self.kmlUrl.replace(/\/[^/]+$/, '/') + requestId; + } + //--------------------------- + // Load additional kml file + //--------------------------- + var requestUrl = requestId.replace(/#.*$/, ''); + var requestIdentify = requestId.replace(/^.*?#/, ''); + + if (requestUrl in self[targetProp]) { + self[targetProp][requestUrl] = self[targetProp][requestUrl] || {}; + results = self[targetProp][requestUrl][requestIdentify] || { + children: [] + }; + for (i = 0; i < results.children.length; i++) { + child = results.children[i]; + if (child.tagName === 'pair' && child.key === 'normal') { + return self.getObjectById.call(self, child.styleIDs[0], targetProp, callback); + } + } + callback.call(self, results); + return; + } + + var loader = new KmlLoader(self.map, self.exec, { + url: requestUrl + }); + loader.parseKmlFile(function(camera, anotherKmlData) { + var extendProps = [ + {src: 'styles', dst: 'kmlStyles'}, + {src: 'schemas', dst: 'kmlSchemas'} + ]; + extendProps.forEach(function(property) { + var properties = anotherKmlData.get('kmlData')[property.src]; + self[property.dst][requestUrl] = {}; + + var keys = Object.keys(properties); + keys.forEach(function(key) { + self[property.dst][requestUrl][key] = properties[key]; + }); + }); + + self[targetProp][requestUrl] = self[targetProp][requestUrl] || {}; + results = self[targetProp][requestUrl][requestIdentify] || { + children: [] + }; + for (i = 0; i < results.children.length; i++) { + child = results.children[i]; + if (child.tagName === 'pair' && child.key === 'normal') { + return self.getObjectById.call(self, child.styleIDs[0], targetProp, callback); + } + } + return callback.call(self, results); + }); + return; + } + + requestId = requestId.replace('#', ''); + if (requestId in self[targetProp] === false) { + callback.call(self, {children: []}); + return; + } + results = self[targetProp][requestId]; + + results.children.filter(function(style) { + if (style.tagName !== 'pair') { + return true; + } + for (var j = 0; j < style.children.length; j++) { + if (style.children[j].tagName === 'key' && + style.children[j].value === 'highlight') { + return false; + } + } + return true; + }); + + var containPairTag = false; + for (i = 0; i < results.children.length; i++) { + if (results.children[i].tagName === 'pair') { + containPairTag = true; + break; + } + } + if (!containPairTag) { + callback.call(self, results); + return; + } + + //--------------------------------------------------------- + // should contain 'tagName = "key", value="normal"' only + //--------------------------------------------------------- + self.getObjectById.call(self, results.children[0].styleIDs[0], targetProp, function(resultSets) { + if (resultSets.children) { + results = resultSets; + } else { + results.children = resultSets; + } + callback.call(self, results); + }); + +}; + +KmlLoader.prototype.getStyleById = function(requestId, callback) { + this.getObjectById.call(this, requestId, 'kmlStyles', callback); +}; + +KmlLoader.prototype.getSchemaById = function(requestId, callback) { + this.getObjectById.call(this, requestId, 'kmlSchemas', callback); +}; + +KmlLoader.prototype.parseKmlTag = function(params, callback) { + var self = this; + switch (params.child.tagName) { + case 'kml': + case 'folder': + case 'placemark': + case 'document': + case 'multigeometry': + self.parseContainerTag.call(self, { + placeMark: params.child, + styles: params.styles, + attrHolder: JSON.parse(JSON.stringify(params.attrHolder)) + }, callback); + break; + + case 'photooverlay': + case 'point': + self.parsePointTag.call(self, { + child: params.child, + placeMark: params.placeMark, + styles: params.styles, + attrHolder: params.attrHolder + }, callback); + break; + case 'polygon': + self.parsePolygonTag.call(self, { + child: params.child, + placeMark: params.placeMark, + styles: params.styles, + attrHolder: params.attrHolder + }, callback); + break; + case 'linestring': + self.parseLineStringTag.call(self, { + child: params.child, + placeMark: params.placeMark, + styles: params.styles, + attrHolder: params.attrHolder + }, callback); + break; + + case 'groundoverlay': + self.parseGroundOverlayTag.call(self, { + child: params.child, + placeMark: params.placeMark, + styles: params.styles, + attrHolder: params.attrHolder + }, callback); + break; + case 'networklink': + self.parseNetworkLinkTag.call(self, { + child: params.child, + placeMark: params.placeMark, + styles: params.styles, + attrHolder: params.attrHolder + }, callback); + break; + + case 'lookat': + self.parseLookAtTag.call(self, { + child: params.child, + }, callback); + break; + + case 'extendeddata': + self.parseExtendedDataTag.call(self, { + child: params.child, + placeMark: params.placeMark, + styles: params.styles, + attrHolder: params.attrHolder + }, callback); + break; + default: + params.attrHolder[params.child.tagName] = params.child; + callback(); + } +}; + +KmlLoader.prototype.parseExtendedDataTag = function(params, callback) { + var self = this; + if (params.child && params.child.children) { + params.attrHolder.extendeddata = {}; + params.child.children.forEach(function(child) { + switch(child.tagName) { + case 'data': + child.children.forEach(function(data) { + var dataName = child.name.toLowerCase(); + switch(data.tagName) { + case 'displayname': + params.attrHolder.extendeddata[dataName + '/displayname'] = data.value; + break; + case 'value': + params.attrHolder.extendeddata[dataName] = data.value; + break; + default: + break; + } + }); + break; + case 'schemadata': + self.getSchemaById(child.schemaUrl, function(schemas) { + var schemaUrl = schemas.name; + schemas.children.forEach(function(simplefield) { + if (simplefield.tagName !== 'simplefield') { + return; + } + if ('children' in simplefield) { + simplefield.children.forEach(function(valueTag) { + var schemaPath = schemaUrl + '/' + simplefield.name + '/' + valueTag.tagName; + schemaPath = schemaPath.toLowerCase(); + params.attrHolder.extendeddata[schemaPath] = valueTag.value; + }); + } else { + var schemaPath = schemaUrl + '/' + simplefield.name; + schemaPath = schemaPath.toLowerCase(); + params.attrHolder.extendeddata[schemaPath] = simplefield.value; + } + }); + child.children.forEach(function(simpledata) { + var schemaPath = schemaUrl + '/' + simpledata.name; + schemaPath = schemaPath.toLowerCase(); + params.attrHolder.extendeddata[schemaPath] = simpledata.value; + }); + }); + break; + + default: + + child.children.forEach(function(data) { + params.attrHolder.extendeddata[child.tagName] = data; + }); + break; + } + }); + } + callback(); +}; + +KmlLoader.prototype.parseContainerTag = function(params, callback) { + var self = this; + + var keys = Object.keys(params.placeMark); + keys = keys.filter(function(key) { + return key !== 'children'; + }); + + //-------------------------------------------------------- + // Generate overlays or load another files...etc + //-------------------------------------------------------- + var children = new BaseArrayClass(params.placeMark.children); + children.mapAsync(function(child, cb) { + + //------------------------- + // Copy parent information + //------------------------- + keys.forEach(function(key) { + if (key in child === false) { + child[key] = params.placeMark[key]; + } + }); + //------------------------- + // read a child element + //------------------------- + self.kmlTagProcess.call(self, { + child: child, + placeMark: params.placeMark, + styles: params.styles, + attrHolder: params.attrHolder + }, cb); + }, function(overlays) { + overlays = overlays.filter(function(overlay) { + return !!overlay; + }); + var attrNames = Object.keys(params.attrHolder); + if (overlays.length === 0) { + overlays.push(new BaseClass()); + } + + if (params.placeMark.tagName === 'placemark') { + // attrNames.forEach(function(name) { + // switch(name) { + // case "extendeddata": + // overlays[0].set(name, params.attrHolder[name]); + // break; + // case "snippet": + // overlays[0].set("_snippet", params.attrHolder[name].value); + // break; + // default: + // overlays[0].set(name, params.attrHolder[name].value); + // break; + // } + // }); + + callback.call(self, overlays[0]); + } else { + var container = new BaseArrayClass(overlays); + Object.defineProperty(container, 'tagName', { + value: params.placeMark.tagName, + writable: false + }); + attrNames.forEach(function(name) { + switch(name) { + case 'extendeddata': + container.set(name, params.attrHolder[name]); + break; + default: + container.set(name, params.attrHolder[name].value); + break; + } + }); + callback.call(self, container); + } + }); +}; + +KmlLoader.prototype.parsePointTag = function(params, callback) { + var self = this; + //console.log("parsePointTag", params); + + //-------------- + // add a marker + //-------------- + var markerOptions = { + visible: true + }; + params.styles.children.forEach(function(child) { + switch (child.tagName) { + + // // Don't use this code because this replace original 'description' field. + // case "balloonstyle": + // child.children.forEach(function(style) { + // switch (style.tagName) { + // case "description": + // markerOptions.description = { + // value: style.value + // }; + // break; + // } + // }); + // break; + + case 'iconstyle': + child.children.forEach(function(style) { + switch (style.tagName) { + case 'hotspot': + markerOptions.icon = markerOptions.icon || {}; + markerOptions.icon.hotspot = style; + break; + case 'heading': + markerOptions.icon = markerOptions.icon || {}; + markerOptions.icon.rotation = style; + break; + case 'icon': + markerOptions.icon = markerOptions.icon || {}; + markerOptions.icon.url = style.children[0].value; + break; + // case "color": + // markerOptions.icon = markerOptions.icon || {}; + // markerOptions.icon.color = kmlColorToRGBA(style.value); + // break; + } + }); + break; + default: + + } + }); + + if (params.child.children) { + var options = new BaseClass(); + params.child.children.forEach(function(child) { + options.set(child.tagName, child); + }); + params.child.children.forEach(function(child) { + switch (child.tagName) { + case 'point': + var coordinates = findTag(child.children, 'coordinates', 'coordinates'); + if (coordinates) { + markerOptions.position = coordinates[0]; + } + break; + case 'coordinates': + markerOptions.position = child.coordinates[0]; + break; + // case "description": + // if (markerOptions.description) { + // markerOptions.description = templateRenderer(markerOptions.description, options); + // } + // markerOptions.description = templateRenderer(markerOptions.description, options); + // break; + // case "snippet": + // if (markerOptions.snippet) { + // markerOptions.snippet = templateRenderer(markerOptions.snippet, options); + // } + // markerOptions.snippet = templateRenderer(markerOptions.snippet, options); + // break; + default: + + } + }); + } + markerOptions.position = markerOptions.position || { + lat: 0, + lng: 0 + }; + + self.camera.target.push(markerOptions.position); + + var ignoreProperties = ['coordinates', 'styleIDs', 'children']; + (Object.keys(params.attrHolder)).forEach(function(pName) { + if (ignoreProperties.indexOf(pName) === -1 && + pName in markerOptions === false) { + if (pName === 'visibility') { + markerOptions.visible = params.attrHolder[pName].value != 0; + } else { + markerOptions[pName] = params.attrHolder[pName]; + } + } + }); + + //console.log(markerOptions); + self.map.addMarker(markerOptions, callback); +}; + +function findTag(children, tagName, fieldName) { + for (var i = 0; i < children.length; i++) { + if (children[i].tagName === tagName) { + return children[i][fieldName]; + } + } +} +KmlLoader.prototype.parsePolygonTag = function(params, callback) { + var self = this; + + // console.log('polygonPlacemark', params); + //-------------- + // add a polygon + //-------------- + var polygonOptions = { + fill: true, + outline: true, + holes: [], + strokeWidth: 1, + clickable: true, + visible: true + }; + params.child.children.forEach(function(element) { + var coordinates; + switch (element.tagName) { + case'visibility': + polygonOptions.visible=element.value!=0; + break; + case 'outerboundaryis': + if (element.children.length === 1) { + switch(element.children[0].tagName) { + case 'linearring': + coordinates = element.children[0].children[0].coordinates; + break; + case 'coordinates': + coordinates = findTag(element.children, 'coordinates', 'coordinates'); + break; + } + coordinates.forEach(function(latLng) { + self.camera.target.push(latLng); + }); + polygonOptions.points = coordinates; + } + break; + case 'innerboundaryis': + switch(element.children[0].tagName) { + case 'linearring': + coordinates = element.children[0].children[0].coordinates; + break; + case 'coordinates': + coordinates = element.children[0].coordinates; + break; + } + polygonOptions.holes.push(coordinates); + break; + } + }); + + params.styles.children.forEach(function(style) { + switch (style.tagName) { + case 'polystyle': + style.children.forEach(function(node) { + switch(node.tagName) { + case 'color': + polygonOptions.fillColor = kmlColorToRGBA(node.value); + break; + case 'fill': + polygonOptions.fill = node.value === '1'; + break; + case 'outline': + polygonOptions.outline = node.value === '1'; + break; + } + }); + break; + + + case 'linestyle': + style.children.forEach(function(node) { + switch(node.tagName) { + case 'color': + polygonOptions.strokeColor = kmlColorToRGBA(node.value); + break; + case 'width': + polygonOptions.strokeWidth = parseFloat(node.value); + break; + } + }); + break; + } + }); + + if (polygonOptions.fill === false) { + polygonOptions.fillColor = [0, 0, 0, 0]; + } else { + polygonOptions.fillColor = polygonOptions.fillColor || [255, 255, 255, 255]; + } + if (polygonOptions.outline === false) { + delete polygonOptions.strokeColor; + polygonOptions.strokeWidth = 0; + } else { + polygonOptions.strokeColor = polygonOptions.strokeColor || [255, 255, 255, 255]; + } + + + var ignoreProperties = ['coordinates', 'styleIDs', 'children']; + (Object.keys(params.attrHolder)).forEach(function(pName) { + if (ignoreProperties.indexOf(pName) === -1 && + pName in polygonOptions === false) { + polygonOptions[pName] = params.attrHolder[pName]; + } + }); + + // console.log('polygonOptions', polygonOptions); + self.map.addPolygon(polygonOptions, callback); + +}; + +KmlLoader.prototype.parseLineStringTag = function(params, callback) { + //console.log(JSON.parse(JSON.stringify(params))); + var self = this; + //-------------- + // add a polyline + //-------------- + var polylineOptions = { + points: [], + clickable: true, + visible: true + }; + if (params.child.children) { + params.child.children.forEach(function(child) { + if (child.tagName === 'visibility') { + polylineOptions.visible=child.value!=0; + } + if (child.tagName === 'coordinates') { + child.coordinates.forEach(function(latLng) { + self.camera.target.push(latLng); + polylineOptions.points.push(latLng); + }); + } + }); + } + + params.styles.children.forEach(function(style) { + switch (style.tagName) { + case 'linestyle': + case 'polystyle': + style.children.forEach(function(node) { + switch(node.tagName) { + case 'color': + polylineOptions.color = kmlColorToRGBA(node.value); + break; + case 'width': + polylineOptions.width = parseFloat(node.value); + break; + } + }); + break; + default: + + } + }); + + var ignoreProperties = ['coordinates', 'styleIDs', 'children']; + (Object.keys(params.attrHolder)).forEach(function(pName) { + if (ignoreProperties.indexOf(pName) === -1 && + pName in polylineOptions === false) { + polylineOptions[pName] = params.attrHolder[pName]; + } + }); + + + //console.log('polylinePlacemark', polylineOptions); + + self.map.addPolyline(polylineOptions, callback); + +}; + +KmlLoader.prototype.parseGroundOverlayTag = function(params, callback) { + var self = this; + // console.log('parseGroundOverlayTag', params); + + //-------------- + // add a ground overlay + //-------------- + var groundoveralyOptions = { + url: null, + bounds: [], + clickable: true, + visible: true + }; + + params.child.children.forEach(function(child) { + switch (child.tagName) { + case'visibility': + groundoveralyOptions.visible=child.value!=0; + break; + case 'color': + groundoveralyOptions.opacity = ((kmlColorToRGBA(child.value)).pop() / 256); + break; + case 'icon': + child.children.forEach(function(iconAttrNode) { + switch (iconAttrNode.tagName) { + case 'href': + groundoveralyOptions.url = iconAttrNode.value; + if (groundoveralyOptions.url && groundoveralyOptions.url.indexOf('://') === -1) { + var requestUrl = self.kmlUrl.replace(/\?.*$/, ''); + requestUrl = requestUrl.replace(/#.*$/, ''); + requestUrl = requestUrl.replace(/[^/]*$/, ''); + groundoveralyOptions.url = requestUrl + groundoveralyOptions.url; + } + break; + } + }); + break; + case 'latlonbox': + var box = {}; + child.children.forEach(function(latlonboxAttrNode) { + box[latlonboxAttrNode.tagName] = parseFloat(latlonboxAttrNode.value); + }); + if (box.rotation) { + groundoveralyOptions.bearing = box.rotation; + } + var ne = {lat: box.north, lng: box.east}; + var sw = {lat: box.south, lng: box.west}; + groundoveralyOptions.bounds.push(ne); + groundoveralyOptions.bounds.push(sw); + self.camera.target.push(ne); + self.camera.target.push(sw); + break; + // case "gx:latlonquad": + // groundoveralyOptions.bounds = child.children[0].coordinates; + // Array.prototype.push.apply(self.camera.target, child.children[0].coordinates); + // break; + default: + } + }); + //delete params.child.children; + // console.log("groundoveralyOptions", groundoveralyOptions); + + var ignoreProperties = ['coordinates', 'styleIDs', 'children']; + (Object.keys(params.attrHolder)).forEach(function(pName) { + if (ignoreProperties.indexOf(pName) === -1 && + pName in groundoveralyOptions === false) { + groundoveralyOptions[pName] = params.attrHolder[pName]; + } + }); + + self.map.addGroundOverlay(groundoveralyOptions, callback); +}; + +KmlLoader.prototype.parseNetworkLinkTag = function(params, callback) { + var self = this; + var networkLinkOptions = {}; + //console.log('parseNetworkLinkTag', params); + + var attrNames = Object.keys(params.attrHolder); + attrNames.forEach(function(attrName) { + switch(attrName.toLowerCase()) { + case 'region': + networkLinkOptions.region = networkLinkOptions.region || {}; + params.attrHolder[attrName].children.forEach(function(gChild) { + switch(gChild.tagName) { + case 'latlonaltbox': + var box = {}; + gChild.children.forEach(function(latlonboxAttrNode) { + box[latlonboxAttrNode.tagName] = parseFloat(latlonboxAttrNode.value); + }); + networkLinkOptions.region.bounds = { + se: {lat: box.south, lng: box.east}, + sw: {lat: box.south, lng: box.west}, + ne: {lat: box.north, lng: box.east}, + nw: {lat: box.north, lng: box.west} + }; + break; + case 'lod': + networkLinkOptions.region.lod = networkLinkOptions.region.lod || {}; + networkLinkOptions.region.lod.minlodpixels = networkLinkOptions.region.lod.minlodpixels || -1; + networkLinkOptions.region.lod.maxlodpixels = networkLinkOptions.region.lod.maxlodpixels || -1; + gChild.children.forEach(function(lodEle) { + networkLinkOptions.region.lod[lodEle.tagName] = parseInt(lodEle.value); + }); + break; + } + }); + break; + + default: + networkLinkOptions[attrName] = params.attrHolder[attrName]; + } + }); + + params.child.children.forEach(function(child) { + switch(child.tagName) { + case 'visibility': + networkLinkOptions.visibility = child.value === '1'; + break; + case 'link': + networkLinkOptions.link = networkLinkOptions.link || {}; + child.children.forEach(function(gChild) { + networkLinkOptions.link[gChild.tagName] = gChild.value; + }); + break; + case 'region': + networkLinkOptions.region = networkLinkOptions.region || {}; + child.children.forEach(function(gChild) { + switch(gChild.tagName) { + case 'latlonaltbox': + var box = {}; + gChild.children.forEach(function(latlonboxAttrNode) { + box[latlonboxAttrNode.tagName] = parseFloat(latlonboxAttrNode.value); + }); + networkLinkOptions.region.bounds = { + se: {lat: box.south, lng: box.east}, + sw: {lat: box.south, lng: box.west}, + ne: {lat: box.north, lng: box.east}, + nw: {lat: box.north, lng: box.west} + }; + break; + case 'lod': + networkLinkOptions.region.lod = networkLinkOptions.region.lod || {}; + networkLinkOptions.region.lod.minlodpixels = networkLinkOptions.region.lod.minlodpixels || -1; + networkLinkOptions.region.lod.maxlodpixels = networkLinkOptions.region.lod.maxlodpixels || -1; + gChild.children.forEach(function(lodEle) { + networkLinkOptions.region.lod[lodEle.tagName] = parseInt(lodEle.value); + }); + break; + } + }); + + } + }); + + //console.log(networkLinkOptions); + + if (!networkLinkOptions.link) { + // tag must contain tag. + // If not contained, simply ignore the tag. + return callback.call(self); + } + + + if (networkLinkOptions.link.href.indexOf('://') === -1 && networkLinkOptions.link.href.substr(0, 1) !== '/') { + var a = document.createElement('a'); + a.href = self.kmlUrl; + networkLinkOptions.link.href = a.protocol + '//' + a.host + ':' + a.port + a.pathname.replace(/\/[^/]+$/, '') + '/' + networkLinkOptions.link.href; + a = null; + } + + var networkOverlay = new BaseClass(); + networkOverlay.set('_loaded', false); + networkOverlay.set('_visible', false); + networkOverlay.on('_visible_changed', function(oldValue, newValue) { + var overlay = networkOverlay.get('overlay'); + if (newValue === true) { + if (overlay) { + overlay.setVisible(true); + } else { + self.map.addKmlOverlay({ + url: networkLinkOptions.link.href, + clickable: self.options.clickable, + suppressInfoWindows: self.options.suppressInfoWindows + }, function(overlay) { + networkOverlay.set('overlay', overlay); + }); + } + } else { + if (overlay) { + overlay.setVisible(false); + } + } + }); + self._overlays.push(networkOverlay); + + if (networkLinkOptions.region && networkLinkOptions.region.bounds) { + self.camera.target.push(networkLinkOptions.region.bounds.se); + self.camera.target.push(networkLinkOptions.region.bounds.sw); + self.camera.target.push(networkLinkOptions.region.bounds.ne); + self.camera.target.push(networkLinkOptions.region.bounds.nw); + } + // self.map.addPolygon({ + // 'points': [ + // networkLinkOptions.region.bounds.se, + // networkLinkOptions.region.bounds.sw, + // networkLinkOptions.region.bounds.nw, + // networkLinkOptions.region.bounds.ne + // ], + // 'strokeColor' : '#FFFFFF77', + // 'strokeWidth': 1, + // 'fillColor' : '#00000000' + // }, function(groundoverlay) { + + if (networkLinkOptions.region && networkLinkOptions.link.viewrefreshmode === 'onRegion') { + self.map.on(event.CAMERA_MOVE_END, function() { + var vRegion = self.map.getVisibleRegion(); + var nRegion = new VisibleRegion(networkLinkOptions.region.bounds.sw, networkLinkOptions.region.bounds.ne); + + if (vRegion.contains(networkLinkOptions.region.bounds.sw) || + vRegion.contains(networkLinkOptions.region.bounds.se) || + vRegion.contains(networkLinkOptions.region.bounds.nw) || + vRegion.contains(networkLinkOptions.region.bounds.ne) || + nRegion.contains(vRegion.farLeft) || + nRegion.contains(vRegion.farRight) || + nRegion.contains(vRegion.nearLeft) || + nRegion.contains(vRegion.nearRight)) { + + (new BaseArrayClass([ + networkLinkOptions.region.bounds.sw, + networkLinkOptions.region.bounds.ne + ]).mapAsync(function(latLng, next) { + self.map.fromLatLngToPoint(latLng, next); + }, function(points) { + var width = Math.abs(points[0][0] - points[1][0]); + var height = Math.abs(points[0][1] - points[1][1]); + + var maxCondition = (networkLinkOptions.region.lod.maxlodpixels === -1 || + width <= networkLinkOptions.region.lod.maxlodpixels && + height <= networkLinkOptions.region.lod.maxlodpixels); + var minCondition = (networkLinkOptions.region.lod.minlodpixels === -1 || + width >= networkLinkOptions.region.lod.minlodpixels && + height >= networkLinkOptions.region.lod.minlodpixels); + + if (maxCondition && minCondition) { + // groundoverlay.setVisible(true); + networkOverlay.set('_visible', true); + } else { + // groundoverlay.setVisible(false); + networkOverlay.set('_visible', false); + } + })); + } else { + // groundoverlay.setVisible(false); + networkOverlay.set('_visible', false); + } + }); + } else { + //------------------------------- + // Simply load another kml file + //------------------------------- + // groundoverlay.setVisible(true); + networkOverlay.set('_visible', networkLinkOptions.visibility); + } + + callback.call(networkOverlay); + //}); + +}; + +KmlLoader.prototype.parseLookAtTag = function(params, callback) { + var self = this; + + if ('latitude' in params.child && 'longitude' in params.child) { + self.camera.target = { + lat: parseFloat(params.child.latitude), + lng: parseFloat(params.child.longitude) + }; + } + if ('heading' in params.child) { + self.camera.bearing = parseInt(params.child.heading); + } + if ('tilt' in params.child) { + self.camera.tilt = parseInt(params.child.tilt); + } + + callback.call(self); +}; + + +//------------------------------- +// KML color (AABBGGRR) to RGBA +//------------------------------- +function kmlColorToRGBA(colorStr) { + var rgba = []; + colorStr = colorStr.replace('#', ''); + for (var i = 6; i >= 0; i -= 2) { + rgba.push(parseInt(colorStr.substring(i, i + 2), 16)); + } + return rgba; +} +//------------------------------- +// KML color (AABBGGRR) to rgba(RR, GG, BB, AA) +//------------------------------- +// function kmlColorToCSS(colorStr) { +// var rgba = []; +// colorStr = colorStr.replace('#', ''); +// for (var i = 6; i >= 0; i -= 2) { +// rgba.push(parseInt(colorStr.substring(i, i + 2), 16)); +// } +// return 'rgba(' + rgba.join(',') + ')'; +// } + +//------------------------------- +// Template engine +//------------------------------- +// function templateRenderer(html, marker) { +// if (!html) { +// return html; +// } +// var extendedData = marker.get('extendeddata'); +// +// return html.replace(/\$[{[](.+?)[}]]/gi, function(match, name) { +// var textProp = marker.get(name); +// var text = ''; +// if (textProp) { +// text = textProp.value; +// if (extendedData) { +// text = text.replace(/\$[{[](.+?)[}]]/gi, function(match1, name1) { +// var extProp = extendedData[name1.toLowerCase()]; +// var extValue = '${' + name1 + '}'; +// if (extProp) { +// extValue = extProp.value; +// } +// return extValue; +// }); +// } +// } +// return text; +// }); +// } + + +module.exports = KmlLoader; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/KmlOverlay.js b/docs/plugins/cordova-plugin-googlemaps/www/KmlOverlay.js new file mode 100644 index 0000000..7ff338f --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/KmlOverlay.js @@ -0,0 +1,370 @@ +cordova.define("cordova-plugin-googlemaps.KmlOverlay", function(require, exports, module) { +var utils = require('cordova/utils'), + common = require('./Common'), + BaseClass = require('./BaseClass'), + event = require('./event'), + BaseArrayClass = require('./BaseArrayClass'), + HtmlInfoWindow = require('./HtmlInfoWindow'); + +var XElement = null; +window.addEventListener('WebComponentsReady', function () { + var XElementPrototype = Object.create(HTMLElement.prototype); + XElement = document.registerElement('pgm-sandbox', { + prototype: XElementPrototype + }); +}); + +/***************************************************************************** + * KmlOverlay Class + *****************************************************************************/ +var KmlOverlay = function (map, kmlId, camera, kmlData, kmlOverlayOptions) { + BaseClass.apply(this); + + var self = this; + //self.set('visible', kmlOverlayOptions.visible === undefined ? true : kmlOverlayOptions.visible); + //self.set('zIndex', kmlOverlayOptions.zIndex || 0); + Object.defineProperty(self, '_isReady', { + value: true, + writable: false + }); + Object.defineProperty(self, 'type', { + value: 'KmlOverlay', + writable: false + }); + Object.defineProperty(self, '__pgmId', { + value: kmlId, + writable: false + }); + Object.defineProperty(self, 'map', { + value: map, + writable: false + }); + Object.defineProperty(self, 'camera', { + value: camera, + writable: false + }); + Object.defineProperty(self, 'kmlData', { + value: kmlData, + writable: false + }); + + + function templateRenderer(html, marker) { + var extendedData = marker.get('extendeddata'); + + return html.replace(/\$[{\\[](.+?)[}\]]/gi, function(match, name) { + var text = ''; + if (marker.get(name)) { + text = marker.get(name).value || ''; + } + if (extendedData && text) { + text = text.replace(/\$[{\\[](.+?)[}\]]/gi, function(match1, name1) { + return extendedData[name1.toLowerCase()] || ''; + }); + } + return text; + }); + } + + function parseBalloonStyle(balloonStyle) { + var css = {}; + var hasBgColor = false; + var keys = Object.keys(balloonStyle); + keys.forEach(function (key) { + switch (key.toLowerCase()) { + case 'bgcolor': + hasBgColor = true; + ballon.setBackgroundColor(common.kmlColorToCSS(balloonStyle[key])); + break; + case 'textcolor': + css.color = common.kmlColorToCSS(balloonStyle[key]); + break; + } + }); + if (!hasBgColor) { + ballon.setBackgroundColor('white'); + } + return css; + } + + self.set('clickable', kmlOverlayOptions.clickable); + + var ballon = new HtmlInfoWindow(); + var onOverlayClick = function (position, overlay) { + if (!self.get('clickable')) { + return; + } + self.trigger(event.KML_CLICK, overlay, position); + + if (kmlOverlayOptions.suppressInfoWindows) { + return; + } + + var description = overlay.get('description'); + if (!description && overlay.get('extendeddata')) { + var extendeddata = overlay.get('extendeddata'); + var keys = Object.keys(extendeddata); + var table = []; + keys.forEach(function (key) { + if (extendeddata[key] !== '' && extendeddata[key] !== null && extendeddata[key] !== undefined) { + table.push('' + key + '' + extendeddata[key] + ''); + } + }); + if (table.length > 0) { + table.unshift(''); + table.push('
'); + description = { + value: table.join('') + }; + overlay.set('description', description); + } + } + + var html = []; + var result; + var descriptionTxt = ''; + if (description && description.value) { + descriptionTxt = description.value; + } + if (description && (descriptionTxt.indexOf('') > -1 || descriptionTxt.indexOf('script') > -1)) { + var text = templateRenderer(descriptionTxt, overlay); + // create a sandbox + // if (text.indexOf(''; + // } + result = document.createElement('div'); + if (overlay.get('name') && overlay.get('name').value) { + var name = document.createElement('div'); + name.style.fontWeight = 500; + name.style.fontSize = 'medium'; + name.style.marginBottom = 0; + name.style.whiteSpace = 'pre'; + name.innerText = overlay.get('name').value || ''; + result.appendChild(name); + } + if (overlay.get('snippet') && overlay.get('snippet').value.length > 0) { + var snippet = document.createElement('div'); + snippet.style.fontWeight = 300; + snippet.style.fontSize = 'small'; + snippet.style.whiteSpace = 'normal'; + snippet.style.whiteSpace = 'pre'; + snippet.style.fontFamily = 'Roboto,Arial,sans-serif'; + snippet.innerText = overlay.get('snippet').value || ''; + result.appendChild(snippet); + } + + if (text && text.length > 0) { + if (XElement) { + var xElement = new XElement(); + xElement.innerHTML = text; + result.appendChild(xElement); + } else { + + var iframe = document.createElement('iframe'); + iframe.sandbox = 'allow-scripts allow-same-origin'; + iframe.frameBorder = 'no'; + iframe.scrolling = 'yes'; + iframe.style.overflow = 'hidden'; + iframe.addEventListener('load', function () { + iframe.contentWindow.document.open(); + iframe.contentWindow.document.write(text); + iframe.contentWindow.document.close(); + }, { + once: true + }); + result.appendChild(iframe); + + } + } + + } else { + if (overlay.get('description')) { + html.push('
${description}
'); + } else { + if (overlay.get('name')) { + html.push('
${name}
'); + } + if (overlay.get('_snippet')) { + html.push('
${_snippet}
'); + } + } + var prevMatchedCnt = 0; + result = html.join(''); + var matches = result.match(/\$[{\\[].+?[}\]]/gi); + while(matches && matches.length !== prevMatchedCnt) { + prevMatchedCnt = matches.length; + result = templateRenderer(result, overlay); + matches = result.match(/\$[{\\[].+?[}\]]/gi); + } + } + var styles = null; + if (overlay.get('balloonstyle')) { + styles = parseBalloonStyle(overlay.get('balloonstyle')); + } + styles = styles || {}; + styles.overflow = 'scroll'; + styles['max-width'] = (map.getDiv().offsetWidth * 0.8) + 'px'; + styles['max-height'] = (map.getDiv().offsetHeight * 0.6) + 'px'; + + ballon.setContent(result, styles); + var marker = map.get('invisible_dot'); + if (overlay.type === 'Marker') { + marker.setVisible(false); + ballon.open(overlay); + } else { + marker.setPosition(position); + marker.setVisible(true); + marker.off(event.MARKER_CLICK); + map.animateCamera({ + target: position, + duration: 300 + }, function () { + marker.setAnimation(window.plugin.google.maps.Animation.DROP, function () { + marker.on(event.MARKER_CLICK, function () { + ballon.open(marker); + }); + marker.trigger(event.MARKER_CLICK); + }); + }); + + } + }; + + var eventNames = { + 'Marker': event.MARKER_CLICK, + 'Polyline': event.POLYLINE_CLICK, + 'Polygon': event.POLYGON_CLICK, + 'GroundOverlay': event.GROUND_OVERLAY_CLICK + }; + var seekOverlays = function (overlay) { + if (overlay instanceof BaseArrayClass) { + overlay.forEach(seekOverlays); + } else if (Array.isArray(overlay)) { + (new BaseArrayClass(overlay)).forEach(seekOverlays); + } else if (overlay instanceof BaseClass && overlay.type in eventNames) { + overlay.on(eventNames[overlay.type], onOverlayClick); + } + }; + + kmlData.forEach(seekOverlays); + + /* + var ignores = ['map', '__pgmId', 'hashCode', 'type']; + for (var key in kmlOverlayOptions) { + if (ignores.indexOf(key) === -1) { + self.set(key, kmlOverlayOptions[key]); + } + } + */ +}; + +utils.extend(KmlOverlay, BaseClass); + +KmlOverlay.prototype.getPluginName = function () { + return this.map.getId() + '-kmloverlay'; +}; + +KmlOverlay.prototype.getHashCode = function () { + return this.hashCode; +}; + +KmlOverlay.prototype.getDefaultViewport = function () { + return this.camera; +}; +KmlOverlay.prototype.getKmlData = function () { + return this.kmlData; +}; +KmlOverlay.prototype.getMap = function () { + return this.map; +}; +KmlOverlay.prototype.getId = function () { + return this.__pgmId; +}; + +KmlOverlay.prototype.setClickable = function (clickable) { + clickable = common.parseBoolean(clickable); + this.set('clickable', clickable); + return this; +}; + +KmlOverlay.prototype.getClickable = function () { + return this.get('clickable'); +}; + +KmlOverlay.prototype.getVisible = function () { + return this.get('visible'); +}; + +KmlOverlay.prototype.setVisible = function (visible) { + var self = this; + if (self._isRemoved) { + return; + } + + visible = common.parseBoolean(visible); + this.set('visible', visible); + + var applyChildren = function (children) { + children.forEach(function (child) { + if ('setVisible' in child && + typeof child.setVisible === 'function') { + child.setVisible(visible); + return; + } + if (child instanceof BaseArrayClass) { + applyChildren(child); + return; + } + }); + }; + + applyChildren(self.kmlData); +}; + +KmlOverlay.prototype.remove = function (callback) { + var self = this; + if (self._isRemoved) { + if (typeof callback === 'function') { + return; + } else { + return Promise.resolve(); + } + } + Object.defineProperty(self, '_isRemoved', { + value: true, + writable: false + }); + + var removeChildren = function (children, cb) { + children.forEach(function (child, next) { + if ('remove' in child && + typeof child.remove === 'function') { + child.remove(next); + return; + } + if (child instanceof BaseArrayClass) { + removeChildren(child, next); + return; + } + next(); + }, cb); + }; + + var resolver = function (resolve) { + removeChildren(self.kmlData, function () { + self.destroy(); + resolve.call(self); + }); + }; + + if (typeof callback === 'function') { + resolver.call(self, callback, null); + return; + } else { + return Promise.resolve(); + } +}; + +module.exports = KmlOverlay; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/LatLng.js b/docs/plugins/cordova-plugin-googlemaps/www/LatLng.js new file mode 100644 index 0000000..b876ea5 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/LatLng.js @@ -0,0 +1,53 @@ +cordova.define("cordova-plugin-googlemaps.LatLng", function(require, exports, module) { /******************************************************************************* + * @name LatLng + * @class This class represents new camera position + * @param {Number} latitude + * @param {Number} longitude + ******************************************************************************/ +function LatLng(latitude, longitude) { + var self = this; + /** + * @property {Number} latitude + */ + self.lat = parseFloat(latitude || 0, 10); + + /** + * @property {Number} longitude + */ + self.lng = parseFloat(longitude || 0, 10); +} + +LatLng.prototype = { + /** + * Comparison function. + * @method + * @return {Boolean} + */ + equals: function(other) { + other = other || {}; + return other.lat === this.lat && + other.lng === this.lng; + }, + + /** + * @method + * @return {String} latitude,lontitude + */ + toString: function() { + return '{"lat": ' + this.lat + ', "lng": ' + this.lng + '}'; + }, + + /** + * @method + * @param {Number} + * @return {String} latitude,lontitude + */ + toUrlValue: function(precision) { + precision = precision || 6; + return '{"lat": ' + this.lat.toFixed(precision) + ', "lng": ' + this.lng.toFixed(precision) + '}'; + } +}; + +module.exports = LatLng; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/LatLngBounds.js b/docs/plugins/cordova-plugin-googlemaps/www/LatLngBounds.js new file mode 100644 index 0000000..6967c89 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/LatLngBounds.js @@ -0,0 +1,132 @@ +cordova.define("cordova-plugin-googlemaps.LatLngBounds", function(require, exports, module) { var LatLng = require('./LatLng'); + +/***************************************************************************** + * LatLngBounds Class + *****************************************************************************/ +var LatLngBounds = function () { + Object.defineProperty(this, 'type', { + value: 'LatLngBounds', + writable: false + }); + + var args = []; + if (arguments.length === 1 && + typeof arguments[0] === 'object' && + 'push' in arguments[0]) { + args = arguments[0]; + } else { + args = Array.prototype.slice.call(arguments, 0); + } + + for (var i = 0; i < args.length; i++) { + if (args[i] && 'lat' in args[i] && 'lng' in args[i]) { + this.extend(args[i]); + } + } +}; + +LatLngBounds.prototype.northeast = null; +LatLngBounds.prototype.southwest = null; + +LatLngBounds.prototype.toString = function () { + return '{"southwest":' + this.southwest.toString() + ', "northeast":' + this.northeast.toString() + '}'; +}; +LatLngBounds.prototype.toUrlValue = function (precision) { + precision = precision || 6; + return '[' + this.southwest.toUrlValue(precision) + ',' + this.northeast.toUrlValue(precision) + ']'; +}; + +LatLngBounds.prototype.extend = function (latLng) { + if (latLng && 'lat' in latLng && 'lng' in latLng) { + if (!this.southwest && !this.northeast) { + this.southwest = latLng; + this.northeast = latLng; + } else { + var south = Math.min(latLng.lat, this.southwest.lat); + var north = Math.max(latLng.lat, this.northeast.lat); + + var west = this.southwest.lng, + east = this.northeast.lng; + + if (west > 0 && east < 0) { + if (latLng.lng > 0) { + west = Math.min(latLng.lng, west); + } else { + east = Math.max(latLng.lng, east); + } + } else { + + west = Math.min(latLng.lng, this.southwest.lng); + east = Math.max(latLng.lng, this.northeast.lng); + } + + delete this.southwest; + delete this.northeast; + this.southwest = new LatLng(south, west); + this.northeast = new LatLng(north, east); + } + } +}; + +LatLngBounds.prototype.getCenter = function () { + var centerLat = (this.southwest.lat + this.northeast.lat) / 2; + + var swLng = this.southwest.lng; + var neLng = this.northeast.lng; + var sumLng = swLng + neLng; + var centerLng = sumLng / 2; + + if ((swLng > 0 && neLng < 0 && sumLng < 180)) { + centerLng += sumLng > 0 ? -180 : 180; + } + return new LatLng(centerLat, centerLng); +}; +LatLngBounds.prototype.contains = function (latLng) { + if (!latLng || !('lat' in latLng) || !('lng' in latLng)) { + return false; + } + var y = latLng.lat, + x = latLng.lng; + + var y90 = y + 90; + var south = this.southwest.lat, + north = this.northeast.lat, + west = this.southwest.lng, + east = this.northeast.lng; + var south90 = south + 90, + north90 = north + 90; + + var containX = false, + containY = false; + + if (west <= 0 && east <= 0 && west <= east) { + if (x > 0) { + containX = false; + } else { + containX = (west <= x && x <= east); + } + } else if (east <= 0 && west > 0 && east <= west) { + if (x > 0) { + containX = (x >= west && x <= 180); + } else { + containX = (-180 <= x && x <= west); + } + } else if (west <= 0 && east > 0 && west <= east) { + if (x < 0) { + containX = (west <= x && x <= 0); + } else { + containX = (x >= 0 && x <= east); + } + } else { + containX = (west <= x && x <= east); + } + + containY = (south90 <= y90 && y90 <= north90) || //#a + (south >= 0 && north <= 0 && ((south <= y && y <= 90) || (y >= -90 && y <= north))); // #d + + return containX && containY; +}; + +module.exports = LatLngBounds; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Location.js b/docs/plugins/cordova-plugin-googlemaps/www/Location.js new file mode 100644 index 0000000..745915e --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Location.js @@ -0,0 +1,20 @@ +cordova.define("cordova-plugin-googlemaps.Location", function(require, exports, module) { /***************************************************************************** + * Location Class + *****************************************************************************/ +var LatLng = require('./LatLng'); +var Location = function(params) { + var self = this; + self.latLng = params.latLng || new LatLng(params.lat || 0, params.lng || 0); + self.elapsedRealtimeNanos = params.elapsedRealtimeNanos; + self.time = params.time; + self.accuracy = params.accuracy || null; + self.bearing = params.bearing || null; + self.altitude = params.altitude || null; + self.speed = params.speed || null; + self.provider = params.provider; + self.hashCode = params.hashCode; +}; + +module.exports = Location; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/LocationService.js b/docs/plugins/cordova-plugin-googlemaps/www/LocationService.js new file mode 100644 index 0000000..17da61a --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/LocationService.js @@ -0,0 +1,116 @@ +cordova.define("cordova-plugin-googlemaps.LocationService", function(require, exports, module) { /***************************************************************************** + * LocationService class + *****************************************************************************/ +var LatLng = require('./LatLng'); + +var LocationService = function(exec) { + function _errorHandler(err) { + console.error(err); + } + return { + hasPermission: function(callback, errorCallback) { + var self = this; + + var resolver = function(resolve, reject) { + exec.call({ + _isReady: true + }, + function(hasPermission) { + resolve.call(self, hasPermission === 1); + }, + reject.bind(self), 'PluginLocationService', 'hasPermission', [], {sync: true}); + }; + + var errorHandler = function(result) { + if (typeof errorCallback === 'function') { + errorCallback.call(self, result); + } else { + (self.errorHandler || _errorHandler).call(self, result); + } + }; + if (typeof callback === 'function') { + resolver(callback, errorHandler); + return self; + } else { + return new Promise(resolver); + } + }, + getMyLocation: function(params, success_callback, errorCallback) { + var self = this; + var args = [params || {}, success_callback || null, errorCallback]; + if (typeof args[0] === 'function') { + args.unshift({}); + } + params = args[0]; + success_callback = args[1]; + errorCallback = args[2]; + + + var resolver = function(resolve, reject) { + exec.call({ + _isReady: true + }, + function(location) { + location.latLng = new LatLng(location.latLng.lat, location.latLng.lng); + resolve.call(self, location); + }, + reject.bind(self), 'PluginLocationService', 'getMyLocation', [params], {sync: true}); + }; + + params.enableHighAccuracy = params.enableHighAccuracy === true; + var errorHandler = function(result) { + if (typeof errorCallback === 'function') { + errorCallback.call(self, result); + } else { + (self.errorHandler || _errorHandler).call(self, result); + } + }; + + if (typeof success_callback === 'function') { + resolver(success_callback, errorHandler); + return self; + } else { + return new Promise(resolver); + } + } + }; +}; + +/** + // TODO: +LocationService.prototype.followMyPosition = function(params, success_callback, errorCallback) { + var self = this; + var args = [params || {}, success_callback || null, errorCallback]; + if (typeof args[0] === 'function') { + args.unshift({}); + } + self.on('currentPosition_changed', success_callback); + var successHandler = function(location) { + location.latLng = new LatLng(location.latLng.lat, location.latLng.lng); + if (typeof success_callback === 'function') { + success_callback.call(self, location); + } + self.set('currentPosition', location); + }; + var errorHandler = function(result) { + if (typeof errorCallback === 'function') { + errorCallback.call(self, result); + } + }; + exec.call({ + _isReady: true + }, successHandler, errorHandler, 'CordovaGoogleMaps', 'followMyPosition', [params], {sync: true}); +}; + +LocationService.prototype.clearFollowing = function() { + var self = this; + self.off('currentPosition_changed'); + exec.call({ + _isReady: true + }, successHandler, errorHandler, 'CordovaGoogleMaps', 'clearFollowing', [params], {sync: true}); +}; +**/ + +module.exports = LocationService; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Map.js b/docs/plugins/cordova-plugin-googlemaps/www/Map.js new file mode 100644 index 0000000..f87a92e --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Map.js @@ -0,0 +1,1534 @@ +cordova.define("cordova-plugin-googlemaps.Map", function(require, exports, module) { + +var utils = require('cordova/utils'), + cordova_exec = require('cordova/exec'), + common = require('./Common'), + Overlay = require('./Overlay'), + BaseClass = require('./BaseClass'), + BaseArrayClass = require('./BaseArrayClass'), + LatLng = require('./LatLng'), + MapTypeId = require('./MapTypeId'), + event = require('./event'), + VisibleRegion = require('./VisibleRegion'), + Marker = require('./Marker'), + Circle = require('./Circle'), + Polyline = require('./Polyline'), + Polygon = require('./Polygon'), + TileOverlay = require('./TileOverlay'), + GroundOverlay = require('./GroundOverlay'), + KmlOverlay = require('./KmlOverlay'), + KmlLoader = require('./KmlLoader'), + MarkerCluster = require('./MarkerCluster'); + +/** + * Google Maps model. + */ +var exec; +var Map = function(__pgmId, _exec) { + var self = this; + exec = _exec; + Overlay.call(self, self, {}, 'Map', _exec, { + __pgmId: __pgmId + }); + delete self.map; + + + self.set('myLocation', false); + self.set('myLocationButton', false); + + self.MARKERS = {}; + self.OVERLAYS = {}; + + var infoWindowLayer = document.createElement('div'); + infoWindowLayer.style.position = 'absolute'; + infoWindowLayer.style.left = 0; + infoWindowLayer.style.top = 0; + infoWindowLayer.style.width = 0; + infoWindowLayer.style.height = 0; + infoWindowLayer.style.overflow = 'visible'; + infoWindowLayer.style['z-index'] = 1; + + Object.defineProperty(self, '_layers', { + value: { + info: infoWindowLayer + }, + enumerable: false, + writable: false + }); + + self.on(event.MAP_CLICK, function() { + self.set('active_marker', undefined); + }); + + self.on('active_marker_changed', function(prevMarker, newMarker) { + var newMarkerId = newMarker ? newMarker.getId() : null; + if (prevMarker) { + prevMarker.hideInfoWindow.call(prevMarker); + } + self.exec.call(self, null, null, self.__pgmId, 'setActiveMarkerId', [newMarkerId]); + }); +}; + +utils.extend(Map, Overlay); + +/** + * @desc Recalculate the position of HTML elements + */ +Map.prototype.refreshLayout = function() { + this.exec.call(this, null, null, this.__pgmId, 'resizeMap', []); +}; + +Map.prototype.getMap = function(meta, div, options) { + var self = this, + args = [meta]; + options = options || {}; + + self.set('clickable', options.clickable === false ? false : true); + self.set('visible', options.visible === false ? false : true); + + if (options.controls) { + this.set('myLocation', options.controls.myLocation === true); + this.set('myLocationButton', options.controls.myLocationButton === true); + } + + if (options.preferences && options.preferences.gestureBounds) { + if (utils.isArray(options.preferences.gestureBounds) || + options.preferences.gestureBounds.type === 'LatLngBounds') { + options.preferences.gestureBounds = common.convertToPositionArray(options.preferences.gestureBounds); + } + } + + if (!common.isDom(div)) { + self.set('visible', false); + options = div; + options = options || {}; + if (options.camera) { + if (options.camera.latLng) { + options.camera.target = options.camera.latLng; + delete options.camera.latLng; + } + this.set('camera', options.camera); + if (options.camera.target) { + this.set('camera_target', options.camera.target); + } + if (options.camera.bearing) { + this.set('camera_bearing', options.camera.bearing); + } + if (options.camera.zoom) { + this.set('camera_zoom', options.camera.zoom); + } + if (options.camera.tilt) { + this.set('camera_tilt', options.camera.tilt); + } + } + args.push(options); + } else { + + var positionCSS = common.getStyle(div, 'position'); + if (!positionCSS || positionCSS === 'static') { + // important for HtmlInfoWindow + div.style.position = 'relative'; + } + options = options || {}; + if (options.camera) { + if (options.camera.latLng) { + options.camera.target = options.camera.latLng; + delete options.camera.latLng; + } + this.set('camera', options.camera); + if (options.camera.target) { + this.set('camera_target', options.camera.target); + } + if (options.camera.bearing) { + this.set('camera_bearing', options.camera.bearing); + } + if (options.camera.zoom) { + this.set('camera_zoom', options.camera.zoom); + } + if (options.camera.tilt) { + this.set('camera_tilt', options.camera.tilt); + } + } + if (utils.isArray(options.styles)) { + options.styles = JSON.stringify(options.styles); + } + args.push(options); + + div.style.overflow = 'hidden'; + self.set('div', div); + + if (div.offsetWidth < 100 || div.offsetHeight < 100) { + // If the map Div is too small, wait a little. + var callee = arguments.callee; + setTimeout(function() { + callee.call(self, meta, div, options); + }, 250 + Math.random() * 100); + return; + } + + // Gets the map div size. + // The plugin needs to consider the viewport zoom ratio + // for the case window.innerHTML > body.offsetWidth. + var elemId = common.getPluginDomId(div); + args.push(elemId); + + } + + exec.call({ + _isReady: true + }, function() { + + //------------------------------------------------------------------------ + // Clear background colors of map div parents after the map is created + //------------------------------------------------------------------------ + var div = self.get('div'); + if (common.isDom(div)) { + + // Insert the infoWindow layer + if (self._layers.info.parentNode) { + try { + self._layers.info.parentNode.removeChild(self._layers.info.parentNode); + } catch (e) { + // ignore + } + } + var positionCSS; + for (var i = 0; i < div.children.length; i++) { + positionCSS = common.getStyle(div.children[i], 'position'); + if (positionCSS === 'static') { + div.children[i].style.position = 'relative'; + } + } + div.insertBefore(self._layers.info, div.firstChild); + + + while (div.parentNode) { + div.style.backgroundColor = 'rgba(0,0,0,0) !important'; + + // Add _gmaps_cdv_ class + common.attachTransparentClass(div); + + div = div.parentNode; + } + } + cordova.fireDocumentEvent('plugin_touch', { + force: true + }); + + //------------------------------------------------------------------------ + // In order to work map.getVisibleRegion() correctly, wait a little. + //------------------------------------------------------------------------ + var waitCnt = 0; + var waitCameraSync = function() { + if (!self.getVisibleRegion() && (waitCnt++ < 10)) { + setTimeout(function() { + common.nextTick(waitCameraSync); + }, 100); + return; + } + + + self._privateInitialize(); + delete self._privateInitialize; + self.refreshLayout(); + self.trigger(event.MAP_READY, self); + }; + setTimeout(function() { + common.nextTick(waitCameraSync); + }, 100); + }, self.errorHandler, 'CordovaGoogleMaps', 'getMap', args, { + sync: true + }); +}; + +Map.prototype.setOptions = function(options) { + options = options || {}; + + if (options.controls) { + var myLocation = this.get('myLocation'); + if ('myLocation' in options.controls) { + myLocation = options.controls.myLocation === true; + } + var myLocationButton = this.get('myLocationButton'); + if ('myLocationButton' in options.controls) { + myLocationButton = options.controls.myLocationButton === true; + } + this.set('myLocation', myLocation); + this.set('myLocationButton', myLocationButton); + if (myLocation === true || myLocation === false) { + options.controls.myLocation = myLocation; + } + if (myLocationButton === true || myLocationButton === false) { + options.controls.myLocationButton = myLocationButton; + } + } + if (options.camera) { + if (options.camera.latLng) { + options.camera.target = options.camera.latLng; + delete options.camera.latLng; + } + this.set('camera', options.camera); + if (options.camera.target) { + this.set('camera_target', options.camera.target); + } + if (options.camera.bearing) { + this.set('camera_bearing', options.camera.bearing); + } + if (options.camera.zoom) { + this.set('camera_zoom', options.camera.zoom); + } + if (options.camera.tilt) { + this.set('camera_tilt', options.camera.tilt); + } + } + + if (options.preferences && options.preferences.gestureBounds) { + if (utils.isArray(options.preferences.gestureBounds) || + options.preferences.gestureBounds.type === 'LatLngBounds') { + options.preferences.gestureBounds = common.convertToPositionArray(options.preferences.gestureBounds); + } + } + + if (utils.isArray(options.styles)) { + options.styles = JSON.stringify(options.styles); + } + this.exec.call(this, null, this.errorHandler, this.__pgmId, 'setOptions', [options]); + return this; +}; + +Map.prototype.getMyLocation = function(params, success_callback, error_callback) { + return window.plugin.google.maps.LocationService.getMyLocation.call(this, params, success_callback, error_callback); +}; + +Map.prototype.setCameraTarget = function(latLng) { + this.set('camera_target', latLng); + this.exec.call(this, null, this.errorHandler, this.__pgmId, 'setCameraTarget', [latLng.lat, latLng.lng]); + return this; +}; + +Map.prototype.setCameraZoom = function(zoom) { + this.set('camera_zoom', zoom); + this.exec.call(this, null, this.errorHandler, this.__pgmId, 'setCameraZoom', [zoom], { + sync: true + }); + return this; +}; +Map.prototype.panBy = function(x, y) { + x = parseInt(x, 10); + y = parseInt(y, 10); + this.exec.call(this, null, this.errorHandler, this.__pgmId, 'panBy', [x, y], { + sync: true + }); + return this; +}; + +/** + * Clears all markup that has been added to the map, + * including markers, polylines and ground overlays. + */ +Map.prototype.clear = function(callback) { + var self = this; + if (self._isRemoved) { + // Simply ignore because this map is already removed. + return Promise.resolve(); + } + + // Close the active infoWindow + var active_marker = self.get('active_marker'); + if (active_marker) { + active_marker.trigger(event.INFO_CLOSE); + } + + var clearObj = function(obj) { + var ids = Object.keys(obj); + var id, instance; + for (var i = 0; i < ids.length; i++) { + id = ids[i]; + instance = obj[id]; + if (instance) { + if (typeof instance.remove === 'function') { + instance.remove(); + } + instance.off(); + delete obj[id]; + } + } + obj = {}; + }; + + clearObj(self.OVERLAYS); + clearObj(self.MARKERS); + self.trigger('map_clear'); + + var resolver = function(resolve, reject) { + self.exec.call(self, + resolve.bind(self), + reject.bind(self), + self.__pgmId, 'clear', [], { + sync: true + }); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } + +}; + +/** + * @desc Change the map type + * @param {String} mapTypeId Specifies the one of the follow strings: + * MAP_TYPE_HYBRID + * MAP_TYPE_SATELLITE + * MAP_TYPE_TERRAIN + * MAP_TYPE_NORMAL + * MAP_TYPE_NONE + */ +Map.prototype.setMapTypeId = function(mapTypeId) { + if (mapTypeId !== MapTypeId[mapTypeId.replace('MAP_TYPE_', '')]) { + return this.errorHandler('Invalid MapTypeId was specified.'); + } + this.set('mapTypeId', mapTypeId); + this.exec.call(this, null, this.errorHandler, this.__pgmId, 'setMapTypeId', [mapTypeId]); + return this; +}; + +/** + * @desc Change the map view angle + * @param {Number} tilt The angle + */ +Map.prototype.setCameraTilt = function(tilt) { + this.set('camera_tilt', tilt); + this.exec.call(this, null, this.errorHandler, this.__pgmId, 'setCameraTilt', [tilt], { + sync: true + }); + return this; +}; + +/** + * @desc Change the map view bearing + * @param {Number} bearing The bearing + */ +Map.prototype.setCameraBearing = function(bearing) { + this.set('camera_bearing', bearing); + this.exec.call(this, null, this.errorHandler, this.__pgmId, 'setCameraBearing', [bearing], { + sync: true + }); + return this; +}; + +Map.prototype.moveCameraZoomIn = function(callback) { + var self = this; + var cameraPosition = self.get('camera'); + cameraPosition.zoom++; + cameraPosition.zoom = cameraPosition.zoom < 0 ? 0 : cameraPosition.zoom; + + return self.moveCamera(cameraPosition, callback); + +}; +Map.prototype.moveCameraZoomOut = function(callback) { + var self = this; + var cameraPosition = self.get('camera'); + cameraPosition.zoom--; + cameraPosition.zoom = cameraPosition.zoom < 0 ? 0 : cameraPosition.zoom; + + return self.moveCamera(cameraPosition, callback); +}; +Map.prototype.animateCameraZoomIn = function(callback) { + var self = this; + var cameraPosition = self.get('camera'); + cameraPosition.zoom++; + cameraPosition.zoom = cameraPosition.zoom < 0 ? 0 : cameraPosition.zoom; + cameraPosition.duration = 500; + return self.animateCamera(cameraPosition, callback); +}; +Map.prototype.animateCameraZoomOut = function(callback) { + var self = this; + var cameraPosition = self.get('camera'); + cameraPosition.zoom--; + cameraPosition.zoom = cameraPosition.zoom < 0 ? 0 : cameraPosition.zoom; + cameraPosition.duration = 500; + return self.animateCamera(cameraPosition, callback); +}; +/** + * Move the map camera with animation + * @name animateCamera + * @param {CameraPosition} cameraPosition - New camera position + * @param {Function} [callback] - This callback is involved when the animation is completed. + * @return {Promise} if you omit `callback`. + */ +Map.prototype.animateCamera = function(cameraPosition, callback) { + var self = this, + error; + + var target = cameraPosition.target; + if (!target && 'position' in cameraPosition) { + target = cameraPosition.position; + } + if (!target) { + error = new Error('No target field is specified.'); + if (typeof callback === 'function') { + throw error; + } else { + return Promise.reject(error); + } + } + // if (!('padding' in cameraPosition)) { + // cameraPosition.padding = 10; + // } + + if (utils.isArray(target) || target.type === 'LatLngBounds') { + target = common.convertToPositionArray(target); + if (target.length === 0) { + // skip if no point is specified + error = new Error('No point is specified.'); + if (typeof callback === 'function') { + throw error; + } else { + return Promise.reject(error); + } + } + } + cameraPosition.target = target; + + var resolver = function(resolve, reject) { + + self.exec.call(self, + resolve.bind(self), + reject.bind(self), + self.__pgmId, 'animateCamera', [cameraPosition], { + sync: true + }); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } +}; +/** + * Move the map camera without animation + * + * @name moveCamera + * @param {CameraPosition} - cameraPosition New camera position + * @param {Function} [callback] - This callback is involved when the animation is completed. + * @return {Promise} if you omit `callback`. + */ +Map.prototype.moveCamera = function(cameraPosition, callback) { + var self = this; + var target = cameraPosition.target; + if (!target && 'position' in cameraPosition) { + target = cameraPosition.position; + } + if (!target) { + return Promise.reject('No target field is specified.'); + } + + // if (!('padding' in cameraPosition)) { + // cameraPosition.padding = 10; + // } + if (utils.isArray(target) || target.type === 'LatLngBounds') { + target = common.convertToPositionArray(target); + if (target.length === 0) { + // skip if no point is specified + if (typeof callback === 'function') { + callback.call(self); + return; + } else { + return Promise.reject('No point is specified.'); + } + } + } + cameraPosition.target = target; + + var resolver = function(resolve, reject) { + + self.exec.call(self, + resolve.bind(self), + reject.bind(self), + self.__pgmId, 'moveCamera', [cameraPosition], { + sync: true + }); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } +}; + +Map.prototype.setMyLocationButtonEnabled = function(enabled) { + var self = this; + enabled = common.parseBoolean(enabled); + this.set('myLocationButton', enabled); + self.exec.call(self, null, this.errorHandler, this.__pgmId, 'setMyLocationEnabled', [{ + myLocationButton: enabled, + myLocation: self.get('myLocation') === true + }], { + sync: true + }); + return this; +}; + +Map.prototype.setMyLocationEnabled = function(enabled) { + var self = this; + enabled = common.parseBoolean(enabled); + this.set('myLocation', enabled); + self.exec.call(self, null, this.errorHandler, this.__pgmId, 'setMyLocationEnabled', [{ + myLocationButton: self.get('myLocationButton') === true, + myLocation: enabled + }], { + sync: true + }); + return this; +}; + +Map.prototype.setIndoorEnabled = function(enabled) { + enabled = common.parseBoolean(enabled); + this.exec.call(this, null, this.errorHandler, this.__pgmId, 'setIndoorEnabled', [enabled]); + return this; +}; +Map.prototype.setTrafficEnabled = function(enabled) { + enabled = common.parseBoolean(enabled); + this.exec.call(this, null, this.errorHandler, this.__pgmId, 'setTrafficEnabled', [enabled]); + return this; +}; +Map.prototype.setCompassEnabled = function(enabled) { + var self = this; + enabled = common.parseBoolean(enabled); + self.exec.call(self, null, self.errorHandler, this.__pgmId, 'setCompassEnabled', [enabled]); + return this; +}; +Map.prototype.getFocusedBuilding = function(callback) { + var self = this; + var resolver = function(resolve, reject) { + self.exec.call(self, + resolve.bind(self), + reject.bind(self), + self.__pgmId, 'getFocusedBuilding', []); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } +}; +Map.prototype.getVisible = function() { + return this.get('visible'); +}; +Map.prototype.setVisible = function(isVisible) { + cordova.fireDocumentEvent('plugin_touch'); + var self = this; + isVisible = common.parseBoolean(isVisible); + self.set('visible', isVisible); + self.exec.call(self, null, self.errorHandler, this.__pgmId, 'setVisible', [isVisible]); + return this; +}; + +Map.prototype.setClickable = function(isClickable) { + cordova.fireDocumentEvent('plugin_touch'); + var self = this; + isClickable = common.parseBoolean(isClickable); + self.set('clickable', isClickable); + self.exec.call(self, null, self.errorHandler, this.__pgmId, 'setClickable', [isClickable]); + return this; +}; +Map.prototype.getClickable = function() { + return this.get('clickable'); +}; + + +/** + * Sets the preference for whether all gestures should be enabled or disabled. + */ +Map.prototype.setAllGesturesEnabled = function(enabled) { + var self = this; + enabled = common.parseBoolean(enabled); + self.exec.call(self, null, self.errorHandler, this.__pgmId, 'setAllGesturesEnabled', [enabled]); + return this; +}; + +/** + * Return the current position of the camera + * @return {CameraPosition} + */ +Map.prototype.getCameraPosition = function() { + return this.get('camera'); +}; + +/** + * Remove the map completely. + */ +Map.prototype.remove = function(callback) { + var self = this; + if (self._isRemoved) { + return; + } + Object.defineProperty(self, '_isRemoved', { + value: true, + writable: false + }); + + self.trigger('remove'); + // var div = self.get('div'); + // if (div) { + // while (div) { + // if (div.style) { + // div.style.backgroundColor = ''; + // } + // if (div.classList) { + // div.classList.remove('_gmaps_cdv_'); + // } else if (div.className) { + // div.className = div.className.replace(/_gmaps_cdv_/g, ''); + // div.className = div.className.replace(/\s+/g, ' '); + // } + // div = div.parentNode; + // } + // } + // self.set('div', undefined); + + + // Close the active infoWindow + var active_marker = self.get('active_marker'); + if (active_marker) { + active_marker.trigger(event.INFO_CLOSE); + } + + var clearObj = function(obj) { + var ids = Object.keys(obj); + var id, instance; + for (var i = 0; i < ids.length; i++) { + id = ids[i]; + instance = obj[id]; + if (instance) { + if (typeof instance.remove === 'function') { + instance.remove(); + } + instance.off(); + delete obj[id]; + } + } + obj = {}; + }; + + clearObj(self.OVERLAYS); + clearObj(self.MARKERS); + + + var resolver = function(resolve, reject) { + self.exec.call(self, + resolve.bind(self), + reject.bind(self), + 'CordovaGoogleMaps', 'removeMap', [self.__pgmId], + { + sync: true, + remove: true + }); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } +}; + + +Map.prototype.toDataURL = function(params, callback) { + var args = [params || {}, callback]; + if (typeof args[0] === 'function') { + args.unshift({}); + } + + params = args[0]; + callback = args[1]; + + params.uncompress = params.uncompress === true; + var self = this; + + var resolver = function(resolve, reject) { + self.exec.call(self, + resolve.bind(self), + reject.bind(self), + self.__pgmId, 'toDataURL', [params]); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } +}; + +/** + * Show the map into the specified div. + */ +Map.prototype.getDiv = function() { + return this.get('div'); +}; + +/** + * Show the map into the specified div. + */ +Map.prototype.setDiv = function(div) { + var self = this, + args = []; + + if (!common.isDom(div)) { + div = self.get('div'); + if (common.isDom(div)) { + div.removeAttribute('__pluginMapId'); + } + self.set('div', null); + } else { + div.setAttribute('__pluginMapId', self.__pgmId); + + // Insert the infoWindow layer + if (self._layers.info.parentNode) { + try { + self._layers.info.parentNode.removeChild(self._layers.info.parentNode); + } catch(e) { + //ignore + } + } + var positionCSS; + for (var i = 0; i < div.children.length; i++) { + positionCSS = common.getStyle(div.children[i], 'position'); + if (positionCSS === 'static') { + div.children[i].style.position = 'relative'; + } + } + div.insertBefore(self._layers.info, div.firstChild); + + // Webkit redraw mandatory + // http://stackoverflow.com/a/3485654/697856 + div.style.display = 'none'; + div.offsetHeight; + div.style.display = ''; + + self.set('div', div); + + if (cordova.platform === 'browser') { + return; + } + + + positionCSS = common.getStyle(div, 'position'); + if (!positionCSS || positionCSS === 'static') { + div.style.position = 'relative'; + } + var elemId = common.getPluginDomId(div); + args.push(elemId); + while (div.parentNode) { + div.style.backgroundColor = 'rgba(0,0,0,0)'; + + // Add _gmaps_cdv_ class + common.attachTransparentClass(div); + + div = div.parentNode; + } + } + self.exec.call(self, function() { + cordova.fireDocumentEvent('plugin_touch', { + force: true, + action: 'setDiv' + }); + self.refreshLayout(); + }, self.errorHandler, self.__pgmId, 'setDiv', args, { + sync: true + }); + return self; +}; + +/** + * Return the visible region of the map. + */ +Map.prototype.getVisibleRegion = function(callback) { + var self = this; + var cameraPosition = self.get('camera'); + if (!cameraPosition || !cameraPosition.southwest || !cameraPosition.northeast) { + return null; + } + + var latLngBounds = new VisibleRegion( + cameraPosition.southwest, + cameraPosition.northeast, + cameraPosition.farLeft, + cameraPosition.farRight, + cameraPosition.nearLeft, + cameraPosition.nearRight + ); + + if (typeof callback === 'function') { + console.log('[deprecated] getVisibleRegion() is changed. Please check out the https://goo.gl/yHstHQ'); + callback.call(self, latLngBounds); + } + return latLngBounds; +}; + +/** + * Maps an Earth coordinate to a point coordinate in the map's view. + */ +Map.prototype.fromLatLngToPoint = function(latLng, callback) { + var self = this; + + if ('lat' in latLng && 'lng' in latLng) { + + var resolver = function(resolve, reject) { + self.exec.call(self, + resolve.bind(self), + reject.bind(self), + self.__pgmId, 'fromLatLngToPoint', [latLng.lat, latLng.lng]); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } + } else { + var rejector = function(resolve, reject) { + reject('The latLng is invalid'); + }; + + if (typeof callback === 'function') { + rejector(callback, self.errorHandler); + } else { + return new Promise(rejector); + } + } + +}; +/** + * Maps a point coordinate in the map's view to an Earth coordinate. + */ +Map.prototype.fromPointToLatLng = function(pixel, callback) { + var self = this; + if (typeof pixel === 'object' && 'x' in pixel && 'y' in pixel) { + pixel = [pixel.x, pixel.y]; + } + if (pixel.length == 2 && utils.isArray(pixel)) { + + var resolver = function(resolve, reject) { + self.exec.call(self, + function(result) { + var latLng = new LatLng(result[0] || 0, result[1] || 0); + resolve.call(self, latLng); + }, + reject.bind(self), + self.__pgmId, 'fromPointToLatLng', [pixel[0], pixel[1]]); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } + } else { + var rejector = function(resolve, reject) { + reject('The pixel[] argument is invalid'); + }; + + if (typeof callback === 'function') { + rejector(callback, self.errorHandler); + } else { + return new Promise(rejector); + } + } + +}; + +Map.prototype.setPadding = function(p1, p2, p3, p4) { + if (arguments.length === 0 || arguments.length > 4) { + return this; + } + var padding = {}; + padding.top = parseInt(p1, 10); + switch (arguments.length) { + case 4: + // top right bottom left + padding.right = parseInt(p2, 10); + padding.bottom = parseInt(p3, 10); + padding.left = parseInt(p4, 10); + break; + + case 3: + // top right&left bottom + padding.right = parseInt(p2, 10); + padding.left = padding.right; + padding.bottom = parseInt(p3, 10); + break; + + case 2: + // top & bottom right&left + padding.bottom = parseInt(p1, 10); + padding.right = parseInt(p2, 10); + padding.left = padding.right; + break; + + case 1: + // top & bottom right & left + padding.bottom = padding.top; + padding.right = padding.top; + padding.left = padding.top; + break; + } + this.exec.call(this, null, self.errorHandler, this.__pgmId, 'setPadding', [padding]); + return this; +}; + + +Map.prototype.addKmlOverlay = function(kmlOverlayOptions, callback) { + var self = this; + kmlOverlayOptions = kmlOverlayOptions || {}; + kmlOverlayOptions.url = kmlOverlayOptions.url || null; + kmlOverlayOptions.clickable = common.defaultTrueOption(kmlOverlayOptions.clickable); + kmlOverlayOptions.suppressInfoWindows = kmlOverlayOptions.suppressInfoWindows === true; + + if (kmlOverlayOptions.url) { + + var link = document.createElement('a'); + link.href = kmlOverlayOptions.url; + kmlOverlayOptions.url = link.protocol+'//'+link.host+link.pathname + link.search; + + var invisible_dot = self.get('invisible_dot'); + if (!invisible_dot || invisible_dot._isRemoved) { + // Create an invisible marker for kmlOverlay + self.set('invisible_dot', self.addMarker({ + position: { + lat: 0, + lng: 0 + }, + icon: 'skyblue', + visible: false + })); + } + if ('icon' in kmlOverlayOptions) { + self.get('invisible_dot').setIcon(kmlOverlayOptions.icon); + } + + var resolver = function(resolve, reject) { + + var loader = new KmlLoader(self, self.exec, kmlOverlayOptions); + loader.parseKmlFile(function(camera, kmlData) { + if (kmlData instanceof BaseClass) { + kmlData = new BaseArrayClass([kmlData]); + } + var kmlId = 'kmloverlay_' + Math.floor(Math.random() * Date.now()); + var kmlOverlay = new KmlOverlay(self, kmlId, camera, kmlData, kmlOverlayOptions); + self.OVERLAYS[kmlId] = kmlOverlay; + resolve.call(self, kmlOverlay); + }, reject); + + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } + } else { + + if (typeof callback === 'function') { + throw new Error('KML file url is required.'); + } else { + return Promise.reject('KML file url is required.'); + } + } +}; + + +//------------- +// Ground overlay +//------------- +Map.prototype.addGroundOverlay = function(groundOverlayOptions, callback) { + var self = this; + groundOverlayOptions = groundOverlayOptions || {}; + groundOverlayOptions.anchor = groundOverlayOptions.anchor || [0.5, 0.5]; + groundOverlayOptions.bearing = 'bearing' in groundOverlayOptions ? groundOverlayOptions.bearing : 0; + groundOverlayOptions.url = groundOverlayOptions.url || null; + groundOverlayOptions.clickable = groundOverlayOptions.clickable === true; + groundOverlayOptions.visible = common.defaultTrueOption(groundOverlayOptions.visible); + groundOverlayOptions.zIndex = groundOverlayOptions.zIndex || 0; + groundOverlayOptions.bounds = common.convertToPositionArray(groundOverlayOptions.bounds); + groundOverlayOptions.noCaching = true; + + var groundOverlay = new GroundOverlay(self, groundOverlayOptions, exec); + var groundOverlayId = groundOverlay.getId(); + self.OVERLAYS[groundOverlayId] = groundOverlay; + groundOverlay.one(groundOverlayId + '_remove', function() { + groundOverlay.off(); + delete self.OVERLAYS[groundOverlayId]; + groundOverlay = undefined; + }); + + self.exec.call(self, function() { + groundOverlay._privateInitialize(); + delete groundOverlay._privateInitialize; + if (typeof callback === 'function') { + callback.call(self, groundOverlay); + } + }, self.errorHandler, self.__pgmId, 'loadPlugin', ['GroundOverlay', groundOverlayOptions, groundOverlay.hashCode]); + + return groundOverlay; +}; + +//------------- +// Tile overlay +//------------- +Map.prototype.addTileOverlay = function(tilelayerOptions, callback) { + var self = this; + tilelayerOptions = tilelayerOptions || {}; + tilelayerOptions.tileUrlFormat = tilelayerOptions.tileUrlFormat || null; + if (typeof tilelayerOptions.tileUrlFormat === 'string') { + console.log('[deprecated] the tileUrlFormat property is now deprecated. Use the getTile property.'); + tilelayerOptions.getTile = function(x, y, zoom) { + return tilelayerOptions.tileUrlFormat.replace(//gi, x) + .replace(//gi, y) + .replace(//gi, zoom); + }; + } + if (typeof tilelayerOptions.getTile !== 'function') { + throw new Error('[error] the getTile property is required.'); + } + tilelayerOptions.visible = common.defaultTrueOption(tilelayerOptions.visible); + tilelayerOptions.zIndex = tilelayerOptions.zIndex || 0; + tilelayerOptions.tileSize = tilelayerOptions.tileSize || 512; + tilelayerOptions.opacity = (tilelayerOptions.opacity === null || tilelayerOptions.opacity === undefined) ? 1 : tilelayerOptions.opacity; + tilelayerOptions.debug = tilelayerOptions.debug === true; + tilelayerOptions.userAgent = tilelayerOptions.userAgent || navigator.userAgent; + + + var tileOverlay = new TileOverlay(self, tilelayerOptions, exec); + var tileOverlayId = tileOverlay.getId(); + self.OVERLAYS[tileOverlayId] = tileOverlay; + var hashCode = tileOverlay.hashCode; + + tileOverlay.one(tileOverlayId + '_remove', function() { + document.removeEventListener(tileOverlayId + '-' + hashCode + '-tileoverlay', onNativeCallback); + tileOverlay.off(); + delete self.OVERLAYS[tileOverlayId]; + tileOverlay = undefined; + }); + + var options = { + visible: tilelayerOptions.visible, + zIndex: tilelayerOptions.zIndex, + tileSize: tilelayerOptions.tileSize, + opacity: tilelayerOptions.opacity, + userAgent: tilelayerOptions.userAgent, + debug: tilelayerOptions.debug + }; + + var onNativeCallback = function(params) { + var url = tilelayerOptions.getTile(params.x, params.y, params.zoom); + if (!url || url === '(null)' || url === 'undefined' || url === 'null') { + url = '(null)'; + } + if (url instanceof Promise) { + common.promiseTimeout(5000, url) + .then(function(finalUrl) { + cordova_exec(null, self.errorHandler, self.__pgmId + '-tileoverlay', 'onGetTileUrlFromJS', [hashCode, params.key, finalUrl]); + }) + .catch(function() { + cordova_exec(null, self.errorHandler, self.__pgmId + '-tileoverlay', 'onGetTileUrlFromJS', [hashCode, params.key, '(null)']); + }); + } else { + cordova_exec(null, self.errorHandler, self.__pgmId + '-tileoverlay', 'onGetTileUrlFromJS', [hashCode, params.key, url]); + } + }; + document.addEventListener(self.__pgmId + '-' + hashCode + '-tileoverlay', onNativeCallback); + + self.exec.call(self, function() { + tileOverlay._privateInitialize(); + delete tileOverlay._privateInitialize; + + if (typeof callback === 'function') { + callback.call(self, tileOverlay); + } + }, self.errorHandler, self.__pgmId, 'loadPlugin', ['TileOverlay', options, hashCode]); + + return tileOverlay; +}; + +//------------- +// Polygon +//------------- +Map.prototype.addPolygon = function(polygonOptions, callback) { + var self = this; + polygonOptions.points = polygonOptions.points || []; + var _orgs = polygonOptions.points; + polygonOptions.points = common.convertToPositionArray(polygonOptions.points); + polygonOptions.holes = polygonOptions.holes || []; + if (polygonOptions.holes.length > 0 && !Array.isArray(polygonOptions.holes[0])) { + polygonOptions.holes = [polygonOptions.holes]; + } + polygonOptions.holes = polygonOptions.holes.map(function(hole) { + if (!utils.isArray(hole)) { + return []; + } + return hole.map(function(position) { + return { + 'lat': position.lat, + 'lng': position.lng + }; + }); + }); + polygonOptions.strokeColor = common.HTMLColor2RGBA(polygonOptions.strokeColor || '#FF000080', 0.75); + if (polygonOptions.fillColor) { + polygonOptions.fillColor = common.HTMLColor2RGBA(polygonOptions.fillColor || '#FF000080', 0.75); + } else { + polygonOptions.fillColor = common.HTMLColor2RGBA('#FF000080', 0.75); + } + polygonOptions.strokeWidth = 'strokeWidth' in polygonOptions ? polygonOptions.strokeWidth : 10; + polygonOptions.visible = common.defaultTrueOption(polygonOptions.visible); + polygonOptions.clickable = polygonOptions.clickable === true; + polygonOptions.zIndex = polygonOptions.zIndex || 0; + polygonOptions.geodesic = polygonOptions.geodesic === true; + + var opts = JSON.parse(JSON.stringify(polygonOptions)); + polygonOptions.points = _orgs; + var polygon = new Polygon(self, polygonOptions, exec); + var polygonId = polygon.getId(); + self.OVERLAYS[polygonId] = polygon; + polygon.one(polygonId + '_remove', function() { + polygon.off(); + delete self.OVERLAYS[polygonId]; + polygon = undefined; + }); + + self.exec.call(self, function() { + polygon._privateInitialize(); + delete polygon._privateInitialize; + + if (typeof callback === 'function') { + callback.call(self, polygon); + } + }, self.errorHandler, self.__pgmId, 'loadPlugin', ['Polygon', opts, polygon.hashCode]); + + return polygon; +}; + +//------------- +// Polyline +//------------- +Map.prototype.addPolyline = function(polylineOptions, callback) { + var self = this; + polylineOptions.points = polylineOptions.points || []; + var _orgs = polylineOptions.points; + polylineOptions.points = common.convertToPositionArray(polylineOptions.points); + polylineOptions.color = common.HTMLColor2RGBA(polylineOptions.color || '#FF000080', 0.75); + polylineOptions.width = 'width' in polylineOptions ? polylineOptions.width : 10; + polylineOptions.visible = common.defaultTrueOption(polylineOptions.visible); + polylineOptions.clickable = polylineOptions.clickable === true; + polylineOptions.zIndex = polylineOptions.zIndex || 0; + polylineOptions.geodesic = polylineOptions.geodesic === true; + + var opts = JSON.parse(JSON.stringify(polylineOptions)); + polylineOptions.points = _orgs; + var polyline = new Polyline(self, polylineOptions, exec); + var polylineId = polyline.getId(); + self.OVERLAYS[polylineId] = polyline; + + polyline.one(polylineId + '_remove', function() { + polyline.off(); + delete self.OVERLAYS[polylineId]; + polyline = undefined; + }); + + self.exec.call(self, function() { + polyline._privateInitialize(); + delete polyline._privateInitialize; + + if (typeof callback === 'function') { + callback.call(self, polyline); + } + }, self.errorHandler, self.__pgmId, 'loadPlugin', ['Polyline', opts, polyline.hashCode]); + + return polyline; +}; + +//------------- +// Circle +//------------- +Map.prototype.addCircle = function(circleOptions, callback) { + var self = this; + circleOptions.center = circleOptions.center || {}; + circleOptions.center.lat = circleOptions.center.lat || 0.0; + circleOptions.center.lng = circleOptions.center.lng || 0.0; + circleOptions.strokeColor = common.HTMLColor2RGBA(circleOptions.strokeColor || '#FF0000', 0.75); + circleOptions.fillColor = common.HTMLColor2RGBA(circleOptions.fillColor || '#000000', 0.75); + circleOptions.strokeWidth = 'strokeWidth' in circleOptions ? circleOptions.strokeWidth : 10; + circleOptions.visible = common.defaultTrueOption(circleOptions.visible); + circleOptions.zIndex = circleOptions.zIndex || 0; + circleOptions.radius = 'radius' in circleOptions ? circleOptions.radius : 1; + + var circle = new Circle(self, circleOptions, exec); + var circleId = circle.getId(); + self.OVERLAYS[circleId] = circle; + circle.one(circleId + '_remove', function() { + circle.off(); + delete self.OVERLAYS[circleId]; + circle = undefined; + }); + + self.exec.call(self, function() { + circle._privateInitialize(); + delete circle._privateInitialize; + + if (typeof callback === 'function') { + callback.call(self, circle); + } + }, self.errorHandler, self.__pgmId, 'loadPlugin', ['Circle', circleOptions, circle.hashCode]); + + return circle; +}; + +//------------- +// Marker +//------------- + +Map.prototype.addMarker = function(markerOptions, callback) { + var self = this; + markerOptions = common.markerOptionsFilter(markerOptions); + + //------------------------------------ + // Generate a makrer instance at once. + //------------------------------------ + markerOptions.icon = markerOptions.icon || {}; + if (typeof markerOptions.icon === 'string' || Array.isArray(markerOptions.icon)) { + markerOptions.icon = { + url: markerOptions.icon + }; + } + + var marker = new Marker(self, markerOptions, exec); + var markerId = marker.getId(); + + self.MARKERS[markerId] = marker; + self.OVERLAYS[markerId] = marker; + marker.one(markerId + '_remove', function() { + delete self.MARKERS[markerId]; + delete self.OVERLAYS[markerId]; + marker.destroy(); + marker = undefined; + }); + + self.exec.call(self, function(result) { + + markerOptions.icon.size = markerOptions.icon.size || {}; + markerOptions.icon.size.width = markerOptions.icon.size.width || result.width; + markerOptions.icon.size.height = markerOptions.icon.size.height || result.height; + markerOptions.icon.anchor = markerOptions.icon.anchor || [markerOptions.icon.size.width / 2, markerOptions.icon.size.height]; + + if (!markerOptions.infoWindowAnchor) { + markerOptions.infoWindowAnchor = [markerOptions.icon.size.width / 2, 0]; + } + marker._privateInitialize(markerOptions); + delete marker._privateInitialize; + + if (typeof callback === 'function') { + callback.call(self, marker); + } + }, self.errorHandler, self.__pgmId, 'loadPlugin', ['Marker', markerOptions, marker.hashCode]); + + return marker; +}; + + +//------------------ +// Marker cluster +//------------------ +Map.prototype.addMarkerCluster = function(markerClusterOptions, callback) { + var self = this; + if (typeof markerClusterOptions === 'function') { + callback = markerClusterOptions; + markerClusterOptions = null; + } + markerClusterOptions = markerClusterOptions || {}; + var positionList = markerClusterOptions.markers.map(function(marker) { + return marker.position; + }); + + var markerCluster = new MarkerCluster(self, { + 'icons': markerClusterOptions.icons, + //'markerMap': markerMap, + 'idxCount': positionList.length + 1, + 'maxZoomLevel': Math.min(markerClusterOptions.maxZoomLevel || 15, 18), + 'debug': markerClusterOptions.debug === true, + 'boundsDraw': common.defaultTrueOption(markerClusterOptions.boundsDraw) + }, exec); + var markerClusterId = markerCluster.getId(); + self.OVERLAYS[markerClusterId] = markerCluster; + + self.exec.call(self, function(result) { + + result.geocellList.forEach(function(geocell, idx) { + var markerOptions = markerClusterOptions.markers[idx]; + markerOptions = common.markerOptionsFilter(markerOptions); + + markerOptions._cluster = { + isRemoved: false, + isAdded: false, + geocell: geocell + }; + markerCluster.addMarker(markerOptions); + + //self.MARKERS[marker.getId()] = marker; + //self.OVERLAYS[marker.getId()] = marker; + }); + + + markerCluster.one('remove', function() { + delete self.OVERLAYS[result.__pgmId]; + /* + result.geocellList.forEach(function(geocell, idx) { + var markerOptions = markerClusterOptions.markers[idx]; + var markerId = result.__pgmId + '-' + (markerOptions.__pgmId || 'marker_' + idx); + var marker = self.MARKERS[markerId]; + if (marker) { + marker.off(); + } + //delete self.MARKERS[markerId]; + delete self.OVERLAYS[markerId]; + }); + */ + markerCluster.destroy(); + }); + + markerCluster._privateInitialize(); + delete markerCluster._privateInitialize; + + markerCluster._triggerRedraw.call(markerCluster, { + force: true + }); + + if (typeof callback === 'function') { + callback.call(self, markerCluster); + } + }, self.errorHandler, self.__pgmId, 'loadPlugin', ['MarkerCluster', { + 'positionList': positionList, + 'debug': markerClusterOptions.debug === true + }, markerCluster.hashCode]); + + return markerCluster; +}; + +/***************************************************************************** + * Callbacks from the native side + *****************************************************************************/ + +Map.prototype._onSyncInfoWndPosition = function(eventName, points) { + this.set('infoPosition', points); +}; + +Map.prototype._onMapEvent = function(eventName) { + if (!this._isReady) { + return; + } + var args = [eventName]; + for (var i = 1; i < arguments.length; i++) { + args.push(arguments[i]); + } + this.trigger.apply(this, args); +}; + +Map.prototype._onMarkerEvent = function(eventName, markerId, position) { + var self = this; + var marker = self.MARKERS[markerId] || null; + + if (marker) { + marker.set('position', position); + if (eventName === event.INFO_OPEN) { + marker.set('isInfoWindowVisible', true); + } + if (eventName === event.INFO_CLOSE) { + marker.set('isInfoWindowVisible', false); + } + marker.trigger(eventName, position, marker); + } +}; + +Map.prototype._onClusterEvent = function(eventName, markerClusterId, clusterId, position) { + var self = this; + var markerCluster = self.OVERLAYS[markerClusterId] || null; + if (markerCluster) { + if (/^marker_/i.test(clusterId)) { + // regular marker + var marker = markerCluster.getMarkerById(clusterId); + if (eventName === event.MARKER_CLICK) { + markerCluster.trigger(eventName, position, marker); + } else { + if (eventName === event.INFO_OPEN) { + marker.set('isInfoWindowVisible', true); + } + if (eventName === event.INFO_CLOSE) { + marker.set('isInfoWindowVisible', false); + } + } + marker.trigger(eventName, position, marker); + } else { + // cluster marker + var cluster = markerCluster._getClusterByClusterId(clusterId); + if (cluster) { + markerCluster.trigger(eventName, cluster); + } else { + console.log('-----> This is remained cluster icon : ' + clusterId); + } + } + } +}; + +Map.prototype._onOverlayEvent = function(eventName, overlayId) { + var self = this; + var overlay = self.OVERLAYS[overlayId] || null; + + if (overlay) { + var args = [eventName]; + for (var i = 2; i < arguments.length; i++) { + args.push(arguments[i]); + } + args.push(overlay); // for ionic + overlay.trigger.apply(overlay, args); + } +}; + +Map.prototype.getCameraTarget = function() { + return this.get('camera_target'); +}; + +Map.prototype.getCameraZoom = function() { + return this.get('camera_zoom'); +}; +Map.prototype.getCameraTilt = function() { + return this.get('camera_tilt'); +}; +Map.prototype.getCameraBearing = function() { + return this.get('camera_bearing'); +}; + +Map.prototype._onCameraEvent = function(eventName, cameraPosition) { + this.set('camera', cameraPosition); + this.set('camera_target', cameraPosition.target); + this.set('camera_zoom', cameraPosition.zoom); + this.set('camera_bearing', cameraPosition.bearing); + this.set('camera_tilt', cameraPosition.viewAngle || cameraPosition.tilt); + this.set('camera_northeast', cameraPosition.northeast); + this.set('camera_southwest', cameraPosition.southwest); + this.set('camera_nearLeft', cameraPosition.nearLeft); + this.set('camera_nearRight', cameraPosition.nearRight); + this.set('camera_farLeft', cameraPosition.farLeft); + this.set('camera_farRight', cameraPosition.farRight); + if (this._isReady) { + this.trigger(eventName, cameraPosition, this); + } +}; + +module.exports = Map; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/MapTypeId.js b/docs/plugins/cordova-plugin-googlemaps/www/MapTypeId.js new file mode 100644 index 0000000..868206d --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/MapTypeId.js @@ -0,0 +1,10 @@ +cordova.define("cordova-plugin-googlemaps.MapTypeId", function(require, exports, module) { module.exports = { + 'NORMAL': 'MAP_TYPE_NORMAL', + 'ROADMAP': 'MAP_TYPE_NORMAL', + 'SATELLITE': 'MAP_TYPE_SATELLITE', + 'HYBRID': 'MAP_TYPE_HYBRID', + 'TERRAIN': 'MAP_TYPE_TERRAIN', + 'NONE': 'MAP_TYPE_NONE' +}; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Marker.js b/docs/plugins/cordova-plugin-googlemaps/www/Marker.js new file mode 100644 index 0000000..4eada02 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Marker.js @@ -0,0 +1,335 @@ +cordova.define("cordova-plugin-googlemaps.Marker", function(require, exports, module) { + +var utils = require('cordova/utils'), + common = require('./Common'), + LatLng = require('./LatLng'), + event = require('./event'), + Overlay = require('./Overlay'); + +/***************************************************************************** + * Marker Class + *****************************************************************************/ +var Marker = function(map, markerOptions, _exec, extras) { + extras = extras || {}; + Overlay.call(this, map, markerOptions, extras.className || 'Marker', _exec, extras); + + var self = this; + + if (markerOptions && markerOptions.position) { + markerOptions.position.lat = parseFloat(markerOptions.position.lat); + markerOptions.position.lng = parseFloat(markerOptions.position.lng); + self.set('position', markerOptions.position); + } + + //----------------------------------------------- + // Sets event listeners + //----------------------------------------------- + self.on(event.MARKER_CLICK, function() { + self.showInfoWindow.apply(self); + }); + + self.on('position_changed', function() { + var position = self.get('position'); + try { + position.lat = parseFloat(position.lat, 10); + position.lng = parseFloat(position.lng, 10); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setPosition', [self.getId(), position.lat, position.lng]); + } catch (e) { + return; + } + }); + self.on('rotation_changed', function() { + var rotation = self.get('rotation'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setRotation', [self.getId(), rotation]); + }); + self.on('snippet_changed', function() { + var snippet = self.get('snippet'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setSnippet', [self.getId(), snippet]); + }); + self.on('visible_changed', function() { + var visible = self.get('visible'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setVisible', [self.getId(), visible]); + }); + self.on('title_changed', function() { + var title = self.get('title'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setTitle', [self.getId(), title]); + }); + self.on('icon_changed', function() { + var icon = self.get('icon'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setIcon', [self.getId(), icon]); + }); + self.on('flat_changed', function() { + var flat = self.get('flat'); + flat = flat === true; + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setFlat', [self.getId(), flat]); + }); + self.on('draggable_changed', function() { + var draggable = self.get('draggable'); + draggable = draggable === true; + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setDraggable', [self.getId(), draggable]); + }); + self.on('anchor_changed', function() { + var anchor = self.get('anchor'); + if (!anchor) { + return; + } + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setIconAnchor', [self.getId(), anchor[0], anchor[1]]); + }); + self.on('infoWindowAnchor_changed', function() { + var anchor = self.get('infoWindowAnchor'); + if (!anchor) { + return; + } + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setInfoWindowAnchor', [self.getId(), anchor[0], anchor[1]]); + }); + self.on('zIndex_changed', function() { + var zIndex = self.get('zIndex'); + if (zIndex === null || zIndex === undefined) { + return; + } + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setZIndex', [self.getId(), zIndex]); + }); + self.on('opacity_changed', function() { + var opacity = self.get('opacity'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setOpacity', [self.getId(), opacity]); + }); + self.on('disableAutoPan_changed', function() { + var disableAutoPan = self.get('disableAutoPan'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setDisableAutoPan', [self.getId(), disableAutoPan]); + }); + +}; + +utils.extend(Marker, Overlay); + +Marker.prototype.remove = function(callback) { + var self = this; + if (self._isRemoved) { + if (typeof callback === 'function') { + return; + } else { + return Promise.resolve(); + } + } + Object.defineProperty(self, '_isRemoved', { + value: true, + writable: false + }); + self.trigger(event.INFO_CLOSE); // close open infowindow, otherwise it will stay + self.trigger(self.__pgmId + '_remove'); + + var resolver = function(resolve, reject) { + self.exec.call(self, + function() { + self.destroy(); + resolve.call(self); + }, + reject.bind(self), + self.getPluginName(), 'remove', [self.getId()], { + remove: true + }); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } + + +}; + +Marker.prototype.getOptions = function() { + var self = this; + return { + '__pgmId': self.getId(), + 'position': self.getPosition(), + 'disableAutoPan': self.get('disableAutoPan'), + 'opacity': self.get('opacity'), + 'icon': self.get('icon'), + 'zIndex': self.get('zIndex'), + 'anchor': self.get('anchor'), + 'infoWindowAnchor': self.get('infoWindowAnchor'), + 'draggable': self.get('draggable'), + 'title': self.getTitle(), + 'snippet': self.getSnippet(), + 'visible': self.get('visible'), + 'rotation': self.getRotation() + }; +}; +Marker.prototype.getPosition = function() { + var position = this.get('position'); + if (!(position instanceof LatLng)) { + return new LatLng(position.lat, position.lng); + } + return position; +}; + +Marker.prototype.setAnimation = function(animation, callback) { + var self = this; + + animation = animation || null; + if (!animation) { + // just ignore + if (typeof callback === 'function') { + return self; + } else { + return Promise.resolve(); + } + } + self.set('animation', animation); + + var resolver = function(resolve, reject) { + self.exec.call(self, + resolve.bind(self), + reject.bind(self), + self.getPluginName(), 'setAnimation', [self.getId(), animation]); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + return self; + } else { + return new Promise(resolver); + } + +}; + +Marker.prototype.setDisableAutoPan = function(disableAutoPan) { + disableAutoPan = common.parseBoolean(disableAutoPan); + this.set('disableAutoPan', disableAutoPan); + return this; +}; +Marker.prototype.setOpacity = function(opacity) { + if (!opacity && opacity !== 0) { + console.log('opacity value must be int or double'); + return false; + } + this.set('opacity', opacity); + return this; +}; +Marker.prototype.setZIndex = function(zIndex) { + if (typeof zIndex === 'undefined') { + return false; + } + this.set('zIndex', zIndex); + return this; +}; +Marker.prototype.getOpacity = function() { + return this.get('opacity'); +}; +Marker.prototype.setIconAnchor = function(anchorX, anchorY) { + this.set('anchor', [anchorX, anchorY]); + return this; +}; +Marker.prototype.setInfoWindowAnchor = function(anchorX, anchorY) { + this.set('infoWindowAnchor', [anchorX, anchorY]); + return this; +}; +Marker.prototype.setDraggable = function(draggable) { + draggable = common.parseBoolean(draggable); + this.set('draggable', draggable); + return this; +}; +Marker.prototype.isDraggable = function() { + return this.get('draggable'); +}; +Marker.prototype.setFlat = function(flat) { + flat = common.parseBoolean(flat); + this.set('flat', flat); + return this; +}; +Marker.prototype.setIcon = function(url) { + if (url && common.isHTMLColorString(url)) { + url = common.HTMLColor2RGBA(url); + } + this.set('icon', url); + return this; +}; +Marker.prototype.setTitle = function(title) { + if (!title) { + console.log('missing value for title'); + return this; + } + title = '' + title; // Convert to strings mandatory + this.set('title', title); + return this; +}; +Marker.prototype.setVisible = function(visible) { + visible = common.parseBoolean(visible); + this.set('visible', visible); + if (!visible && this.map.get('active_marker_id') === this.__pgmId) { + this.map.set('active_marker_id', undefined); + } + return this; +}; +Marker.prototype.getTitle = function() { + return this.get('title'); +}; +Marker.prototype.setSnippet = function(snippet) { + this.set('snippet', snippet); + return this; +}; +Marker.prototype.getSnippet = function() { + return this.get('snippet'); +}; +Marker.prototype.setRotation = function(rotation) { + if (typeof rotation !== 'number') { + console.log('missing value for rotation'); + return false; + } + this.set('rotation', rotation); + return this; +}; +Marker.prototype.getRotation = function() { + return this.get('rotation'); +}; +Marker.prototype.showInfoWindow = function() { + var self = this; + //if (!self.get('title') && !self.get('snippet') || + // self.get('isInfoWindowVisible')) { + if (!self.get('title') && !self.get('snippet')) { + return; + } + self.set('isInfoWindowVisible', true); + self.map.set('active_marker_id', self.__pgmId); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'showInfoWindow', [self.getId()], { + sync: true + }); + return self; +}; +Marker.prototype.hideInfoWindow = function() { + var self = this; + if (self.map.get('active_marker_id') === self.__pgmId) { + self.map.set('active_marker_id', null); + } + if (self.get('isInfoWindowVisible')) { + self.set('isInfoWindowVisible', false); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'hideInfoWindow', [self.getId()], { + sync: true + }); + } + return self; +}; +Marker.prototype.isInfoWindowShown = function() { + return this.get('isInfoWindowVisible') === true; +}; +Marker.prototype.isVisible = function() { + return this.get('visible') === true; +}; + +Marker.prototype.setPosition = function(position) { + if (!position) { + console.log('missing value for position'); + return false; + } + this.set('position', { + 'lat': position.lat, + 'lng': position.lng + }); + return this; +}; + +module.exports = Marker; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/MarkerCluster.js b/docs/plugins/cordova-plugin-googlemaps/www/MarkerCluster.js new file mode 100644 index 0000000..d063c0e --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/MarkerCluster.js @@ -0,0 +1,1188 @@ +cordova.define("cordova-plugin-googlemaps.MarkerCluster", function(require, exports, module) { +/* eslint no-useless-escape: off */ + +var utils = require('cordova/utils'), + common = require('./Common'), + event = require('./event'), + geomodel = require('./geomodel'), + Marker = require('./Marker'), + Cluster = require('./Cluster'), + spherical = require('./spherical'), + Overlay = require('./Overlay'), + BaseArrayClass = require('./BaseArrayClass'); + +/***************************************************************************** + * MarkerCluster Class + *****************************************************************************/ +var exec; +var MarkerCluster = function (map, markerClusterOptions, _exec) { + exec = _exec; + Overlay.call(this, map, markerClusterOptions, 'MarkerCluster', _exec); + + var self = this; + Object.defineProperty(self, 'maxZoomLevel', { + value: markerClusterOptions.maxZoomLevel, + writable: false + }); + Object.defineProperty(self, '_markerMap', { + enumerable: false, + value: {}, + writable: false + }); + Object.defineProperty(self, '_clusterBounds', { + enumerable: false, + value: new BaseArrayClass(), + writable: false + }); + Object.defineProperty(self, '_geocellBounds', { + enumerable: false, + value: {}, + writable: false + }); + Object.defineProperty(self, '_clusters', { + enumerable: false, + value: {}, + writable: false + }); + Object.defineProperty(self, 'debug', { + value: markerClusterOptions.debug === true, + writable: false + }); + Object.defineProperty(self, 'MAX_RESOLUTION', { + enumerable: false, + value: 11, + writable: false + }); + Object.defineProperty(self, 'OUT_OF_RESOLUTION', { + enumerable: false, + value: 999, + writable: false + }); + Object.defineProperty(self, 'boundsDraw', { + value: markerClusterOptions.boundsDraw === true, + writable: false + }); + + if (self.boundsDraw) { + self.map.addPolygon({ + visible: false, + points: [ + { + lat: 0, + lng: 0 + }, + { + lat: 0, + lng: 0 + }, + { + lat: 0, + lng: 0 + }, + { + lat: 0, + lng: 0 + } + ], + strokeWidth: 1 + }, function (polygon) { + self.set('polygon', polygon); + }); + } + self.taskQueue = []; + self._stopRequest = false; + self._isWorking = false; + + var icons = markerClusterOptions.icons; + if (icons.length > 0 && !icons[0].min) { + icons[0].min = 2; + } + + for (var i = 0; i < icons.length; i++) { + if (!icons[i]) { + continue; + } + if (icons[i].anchor && + typeof icons[i].anchor === 'object' && + 'x' in icons[i].anchor && + 'y' in icons[i].anchor) { + icons[i].anchor = [icons[i].anchor.x, icons[i].anchor.y]; + } + if (icons[i].infoWindowAnchor && + typeof icons[i].infoWindowAnchor === 'object' && + 'x' in icons[i].infoWindowAnchor && + 'y' in icons[i].infoWindowAnchor) { + icons[i].infoWindowAnchor = [icons[i].infoWindowAnchor.x, icons[i].infoWindowAnchor.anchor.y]; + } + if (icons[i].label && + common.isHTMLColorString(icons[i].label.color)) { + icons[i].label.color = common.HTMLColor2RGBA(icons[i].label.color); + } + } + + Object.defineProperty(self, 'icons', { + value: icons, + writable: false + }); + + self.addMarker = function (markerOptions, skipRedraw) { + + markerOptions = common.markerOptionsFilter(markerOptions); + var geocell = geomodel.getGeocell(markerOptions.position.lat, markerOptions.position.lng, self.MAX_RESOLUTION + 1); + + markerOptions._cluster = { + isRemoved: false, + isAdded: false, + geocell: geocell + }; + + var marker = self._createMarker(markerOptions); + var markerId = marker.__pgmId.split(/\-/)[1]; + self._markerMap[markerId] = marker; + if (skipRedraw || !self._isReady) { + return marker; + } + self._triggerRedraw({ + force: true + }); + return marker; + }; + self.addMarkers = function (markers) { + var results = []; + if (utils.isArray(markers) || Array.isArray(markers)) { + for (var i = 0; i < markers.length; i++) { + results.push(self.addMarker(markers[i], true)); + } + if (!self._isReady) { + return results; + } + self._triggerRedraw({ + force: true + }); + } + return results; + }; + + map.on(event.CAMERA_MOVE_END, self._onCameraMoved.bind(self)); + window.addEventListener('orientationchange', self._onCameraMoved.bind(self)); + + self.on('cluster_click', self.onClusterClicked); + self.on('nextTask', function () { + self._isWorking = false; + if (self._stopRequest || self._isRemoved || + self.taskQueue.length === 0 || !self._isReady) { + return; + } + self._triggerRedraw.call(self); + }); + + // self._triggerRedraw.call(self, { + // force: true + // }); + + if (self.debug) { + self.debugTimer = setInterval(function () { + console.log('self.taskQueue.push = ' + self.taskQueue.length); + }, 5000); + } + + return self; +}; + +utils.extend(MarkerCluster, Overlay); + +MarkerCluster.prototype.onClusterClicked = function (cluster) { + if (this._isRemoved) { + return null; + } + var self = this; + var polygon = self.get('polygon'); + var bounds = cluster.getBounds(); + if (self.boundsDraw) { + polygon.setPoints([ + bounds.southwest, + { + lat: bounds.northeast.lat, + lng: bounds.southwest.lng + }, + bounds.northeast, + { + lat: bounds.southwest.lat, + lng: bounds.northeast.lng + } + ]); + polygon.setVisible(true); + } + var zoomLevel = computeZoom(cluster.getBounds(), self.map.getDiv()); + zoomLevel += zoomLevel === self.map.get('camera_zoom') ? 1 : 0; + self.map.animateCamera({ + target: cluster.getBounds().getCenter(), + zoom: zoomLevel, + duration: 500 + }, function () { + if (self.boundsDraw) { + setTimeout(function () { + polygon.setVisible(false); + }, 500); + } + }); +}; + +Object.defineProperty(MarkerCluster.prototype, '_onCameraMoved', { + value: function () { + var self = this; + + if (self._isRemoved || self._stopRequest || !self._isReady) { + return null; + } + + self._triggerRedraw({ + force: false + }); + + }, + enumerable: false, + writable: false +}); + +MarkerCluster.prototype.remove = function (callback) { + var self = this; + self._stopRequest = self.hashCode; + if (self._isRemoved) { + if (typeof callback === 'function') { + return; + } else { + return Promise.resolve(); + } + } + if (self.debug) { + clearInterval(self.debugTimer); + self.self.debugTimer = undefined; + } + + if (self._isWorking) { + setTimeout(arguments.callee.bind(self), 20); + return; + } + + var keys; + var resolution = self.get('resolution'), + activeMarker = self.map.get('active_marker'), + deleteClusters = []; + + self.taskQueue = []; + Object.defineProperty(self, '_isRemoved', { + value: true, + writable: false + }); + self.trigger('remove'); + + var activeMarkerId = activeMarker ? activeMarker.getId() : null; + var marker; + if (resolution === self.OUT_OF_RESOLUTION) { + while (self._clusters[resolution].length > 0) { + marker = self._clusters[resolution].shift(); + deleteClusters.push(marker.__pgmId); + if (marker.__pgmId === activeMarkerId) { + marker.trigger(event.INFO_CLOSE); + marker.hideInfoWindow(); + } + } + } else if (self._clusters[resolution]) { + keys = Object.keys(self._clusters[resolution]); + keys.forEach(function (geocell) { + var cluster = self._clusters[resolution][geocell]; + var noClusterMode = cluster.getMode() === cluster.NO_CLUSTER_MODE; + if (noClusterMode) { + cluster.getMarkers().forEach(function (marker) { + if (marker.__pgmId === activeMarkerId) { + marker.trigger(event.INFO_CLOSE); + marker.hideInfoWindow(); + } + deleteClusters.push(marker.__pgmId); + }); + } + if (!noClusterMode) { + deleteClusters.push(geocell); + } + cluster.remove(); + }); + } + + var resolver = function (resolve, reject) { + self.exec.call(self, + resolve.bind(self), + reject.bind(self), + self.getPluginName(), 'remove', [self.getId()], { + sync: true, + remove: true + }); + }; + + var answer; + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + answer = new Promise(resolver); + } + + keys = Object.keys(self._markerMap); + keys.forEach(function (markerId) { + self._markerMap[markerId].remove(function() { + self._markerMap[markerId].destroy(); + self._markerMap[markerId] = undefined; + delete self._markerMap[markerId]; + }); + }); + if (self.boundsDraw && self.get('polygon')) { + self.get('polygon').remove(); + } + self.off(); + + return answer; +}; + + +Object.defineProperty(MarkerCluster.prototype, '_removeMarkerById', { + enumerable: false, + value: function (markerId) { + var self = this; + if (self._isRemoved) { + return null; + } + //if (markerId.indexOf(self.__pgmId + '-') === -1) { + //} + var marker = self._markerMap[markerId]; + if (!marker) { + return; + } + var isAdded = marker.get('_cluster').isAdded; + var resolutionList = Object.keys(self._clusters); + var resolution, geocellKey, cluster; + for (var i = 0; i < resolutionList.length; i++) { + resolution = parseInt(resolutionList[i], 10); + geocellKey = marker.get('_cluster').geocell.substr(0, resolution + 1); + if (geocellKey in self._clusters[resolution]) { + cluster = self._clusters[resolution][geocellKey]; + if (cluster) { + cluster.removeMarker(marker); + } + } + } + + marker.remove(); + marker.destroy(); + delete self._markerMap[markerId]; + if (isAdded) { + self.exec.call(self, null, null, self.getPluginName(), 'redrawClusters', [self.getId(), { + 'delete': [markerId] + }], { + sync: true + }); + } + }, + writable: false +}); + +MarkerCluster.prototype.getMarkerById = function (markerId) { + var self = this; + if (self._isRemoved) { + return null; + } + return self._markerMap[markerId]; +}; + +Object.defineProperty(MarkerCluster.prototype, '_getClusterByClusterId', { + enumerable: false, + value: function (clusterId) { + var self = this; + + if (self._isRemoved) { + return null; + } + var resolution = self.get('resolution'); + + if (!self._clusters[resolution]) { + return null; + } + + return self._clusters[resolution][clusterId]; + }, + writable: false +}); + + +Object.defineProperty(MarkerCluster.prototype, '_triggerRedraw', { + enumerable: false, + value: function (params) { + var self = this; + if (self._isRemoved || self._stopRequest || !self._isReady) { + return null; + } + + self.taskQueue.push(params); + if (self.debug) { + console.log('self.taskQueue.push = ' + self.taskQueue.length); + } + if (self._isRemoved || self._stopRequest || self.taskQueue.length > 1) { + return; + } + if (self.debug) { + self._clusterBounds.forEach(function(polyline, cb) { + polyline.remove(); + cb(); + }, function() { + self._clusterBounds.empty(); + var taskParams = self.taskQueue.pop(); + self.taskQueue.length = 0; + var visibleRegion = self.map.getVisibleRegion(); + self._redraw.call(self, { + visibleRegion: visibleRegion, + force: taskParams.force + }); + }); + } else { + var taskParams = self.taskQueue.pop(); + self.taskQueue.length = 0; + + var visibleRegion = self.map.getVisibleRegion(); + self._redraw.call(self, { + visibleRegion: visibleRegion, + force: taskParams.force + }); + } + }, + writable: false +}); + +Object.defineProperty(MarkerCluster.prototype, '_redraw', { + enumerable: false, + value: function (params) { + var self = this; + + if (self._isRemoved || self._stopRequest || self._isWorking || !self._isReady) { + return null; + } + self._isWorking = true; + var currentZoomLevel = self.map.getCameraZoom(), + prevResolution = self.get('resolution'); + + currentZoomLevel = currentZoomLevel < 0 ? 0 : currentZoomLevel; + self.set('zoom', currentZoomLevel); + + var resolution = 1; + resolution = self.maxZoomLevel > 3 && currentZoomLevel > 3 ? 2 : resolution; + resolution = self.maxZoomLevel > 5 && currentZoomLevel > 5 ? 3 : resolution; + resolution = self.maxZoomLevel > 7 && currentZoomLevel > 7 ? 4 : resolution; + resolution = self.maxZoomLevel > 9 && currentZoomLevel > 9 ? 5 : resolution; + resolution = self.maxZoomLevel > 11 && currentZoomLevel > 11 ? 6 : resolution; + resolution = self.maxZoomLevel > 13 && currentZoomLevel > 13 ? 7 : resolution; + resolution = self.maxZoomLevel > 15 && currentZoomLevel > 15 ? 8 : resolution; + resolution = self.maxZoomLevel > 17 && currentZoomLevel > 17 ? 9 : resolution; + resolution = self.maxZoomLevel > 19 && currentZoomLevel > 19 ? 10 : resolution; + resolution = self.maxZoomLevel > 21 && currentZoomLevel > 21 ? 11 : resolution; + + //------------------------------------------------------------------------ + // If the current viewport contains the previous viewport, + // and also the same resolution, + // skip this task except the params.force = true (such as addMarker) + //------------------------------------------------------------------------ + + var cellLen = resolution + 1; + var prevSWcell = self.get('prevSWcell'); + var prevNEcell = self.get('prevNEcell'); + + var distanceA = spherical.computeDistanceBetween(params.visibleRegion.farRight, params.visibleRegion.farLeft); + var distanceB = spherical.computeDistanceBetween(params.visibleRegion.farRight, params.visibleRegion.nearRight); + params.clusterDistance = Math.min(distanceA, distanceB) / 4; + var expandedRegion = params.visibleRegion; + + var swCell = geomodel.getGeocell(expandedRegion.southwest.lat, expandedRegion.southwest.lng, cellLen); + var neCell = geomodel.getGeocell(expandedRegion.northeast.lat, expandedRegion.northeast.lng, cellLen); + + if (!params.force && + prevSWcell === swCell && + prevNEcell === neCell) { + self.trigger('nextTask'); + return; + } + var nwCell = geomodel.getGeocell(expandedRegion.northeast.lat, expandedRegion.southwest.lng, cellLen); + var seCell = geomodel.getGeocell(expandedRegion.southwest.lat, expandedRegion.northeast.lng, cellLen); + + if (currentZoomLevel > self.maxZoomLevel || resolution === 0) { + resolution = self.OUT_OF_RESOLUTION; + } + self.set('resolution', resolution); + //console.log('--->prevResolution = ' + prevResolution + ', resolution = ' + resolution); + + var targetMarkers = []; + + if (self._isRemoved || self._stopRequest) { + self._isWorking = false; + return; + } + //---------------------------------------------------------------- + // Remove the clusters that is in outside of the visible region + //---------------------------------------------------------------- + if (resolution !== self.OUT_OF_RESOLUTION) { + self._clusters[resolution] = self._clusters[resolution] || {}; + } else { + self._clusters[resolution] = self._clusters[resolution] || []; + } + var deleteClusters = {}; + var keys, i, j; + var ignoreGeocells = []; + var allowGeocells = [swCell, neCell, nwCell, seCell]; + + var pos, cell; + var coners = [ + expandedRegion.northeast, + { + lat: expandedRegion.northeast.lat, + lng: expandedRegion.southwest.lng + }, + expandedRegion.southwest, + { + lat: expandedRegion.southwest.lat, + lng: expandedRegion.northeast.lng + }, + expandedRegion.northeast + ]; + for (j = 0; j < 4; j++) { + for (i = 0.25; i < 1; i += 0.25) { + pos = window.plugin.google.maps.geometry.spherical.interpolate(coners[j], coners[j + 1], i); + + cell = geomodel.getGeocell(pos.lat, pos.lng, cellLen); + if (allowGeocells.indexOf(cell) === -1) { + allowGeocells.push(cell); + } + } + } + + //console.log('---->548'); + var activeMarker = self.map.get('active_marker'); + var activeMarkerId = activeMarker ? activeMarker.getId() : null; + if (prevResolution === self.OUT_OF_RESOLUTION) { + if (resolution === self.OUT_OF_RESOLUTION) { + //-------------------------------------- + // Just camera move, no zoom changed + //-------------------------------------- + keys = Object.keys(self._markerMap); + keys.forEach(function (markerId) { + var marker = self._markerMap[markerId]; + if (self._isRemoved || + self._stopRequest || + !marker.isVisible() || + marker.get('_cluster').isRemoved || + marker.get('_cluster').isAdded) { + return; + } + + var geocell = marker.get('_cluster').geocell.substr(0, cellLen); + if (ignoreGeocells.indexOf(geocell) > -1) { + return; + } + + if (allowGeocells.indexOf(geocell) > -1) { + targetMarkers.push(marker); + return; + } + + if (expandedRegion.contains(marker.get('position'))) { + allowGeocells.push(geocell); + targetMarkers.push(marker); + } else { + ignoreGeocells.push(geocell); + } + }); + } else { + //-------------- + // zoom out + //-------------- + var marker; + var markerId; + while (self._clusters[self.OUT_OF_RESOLUTION].length > 0) { + marker = self._clusters[self.OUT_OF_RESOLUTION].shift(); + marker.get('_cluster').isAdded = false; + markerId = marker.__pgmId.split(/\-/)[1]; + deleteClusters[markerId] = 1; + + if (marker.__pgmId === activeMarkerId) { + marker.trigger(event.INFO_CLOSE); + marker.hideInfoWindow(); + } + if (self.debug) { + console.log('---> (js:489)delete:' + markerId); + } + } + keys = Object.keys(self._markerMap); + keys.forEach(function (markerId) { + var marker = self._markerMap[markerId]; + if (self._isRemoved || + !marker.isVisible() || + self._stopRequest || + marker.get('_cluster').isRemoved) { + return; + } + + var geocell = marker.get('_cluster').geocell.substr(0, cellLen); + if (ignoreGeocells.indexOf(geocell) > -1) { + return; + } + + if (allowGeocells.indexOf(geocell) > -1) { + targetMarkers.push(marker); + return; + } + + if (expandedRegion.contains(marker.get('position'))) { + allowGeocells.push(geocell); + targetMarkers.push(marker); + } else { + ignoreGeocells.push(geocell); + } + }); + } + + } else if (resolution === prevResolution) { + //console.log('--->prevResolution(' + prevResolution + ') == resolution(' + resolution + ')'); + //-------------------------------------- + // Just camera move, no zoom changed + //-------------------------------------- + + keys = Object.keys(self._clusters[prevResolution]); + keys.forEach(function (geocell) { + if (self._isRemoved || self._stopRequest) { + return; + } + var cluster = self._clusters[prevResolution][geocell]; + var bounds = cluster.getBounds(); + + if (!self._isRemoved && + !expandedRegion.contains(bounds.northeast) && + !expandedRegion.contains(bounds.southwest)) { + ignoreGeocells.push(geocell); + + if (cluster.getMode() === cluster.NO_CLUSTER_MODE) { + cluster.getMarkers().forEach(function (marker) { + var markerId = marker.__pgmId.split(/\-/)[1]; + deleteClusters[markerId] = 1; + marker.get('_cluster').isAdded = false; + if (self.debug) { + console.log('---> (js:534)delete:' + markerId); + } + if (marker.__pgmId === activeMarkerId) { + marker.trigger(event.INFO_CLOSE); + marker.hideInfoWindow(); + } + }); + } else { + deleteClusters[geocell] = 1; + if (self.debug) { + console.log('---> (js:549)delete:' + geocell); + } + } + cluster.remove(); + delete self._clusters[resolution][geocell]; + } + }); + keys = Object.keys(self._markerMap); + keys.forEach(function (markerId) { + var marker = self._markerMap[markerId]; + var geocell = marker.get('_cluster').geocell.substr(0, cellLen); + if (self._isRemoved || + self._stopRequest || + marker.get('_cluster').isRemoved || + !marker.isVisible() || + ignoreGeocells.indexOf(geocell) > -1 || + marker.get('_cluster').isAdded) { + return; + } + + if (allowGeocells.indexOf(geocell) > -1) { + targetMarkers.push(marker); + return; + } + + if (expandedRegion.contains(marker.get('position'))) { + targetMarkers.push(marker); + allowGeocells.push(geocell); + } else { + ignoreGeocells.push(geocell); + marker.get('_cluster').isAdded = false; + } + }); + + } else if (prevResolution in self._clusters) { + //console.log('--->prevResolution(' + prevResolution + ') != resolution(' + resolution + ')'); + + if (prevResolution < resolution) { + //-------------- + // zooming in + //-------------- + keys = Object.keys(self._clusters[prevResolution]); + keys.forEach(function (geocell) { + if (self._isRemoved) { + return; + } + var cluster = self._clusters[prevResolution][geocell]; + var noClusterMode = cluster.getMode() === cluster.NO_CLUSTER_MODE; + cluster.getMarkers().forEach(function (marker) { + if (self._isRemoved || + self._stopRequest) { + return; + } + var markerId = marker.__pgmId.split(/\-/)[1]; + marker.get('_cluster').isAdded = false; + //targetMarkers.push(markerOpts); + if (noClusterMode) { + if (self.debug) { + console.log('---> (js:581)delete:' + markerId); + } + if (marker.__pgmId === activeMarkerId) { + marker.trigger(event.INFO_CLOSE); + marker.hideInfoWindow(); + } + deleteClusters[markerId] = 1; + } + }); + if (!noClusterMode) { + if (self.debug) { + console.log('---> (js:597)delete:' + geocell); + } + deleteClusters[geocell] = 1; + } + cluster.remove(); + }); + } else { + //-------------- + // zooming out + //-------------- + keys = Object.keys(self._clusters[prevResolution]); + keys.forEach(function (geocell) { + if (self._stopRequest || + self._isRemoved) { + return; + } + var cluster = self._clusters[prevResolution][geocell]; + var noClusterMode = cluster.getMode() === cluster.NO_CLUSTER_MODE; + cluster.getMarkers().forEach(function (marker) { + marker.get('_cluster').isAdded = false; + var markerId = marker.__pgmId.split(/\-/)[1]; + if (noClusterMode) { + if (self.debug) { + console.log('---> (js:614)delete:' + markerId); + } + if (marker.__pgmId === activeMarkerId) { + marker.trigger(event.INFO_CLOSE); + marker.hideInfoWindow(); + } + deleteClusters[markerId] = 1; + } + }); + if (!noClusterMode) { + deleteClusters[geocell] = 1; + if (self.debug) { + console.log('---> (js:632)delete:' + geocell); + } + } + cluster.remove(); + + geocell = geocell.substr(0, cellLen); + }); + } + keys = Object.keys(self._markerMap); + keys.forEach(function (markerId) { + if (self._stopRequest || + self._isRemoved) { + return; + } + var marker = self._markerMap[markerId]; + var geocell = marker.get('_cluster').geocell.substr(0, cellLen); + if (marker.get('_cluster').isRemoved || + ignoreGeocells.indexOf(geocell) > -1) { + marker.get('_cluster').isAdded = false; + return; + } + if (marker.get('_cluster').isAdded) { + return; + } + + if (allowGeocells.indexOf(geocell) > -1) { + targetMarkers.push(marker); + return; + } + + if (expandedRegion.contains(marker.get('position'))) { + targetMarkers.push(marker); + allowGeocells.push(geocell); + } else { + ignoreGeocells.push(geocell); + marker.get('_cluster').isAdded = false; + } + }); + delete self._clusters[prevResolution]; + } else { + //console.log('-----> initialize'); + keys = Object.keys(self._markerMap); + keys.forEach(function (markerId) { + if (self._stopRequest || + self._isRemoved) { + return; + } + var marker = self._markerMap[markerId]; + var geocell = marker.get('_cluster').geocell.substr(0, cellLen); + if (marker.get('_cluster').isRemoved || + ignoreGeocells.indexOf(geocell) > -1) { + return; + } + + if (allowGeocells.indexOf(geocell) > -1) { + targetMarkers.push(marker); + return; + } + if (expandedRegion.contains(marker.get('position'))) { + targetMarkers.push(marker); + allowGeocells.push(geocell); + } else { + ignoreGeocells.push(geocell); + } + }); + } + + if (self._stopRequest || + self._isRemoved) { + self._isWorking = false; + return; + } + if (self.debug) { + console.log('targetMarkers = ' + targetMarkers.length); + } + + //-------------------------------- + // Pick up markers are containted in the current viewport. + //-------------------------------- + var new_or_update_clusters = []; + + if (params.force || + resolution == self.OUT_OF_RESOLUTION || + resolution !== prevResolution || + prevSWcell !== swCell || + prevNEcell !== neCell) { + + self.set('prevSWcell', swCell); + self.set('prevNEcell', neCell); + + if (resolution !== self.OUT_OF_RESOLUTION) { + + //------------------ + // Create clusters + //------------------ + var prepareClusters = {}; + targetMarkers.forEach(function (marker) { + if (marker.get('_cluster').isAdded) { + if (self.debug) { + console.log('isAdded', marker); + } + return; + } + var geocell = marker.get('_cluster').geocell.substr(0, resolution + 1); + prepareClusters[geocell] = prepareClusters[geocell] || []; + prepareClusters[geocell].push(marker); + + if (marker && marker.__pgmId === activeMarkerId) { + marker.trigger(event.INFO_CLOSE); + marker.hideInfoWindow(); + } + }); + + if (self.debug) { + console.log('prepareClusters = ', prepareClusters, targetMarkers); + } + + //------------------------------------------ + // Create/update clusters + //------------------------------------------ + keys = Object.keys(prepareClusters); + + var sortedClusters = []; + keys.forEach(function (geocell) { + var cluster = self.getClusterByGeocellAndResolution(geocell, resolution); + cluster.addMarkers(prepareClusters[geocell]); + + cluster._markerCenter = cluster.getBounds().getCenter(); + //cluster._distanceFrom0 = spherical.computeDistanceBetween({lat: 0, lng: 0}, cluster._markerCenter); + sortedClusters.push(cluster); + }); + + sortedClusters = sortedClusters.sort(function (a, b) { + return a.geocell.localeCompare(b.geocell); + }); + + //------------------------- + // Union close clusters + //------------------------- + var cluster, anotherCluster, distance; + var unionedMarkers = []; + i = 0; + while (i < sortedClusters.length) { + cluster = sortedClusters[i]; + for (j = i + 1; j < sortedClusters.length; j++) { + anotherCluster = sortedClusters[j]; + distance = spherical.computeDistanceBetween(cluster._markerCenter, anotherCluster._markerCenter); + if (distance < params.clusterDistance) { + if (self.debug) { + console.log('---> (js:763)delete:' + anotherCluster.geocell); + } + cluster.addMarkers(anotherCluster.getMarkers()); + deleteClusters[anotherCluster.getId()] = 1; + delete self._clusters[resolution][anotherCluster.geocell]; + self._clusters[resolution][cluster.geocell] = cluster; + i = j; + } else { + break; + } + } + i++; + cluster._markerCnt = cluster.getItemLength(); + unionedMarkers.push(cluster); + } + + unionedMarkers.forEach(function (cluster) { + + var icon = self.getClusterIcon(cluster), + clusterOpts = { + 'count': cluster.getItemLength(), + 'position': cluster.getBounds().getCenter(), + '__pgmId': cluster.getId() + }; + + if (self.debug) { + clusterOpts.geocell = cluster.geocell; + } + + if (icon) { + clusterOpts.icon = icon; + clusterOpts.isClusterIcon = true; + if (cluster.getMode() === cluster.NO_CLUSTER_MODE) { + cluster.getMarkers().forEach(function (marker) { + var markerId = marker.__pgmId.split(/\-/)[1]; + deleteClusters[markerId] = 1; + if (self.debug) { + console.log('---> (js:800)delete:' + markerId); + } + }); + } + if (self.debug) { + console.log('---> (js:805)add:' + clusterOpts.__pgmId, icon); + var geocell = clusterOpts.geocell.substr(0, cellLen); + var bounds = self._geocellBounds[geocell] || geomodel.computeBox(geocell); + self._geocellBounds[geocell] = bounds; + self.map.addPolyline({ + color: 'blue', + points: [ + bounds.southwest, + { + lat: bounds.southwest.lat, + lng: bounds.northeast.lng + }, + bounds.northeast, + { + lat: bounds.northeast.lat, + lng: bounds.southwest.lng + }, + bounds.southwest + ] + }, function (polyline) { + self._clusterBounds.push(polyline); + }); + } + cluster.setMode(cluster.CLUSTER_MODE); + new_or_update_clusters.push(clusterOpts); + return; + } + + cluster.getMarkers().forEach(function (marker) { + if (!marker.get('_cluster').isAdded) { + return; + } + var markerId = marker.__pgmId.split(/\-/)[1]; + delete deleteClusters[markerId]; + marker.get('_cluster').isClusterIcon = false; + if (self.debug) { + console.log('---> (js:831)add:' + markerId + ', isAdded = ' + marker.get('_cluster').isAdded); + marker.set('title', markerId, true); + } + + var opts = marker.getOptions(); + opts.__pgmId = markerId; + new_or_update_clusters.push(opts); + }); + cluster.setMode(cluster.NO_CLUSTER_MODE); + }); + } else { + cellLen = swCell.length; + targetMarkers.forEach(function (marker) { + if (marker.get('_cluster').isAdded) { + return; + } + var markerId = marker.__pgmId.split(/\-/)[1]; + marker.get('_cluster').isClusterIcon = false; + if (self.debug) { + console.log('---> (js:859)add:' + markerId); + marker.set('title', markerId, true); + } + delete deleteClusters[markerId]; + marker.get('_cluster').isAdded = true; + new_or_update_clusters.push(marker.getOptions()); + self._clusters[self.OUT_OF_RESOLUTION].push(marker); + }); + } + } + var delete_clusters = Object.keys(deleteClusters); + + if (self._stopRequest || + new_or_update_clusters.length === 0 && delete_clusters.length === 0) { + self.trigger('nextTask'); + return; + } + + if (self._stopRequest || + self._isRemoved) { + self._isWorking = false; + return; + } + + self.exec.call(self, function (allResults) { + var markerIDs = Object.keys(allResults); + markerIDs.forEach(function (markerId) { + if (!self._markerMap[markerId]) { + return; + } + var marker = self._markerMap[markerId]; + var size = allResults[markerId]; + if (typeof marker.get('icon') === 'string') { + marker.set('icon', { + 'url': marker.get('icon'), + 'size': size, + 'anchor': [size.width / 2, size.height] + }, true); + } else { + var icon = marker.get('icon') || {}; + icon.size = icon.size || size; + icon.anchor = icon.anchor || [size.width / 2, size.height]; + self._markerMap[markerId].set('icon', icon, true); + } + marker.set('infoWindowAnchor', marker.get('infoWindowAnchor') || [marker.get('icon').size.width / 2, 0], true); + }); + self.trigger('nextTask'); + }, self.errorHandler, self.getPluginName(), 'redrawClusters', [self.getId(), { + 'resolution': resolution, + 'new_or_update': new_or_update_clusters, + 'delete': delete_clusters + }], { + sync: true + }); + /* + console.log({ + 'resolution': resolution, + 'new_or_update': new_or_update_clusters, + 'delete': delete_clusters + }); + */ + } +}); + +MarkerCluster.prototype.getClusterIcon = function (cluster) { + var self = this, + hit, + clusterCnt = cluster.getItemLength(); + + for (var i = 0; i < self.icons.length; i++) { + hit = false; + if ('min' in self.icons[i]) { + if (clusterCnt >= self.icons[i].min) { + if ('max' in self.icons[i]) { + hit = (clusterCnt <= self.icons[i].max); + } else { + hit = true; + } + } + } else { + if ('max' in self.icons[i]) { + hit = (clusterCnt <= self.icons[i].max); + } + } + if (hit) { + return self.icons[i]; + } + } + return null; +}; + +MarkerCluster.prototype._createMarker = function (markerOpts) { + var self = this; + var markerId = self.getId() + '-marker_' + Math.floor(Date.now() * Math.random()); + var marker = new Marker(self.getMap(), markerOpts, exec, { + className: 'MarkerCluster', + __pgmId: markerId + }); + marker._privateInitialize(markerOpts); + delete marker._privateInitialize; + + // Recalulate geocell if marker position is changed. + marker.onThrottled('position_changed', function(ignore, newPosition) { + marker.get('_cluster').geocell = geomodel.getGeocell(newPosition.lat, newPosition.lng, self.MAX_RESOLUTION + 1); + }, 500); + marker.one(marker.getId() + '_remove', function () { + self._removeMarkerById(markerId); + }); + return marker; +}; + +MarkerCluster.prototype.getClusterByGeocellAndResolution = function (geocell, resolution) { + var self = this; + geocell = geocell.substr(0, resolution + 1); + + var cluster = self._clusters[resolution][geocell]; + if (!cluster) { + cluster = new Cluster(geocell, geocell); + self._clusters[resolution][geocell] = cluster; + } + return cluster; +}; + +/* + * http://jsfiddle.net/john_s/BHHs8/6/ + */ +function latRad(lat) { + var sin = Math.sin(lat * Math.PI / 180); + var radX2 = Math.log((1 + sin) / (1 - sin)) / 2; + return Math.max(Math.min(radX2, Math.PI), -Math.PI) / 2; +} + +function zoom(mapPx, worldPx, fraction) { + return Math.log(mapPx / worldPx / fraction) / Math.LN2; +} + +function computeZoom(bounds, mapDim) { + var tileSize = cordova.platformId === 'browser' ? 256 : 512; + var ZOOM_MAX = 21; + + var ne = bounds.northeast; + var sw = bounds.southwest; + + var latFraction = (latRad(ne.lat) - latRad(sw.lat)) / Math.PI; + + var lngDiff = ne.lng - sw.lng; + var lngFraction = ((lngDiff < 0) ? (lngDiff + 360) : lngDiff) / 360; + + var latZoom = zoom(mapDim.offsetHeight, tileSize, latFraction); + var lngZoom = zoom(mapDim.offsetWidth, tileSize, lngFraction); + + return Math.min(latZoom, lngZoom, ZOOM_MAX); +} + +module.exports = MarkerCluster; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Overlay.js b/docs/plugins/cordova-plugin-googlemaps/www/Overlay.js new file mode 100644 index 0000000..89185e7 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Overlay.js @@ -0,0 +1,122 @@ +cordova.define("cordova-plugin-googlemaps.Overlay", function(require, exports, module) { +var BaseClass = require('./BaseClass'), + utils = require('cordova/utils'), + BaseArrayClass = require('./BaseArrayClass'); + +/***************************************************************************** + * Overlay Class + *****************************************************************************/ +var Overlay = function (map, options, className, _exec, extras) { + extras = extras || {}; + BaseClass.apply(this); + + var self = this; + + //----------------------------------------------- + // Sets the initialize option to each property + //----------------------------------------------- + var ignores = ['map', '__pgmId', 'hashCode', 'type']; + if (extras.ignores) { + ignores = ignores.concat(extras.ignores); + } + for (var key in options) { + if (ignores.indexOf(key) === -1) { + self.set(key, options[key]); + } + } + + //------------------------------------------------------------------------------- + // If app code wants to execute some method before `_isReady = true`, + // just stack in to the internal queue. + // If this overlay is ready, execute it. + //------------------------------------------------------------------------------- + var cmdQueue = new BaseArrayClass(); + cmdQueue.on('insert_at', function () { + if (!self._isReady) { + return; + } + var cmd; + while (cmdQueue.getLength() > 0) { + cmd = cmdQueue.removeAt(0, true); + if (cmd && cmd.target && cmd.args && cmd.args[0] !== 'nop') { + _exec.apply(cmd.target, cmd.args); + } + } + }); + + Object.defineProperty(self, '_cmdQueue', { + enumerable: false, + value: cmdQueue, + writable: false + }); + + Object.defineProperty(self, '_isReady', { + value: false, + writable: true + }); + Object.defineProperty(self, 'map', { + value: map, + writable: false + }); + Object.defineProperty(self, '__pgmId', { + value: extras.__pgmId || (className.toLowerCase()) + '_' + this.hashCode, + writable: false + }); + Object.defineProperty(self, 'type', { + value: className, + writable: false + }); + + Object.defineProperty(self, 'getPluginName', { + writable: false, + value: function () { + return this.map.getId() + '-' + className.toLowerCase(); + } + }); +}; + +utils.extend(Overlay, BaseClass); + +Overlay.prototype._privateInitialize = function (options) { + var self = this; + //----------------------------------------------- + // Sets the initialize option to each property + //----------------------------------------------- + if (options) { + var ignores = ['map', '__pgmId', 'hashCode', 'type']; + for (var key in options) { + if (ignores.indexOf(key) === -1) { + self.set(key, options[key], true); + } + } + } + + //----------------------------------------------- + // Trigger internal command queue + //----------------------------------------------- + Object.defineProperty(self, '_isReady', { + value: true, + writable: false + }); + self.exec('nop'); +}; + +Overlay.prototype.exec = function () { + this._cmdQueue.push.call(this._cmdQueue, { + target: this, + args: Array.prototype.slice.call(arguments, 0) + }); +}; +Overlay.prototype.getId = function () { + return this.__pgmId; +}; +Overlay.prototype.getMap = function () { + return this.map; +}; +Overlay.prototype.getHashCode = function () { + return this.hashCode; +}; + +module.exports = Overlay; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Polygon.js b/docs/plugins/cordova-plugin-googlemaps/www/Polygon.js new file mode 100644 index 0000000..2c38a77 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Polygon.js @@ -0,0 +1,250 @@ +cordova.define("cordova-plugin-googlemaps.Polygon", function(require, exports, module) { var utils = require('cordova/utils'), + common = require('./Common'), + Overlay = require('./Overlay'); + +/***************************************************************************** + * Polygon Class + *****************************************************************************/ +var Polygon = function (map, polygonOptions, _exec) { + Overlay.call(this, map, polygonOptions, 'Polygon', _exec); + + var self = this; + var polygonId = this.getId(); + + //-------------------------- + // points property + //-------------------------- + var pointsProperty = common.createMvcArray(polygonOptions.points); + pointsProperty.on('set_at', function (index) { + var value = common.getLatLng(pointsProperty.getAt(index)); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setPointAt', [polygonId, index, value]); + }); + pointsProperty.on('insert_at', function (index) { + var value = common.getLatLng(pointsProperty.getAt(index)); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'insertPointAt', [polygonId, index, value]); + }); + pointsProperty.on('remove_at', function (index) { + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'removePointAt', [polygonId, index]); + }); + + Object.defineProperty(self, 'points', { + value: pointsProperty, + writable: false + }); + //-------------------------- + // holes property + //-------------------------- + var holesProperty = common.createMvcArray(polygonOptions.holes); + var _holes = common.createMvcArray(holesProperty.getArray()); + + holesProperty.on('set_at', function (index) { + var value = common.getLatLng(holesProperty.getAt(index)); + _holes.setAt(index, value); + }); + holesProperty.on('remove_at', function (index) { + _holes.removeAt(index); + }); + holesProperty.on('insert_at', function (index) { + var array = holesProperty.getAt(index); + if (array && (array instanceof Array || Array.isArray(array))) { + array = common.createMvcArray(array); + } + array.on('insert_at', function (idx) { + var value = common.getLatLng(array.getAt(idx)); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'insertPointOfHoleAt', [polygonId, index, idx, value]); + }); + array.on('set_at', function (idx) { + var value = common.getLatLng(array.getAt(idx)); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setPointOfHoleAt', [polygonId, index, idx, value]); + }); + array.on('remove_at', function (idx) { + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'removePointOfHoleAt', [polygonId, index, idx]); + }); + + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'insertHoleAt', [polygonId, index, array.getArray()]); + }); + + Object.defineProperty(self, 'holes', { + value: holesProperty, + writable: false + }); + + //-------------------------- + // other properties + //--------------------------. + // var ignores = ['map', '__pgmId', 'hashCode', 'type', 'points', 'holes']; + // for (var key in polygonOptions) { + // if (ignores.indexOf(key) === -1) { + // self.set(key, polygonOptions[key]); + // } + // } + //----------------------------------------------- + // Sets event listeners + //----------------------------------------------- + self.on('clickable_changed', function () { + var clickable = self.get('clickable'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setClickable', [self.getId(), clickable]); + }); + self.on('geodesic_changed', function () { + var geodesic = self.get('geodesic'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setGeodesic', [self.getId(), geodesic]); + }); + self.on('zIndex_changed', function () { + var zIndex = self.get('zIndex'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setZIndex', [self.getId(), zIndex]); + }); + self.on('visible_changed', function () { + var visible = self.get('visible'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setVisible', [self.getId(), visible]); + }); + self.on('strokeWidth_changed', function () { + var width = self.get('strokeWidth'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setStrokeWidth', [self.getId(), width]); + }); + self.on('strokeColor_changed', function () { + var color = self.get('strokeColor'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setStrokeColor', [self.getId(), common.HTMLColor2RGBA(color, 0.75)]); + }); + self.on('fillColor_changed', function () { + var color = self.get('fillColor'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setFillColor', [self.getId(), common.HTMLColor2RGBA(color, 0.75)]); + }); + +}; + +utils.extend(Polygon, Overlay); + +Polygon.prototype.remove = function (callback) { + var self = this; + if (self._isRemoved) { + if (typeof callback === 'function') { + return; + } else { + return Promise.resolve(); + } + } + Object.defineProperty(self, '_isRemoved', { + value: true, + writable: false + }); + self.trigger(this.__pgmId + '_remove'); + + var resolver = function(resolve, reject) { + self.exec.call(self, + function() { + self.destroy(); + resolve.call(self); + }, + reject.bind(self), + self.getPluginName(), 'remove', [self.getId()], { + remove: true + }); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } + +}; + +Polygon.prototype.setPoints = function (points) { + var self = this; + var mvcArray = self.points; + mvcArray.empty(true); + + var i; + + for (i = 0; i < points.length; i++) { + mvcArray.push(common.getLatLng(points[i]), true); + } + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setPoints', [self.__pgmId, mvcArray.getArray()]); + return self; +}; +Polygon.prototype.getPoints = function () { + return this.points; +}; +Polygon.prototype.setHoles = function (holes) { + var self = this; + var mvcArray = this.holes; + mvcArray.empty(true); + + holes = holes || []; + if (holes.length > 0 && !utils.isArray(holes[0])) { + holes = [holes]; + } + holes.forEach(function (hole) { + if (!utils.isArray(hole)) { + hole = [hole]; + mvcArray.push(hole, true); + } else { + var newHole = []; + for (var i = 0; i < hole.length; i++) { + newHole.push(common.getLatLng(hole[i])); + } + mvcArray.push(newHole, true); + } + }); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setHoles', [self.__pgmId, mvcArray.getArray()]); + return this; +}; +Polygon.prototype.getHoles = function () { + return this.holes; +}; +Polygon.prototype.setFillColor = function (color) { + this.set('fillColor', color); + return this; +}; +Polygon.prototype.getFillColor = function () { + return this.get('fillColor'); +}; +Polygon.prototype.setStrokeColor = function (color) { + this.set('strokeColor', color); + return this; +}; +Polygon.prototype.getStrokeColor = function () { + return this.get('strokeColor'); +}; +Polygon.prototype.setStrokeWidth = function (width) { + this.set('strokeWidth', width); + return this; +}; +Polygon.prototype.getStrokeWidth = function () { + return this.get('strokeWidth'); +}; +Polygon.prototype.setVisible = function (visible) { + visible = common.parseBoolean(visible); + this.set('visible', visible); + return this; +}; +Polygon.prototype.getVisible = function () { + return this.get('visible'); +}; +Polygon.prototype.setClickable = function (clickable) { + clickable = common.parseBoolean(clickable); + this.set('clickable', clickable); + return this; +}; +Polygon.prototype.getClickable = function () { + return this.get('clickable'); +}; +Polygon.prototype.setGeodesic = function (geodesic) { + geodesic = common.parseBoolean(geodesic); + this.set('geodesic', geodesic); + return this; +}; +Polygon.prototype.getGeodesic = function () { + return this.get('geodesic'); +}; +Polygon.prototype.setZIndex = function (zIndex) { + this.set('zIndex', zIndex); + return this; +}; +Polygon.prototype.getZIndex = function () { + return this.get('zIndex'); +}; + +module.exports = Polygon; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Polyline.js b/docs/plugins/cordova-plugin-googlemaps/www/Polyline.js new file mode 100644 index 0000000..4b422b2 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Polyline.js @@ -0,0 +1,191 @@ +cordova.define("cordova-plugin-googlemaps.Polyline", function(require, exports, module) { var utils = require('cordova/utils'), + common = require('./Common'), + Overlay = require('./Overlay'); + +/***************************************************************************** + * Polyline Class + *****************************************************************************/ +var Polyline = function (map, polylineOptions, _exec) { + Overlay.call(this, map, polylineOptions, 'Polyline', _exec, { + 'ignores': ['points'] + }); + + var self = this; + var polylineId = this.getId(); + + var pointsProperty = common.createMvcArray(polylineOptions.points); + pointsProperty.on('set_at', function (index) { + if (self._isRemoved) return; + var value = common.getLatLng(pointsProperty.getAt(index)); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setPointAt', [polylineId, index, value]); + }); + pointsProperty.on('insert_at', function (index) { + if (self._isRemoved) return; + var value = common.getLatLng(pointsProperty.getAt(index)); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'insertPointAt', [polylineId, index, value]); + }); + pointsProperty.on('remove_at', function (index) { + if (self._isRemoved) return; + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'removePointAt', [polylineId, index]); + }); + + Object.defineProperty(self, 'points', { + value: pointsProperty, + writable: false + }); + //----------------------------------------------- + // Sets the initialize option to each property + //----------------------------------------------- + // var ignores = ['map', '__pgmId', 'hashCode', 'type', 'points']; + // for (var key in polylineOptions) { + // if (ignores.indexOf(key) === -1) { + // self.set(key, polylineOptions[key]); + // } + // } + + //----------------------------------------------- + // Sets event listeners + //----------------------------------------------- + self.on('geodesic_changed', function () { + if (self._isRemoved) return; + var geodesic = self.get('geodesic'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setGeodesic', [self.getId(), geodesic]); + }); + self.on('zIndex_changed', function () { + if (self._isRemoved) return; + var zIndex = self.get('zIndex'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setZIndex', [self.getId(), zIndex]); + }); + self.on('clickable_changed', function () { + if (self._isRemoved) return; + var clickable = self.get('clickable'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setClickable', [self.getId(), clickable]); + }); + self.on('visible_changed', function () { + if (self._isRemoved) return; + var visible = self.get('visible'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setVisible', [self.getId(), visible]); + }); + self.on('strokeWidth_changed', function () { + if (self._isRemoved) return; + var strokeWidth = self.get('strokeWidth'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setStrokeWidth', [self.getId(), strokeWidth]); + }); + self.on('strokeColor_changed', function () { + if (self._isRemoved) return; + var color = self.get('strokeColor'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setStrokeColor', [self.getId(), common.HTMLColor2RGBA(color, 0.75)]); + }); + +}; + +utils.extend(Polyline, Overlay); + +Polyline.prototype.setPoints = function (points) { + var self = this; + var mvcArray = self.points; + mvcArray.empty(true); + + var i; + + for (i = 0; i < points.length; i++) { + mvcArray.push({ + 'lat': points[i].lat, + 'lng': points[i].lng + }, true); + } + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setPoints', [self.__pgmId, mvcArray.getArray()]); + return self; +}; +Polyline.prototype.getPoints = function () { + return this.points; +}; +Polyline.prototype.setStrokeColor = function (color) { + this.set('strokeColor', color); + return this; +}; +Polyline.prototype.getStrokeColor = function () { + return this.get('strokeColor'); +}; +Polyline.prototype.setStrokeWidth = function (width) { + this.set('strokeWidth', width); + return this; +}; +Polyline.prototype.getStrokeWidth = function () { + return this.get('strokeWidth'); +}; +Polyline.prototype.setVisible = function (visible) { + visible = common.parseBoolean(visible); + this.set('visible', visible); + return this; +}; +Polyline.prototype.getVisible = function () { + return this.get('visible'); +}; +Polyline.prototype.setClickable = function (clickable) { + clickable = common.parseBoolean(clickable); + this.set('clickable', clickable); + return this; +}; +Polyline.prototype.getClickable = function () { + return this.get('clickable'); +}; +Polyline.prototype.setGeodesic = function (geodesic) { + geodesic = common.parseBoolean(geodesic); + this.set('geodesic', geodesic); + return this; +}; +Polyline.prototype.getGeodesic = function () { + return this.get('geodesic'); +}; +Polyline.prototype.setZIndex = function (zIndex) { + this.set('zIndex', zIndex); + return this; +}; +Polyline.prototype.getZIndex = function () { + return this.get('zIndex'); +}; + +Polyline.prototype.remove = function (callback) { + var self = this; + if (self._isRemoved) { + if (typeof callback === 'function') { + return; + } else { + return Promise.resolve(); + } + } + Object.defineProperty(self, '_isRemoved', { + value: true, + writable: false + }); + + var resolver = function (resolve, reject) { + self.exec.call(self, + function () { + self.destroy(); + resolve.call(self); + }, + reject.bind(self), + self.getPluginName(), 'remove', [self.getId()], { + remove: true + }); + }; + + var result; + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + result = new Promise(resolver); + } + + if (self.points) { + self.points.empty(); + } + self.trigger(self.__pgmId + '_remove'); + + return result; +}; +module.exports = Polyline; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Promise.js b/docs/plugins/cordova-plugin-googlemaps/www/Promise.js new file mode 100644 index 0000000..c5db7a4 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Promise.js @@ -0,0 +1,23 @@ +cordova.define("cordova-plugin-googlemaps.Promise", function(require, exports, module) { // Copyright (c) 2013 Forbes Lindesay +// +// 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. +!function n(t,e,r){function o(u,f){if(!e[u]){if(!t[u]){var c="function"==typeof require&&require;if(!f&&c)return c(u,!0);if(i)return i(u,!0);var s=new Error("Cannot find module '"+u+"'");throw s.code="MODULE_NOT_FOUND",s}var l=e[u]={exports:{}};t[u][0].call(l.exports,function(n){var e=t[u][1][n];return o(e?e:n)},l,l.exports,n,t,e,r)}return e[u].exports}for(var i="function"==typeof require&&require,u=0;ul){for(var t=0,e=f.length-s;e>t;t++)f[t]=f[t+s];f.length-=s,s=0}}f.length=0,s=0,c=!1}function o(n){var t=1,e=new a(n),r=document.createTextNode("");return e.observe(r,{characterData:!0}),function(){t=-t,r.data=t}}function i(n){return function(){function t(){clearTimeout(e),clearInterval(r),n()}var e=setTimeout(t,0),r=setInterval(t,50)}}t.exports=e;var u,f=[],c=!1,s=0,l=1024,a=n.MutationObserver||n.WebKitMutationObserver;u="function"==typeof a?o(r):i(r),e.requestFlush=u,e.makeRequestCallFromTimer=i}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],5:[function(n,t,e){"function"!=typeof Promise.prototype.done&&(Promise.prototype.done=function(n,t){var e=arguments.length?this.then.apply(this,arguments):this;e.then(null,function(n){setTimeout(function(){throw n},0)})})},{}],6:[function(n,t,e){n("asap");"undefined"==typeof Promise&&(Promise=n("./lib/core.js"),n("./lib/es6-extensions.js")),n("./polyfill-done.js")},{"./lib/core.js":1,"./lib/es6-extensions.js":2,"./polyfill-done.js":5,asap:3}]},{},[6]); +//# sourceMappingURL=promise-7.0.4.min.js.map + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/StreetViewPanorama.js b/docs/plugins/cordova-plugin-googlemaps/www/StreetViewPanorama.js new file mode 100644 index 0000000..e3d62be --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/StreetViewPanorama.js @@ -0,0 +1,322 @@ +cordova.define("cordova-plugin-googlemaps.StreetViewPanorama", function(require, exports, module) { var utils = require('cordova/utils'), + common = require('./Common'), + event = require('./event'), + Overlay = require('./Overlay'); + +/***************************************************************************** + * StreetViewPanorama Class + *****************************************************************************/ +var exec; +var StreetViewPanorama = function(streetViewId, _exec) { + exec = _exec; + Overlay.call(this, this, {}, 'StreetViewPanorama', _exec, { + __pgmId: streetViewId + }); + + var self = this; + self.set('visible', true); + self.set('gesture_panning', true); + self.set('gesture_zoom', true); + self.set('control_navigation', true); + self.set('control_streetNames', true); + self.set('camera_zoom', 0); + self.set('camera_tilt', 0); + self.set('camera_bearing', 0); + + //----------------------------------------------- + // Sets event listeners + //----------------------------------------------- + self.on('gesture_panning_changed', function() { + var booleanValue = self.get('gesture_panning'); + self.exec.call(self, null, self.errorHandler, self.__pgmId, 'setPanningGesturesEnabled', [booleanValue]); + }); + self.on('gesture_zoom_changed', function() { + var booleanValue = self.get('gesture_zoom'); + self.exec.call(self, null, self.errorHandler, self.__pgmId, 'setZoomGesturesEnabled', [booleanValue]); + }); + self.on('control_navigation_changed', function() { + var booleanValue = self.get('control_navigation'); + self.exec.call(self, null, self.errorHandler, self.__pgmId, 'setNavigationEnabled', [booleanValue]); + }); + self.on('control_streetNames_changed', function() { + var booleanValue = self.get('control_streetNames'); + self.exec.call(self, null, self.errorHandler, self.__pgmId, 'setStreetNamesEnabled', [booleanValue]); + }); + self.on('visible_changed', function() { + var booleanValue = self.get('visible'); + self.exec.call(self, null, self.errorHandler, self.__pgmId, 'setVisible', [booleanValue]); + }); +}; + + +utils.extend(StreetViewPanorama, Overlay); + +StreetViewPanorama.prototype.getPluginName = function() { + return this.map.getId() + '-streetview'; +}; + +StreetViewPanorama.prototype.getHashCode = function() { + return this.hashCode; +}; + +StreetViewPanorama.prototype.getId = function() { + return this.__pgmId; +}; +StreetViewPanorama.prototype.getPanorama = function(meta, panorama, div, options) { + var self = this, + args = [meta]; + options = options || {}; + + + //self.set('clickable', options.clickable === false ? false : true); + self.set('visible', options.visible === false ? false : true, true); + args.push(options); + + // Initial camera options + if ('camera' in options) { + self.set('camera', options.camera, true); + if ('zoom' in options.camera) { + self.set('camera_zoom', options.camera.zoom, true); + } + if ('bearing' in options.camera) { + self.set('camera_bearing', options.camera.bearing, true); + } + if ('tilt' in options.camera) { + self.set('camera_tilt', options.camera.tilt, true); + } + if ('target' in options.camera) { + self.set('position', options.camera.target, true); + } + } + + // Gesture options + options.gestures = options.gestures || {}; + options.gestures.panning = common.defaultTrueOption(options.gestures.panning); + options.gestures.zoom = common.defaultTrueOption(options.gestures.zoom); + self.set('gesture_panning', options.gestures.panning, true); + self.set('gesture_zoom', options.gestures.zoom, true); + + // Controls options + options.controls = options.controls || {}; + options.controls.navigation = common.defaultTrueOption(options.controls.navigation); + options.controls.streetNames = common.defaultTrueOption(options.controls.streetNames); + self.set('control_navigation', options.controls.navigation, true); + self.set('control_streetNames', options.controls.streetNames, true); + + // Gets the map div size. + // The plugin needs to consider the viewport zoom ratio + // for the case window.innerHTML > body.offsetWidth. + self.set('div', div); + var elemId = common.getPluginDomId(div); + args.push(elemId); + + exec.call({ + _isReady: true + }, function() { + + //------------------------------------------------------------------------ + // Clear background colors of map div parents after the map is created + //------------------------------------------------------------------------ + var positionCSS; + for (var i = 0; i < div.children.length; i++) { + positionCSS = common.getStyle(div.children[i], 'position'); + if (positionCSS === 'static') { + div.children[i].style.position = 'relative'; + } + } + //div.insertBefore(self._layers.info, div.firstChild); + + + while (div.parentNode) { + div.style.backgroundColor = 'rgba(0,0,0,0) !important'; + + common.attachTransparentClass(div); + + div = div.parentNode; + } + cordova.fireDocumentEvent('plugin_touch', { + force: true + }); + self._privateInitialize(); + delete self._privateInitialize; + + self.trigger(event.PANORAMA_READY, self); + }, self.errorHandler, 'CordovaGoogleMaps', 'getPanorama', args, { + sync: true + }); +}; + +StreetViewPanorama.prototype.setVisible = function(isVisible) { + this.set('visible', common.parseBoolean(isVisible)); + return this; +}; + +StreetViewPanorama.prototype.getVisible = function() { + return this.get('visible'); +}; + +StreetViewPanorama.prototype.getDiv = function() { + return this.get('div'); +}; +StreetViewPanorama.prototype.getMap = function() { + // stub +}; + +StreetViewPanorama.prototype.setPanningGesturesEnabled = function (boolValue) { + boolValue = common.parseBoolean(boolValue); + this.set('gesture_panning', boolValue); + return this; +}; +StreetViewPanorama.prototype.getPanningGesturesEnabled = function () { + return this.get('gesture_panning'); +}; +StreetViewPanorama.prototype.setZoomGesturesEnabled = function (boolValue) { + boolValue = common.parseBoolean(boolValue); + this.set('gesture_zoom', boolValue); + return this; +}; +StreetViewPanorama.prototype.getZoomGesturesEnabled = function () { + return this.get('gesture_zoom'); +}; +StreetViewPanorama.prototype.setNavigationEnabled = function (boolValue) { + boolValue = common.parseBoolean(boolValue); + this.set('control_navigation', boolValue); + return this; +}; +StreetViewPanorama.prototype.getNavigationEnabled = function () { + return this.get('control_navigation'); +}; +StreetViewPanorama.prototype.setStreetNamesEnabled = function (boolValue) { + boolValue = common.parseBoolean(boolValue); + this.set('control_streetNames', boolValue); + return this; +}; +StreetViewPanorama.prototype.getStreetNamesEnabled = function () { + return this.get('control_streetNames'); +}; +StreetViewPanorama.prototype.getLinks = function () { + return this.get('links'); +}; +StreetViewPanorama.prototype.getLocation = function () { + return this.get('location'); +}; +StreetViewPanorama.prototype.getPanoId = function () { + return this.get('pano'); +}; +StreetViewPanorama.prototype.getPosition = function () { + return this.get('position'); +}; + +StreetViewPanorama.prototype.setPosition = function(cameraPosition, callback) { + var self = this; + cameraPosition = cameraPosition || {}; + if (typeof cameraPosition === 'string') { + // case: panorama.setPosition(panoId); + cameraPosition = { + target : cameraPosition + }; + } + if (typeof cameraPosition.target === 'object') { + // case: panorama.setPosition({ + // target: {lat: ..., lng: ...} + // }); + self.set('position', cameraPosition.target); + } + self.exec.call(self, function() { + if (typeof callback === 'function') { + callback.call(self); + } + }, self.errorHandler, self.__pgmId, 'setPosition', [cameraPosition], { + sync: true + }); + return this; +}; + +StreetViewPanorama.prototype.setPov = function(pov, callback) { + var self = this; + pov = pov || {}; + if ('zoom' in pov) { + self.set('camera_zoom', pov.zoom); + } + if ('bearing' in pov) { + self.set('camera_bearing', pov.bearing); + } + if ('tilt' in pov) { + self.set('camera_tilt', pov.tilt); + } + self.exec.call(self, function() { + if (typeof callback === 'function') { + callback.call(self); + } + }, self.errorHandler, self.__pgmId, 'setPov', [pov], { + sync: true + }); + return this; +}; + + +StreetViewPanorama.prototype.remove = function(callback) { + var self = this; + + var resolver = function(resolve, reject) { + self.exec.call(self, + function() { + self.destroy(); + resolve.call(self); + }, + reject.bind(self), + 'CordovaGoogleMaps', 'removeMap', [self.__pgmId], { + sync: true, + remove: true + }); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } + + + + + + + + + self.trigger('remove'); +}; +StreetViewPanorama.prototype._onPanoramaCameraChange = function(eventName, cameraPosition) { + var self = this; + self.set('camera', utils.clone(self.get('camera') || {}, cameraPosition)); + self.set('camera_zoom', cameraPosition.zoom); + self.set('camera_bearing', cameraPosition.bearing); + self.set('camera_tilt', cameraPosition.viewAngle || cameraPosition.tilt); + self.set('links', cameraPosition.links || []); + if (self._isReady) { + self._onPanoramaEvent(eventName, cameraPosition); + } +}; + +StreetViewPanorama.prototype._onPanoramaLocationChange = function(eventName, panoramaLocation) { + var self = this; + self.set('location', panoramaLocation); + self.set('pano', panoramaLocation ? panoramaLocation.panoId : null); + self.set('position', panoramaLocation ? panoramaLocation.latLng : null); + if (self._isReady) { + self._onPanoramaEvent(eventName, panoramaLocation); + } +}; + +StreetViewPanorama.prototype._onPanoramaEvent = function() { + var self = this; + if (self._isReady) { + var args = Array.prototype.slice.call(arguments, 0); + args.push(self); + self.trigger.apply(self, args); + } +}; + +module.exports = StreetViewPanorama; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/Thread.js b/docs/plugins/cordova-plugin-googlemaps/www/Thread.js new file mode 100644 index 0000000..3ac1417 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/Thread.js @@ -0,0 +1,383 @@ +cordova.define("cordova-plugin-googlemaps.Thread", function(require, exports, module) { // Thread.js +// https://threadjs.deep-rain.com +// https://github.com/deep-rain/thread +// Apache License +// Version 2.0, January 2004 +// http://www.apache.org/licenses/ +// +// TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION +// +// 1. Definitions. +// +// 'License' shall mean the terms and conditions for use, reproduction, +// and distribution as defined by Sections 1 through 9 of this document. +// +// 'Licensor' shall mean the copyright owner or entity authorized by +// the copyright owner that is granting the License. +// +// 'Legal Entity' shall mean the union of the acting entity and all +// other entities that control, are controlled by, or are under common +// control with that entity. For the purposes of this definition, +// 'control' means (i) the power, direct or indirect, to cause the +// direction or management of such entity, whether by contract or +// otherwise, or (ii) ownership of fifty percent (50%) or more of the +// outstanding shares, or (iii) beneficial ownership of such entity. +// +// 'You' (or 'Your') shall mean an individual or Legal Entity +// exercising permissions granted by this License. +// +// 'Source' form shall mean the preferred form for making modifications, +// including but not limited to software source code, documentation +// source, and configuration files. +// +// 'Object' form shall mean any form resulting from mechanical +// transformation or translation of a Source form, including but +// not limited to compiled object code, generated documentation, +// and conversions to other media types. +// +// 'Work' shall mean the work of authorship, whether in Source or +// Object form, made available under the License, as indicated by a +// copyright notice that is included in or attached to the work +// (an example is provided in the Appendix below). +// +// 'Derivative Works' shall mean any work, whether in Source or Object +// form, that is based on (or derived from) the Work and for which the +// editorial revisions, annotations, elaborations, or other modifications +// represent, as a whole, an original work of authorship. For the purposes +// of this License, Derivative Works shall not include works that remain +// separable from, or merely link (or bind by name) to the interfaces of, +// the Work and Derivative Works thereof. +// +// 'Contribution' shall mean any work of authorship, including +// the original version of the Work and any modifications or additions +// to that Work or Derivative Works thereof, that is intentionally +// submitted to Licensor for inclusion in the Work by the copyright owner +// or by an individual or Legal Entity authorized to submit on behalf of +// the copyright owner. For the purposes of this definition, 'submitted' +// means any form of electronic, verbal, or written communication sent +// to the Licensor or its representatives, including but not limited to +// communication on electronic mailing lists, source code control systems, +// and issue tracking systems that are managed by, or on behalf of, the +// Licensor for the purpose of discussing and improving the Work, but +// excluding communication that is conspicuously marked or otherwise +// designated in writing by the copyright owner as 'Not a Contribution.' +// +// 'Contributor' shall mean Licensor and any individual or Legal Entity +// on behalf of whom a Contribution has been received by Licensor and +// subsequently incorporated within the Work. +// +// 2. Grant of Copyright License. Subject to the terms and conditions of +// this License, each Contributor hereby grants to You a perpetual, +// worldwide, non-exclusive, no-charge, royalty-free, irrevocable +// copyright license to reproduce, prepare Derivative Works of, +// publicly display, publicly perform, sublicense, and distribute the +// Work and such Derivative Works in Source or Object form. +// +// 3. Grant of Patent License. Subject to the terms and conditions of +// this License, each Contributor hereby grants to You a perpetual, +// worldwide, non-exclusive, no-charge, royalty-free, irrevocable +// (except as stated in this section) patent license to make, have made, +// use, offer to sell, sell, import, and otherwise transfer the Work, +// where such license applies only to those patent claims licensable +// by such Contributor that are necessarily infringed by their +// Contribution(s) alone or by combination of their Contribution(s) +// with the Work to which such Contribution(s) was submitted. If You +// institute patent litigation against any entity (including a +// cross-claim or counterclaim in a lawsuit) alleging that the Work +// or a Contribution incorporated within the Work constitutes direct +// or contributory patent infringement, then any patent licenses +// granted to You under this License for that Work shall terminate +// as of the date such litigation is filed. +// +// 4. Redistribution. You may reproduce and distribute copies of the +// Work or Derivative Works thereof in any medium, with or without +// modifications, and in Source or Object form, provided that You +// meet the following conditions: +// +// (a) You must give any other recipients of the Work or +// Derivative Works a copy of this License; and +// +// (b) You must cause any modified files to carry prominent notices +// stating that You changed the files; and +// +// (c) You must retain, in the Source form of any Derivative Works +// that You distribute, all copyright, patent, trademark, and +// attribution notices from the Source form of the Work, +// excluding those notices that do not pertain to any part of +// the Derivative Works; and +// +// (d) If the Work includes a 'NOTICE' text file as part of its +// distribution, then any Derivative Works that You distribute must +// include a readable copy of the attribution notices contained +// within such NOTICE file, excluding those notices that do not +// pertain to any part of the Derivative Works, in at least one +// of the following places: within a NOTICE text file distributed +// as part of the Derivative Works; within the Source form or +// documentation, if provided along with the Derivative Works; or, +// within a display generated by the Derivative Works, if and +// wherever such third-party notices normally appear. The contents +// of the NOTICE file are for informational purposes only and +// do not modify the License. You may add Your own attribution +// notices within Derivative Works that You distribute, alongside +// or as an addendum to the NOTICE text from the Work, provided +// that such additional attribution notices cannot be construed +// as modifying the License. +// +// You may add Your own copyright statement to Your modifications and +// may provide additional or different license terms and conditions +// for use, reproduction, or distribution of Your modifications, or +// for any such Derivative Works as a whole, provided Your use, +// reproduction, and distribution of the Work otherwise complies with +// the conditions stated in this License. +// +// 5. Submission of Contributions. Unless You explicitly state otherwise, +// any Contribution intentionally submitted for inclusion in the Work +// by You to the Licensor shall be under the terms and conditions of +// this License, without any additional terms or conditions. +// Notwithstanding the above, nothing herein shall supersede or modify +// the terms of any separate license agreement you may have executed +// with Licensor regarding such Contributions. +// +// 6. Trademarks. This License does not grant permission to use the trade +// names, trademarks, service marks, or product names of the Licensor, +// except as required for reasonable and customary use in describing the +// origin of the Work and reproducing the content of the NOTICE file. +// +// 7. Disclaimer of Warranty. Unless required by applicable law or +// agreed to in writing, Licensor provides the Work (and each +// Contributor provides its Contributions) on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +// implied, including, without limitation, any warranties or conditions +// of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A +// PARTICULAR PURPOSE. You are solely responsible for determining the +// appropriateness of using or redistributing the Work and assume any +// risks associated with Your exercise of permissions under this License. +// +// 8. Limitation of Liability. In no event and under no legal theory, +// whether in tort (including negligence), contract, or otherwise, +// unless required by applicable law (such as deliberate and grossly +// negligent acts) or agreed to in writing, shall any Contributor be +// liable to You for damages, including any direct, indirect, special, +// incidental, or consequential damages of any character arising as a +// result of this License or out of the use or inability to use the +// Work (including but not limited to damages for loss of goodwill, +// work stoppage, computer failure or malfunction, or any and all +// other commercial damages or losses), even if such Contributor +// has been advised of the possibility of such damages. +// +// 9. Accepting Warranty or Additional Liability. While redistributing +// the Work or Derivative Works thereof, You may choose to offer, +// and charge a fee for, acceptance of support, warranty, indemnity, +// or other liability obligations and/or rights consistent with this +// License. However, in accepting such obligations, You may act only +// on Your own behalf and on Your sole responsibility, not on behalf +// of any other Contributor, and only if You agree to indemnify, +// defend, and hold each Contributor harmless for any liability +// incurred by, or claims asserted against, such Contributor by reason +// of your accepting any such warranty or additional liability. +// +// END OF TERMS AND CONDITIONS +// +// APPENDIX: How to apply the Apache License to your work. +// +// To apply the Apache License to your work, attach the following +// boilerplate notice, with the fields enclosed by brackets '{}' +// replaced with your own identifying information. (Don't include +// the brackets!) The text should be enclosed in the appropriate +// comment syntax for the file format. We also recommend that a +// file or class name and description of purpose be included on the +// same 'printed page' as the copyright notice for easier +// identification within third-party archives. +// +// Copyright 2017 deep-rain.com +// +// Licensed under the Apache License, Version 2.0 (the 'License'); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an 'AS IS' BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Constants +var Type = { + RESOLVE: 'resolve', + NOTIFY: 'notify' +}; +var REPLACE_SEQUENCE = '{{#CODE}}'; +var CODE = 'onmessage = function(e){ postMessage({type:"' + Type.RESOLVE + '",content:({{#CODE}}).call(this, (e.data ? JSON.parse(e.data) : undefined))});};function notify(c){postMessage({type:"' + Type.NOTIFY + '", content:c})}'; + +var getEmbeddedCode = function (s) { + return CODE.replace(REPLACE_SEQUENCE, s); +}; + +module.exports = (function () { + + // Deferred class + var Deferred = function () { + this.resolveQueues = []; + this.rejectQueues = []; + this.progressQueues = []; + this.args = null; + this.isDone = false; + this.isFailed = false; + }; + + Deferred.prototype.done = function (func) { + if (this.isDone) { + func(this.args); + } else { + this.resolveQueues.push(func); + } + return this; + }; + + Deferred.prototype.fail = function (func) { + if (this.isFailed) { + func(this.args); + } else { + this.rejectQueues.push(func); + } + return this; + }; + + Deferred.prototype.always = function (func) { + if (this.isFailed || this.isDone) { + func(this.args); + } else { + this.resolveQueues.push(func); + this.rejectQueues.push(func); + } + return this; + }; + + Deferred.prototype.progress = function (func) { + this.progressQueues.push(func); + }; + + Deferred.prototype.resolve = function (obj) { + this.isDone = true; + this.args = obj; + this.resolveQueues.forEach(function (q) { + q(obj); + }); + return this; + }; + + Deferred.prototype.notify = function (obj) { + this.progressQueues.forEach(function (q) { + q(obj); + }); + }; + + Deferred.prototype.reject = function (obj) { + this.isFailed = true; + this.args = obj; + this.rejectQueues.forEach(function (q) { + q(obj); + }); + return this; + }; + + // Thread class + var Thread = function (func, depends) { + + // check browser + if (!window.Blob || + !window.URL || + !window.Worker) { + throw new Error('this browser is not supported'); + } + + // inject dependent libraries. + depends = depends || []; + if (!(depends instanceof window.Array)) { + depends = [depends]; + } + + var scripts = ''; + if (depends.length > 0) { + scripts = 'importScripts("' + depends.join('','') + '");'; + } + + // create Blob object. + var blob = new window.Blob([scripts + getEmbeddedCode(func.toString())]); + this.blobUrl = window.URL.createObjectURL(blob); + + // greate Worker object. + this.worker = new window.Worker(this.blobUrl); + this.deferred = new Deferred(); + + // add event listener. + var self = this; + + // onmessage + this.worker.addEventListener('message', function (e) { + switch (e.data.type) { + case Type.RESOLVE: + self.deferred.resolve(e.data.content); + return; + case Type.NOTIFY: + self.deferred.notify(e.data.content); + return; + } + }); + + // onerror + this.worker.addEventListener('error', function (e) { + self.deferred.reject(e); + }); + }; + + Thread.prototype.execute = function (obj) { + if (this.isClosed) { + throw new Error('thread has been closed.'); + } + + var json = JSON.stringify(obj); + this.worker.postMessage(json); + return this; + }; + + Thread.prototype.once = function (args) { + var self = this; + this.deferred.always(function () { + self.terminate(); + }); + this.execute(args); + this.isClosed = true; + return this; + }; + + Thread.prototype.terminate = function () { + window.URL.revokeObjectURL(this.blobUrl); + this.worker.terminate(); + this.worker = null; + this.deferred = null; + this.blobUrl = null; + }; + + Thread.prototype.done = function (f) { + this.deferred.done(f); + return this; + }; + + Thread.prototype.fail = function (f) { + this.deferred.fail(f); + return this; + }; + + Thread.prototype.progress = function (f) { + this.deferred.progress(f); + return this; + }; + + return Thread; +})(); + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/TileOverlay.js b/docs/plugins/cordova-plugin-googlemaps/www/TileOverlay.js new file mode 100644 index 0000000..c19efed --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/TileOverlay.js @@ -0,0 +1,121 @@ +cordova.define("cordova-plugin-googlemaps.TileOverlay", function(require, exports, module) { var utils = require('cordova/utils'), + common = require('./Common'), + Overlay = require('./Overlay'); + +/***************************************************************************** + * TileOverlay Class + *****************************************************************************/ +var TileOverlay = function (map, tileOverlayOptions, _exec) { + Overlay.call(this, map, tileOverlayOptions, 'TileOverlay', _exec); + + var self = this; + + //----------------------------------------------- + // Sets event listeners + //----------------------------------------------- + self.on('fadeIn_changed', function () { + var fadeIn = self.get('fadeIn'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setFadeIn', [self.getId(), fadeIn]); + }); + self.on('opacity_changed', function () { + var opacity = self.get('opacity'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setOpacity', [self.getId(), opacity]); + }); + self.on('zIndex_changed', function () { + var zIndex = self.get('zIndex'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setZIndex', [self.getId(), zIndex]); + }); + self.on('visible_changed', function () { + var visible = self.get('visible'); + self.exec.call(self, null, self.errorHandler, self.getPluginName(), 'setVisible', [self.getId(), visible]); + }); +}; + +utils.extend(TileOverlay, Overlay); + +TileOverlay.prototype.getPluginName = function () { + return this.map.getId() + '-tileoverlay'; +}; + +TileOverlay.prototype.getHashCode = function () { + return this.hashCode; +}; + +TileOverlay.prototype.getMap = function () { + return this.map; +}; +TileOverlay.prototype.getId = function () { + return this.__pgmId; +}; +TileOverlay.prototype.getTileSize = function () { + return this.get('tileSize'); +}; +TileOverlay.prototype.getZIndex = function () { + return this.get('zIndex'); +}; +TileOverlay.prototype.setZIndex = function (zIndex) { + this.set('zIndex', zIndex); +}; +TileOverlay.prototype.setFadeIn = function (fadeIn) { + fadeIn = common.parseBoolean(fadeIn); + this.set('fadeIn', fadeIn); +}; +TileOverlay.prototype.getFadeIn = function () { + return this.get('fadeIn'); +}; +TileOverlay.prototype.setVisible = function (visible) { + visible = common.parseBoolean(visible); + this.set('visible', visible); +}; +TileOverlay.prototype.getOpacity = function () { + return this.get('opacity'); +}; +TileOverlay.prototype.setOpacity = function (opacity) { + if (!opacity && opacity !== 0) { + console.log('opacity value must be int or double'); + return false; + } + this.set('opacity', opacity); +}; +TileOverlay.prototype.getVisible = function () { + return this.get('visible'); +}; + +TileOverlay.prototype.remove = function (callback) { + var self = this; + if (self._isRemoved) { + if (typeof callback === 'function') { + return; + } else { + return Promise.resolve(); + } + } + Object.defineProperty(self, '_isRemoved', { + value: true, + writable: false + }); + self.trigger(self.__pgmId + '_remove'); + + var resolver = function(resolve, reject) { + self.exec.call(self, + function() { + self.destroy(); + resolve.call(self); + }, + reject.bind(self), + self.getPluginName(), 'remove', [self.getId()], { + remove: true + }); + }; + + if (typeof callback === 'function') { + resolver(callback, self.errorHandler); + } else { + return new Promise(resolver); + } + +}; + +module.exports = TileOverlay; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/VisibleRegion.js b/docs/plugins/cordova-plugin-googlemaps/www/VisibleRegion.js new file mode 100644 index 0000000..a25f4bb --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/VisibleRegion.js @@ -0,0 +1,68 @@ +cordova.define("cordova-plugin-googlemaps.VisibleRegion", function(require, exports, module) { var utils = require('cordova/utils'), + LatLngBounds = require('./LatLngBounds'); + +/***************************************************************************** + * VisibleRegion Class + *****************************************************************************/ +var VisibleRegion = function(southwest, northeast, farLeft, farRight, nearLeft, nearRight) { + Object.defineProperty(this, 'type', { + value: 'VisibleRegion', + writable: false + }); + this.southwest = southwest; + this.northeast = northeast; + this.farLeft = farLeft; + this.farRight = farRight; + this.nearLeft = nearLeft; + this.nearRight = nearRight; +}; + +utils.extend(VisibleRegion, LatLngBounds); + +delete VisibleRegion.prototype.extend; +delete VisibleRegion.prototype.getCenter; + +VisibleRegion.prototype.contains = function(latLng) { + if (!latLng || !('lat' in latLng) || !('lng' in latLng)) { + return false; + } + var y = latLng.lat, + x = latLng.lng; + + var y90 = y + 90; + var south = this.southwest.lat, + north = this.northeast.lat, + west = this.southwest.lng, + east = this.northeast.lng; + var south90 = south + 90, + north90 = north + 90; + + var containX = false, + containY = false; + + if (east >= 0 && west >= east) { + if (x <= 0 && x >= -180) { + containX = true; + } else { + containX = (west <= x && x <= east); + } + } else if (west <= 0 && east <= west) { + containX = (west <= x && x <= east); + if (x >= 0 && x <= 180) { + containX = true; + } else { + containX = (x <= 0 && x <= west || x <= east && x>= -180); + } + } else { + return LatLngBounds.prototype.contains.call(this, latLng); + } + + containY = (south90 <= y90 && y90 <= north90) || //#a + (south >= 0 && north <= 0 && ((south <= y && y <= 90) || (y >= -90 && y<= north))); // #d + + return containX && containY; +}; + +module.exports = VisibleRegion; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/commandQueueExecutor.js b/docs/plugins/cordova-plugin-googlemaps/www/commandQueueExecutor.js new file mode 100644 index 0000000..6d5b2c8 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/commandQueueExecutor.js @@ -0,0 +1,187 @@ +cordova.define("cordova-plugin-googlemaps.commandQueueExecutor", function(require, exports, module) { /***************************************************************************** + * Command queue mechanism + * (Save the number of method executing at the same time) + *****************************************************************************/ +var cordova_exec = require('cordova/exec'), + common = require('./Common'); + +var commandQueue = []; +var _isWaitMethod = null; +var _isExecuting = false; +var _executingCnt = 0; +var MAX_EXECUTE_CNT = 10; +var _lastGetMapExecuted = 0; +var _isResizeMapExecuting = false; + +// This flag becomes true when the page will be unloaded. +var _stopRequested = false; + + +function execCmd(success, error, pluginName, methodName, args, execOptions) { + execOptions = execOptions || {}; + + // The JavaScript special keyword 'this' indicates `who call this function`. + // This execCmd function is executed from overlay instances such as marker. + // So `this` means `overlay` instance. + var overlay = this; + + // If the overlay has been already removed from map, + // do not execute any methods on it. + if (overlay._isRemoved && !execOptions.remove) { + console.error('[ignore]' + pluginName + '.' + methodName + ', because removed.'); + return true; + } + + // If the overlay is not ready in native side, + // do not execute any methods except remove on it. + // This code works for map class especially. + if (!this._isReady && methodName !== 'remove') { + console.error('[ignore]' + pluginName + '.' + methodName + ', because it\'s not ready.'); + return true; + } + + // Push the method into the commandQueue(FIFO) at once. + commandQueue.push({ + 'execOptions': execOptions, + 'args': [ + function() { + //------------------------------- + // success callback + //------------------------------- + + if (methodName === 'resizeMap') { + _isResizeMapExecuting = false; + } + + // Even if the method was successful, + // but the _stopRequested flag is true, + // do not execute further code. + if (!_stopRequested && success) { + var results = Array.prototype.slice.call(arguments, 0); + common.nextTick(function() { + success.apply(overlay,results); + }); + } + + // Insert small delays only for `map.getMap()`, + // because if you execute three or four `map.getMap()` at the same time, + // Android OS itself crashes. + // In order to prevent this error, insert small delays. + var delay = 0; + if (methodName === _isWaitMethod) { + if (_isWaitMethod === 'getMap' && Date.now() - _lastGetMapExecuted < 1500) { + delay = 1500; + } + _lastGetMapExecuted = Date.now(); + _isWaitMethod = null; + } + setTimeout(function() { + _executingCnt--; + common.nextTick(_exec); + }, delay); + }, + function() { + //------------------------------- + // error callback + //------------------------------- + if (methodName === 'resizeMap') { + _isResizeMapExecuting = false; + } + if (!_stopRequested && error) { + var results = Array.prototype.slice.call(arguments, 0); + common.nextTick(function() { + error.apply(overlay,results); + }); + } + + if (methodName === _isWaitMethod) { + _isWaitMethod = null; + } + _executingCnt--; + common.nextTick(_exec); + }, + pluginName, methodName, args] + }); + + // In order to execute all methods in safe, + // the maps plugin limits the number of execution in a moment to 10. + // + // Note that Cordova-Android drops has also another internal queue, + // and the internal queue drops our statement if the app send too much. + // + // Also executing too much statements at the same time, + // it would cause many errors in native side, such as out-of-memory. + // + // In order to prevent these troubles, the maps plugin limits the number of execution is 10. + if (_isExecuting || _executingCnt >= MAX_EXECUTE_CNT || _isWaitMethod || commandQueue.length === 0) { + return; + } + common.nextTick(_exec); +} +function _exec() { + + // You probably wonder why there is this code because it's already simular code at the end of the execCmd function. + // + // Because the commandQueue might change after the last code of the execCmd. + // (And yes, it was occurred.) + // In order to block surely, block the execution again. + if (_isExecuting || _executingCnt >= MAX_EXECUTE_CNT || _isWaitMethod || commandQueue.length === 0) { + return; + } + _isExecuting = true; + + // Execute some execution requests (up to 10) from the commandQueue. + var methodName; + while (commandQueue.length > 0 && _executingCnt < MAX_EXECUTE_CNT) { + if (!_stopRequested) { + _executingCnt++; + } + + // Pick up the head one. + var commandParams = commandQueue.shift(); + methodName = commandParams.args[3]; + + // If the request is `map.refreshLayout()` and another `map.refreshLayout()` is executing, + // skip it. + // This prevents to execute multiple `map.refreshLayout()` at the same time. + if (methodName === 'resizeMap') { + if (_isResizeMapExecuting) { + _executingCnt--; + continue; + } + _isResizeMapExecuting = true; + } + + // If the `_stopRequested` flag is true, + // do not execute any statements except `remove()` or `clear()` methods. + if (_stopRequested && (!commandParams.execOptions.remove || methodName !== 'clear')) { + _executingCnt--; + continue; + } + + // Some methods have to block other execution requests, such as `map.clear()` + if (commandParams.execOptions.sync) { + _isWaitMethod = methodName; + cordova_exec.apply(this, commandParams.args); + break; + } + cordova_exec.apply(this, commandParams.args); + } + + _isExecuting = false; + +} + + +//---------------------------------------------------- +// Stop all executions if the page will be closed. +//---------------------------------------------------- +function stopExecution() { + // Request stop all tasks. + _stopRequested = true; +} +window.addEventListener('unload', stopExecution); + +module.exports = execCmd; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/encoding.js b/docs/plugins/cordova-plugin-googlemaps/www/encoding.js new file mode 100644 index 0000000..f65f7fc --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/encoding.js @@ -0,0 +1,98 @@ +cordova.define("cordova-plugin-googlemaps.encoding", function(require, exports, module) { var LatLng = require('./LatLng'); +var common = require('./Common'); + +/***************************************************************************** + * geometry Encode / decode points + * http://jsfiddle.net/8nzg7tta/ + *****************************************************************************/ +//decode function +function decodePath(encoded, precision) { + precision = precision || 5; + precision = Math.pow(10, -precision); + var len = encoded.length, + index = 0, + lat = 0, + lng = 0, + array = []; + while (index < len) { + var b, shift = 0, + result = 0; + do { + b = encoded.charCodeAt(index++) - 63; + result |= (b & 0x1f) << shift; + shift += 5; + } while (b >= 0x20); + var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1)); + lat += dlat; + shift = 0; + result = 0; + do { + b = encoded.charCodeAt(index++) - 63; + result |= (b & 0x1f) << shift; + shift += 5; + } while (b >= 0x20); + var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1)); + lng += dlng; + array.push(new LatLng(lat * precision, lng * precision)); + } + return array; +} + +//encode functions +function encodePath(points) { + var plat = 0; + var plng = 0; + var encoded_points = ''; + + points = common.convertToPositionArray(points); + + for (var i = 0; i < points.length; ++i) { + encoded_points += encodePoint(plat, plng, points[i].lat, points[i].lng); + plat = points[i].lat; + plng = points[i].lng; + } + + return encoded_points; +} + +function encodePoint(plat, plng, lat, lng) { + var late5 = Math.round(lat * 1e5); + var plate5 = Math.round(plat * 1e5); + + var lnge5 = Math.round(lng * 1e5); + var plnge5 = Math.round(plng * 1e5); + + var dlng = lnge5 - plnge5; + var dlat = late5 - plate5; + + return encodeSignedNumber(dlat) + encodeSignedNumber(dlng); +} + +function encodeSignedNumber(num) { + var sgn_num = num << 1; + + if (num < 0) { + sgn_num = ~(sgn_num); + } + + return (encodeNumber(sgn_num)); +} + +function encodeNumber(num) { + var encodeString = ''; + + while (num >= 0x20) { + encodeString += (String.fromCharCode((0x20 | (num & 0x1f)) + 63)); + num >>= 5; + } + + encodeString += (String.fromCharCode(num + 63)); + return encodeString; +} + +module.exports = { + decodePath: decodePath, + encodePath: encodePath +}; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/event.js b/docs/plugins/cordova-plugin-googlemaps/www/event.js new file mode 100644 index 0000000..1c6dc6e --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/event.js @@ -0,0 +1,37 @@ +cordova.define("cordova-plugin-googlemaps.event", function(require, exports, module) { module.exports = { + MAP_READY: 'map_ready', + MAP_CLICK: 'map_click', + MAP_LONG_CLICK: 'map_long_click', + POI_CLICK: 'poi_click', + MY_LOCATION_CLICK: 'my_location_click', + MY_LOCATION_BUTTON_CLICK: 'my_location_button_click', + INDOOR_BUILDING_FOCUSED: 'indoor_building_focused', + INDOOR_LEVEL_ACTIVATED: 'indoor_level_activated', + CAMERA_MOVE_START: 'camera_move_start', + CAMERA_MOVE: 'camera_move', + CAMERA_MOVE_END: 'camera_move_end', + OVERLAY_CLICK: 'overlay_click', + POLYGON_CLICK: 'polygon_click', + POLYLINE_CLICK: 'polyline_click', + CIRCLE_CLICK: 'circle_click', + GROUND_OVERLAY_CLICK: 'groundoverlay_click', + INFO_CLICK: 'info_click', + INFO_LONG_CLICK: 'info_long_click', + INFO_CLOSE: 'info_close', + INFO_OPEN: 'info_open', + MARKER_CLICK: 'marker_click', + MARKER_DRAG: 'marker_drag', + MARKER_DRAG_START: 'marker_drag_start', + MARKER_DRAG_END: 'marker_drag_end', + MAP_DRAG: 'map_drag', + MAP_DRAG_START: 'map_drag_start', + MAP_DRAG_END: 'map_drag_end', + KML_CLICK: 'kml_click', + FUSION_TABLE_CLICK: 'fusion_table_click', + PANORAMA_READY: 'panorama_ready', + PANORAMA_CAMERA_CHANGE: 'panorama_camera_change', + PANORAMA_LOCATION_CHANGE: 'panorama_location_change', + PANORAMA_CLICK: 'panorama_click' +}; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/geomodel.js b/docs/plugins/cordova-plugin-googlemaps/www/geomodel.js new file mode 100644 index 0000000..746545e --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/geomodel.js @@ -0,0 +1,141 @@ +cordova.define("cordova-plugin-googlemaps.geomodel", function(require, exports, module) { /** +# +# Copyright 2010 Alexandre Gellibert +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +*/ + +var LatLng = require('./LatLng'), + LatLngBounds = require('./LatLngBounds'), + GEOCELL_GRID_SIZE = 4, + GEOCELL_ALPHABET = '0123456789abcdef'; + +function computeBox(geocell) { + var subcell_lng_span, subcell_lat_span; + var xy, x, y; + var bbox = _createBoundingBox(90.0, 180.0, -90.0, -180.0); + while(geocell.length > 0) { + //geoChar = geocell.charAt(i); + //pos = GEOCELL_ALPHABET.indexOf(geoChar); + + subcell_lng_span = (bbox.getEast() - bbox.getWest()) / GEOCELL_GRID_SIZE; + subcell_lat_span = (bbox.getNorth() - bbox.getSouth()) / GEOCELL_GRID_SIZE; + + xy = _subdiv_xy(geocell.charAt(0)); + x = xy[0]; + y = xy[1]; + + bbox = _createBoundingBox(bbox.getSouth() + subcell_lat_span * (y + 1), + bbox.getWest() + subcell_lng_span * (x + 1), + bbox.getSouth() + subcell_lat_span * y, + bbox.getWest() + subcell_lng_span * x); + + geocell = geocell.substring(1); + } + var sw = new LatLng(bbox.getSouth(), bbox.getWest()); + var ne = new LatLng(bbox.getNorth(), bbox.getEast()); + var bounds = new LatLngBounds(sw, ne); + return bounds; +} + +function _createBoundingBox(north, east, south, west) { + var north_,south_; + + if(south > north) { + south_ = north; + north_ = south; + } else { + south_ = south; + north_ = north; + } + return { + northEast: {lat: north_, lng: east}, + southWest: {lat: south_, lng: west}, + getNorth: function() { + return this.northEast.lat; + }, + getSouth: function() { + return this.southWest.lat; + }, + getWest: function() { + return this.southWest.lng; + }, + getEast: function() { + return this.northEast.lng; + } + }; +} + + +/** + * https://code.google.com/p/geomodel/source/browse/trunk/geo/geocell.py#370 + * @param latLng + * @param resolution + * @return + */ +function getGeocell(lat, lng, resolution) { + var cell = ''; + var north = 90.0; + var south = -90.0; + var east = 180.0; + var west = -180.0; + + var subcell_lng_span, subcell_lat_span; + var x, y; + 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 += _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; +} + + +/* + * Returns the (x, y) of the geocell character in the 4x4 alphabet grid. + */ +function _subdiv_xy(char) { + // NOTE: This only works for grid size 4. + var charI = GEOCELL_ALPHABET.indexOf(char); + return [(charI & 4) >> 1 | (charI & 1) >> 0, + (charI & 8) >> 2 | (charI & 2) >> 1]; +} + +/** + * Returns the geocell character in the 4x4 alphabet grid at pos. (x, y). + * @return + */ +function _subdiv_char(posX, posY) { + // NOTE: This only works for grid size 4. + return GEOCELL_ALPHABET.charAt( + (posY & 2) << 2 | + (posX & 2) << 1 | + (posY & 1) << 1 | + (posX & 1) << 0); +} + +module.exports = { + computeBox: computeBox, + getGeocell: getGeocell +}; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/js_CordovaGoogleMaps-for-browser.js b/docs/plugins/cordova-plugin-googlemaps/www/js_CordovaGoogleMaps-for-browser.js new file mode 100644 index 0000000..85c4823 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/js_CordovaGoogleMaps-for-browser.js @@ -0,0 +1,284 @@ +cordova.define("cordova-plugin-googlemaps.js_CordovaGoogleMaps", function(require, exports, module) { + +if (!window.Promise) { + window.Promise = require('cordova-plugin-googlemaps.Promise'); +} + +var common = require('cordova-plugin-googlemaps.Common'), + Map = require('cordova-plugin-googlemaps.Map'), + StreetViewPanorama = require('cordova-plugin-googlemaps.StreetViewPanorama'); + + +function nativeCallback(params) { + var args = params.args || []; + args.unshift(params.evtName); + + this[params.callback].apply(this, args); +} + +function CordovaGoogleMaps(execCmd) { + var self = this; + + self.execCmd = execCmd; + + // random unique number + self.saltHash = Math.floor(Math.random() * Date.now()); + + // Hold map instances. + self.MAPS = {}; + self.MAP_CNT = 0; + + var removeMapDiv = function(node) { + if (node.hasAttribute('__pluginmapid') && !node.parentNode) { + var mapId = node.getAttribute('__pluginmapid'); + var map = self.MAPS[mapId]; + if (map) { + map.remove(); + delete self.MAPS[mapId]; + } + } else { + var childNodes = Array.prototype.slice.call(node.childNodes); + childNodes.forEach(function(child) { + if (child.outerHTML && child.outerHTML.indexOf('__pluginmapid') > -1) { + removeMapDiv(child); + } + }); + } + }; + + //------------------------------------------------------------------------------ + // Using MutationObserver, observe only added/removed or style changed elements + //------------------------------------------------------------------------------ + var observer = new MutationObserver(function(mutations) { + common.nextTick(function() { + var mutationRecords = Array.prototype.slice.call(mutations, 0); + mutationRecords.forEach(function(record) { + if (record.removedNodes.length > 0) { + record.removeNodes = Array.prototype.slice.call(record.removedNodes, 0); + record.removeNodes.forEach(function(node) { + if (node.outerHTML && node.outerHTML.indexOf('__pluginmapid') > -1) { + removeMapDiv(node); + } + }); + } + }); + }); + }); + observer.observe(document.body.parentElement, { + childList: true, + subtree: true + }); +} + +CordovaGoogleMaps.prototype.getMap = function(div, mapOptions) { + + //---------------------------------------------------------------------------- + // This procedure return a map instance. + // - usage 1 + // plugin.google.maps.Map.getMap(options?) returns a map instance. + // + // - usage 2 + // plugin.google.maps.Map.getMap(mapDiv, options?) returns a map instance. + // The generated map follows the mapDiv position and size automatically. + // + // - usage 3 (not good way) + // In order to keep the backward compatibility for v1, + // if the mapDiv has already a map, returns the map instance for the map div. + //---------------------------------------------------------------------------- + var self = this, + mapId; + + if (common.isDom(div)) { + mapId = div.getAttribute('__pluginMapId'); + + // Wow, the app specifies the map div that has already another map, + // but the app try to create new map. + // In this case, remove the old map instance automatically. + if (mapId && self.MAPS[mapId].getDiv() !== div) { + var oldMap = self.MAPS[mapId]; + if (oldMap.infoWindowLayer) { + var oldDiv = oldMap.getDiv(); + oldDiv.removeChild(oldMap.infoWindowLayer); + } + oldMap.remove(); + oldMap = undefined; + mapId = undefined; + } + + if (mapId && mapId in self.MAPS) { + // Usage 3 + // If the map div has already a map, + // return the map instance. + return self.MAPS[mapId]; + } + + } + if (!mapId) { + mapId = 'map_' + self.MAP_CNT + '_' + self.saltHash; + } + // Create a map instance. + var map = new Map(mapId, self.execCmd); + window.plugin.google.maps[mapId] = nativeCallback.bind(map); + + // If the map is removed, clean up the information. + map.one('remove', self._remove.bind(self, mapId)); + self.MAP_CNT++; + self.isThereAnyChange = true; + + if (div instanceof Promise) { + // This hack code for @ionic-native/google-maps + div.then(function(params) { + self.MAPS[mapId] = map; + params = params || []; + params.unshift(map); + postMapInit.apply(self, params); + }); + } else { + // Normal code flow + self.MAPS[mapId] = map; + postMapInit.call(self, map, div, mapOptions); + } + + return map; +}; + +CordovaGoogleMaps.prototype.getPanorama = function(div, streetViewOptions) { + var self = this; + var mapId = 'streetview_' + self.MAP_CNT + '_' + self.saltHash; + + // Create a panorama instance. + var panorama = new StreetViewPanorama(mapId, self.execCmd); + + // Catch all events for this map instance, then pass to the instance. + // (Don't execute this native callback from your code) + window.plugin.google.maps[mapId] = nativeCallback.bind(panorama); + + self.MAP_CNT++; + panorama.one('remove', self._remove.bind(self, mapId)); + if (div instanceof Promise) { + // This hack code for @ionic-native/google-maps + div.then(function(params) { + self.MAPS[mapId] = panorama; + params = params || []; + params.unshift(panorama); + postPanoramaInit.apply(self, params); + }); + } else { + // Normal code flow + self.MAPS[mapId] = panorama; + postPanoramaInit.call(self, panorama, div, streetViewOptions); + } + + return panorama; +}; + +CordovaGoogleMaps.prototype._remove = function(mapId) { + var self = this; + var map = self.MAPS[mapId]; + if (map) { + + var div = map.getDiv(); + if (!div) { + div = document.querySelector('[__pluginMapId="' + mapId + '"]'); + } + if (div) { + div.removeAttribute('__pluginMapId'); + } + + self.MAPS[mapId].destroy(); + } + delete self.MAPS[mapId]; + map = undefined; +}; + +function postPanoramaInit(panorama, div, options) { + var self = this; + var mapId = panorama.getId(); + self.isThereAnyChange = true; + + if (!common.isDom(div)) { + console.error('[GoogleMaps] You need to specify a dom element(such as
) for this method', div); + return; + } + // If the given div is not fully ready, wait a little + if (!common.shouldWatchByNative(div)) { + setTimeout(function() { + common.nextTick(postPanoramaInit.bind(self, panorama, div, options)); + }, 50); + return; + } + if (div.offsetWidth < 100 || div.offsetHeight < 100) { + console.error('[GoogleMaps] Minimum container dimention is 100x100 in pixels.', div); + return; + } + + // If the mapDiv is specified, + // the native side needs to know the map div position + // before creating the map view. + div.setAttribute('__pluginMapId', mapId); + + if (div.offsetWidth < 100 || div.offsetHeight < 100) { + console.error('[GoogleMaps] Minimum container dimention is 100x100 in pixels.', div); + return; + } + var args = Array.prototype.slice.call(arguments, 0); + args.unshift({ + __pgmId: mapId + }); + + // If the mapDiv is specified, + // the native side needs to know the map div position + // before creating the map view. + div.setAttribute('__pluginMapId', mapId); + + panorama.getPanorama.apply(panorama, args); +} + +function postMapInit(map, div, options) { + var self = this; + var mapId = map.getId(); + var args = []; + + if (common.isDom(div)) { + // If the given div is not fully ready, wait a little + if (!common.shouldWatchByNative(div)) { + setTimeout(function() { + common.nextTick(postMapInit.bind(self, map, div, options)); + }, 50); + return; + } + if (div.offsetWidth < 100 || div.offsetHeight < 100) { + console.error('[GoogleMaps] Minimum container dimention is 100x100 in pixels.', div); + return; + } + // If the mapDiv is specified, + // the native side needs to know the map div position + // before creating the map view. + div.setAttribute('__pluginMapId', mapId); + + args.push({ + __pgmId: mapId, + depth: 0 + }); + args.push(div); + if (options) { + args.push(options); + } + map.getMap.apply(map, args); + } else { + args.push({ + __pgmId: mapId, + depth: 0 + }); + args.push(null); + if (options) { + args.push(options); + } + map.getMap.apply(map, args); + } +} + + +module.exports = CordovaGoogleMaps; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/plugin-loader-for-browser.js b/docs/plugins/cordova-plugin-googlemaps/www/plugin-loader-for-browser.js new file mode 100644 index 0000000..2b5cfee --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/plugin-loader-for-browser.js @@ -0,0 +1,48 @@ +cordova.define("cordova-plugin-googlemaps.googlemaps-cdv-plugin", function(require, exports, module) { var event = require('cordova-plugin-googlemaps.event'), + BaseClass = require('cordova-plugin-googlemaps.BaseClass'), + BaseArrayClass = require('cordova-plugin-googlemaps.BaseArrayClass'), + execCmd = require('cordova-plugin-googlemaps.commandQueueExecutor'), + cordovaGoogleMaps = new(require('cordova-plugin-googlemaps.js_CordovaGoogleMaps'))(execCmd); + +module.exports = { + event: event, + Animation: { + BOUNCE: 'BOUNCE', + DROP: 'DROP' + }, + BaseClass: BaseClass, + BaseArrayClass: BaseArrayClass, + Map: { + getMap: cordovaGoogleMaps.getMap.bind(cordovaGoogleMaps) + }, + StreetView: { + getPanorama: cordovaGoogleMaps.getPanorama.bind(cordovaGoogleMaps), + Source: { + DEFAULT: 'DEFAULT', + OUTDOOR: 'OUTDOOR' + } + }, + HtmlInfoWindow: require('cordova-plugin-googlemaps.HtmlInfoWindow'), + LatLng: require('cordova-plugin-googlemaps.LatLng'), + LatLngBounds: require('cordova-plugin-googlemaps.LatLngBounds'), + MapTypeId: require('cordova-plugin-googlemaps.MapTypeId'), + environment: require('cordova-plugin-googlemaps.Environment'), + Geocoder: require('cordova-plugin-googlemaps.Geocoder')(execCmd), + LocationService: require('cordova-plugin-googlemaps.LocationService')(execCmd), + geometry: { + encoding: require('cordova-plugin-googlemaps.encoding'), + spherical: require('cordova-plugin-googlemaps.spherical'), + poly: require('cordova-plugin-googlemaps.poly') + } +}; + +cordova.addConstructor(function () { + if (!window.Cordova) { + window.Cordova = cordova; + } + window.plugin = window.plugin || {}; + window.plugin.google = window.plugin.google || {}; + window.plugin.google.maps = window.plugin.google.maps || module.exports; +}); + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/pluginInit.js b/docs/plugins/cordova-plugin-googlemaps/www/pluginInit.js new file mode 100644 index 0000000..d4e5188 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/pluginInit.js @@ -0,0 +1,171 @@ +cordova.define("cordova-plugin-googlemaps.pluginInit", function(require, exports, module) { var cordova_exec = require('cordova/exec'), + common = require('cordova-plugin-googlemaps.Common'); + +function pluginInit() { + //------------------------------------------------------------- + // In some older browsers do not implement these methods. + // For example, Android 4.4 does not have Array.map() + // + // But this plugin needs them. + // That's why if the browser does not have it, implement it. + //------------------------------------------------------------- + if (typeof Array.prototype.forEach !== 'function') { + (function () { + Array.prototype.forEach = function (fn, thisArg) { + thisArg = thisArg || this; + for (var i = 0; i < this.length; i++) { + fn.call(thisArg, this[i], i, this); + } + }; + })(); + } + if (typeof Array.prototype.filter !== 'function') { + (function () { + Array.prototype.filter = function (fn, thisArg) { + thisArg = thisArg || this; + var results = []; + for (var i = 0; i < this.length; i++) { + if (fn.call(thisArg, this[i], i, this) === true) { + results.push(this[i]); + } + } + return results; + }; + })(); + } + if (typeof Array.prototype.map !== 'function') { + (function () { + Array.prototype.map = function (fn, thisArg) { + thisArg = thisArg || this; + var results = []; + for (var i = 0; i < this.length; i++) { + results.push(fn.call(thisArg, this[i], i, this)); + } + return results; + }; + })(); + } + /***************************************************************************** + * To prevent strange things happen, + * disable the changing of viewport zoom level by double clicking. + * This code has to run before the device ready event. + *****************************************************************************/ + var viewportTag = null; + var metaTags = document.getElementsByTagName('meta'); + for (var i = 0; i < metaTags.length; i++) { + if (metaTags[i].getAttribute('name') === 'viewport') { + viewportTag = metaTags[i]; + break; + } + } + if (!viewportTag) { + viewportTag = document.createElement('meta'); + viewportTag.setAttribute('name', 'viewport'); + } + + var viewportTagContent = 'width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no'; + + // + // Detect support for CSS env() variable + // + var envTestDiv = '
'; + + document.body.insertAdjacentHTML('afterbegin', envTestDiv); + + var testElement = document.getElementById('envTest'); + var testResult = common.getStyle(testElement, 'margin-top'); + document.body.removeChild(testElement); + + // if browser supports env(), returns a pixel value as string, even if 0px + if (testResult != '-99px') { + viewportTagContent += ', viewport-fit=cover'; + } + + // Update viewport tag attribute + viewportTag.setAttribute('content', viewportTagContent); + + /***************************************************************************** + * Prevent background, background-color, background-image properties + *****************************************************************************/ + var cssAdjuster = document.createElement('style'); + cssAdjuster.setAttribute('type', 'text/css'); + cssAdjuster.innerText = [ + 'html, body, ._gmaps_cdv_ {', + ' background-image: url() !important;', + ' background: rgba(0,0,0,0) url() !important;', + ' background-color: rgba(0,0,0,0) !important;', + '}', + '._gmaps_cdv_ .nav-decor {', + ' background-color: rgba(0,0,0,0) !important;', + ' background: rgba(0,0,0,0) !important;', + ' display:none !important;', + '}', + '.framework7-root .page-previous {', + ' display:none !important;', + '}' + ].join(''); + document.head.appendChild(cssAdjuster); + + // I guess no longer necessary this code at 2018/March + // //---------------------------------------------- + // // Set transparent mandatory for older browser + // // http://stackoverflow.com/a/3485654/697856 + // //---------------------------------------------- + // if(document.body){ + // document.body.style.backgroundColor = 'rgba(0,0,0,0)'; + // //document.body.style.display='none'; + // document.body.offsetHeight; + // //document.body.style.display=''; + // } + + //-------------------------------------------- + // Hook the backbutton of Android action + //-------------------------------------------- + var anotherBackbuttonHandler = null; + + function onBackButton(e) { + + // Check DOM tree for new page + cordova.fireDocumentEvent('plugin_touch', { + force: true + }); + + if (anotherBackbuttonHandler) { + // anotherBackbuttonHandler must handle the page moving transaction. + // The plugin does not take care anymore if another callback is registered. + anotherBackbuttonHandler(e); + } else { + cordova_exec(null, null, 'CordovaGoogleMaps', 'backHistory', []); + } + } + + document.addEventListener('backbutton', onBackButton); + + var _org_addEventListener = document.addEventListener; + var _org_removeEventListener = document.removeEventListener; + document.addEventListener = function (eventName, callback) { + var args = Array.prototype.slice.call(arguments, 0); + if (eventName.toLowerCase() !== 'backbutton') { + _org_addEventListener.apply(this, args); + return; + } + if (!anotherBackbuttonHandler) { + anotherBackbuttonHandler = callback; + } + }; + document.removeEventListener = function (eventName, callback) { + var args = Array.prototype.slice.call(arguments, 0); + if (eventName.toLowerCase() !== 'backbutton') { + _org_removeEventListener.apply(this, args); + return; + } + if (anotherBackbuttonHandler === callback) { + anotherBackbuttonHandler = null; + } + }; + +} + +module.exports = pluginInit; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/poly.js b/docs/plugins/cordova-plugin-googlemaps/www/poly.js new file mode 100644 index 0000000..34d2d51 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/poly.js @@ -0,0 +1,108 @@ +cordova.define("cordova-plugin-googlemaps.poly", function(require, exports, module) { var LatLngBounds = require('./LatLngBounds'), + BaseArrayClass = require('./BaseArrayClass'); + +function containsLocation(latLng, path) { + if ('lat' in latLng === false || + 'lng' in latLng === false) { + return false; + } + if (path instanceof BaseArrayClass) { + path = path.getArray(); + } + var points = JSON.parse(JSON.stringify(path)); + + var first = points[0], + last = points[points.length - 1]; + if (first.lat !== last.lat || first.lng !== last.lng) { + points.push({ + lat: first.lat, + lng: first.lng + }); + } + var point = { + lat: latLng.lat, + lng: latLng.lng + }; + + var wn = 0, + bounds = new LatLngBounds(points), + sw = bounds.southwest, + ne = bounds.northeast, + offsetLng360 = sw.lng <= 0 && ne.lng >= 0 && sw.lng < ne.lng ? 360 : 0; + + sw.lng += offsetLng360; + point.lng += offsetLng360; + + points = points.map(function(vertex) { + vertex.lng += +offsetLng360; + return vertex; + }); + + var vt, a, b; + + for (var i = 0; i < points.length - 1; i++) { + a = points[i]; + b = points[i + 1]; + + if ((a.lat <= point.lat) && (b.lat > point.lat)) { + vt = (point.lat - a.lat) / (b.lat - a.lat); + if (point.lng < (a.lng + (vt * (b.lng - a.lng)))) { + wn++; + } + } else if ((a.lat > point.lat) && (b.lat <= point.lat)) { + vt = (point.lat - a.lat) / (b.lat - a.lat); + if (point.lng < (a.lng + (vt * (b.lng - a.lng)))) { + wn--; + } + } + } + + return (wn !== 0); +} + +function isLocationOnEdge(latLng, path) { + if ('lat' in latLng === false || + 'lng' in latLng === false) { + return false; + } + + var Sx, Sy; + var p0, p1; + var point = {'lat': latLng.lat, 'lng': latLng.lng}; + + if (path instanceof BaseArrayClass) { + path = path.getArray(); + } + var points = JSON.parse(JSON.stringify(path)); + + var bounds = new LatLngBounds(points), + sw = bounds.southwest, + ne = bounds.northeast, + offsetLng360 = sw.lng <= 0 && ne.lng >= 0 && sw.lng < ne.lng ? 360 : 0; + + point.lng += offsetLng360; + + points = points.map(function(vertex) { + vertex.lng += offsetLng360; + return vertex; + }); + + p0 = points[0]; + for (var i = 1; i < points.length; i++) { + p1 = points[i]; + Sx = (point.lng - p0.lng) / (p1.lng - p0.lng); + Sy = (point.lat - p0.lat) / (p1.lat - p0.lat); + if (Math.abs(Sx - Sy) < 0.05 && Sx < 1 && Sx > 0) { + return true; + } + p0 = p1; + } + return false; +} + +module.exports = { + containsLocation: containsLocation, + isLocationOnEdge: isLocationOnEdge +}; + +}); diff --git a/docs/plugins/cordova-plugin-googlemaps/www/promise-7.0.4.min.js.map b/docs/plugins/cordova-plugin-googlemaps/www/promise-7.0.4.min.js.map new file mode 100644 index 0000000..4e03128 --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/promise-7.0.4.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"generated.js","sources":["node_modules/browserify/node_modules/browser-pack/_prelude.js","node_modules/promise/lib/core.js","node_modules/promise/lib/es6-extensions.js","node_modules/promise/node_modules/asap/browser-asap.js","node_modules/promise/node_modules/asap/browser-raw.js","node_modules/promise/polyfill-done.js","node_modules/promise/polyfill.js"],"names":["e","t","n","r","s","o","u","a","require","i","f","Error","code","l","exports","call","length",1,"module","noop","getThen","obj","then","ex","LAST_ERROR","IS_ERROR","tryCallOne","fn","tryCallTwo","b","Promise","this","TypeError","_37","_12","_59","doResolve","safeThen","self","onFulfilled","onRejected","constructor","resolve","reject","res","handle","Handler","deferred","push","asap","cb","promise","ret","newValue","finale","bind","done","value","reason","_99","prototype","valuePromise","p","TRUE","FALSE","NULL","UNDEFINED","undefined","ZERO","EMPTYSTRING","all","arr","args","Array","slice","val","remaining","race","values","forEach","throwFirstError","pendingErrors","shift","task","rawTask","freeTasks","pop","RawTask","rawAsap","requestErrorThrow","makeRequestCallFromTimer","error","onerror","queue","requestFlush","flushing","flush","index","currentIndex","capacity","scan","newLength","makeRequestCallFromMutationObserver","callback","toggle","observer","BrowserMutationObserver","node","document","createTextNode","observe","characterData","data","handleTimer","clearTimeout","timeoutHandle","clearInterval","intervalHandle","setTimeout","setInterval","global","MutationObserver","WebKitMutationObserver","arguments","apply","err"],"mappings":"AAAA,CAAA,QAAAA,GAAAC,EAAAC,EAAAC,GAAA,QAAAC,GAAAC,EAAAC,GAAA,IAAAJ,EAAAG,GAAA,CAAA,IAAAJ,EAAAI,GAAA,CAAA,GAAAE,GAAA,kBAAAC,UAAAA,OAAA,KAAAF,GAAAC,EAAA,MAAAA,GAAAF,GAAA,EAAA,IAAAI,EAAA,MAAAA,GAAAJ,GAAA,EAAA,IAAAK,GAAA,GAAAC,OAAA,uBAAAN,EAAA,IAAA,MAAAK,GAAAE,KAAA,mBAAAF,EAAA,GAAAG,GAAAX,EAAAG,IAAAS,WAAAb,GAAAI,GAAA,GAAAU,KAAAF,EAAAC,QAAA,SAAAd,GAAA,GAAAE,GAAAD,EAAAI,GAAA,GAAAL,EAAA,OAAAI,GAAAF,EAAAA,EAAAF,IAAAa,EAAAA,EAAAC,QAAAd,EAAAC,EAAAC,EAAAC,GAAA,MAAAD,GAAAG,GAAAS,QAAA,IAAA,GAAAL,GAAA,kBAAAD,UAAAA,QAAAH,EAAA,EAAAA,EAAAF,EAAAa,OAAAX,IAAAD,EAAAD,EAAAE,GAAA,OAAAD,KAAAa,GAAA,SAAAT,EAAAU,EAAAJ,GCAA,YAIA,SAAAK,MAqBA,QAAAC,GAAAC,GACA,IACA,MAAAA,GAAAC,KACA,MAAAC,GAEA,MADAC,GAAAD,EACAE,GAIA,QAAAC,GAAAC,EAAApB,GACA,IACA,MAAAoB,GAAApB,GACA,MAAAgB,GAEA,MADAC,GAAAD,EACAE,GAGA,QAAAG,GAAAD,EAAApB,EAAAsB,GACA,IACAF,EAAApB,EAAAsB,GACA,MAAAN,GAEA,MADAC,GAAAD,EACAE,GAMA,QAAAK,GAAAH,GACA,GAAA,gBAAAI,MACA,KAAA,IAAAC,WAAA,uCAEA,IAAA,kBAAAL,GACA,KAAA,IAAAK,WAAA,iBAEAD,MAAAE,IAAA,EACAF,KAAAG,IAAA,KACAH,KAAAI,OACAR,IAAAR,GACAiB,EAAAT,EAAAI,MAaA,QAAAM,GAAAC,EAAAC,EAAAC,GACA,MAAA,IAAAF,GAAAG,YAAA,SAAAC,EAAAC,GACA,GAAAC,GAAA,GAAAd,GAAAX,EACAyB,GAAAtB,KAAAoB,EAAAC,GACAE,EAAAP,EAAA,GAAAQ,GAAAP,EAAAC,EAAAI,MAGA,QAAAC,GAAAP,EAAAS,GACA,KAAA,IAAAT,EAAAL,KACAK,EAAAA,EAAAJ,GAEA,OAAA,KAAAI,EAAAL,QACAK,GAAAH,IAAAa,KAAAD,OAGAE,GAAA,WACA,GAAAC,GAAA,IAAAZ,EAAAL,IAAAc,EAAAR,YAAAQ,EAAAP,UACA,IAAA,OAAAU,EAMA,YALA,IAAAZ,EAAAL,IACAS,EAAAK,EAAAI,QAAAb,EAAAJ,KAEAS,EAAAI,EAAAI,QAAAb,EAAAJ,KAIA,IAAAkB,GAAA1B,EAAAwB,EAAAZ,EAAAJ,IACAkB,KAAA3B,EACAkB,EAAAI,EAAAI,QAAA3B,GAEAkB,EAAAK,EAAAI,QAAAC,KAIA,QAAAV,GAAAJ,EAAAe,GAEA,GAAAA,IAAAf,EACA,MAAAK,GACAL,EACA,GAAAN,WAAA,6CAGA,IACAqB,IACA,gBAAAA,IAAA,kBAAAA,IACA,CACA,GAAA/B,GAAAF,EAAAiC,EACA,IAAA/B,IAAAG,EACA,MAAAkB,GAAAL,EAAAd,EAEA,IACAF,IAAAgB,EAAAhB,MACA+B,YAAAvB,GAKA,MAHAQ,GAAAL,IAAA,EACAK,EAAAJ,IAAAmB,MACAC,GAAAhB,EAEA,IAAA,kBAAAhB,GAEA,WADAc,GAAAd,EAAAiC,KAAAF,GAAAf,GAIAA,EAAAL,IAAA,EACAK,EAAAJ,IAAAmB,EACAC,EAAAhB,GAGA,QAAAK,GAAAL,EAAAe,GACAf,EAAAL,IAAA,EACAK,EAAAJ,IAAAmB,EACAC,EAAAhB,GAEA,QAAAgB,GAAAhB,GACA,IAAA,GAAA7B,GAAA,EAAAA,EAAA6B,EAAAH,IAAAnB,OAAAP,IACAoC,EAAAP,EAAAA,EAAAH,IAAA1B,GAEA6B,GAAAH,IAAA,KAGA,QAAAW,GAAAP,EAAAC,EAAAW,GACApB,KAAAQ,YAAA,kBAAAA,GAAAA,EAAA,KACAR,KAAAS,WAAA,kBAAAA,GAAAA,EAAA,KACAT,KAAAoB,QAAAA,EASA,QAAAf,GAAAT,EAAAwB,GACA,GAAAK,IAAA,EACAZ,EAAAhB,EAAAD,EAAA,SAAA8B,GACAD,IACAA,GAAA,EACAd,EAAAS,EAAAM,KACA,SAAAC,GACAF,IACAA,GAAA,EACAb,EAAAQ,EAAAO,KAEAF,IAAAZ,IAAAnB,IACA+B,GAAA,EACAb,EAAAQ,EAAA3B,IAnLA,GAAAyB,GAAAzC,EAAA,YAqBAgB,EAAA,KACAC,IA2BAP,GAAAJ,QAAAgB,EAeAA,EAAA6B,IAAAxC,EAEAW,EAAA8B,UAAAtC,KAAA,SAAAiB,EAAAC,GACA,GAAAT,KAAAU,cAAAX,EACA,MAAAO,GAAAN,KAAAQ,EAAAC,EAEA,IAAAI,GAAA,GAAAd,GAAAX,EAEA,OADA0B,GAAAd,KAAA,GAAAe,GAAAP,EAAAC,EAAAI,IACAA,uCC1EA,YAiBA,SAAAiB,GAAAJ,GACA,GAAAK,GAAA,GAAAhC,GAAAA,EAAA6B,IAGA,OAFAG,GAAA7B,IAAA,EACA6B,EAAA5B,IAAAuB,EACAK,EAjBA,GAAAhC,GAAAtB,EAAA,YAEAU,GAAAJ,QAAAgB,CAIA,IAAAiC,GAAAF,GAAA,GACAG,EAAAH,GAAA,GACAI,EAAAJ,EAAA,MACAK,EAAAL,EAAAM,QACAC,EAAAP,EAAA,GACAQ,EAAAR,EAAA,GAQA/B,GAAAY,QAAA,SAAAe,GACA,GAAAA,YAAA3B,GAAA,MAAA2B,EAEA,IAAA,OAAAA,EAAA,MAAAQ,EACA,IAAAE,SAAAV,EAAA,MAAAS,EACA,IAAAT,KAAA,EAAA,MAAAM,EACA,IAAAN,KAAA,EAAA,MAAAO,EACA,IAAA,IAAAP,EAAA,MAAAW,EACA,IAAA,KAAAX,EAAA,MAAAY,EAEA,IAAA,gBAAAZ,IAAA,kBAAAA,GACA,IACA,GAAAnC,GAAAmC,EAAAnC,IACA,IAAA,kBAAAA,GACA,MAAA,IAAAQ,GAAAR,EAAAiC,KAAAE,IAEA,MAAAlC,GACA,MAAA,IAAAO,GAAA,SAAAY,EAAAC,GACAA,EAAApB,KAIA,MAAAsC,GAAAJ,IAGA3B,EAAAwC,IAAA,SAAAC,GACA,GAAAC,GAAAC,MAAAb,UAAAc,MAAA3D,KAAAwD,EAEA,OAAA,IAAAzC,GAAA,SAAAY,EAAAC,GAGA,QAAAC,GAAAnC,EAAAkE,GACA,GAAAA,IAAA,gBAAAA,IAAA,kBAAAA,IAAA,CACA,GAAAA,YAAA7C,IAAA6C,EAAArD,OAAAQ,EAAA8B,UAAAtC,KAAA,CACA,KAAA,IAAAqD,EAAA1C,KACA0C,EAAAA,EAAAzC,GAEA,OAAA,KAAAyC,EAAA1C,IAAAW,EAAAnC,EAAAkE,EAAAzC,MACA,IAAAyC,EAAA1C,KAAAU,EAAAgC,EAAAzC,SACAyC,GAAArD,KAAA,SAAAqD,GACA/B,EAAAnC,EAAAkE,IACAhC,IAGA,GAAArB,GAAAqD,EAAArD,IACA,IAAA,kBAAAA,GAAA,CACA,GAAAwC,GAAA,GAAAhC,GAAAR,EAAAiC,KAAAoB,GAIA,YAHAb,GAAAxC,KAAA,SAAAqD,GACA/B,EAAAnC,EAAAkE,IACAhC,IAKA6B,EAAA/D,GAAAkE,EACA,MAAAC,GACAlC,EAAA8B,GA3BA,GAAA,IAAAA,EAAAxD,OAAA,MAAA0B,MA8BA,KAAA,GA7BAkC,GAAAJ,EAAAxD,OA6BAP,EAAA,EAAAA,EAAA+D,EAAAxD,OAAAP,IACAmC,EAAAnC,EAAA+D,EAAA/D,OAKAqB,EAAAa,OAAA,SAAAc,GACA,MAAA,IAAA3B,GAAA,SAAAY,EAAAC,GACAA,EAAAc,MAIA3B,EAAA+C,KAAA,SAAAC,GACA,MAAA,IAAAhD,GAAA,SAAAY,EAAAC,GACAmC,EAAAC,QAAA,SAAAtB,GACA3B,EAAAY,QAAAe,GAAAnC,KAAAoB,EAAAC,QAOAb,EAAA8B,UAAA,SAAA,SAAApB,GACA,MAAAT,MAAAT,KAAA,KAAAkB,yCCzGA,YAWA,SAAAwC,KACA,GAAAC,EAAAjE,OACA,KAAAiE,GAAAC,QAaA,QAAAjC,GAAAkC,GACA,GAAAC,EAEAA,GADAC,EAAArE,OACAqE,EAAAC,MAEA,GAAAC,GAEAH,EAAAD,KAAAA,EACAK,EAAAJ,GAKA,QAAAG,KACAxD,KAAAoD,KAAA,KArCA,GAAAK,GAAAhF,EAAA,SAEA6E,KAGAJ,KACAQ,EAAAD,EAAAE,yBAAAV,EAgBA9D,GAAAJ,QAAAmC,EAoBAsC,EAAA3B,UAAA7C,KAAA,WACA,IACAgB,KAAAoD,KAAApE,OACA,MAAA4E,GACA1C,EAAA2C,QAIA3C,EAAA2C,QAAAD,IAKAV,EAAAjC,KAAA2C,GACAF,KAEA,QACA1D,KAAAoD,KAAA,KACAE,EAAAA,EAAArE,QAAAe,qDC/DA,YAaA,SAAAyD,GAAAL,GACAU,EAAA7E,SACA8E,IACAC,GAAA,GAGAF,EAAAA,EAAA7E,QAAAmE,EA0BA,QAAAa,KACA,KAAAC,EAAAJ,EAAA7E,QAAA,CACA,GAAAkF,GAAAD,CAUA,IAPAA,GAAA,EACAJ,EAAAK,GAAAnF,OAMAkF,EAAAE,EAAA,CAGA,IAAA,GAAAC,GAAA,EAAAC,EAAAR,EAAA7E,OAAAiF,EAAAI,EAAAD,EAAAA,IACAP,EAAAO,GAAAP,EAAAO,EAAAH,EAEAJ,GAAA7E,QAAAiF,EACAA,EAAA,GAGAJ,EAAA7E,OAAA,EACAiF,EAAA,EACAF,GAAA,EAmEA,QAAAO,GAAAC,GACA,GAAAC,GAAA,EACAC,EAAA,GAAAC,GAAAH,GACAI,EAAAC,SAAAC,eAAA,GAEA,OADAJ,GAAAK,QAAAH,GAAAI,eAAA,IACA,WACAP,GAAAA,EACAG,EAAAK,KAAAR,GA4CA,QAAAd,GAAAa,GACA,MAAA,YAWA,QAAAU,KAGAC,aAAAC,GACAC,cAAAC,GACAd,IAXA,GAAAY,GAAAG,WAAAL,EAAA,GAIAI,EAAAE,YAAAN,EAAA,KAzLA/F,EAAAJ,QAAA0E,CAUA,IAOAM,GAPAD,KAGAE,GAAA,EAQAE,EAAA,EAIAE,EAAA,KA2CAO,EAAAc,EAAAC,kBAAAD,EAAAE,sBAcA5B,GADA,kBAAAY,GACAJ,EAAAN,GA8BAN,EAAAM,GAQAR,EAAAM,aAAAA,EAgFAN,EAAAE,yBAAAA,4IClNA,kBAAA5D,SAAA8B,UAAAJ,OACA1B,QAAA8B,UAAAJ,KAAA,SAAAjB,EAAAC,GACA,GAAAF,GAAAqF,UAAA3G,OAAAe,KAAAT,KAAAsG,MAAA7F,KAAA4F,WAAA5F,IACAO,GAAAhB,KAAA,KAAA,SAAAuG,GACAP,WAAA,WACA,KAAAO,IACA,+BCNArH,EAAA,OAEA,oBAAAsB,WACAA,QAAAtB,EAAA,iBACAA,EAAA,4BAGAA,EAAA;ALTA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;AC5NA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o capacity) {\n // Manually shift all values starting at the index back to the\n // beginning of the queue.\n for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {\n queue[scan] = queue[scan + index];\n }\n queue.length -= index;\n index = 0;\n }\n }\n queue.length = 0;\n index = 0;\n flushing = false;\n}\n\n// `requestFlush` is implemented using a strategy based on data collected from\n// every available SauceLabs Selenium web driver worker at time of writing.\n// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593\n\n// Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that\n// have WebKitMutationObserver but not un-prefixed MutationObserver.\n// Must use `global` instead of `window` to work in both frames and web\n// workers. `global` is a provision of Browserify, Mr, Mrs, or Mop.\nvar BrowserMutationObserver = global.MutationObserver || global.WebKitMutationObserver;\n\n// MutationObservers are desirable because they have high priority and work\n// reliably everywhere they are implemented.\n// They are implemented in all modern browsers.\n//\n// - Android 4-4.3\n// - Chrome 26-34\n// - Firefox 14-29\n// - Internet Explorer 11\n// - iPad Safari 6-7.1\n// - iPhone Safari 7-7.1\n// - Safari 6-7\nif (typeof BrowserMutationObserver === \"function\") {\n requestFlush = makeRequestCallFromMutationObserver(flush);\n\n// MessageChannels are desirable because they give direct access to the HTML\n// task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera\n// 11-12, and in web workers in many engines.\n// Although message channels yield to any queued rendering and IO tasks, they\n// would be better than imposing the 4ms delay of timers.\n// However, they do not work reliably in Internet Explorer or Safari.\n\n// Internet Explorer 10 is the only browser that has setImmediate but does\n// not have MutationObservers.\n// Although setImmediate yields to the browser's renderer, it would be\n// preferrable to falling back to setTimeout since it does not have\n// the minimum 4ms penalty.\n// Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and\n// Desktop to a lesser extent) that renders both setImmediate and\n// MessageChannel useless for the purposes of ASAP.\n// https://github.com/kriskowal/q/issues/396\n\n// Timers are implemented universally.\n// We fall back to timers in workers in most engines, and in foreground\n// contexts in the following browsers.\n// However, note that even this simple case requires nuances to operate in a\n// broad spectrum of browsers.\n//\n// - Firefox 3-13\n// - Internet Explorer 6-9\n// - iPad Safari 4.3\n// - Lynx 2.8.7\n} else {\n requestFlush = makeRequestCallFromTimer(flush);\n}\n\n// `requestFlush` requests that the high priority event queue be flushed as\n// soon as possible.\n// This is useful to prevent an error thrown in a task from stalling the event\n// queue if the exception handled by Node.js’s\n// `process.on(\"uncaughtException\")` or by a domain.\nrawAsap.requestFlush = requestFlush;\n\n// To request a high priority event, we induce a mutation observer by toggling\n// the text of a text node between \"1\" and \"-1\".\nfunction makeRequestCallFromMutationObserver(callback) {\n var toggle = 1;\n var observer = new BrowserMutationObserver(callback);\n var node = document.createTextNode(\"\");\n observer.observe(node, {characterData: true});\n return function requestCall() {\n toggle = -toggle;\n node.data = toggle;\n };\n}\n\n// The message channel technique was discovered by Malte Ubl and was the\n// original foundation for this library.\n// http://www.nonblocking.io/2011/06/windownexttick.html\n\n// Safari 6.0.5 (at least) intermittently fails to create message ports on a\n// page's first load. Thankfully, this version of Safari supports\n// MutationObservers, so we don't need to fall back in that case.\n\n// function makeRequestCallFromMessageChannel(callback) {\n// var channel = new MessageChannel();\n// channel.port1.onmessage = callback;\n// return function requestCall() {\n// channel.port2.postMessage(0);\n// };\n// }\n\n// For reasons explained above, we are also unable to use `setImmediate`\n// under any circumstances.\n// Even if we were, there is another bug in Internet Explorer 10.\n// It is not sufficient to assign `setImmediate` to `requestFlush` because\n// `setImmediate` must be called *by name* and therefore must be wrapped in a\n// closure.\n// Never forget.\n\n// function makeRequestCallFromSetImmediate(callback) {\n// return function requestCall() {\n// setImmediate(callback);\n// };\n// }\n\n// Safari 6.0 has a problem where timers will get lost while the user is\n// scrolling. This problem does not impact ASAP because Safari 6.0 supports\n// mutation observers, so that implementation is used instead.\n// However, if we ever elect to use timers in Safari, the prevalent work-around\n// is to add a scroll event listener that calls for a flush.\n\n// `setTimeout` does not call the passed callback if the delay is less than\n// approximately 7 in web workers in Firefox 8 through 18, and sometimes not\n// even then.\n\nfunction makeRequestCallFromTimer(callback) {\n return function requestCall() {\n // We dispatch a timeout with a specified delay of 0 for engines that\n // can reliably accommodate that request. This will usually be snapped\n // to a 4 milisecond delay, but once we're flushing, there's no delay\n // between events.\n var timeoutHandle = setTimeout(handleTimer, 0);\n // However, since this timer gets frequently dropped in Firefox\n // workers, we enlist an interval handle that will try to fire\n // an event 20 times per second until it succeeds.\n var intervalHandle = setInterval(handleTimer, 50);\n\n function handleTimer() {\n // Whichever timer succeeds will cancel both timers and\n // execute the callback.\n clearTimeout(timeoutHandle);\n clearInterval(intervalHandle);\n callback();\n }\n };\n}\n\n// This is for `asap.js` only.\n// Its name will be periodically randomized to break any code that depends on\n// its existence.\nrawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer;\n\n// ASAP was originally a nextTick shim included in Q. This was factored out\n// into this ASAP package. It was later adapted to RSVP which made further\n// amendments. These decisions, particularly to marginalize MessageChannel and\n// to capture the MutationObserver implementation in a closure, were integrated\n// back into ASAP proper.\n// https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js\n","// should work in any browser without browserify\n\nif (typeof Promise.prototype.done !== 'function') {\n Promise.prototype.done = function (onFulfilled, onRejected) {\n var self = arguments.length ? this.then.apply(this, arguments) : this\n self.then(null, function (err) {\n setTimeout(function () {\n throw err\n }, 0)\n })\n }\n}","// not \"use strict\" so we can declare global \"Promise\"\n\nvar asap = require('asap');\n\nif (typeof Promise === 'undefined') {\n Promise = require('./lib/core.js')\n require('./lib/es6-extensions.js')\n}\n\nrequire('./polyfill-done.js');\n"]} \ No newline at end of file diff --git a/docs/plugins/cordova-plugin-googlemaps/www/spherical.js b/docs/plugins/cordova-plugin-googlemaps/www/spherical.js new file mode 100644 index 0000000..68578ff --- /dev/null +++ b/docs/plugins/cordova-plugin-googlemaps/www/spherical.js @@ -0,0 +1,283 @@ +cordova.define("cordova-plugin-googlemaps.spherical", function(require, exports, module) { var LatLng = require('./LatLng'); +var common = require('./Common'); +var EARTH_RADIUS = 6371009; + +/** + * Port from android-maps-utils + * https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/SphericalUtil.java + */ + +/** + * Returns the non-negative remainder of x / m. + * @param x The operand. + * @param m The modulus. + */ +function mod(x, m) { + return ((x % m) + m) % m; +} +/** + * Wraps the given value into the inclusive-exclusive interval between min and max. + * @param n The value to wrap. + * @param min The minimum. + * @param max The maximum. + */ +function wrap(n, min, max) { + return (n >= min && n < max) ? n : (mod(n - min, max - min) + min); +} + +/** + * Returns haversine(angle-in-radians). + * hav(x) == (1 - cos(x)) / 2 == sin(x / 2)^2. + */ +function hav(x) { + var sinHalf = Math.sin(x * 0.5); + return sinHalf * sinHalf; +} + +/** + * Computes inverse haversine. Has good numerical stability around 0. + * arcHav(x) == acos(1 - 2 * x) == 2 * asin(sqrt(x)). + * The argument must be in [0, 1], and the result is positive. + */ +function arcHav(x) { + return 2 * Math.asin(Math.sqrt(x)); +} + +/** + * Returns hav() of distance from (lat1, lng1) to (lat2, lng2) on the unit sphere. + */ +function havDistance(lat1, lat2, dLng) { + return hav(lat1 - lat2) + hav(dLng) * Math.cos(lat1) * Math.cos(lat2); +} + +/** + * Returns distance on the unit sphere; the arguments are in radians. + */ +function distanceRadians(lat1, lng1, lat2, lng2) { + return arcHav(havDistance(lat1, lat2, lng1 - lng2)); +} + +/** + * Returns the angle between two LatLngs, in radians. This is the same as the distance + * on the unit sphere. + */ +function computeAngleBetween(from, to) { + return distanceRadians(toRadians(from.lat), toRadians(from.lng), + toRadians(to.lat), toRadians(to.lng)); +} + +/** + * Returns the distance between two LatLngs, in meters. + */ +function computeDistanceBetween(from, to) { + return computeAngleBetween(from, to) * EARTH_RADIUS; +} + +/** + * Returns the distance between two LatLngs, in meters. + */ +function computeOffset(from, distance, heading) { + distance /= EARTH_RADIUS; + heading = toRadians(heading); + + // http://williams.best.vwh.net/avform.htm#LL + var fromLat = toRadians(from.lat); + var fromLng = toRadians(from.lng); + var cosDistance = Math.cos(distance); + var sinDistance = Math.sin(distance); + var sinFromLat = Math.sin(fromLat); + var cosFromLat = Math.cos(fromLat); + var sinLat = cosDistance * sinFromLat + sinDistance * cosFromLat * Math.cos(heading); + var dLng = Math.atan2( + sinDistance * cosFromLat * Math.sin(heading), + cosDistance - sinFromLat * sinLat); + return new LatLng(toDegrees(Math.asin(sinLat)), toDegrees(fromLng + dLng)); +} + +function toRadians(d) { + return d * Math.PI / 180; +} + +function toDegrees(r) { + return r * 180 / Math.PI; +} + +/* + * Returns the signed area of a closed path on a sphere of given radius. + */ +function computeSignedArea(path) { + var radius = EARTH_RADIUS; + path = common.convertToPositionArray(path); + + var size = path.length; + if (size < 3) { + return 0; + } + var total = 0; + + var prev = path[size - 1]; + var prevTanLat = Math.tan((Math.PI / 2 - toRadians(prev.lat)) / 2); + var prevLng = toRadians(prev.lng); + + // For each edge, accumulate the signed area of the triangle formed by the North Pole + // and that edge ("polar triangle"). + path.forEach(function (position) { + var tanLat = Math.tan((Math.PI / 2 - toRadians(position.lat)) / 2); + var lng = toRadians(position.lng); + total += polarTriangleArea(tanLat, lng, prevTanLat, prevLng); + prevTanLat = tanLat; + prevLng = lng; + }); + return total * (radius * radius); +} + +/* + * Returns the signed area of a triangle which has North Pole as a vertex. + * Formula derived from "Area of a spherical triangle given two edges and the included angle" + * as per "Spherical Trigonometry" by Todhunter, page 71, section 103, point 2. + * See http://books.google.com/books?id=3uBHAAAAIAAJ&pg=PA71 + * The arguments named "tan" are tan((pi/2 - latitude)/2). + */ +function polarTriangleArea(tan1, lng1, tan2, lng2) { + + var deltaLng = lng1 - lng2; + var t = tan1 * tan2; + return 2 * Math.atan2(t * Math.sin(deltaLng), 1 + t * Math.cos(deltaLng)); +} + +function computeArea(path) { + return Math.abs(computeSignedArea(path)); +} + +/** + * Returns the heading from one LatLng to another LatLng. Headings are + * expressed in degrees clockwise from North within the range [-180,180). + * @return The heading in degrees clockwise from north. + */ +function computeHeading(from, to) { + // http://williams.best.vwh.net/avform.htm#Crs + var fromLat = toRadians(from.lat); + var fromLng = toRadians(from.lng); + var toLat = toRadians(to.lat); + var toLng = toRadians(to.lng); + var dLng = toLng - fromLng; + var heading = Math.atan2( + Math.sin(dLng) * Math.cos(toLat), + Math.cos(fromLat) * Math.sin(toLat) - Math.sin(fromLat) * Math.cos(toLat) * Math.cos(dLng)); + return wrap(toDegrees(heading), -180, 180); +} + +/** + * Returns the location of origin when provided with a LatLng destination, + * meters travelled and original heading. Headings are expressed in degrees + * clockwise from North. This function returns null when no solution is + * available. + * @param to The destination LatLng. + * @param distance The distance travelled, in meters. + * @param heading The heading in degrees clockwise from north. + */ +function computeOffsetOrigin(to, distance, heading) { + heading = toRadians(heading); + distance /= EARTH_RADIUS; + // http://lists.maptools.org/pipermail/proj/2008-October/003939.html + var n1 = Math.cos(distance); + var n2 = Math.sin(distance) * Math.cos(heading); + var n3 = Math.sin(distance) * Math.sin(heading); + var n4 = Math.sin(toRadians(to.lat)); + // There are two solutions for b. b = n2 * n4 +/- sqrt(), one solution results + // in the latitude outside the [-90, 90] range. We first try one solution and + // back off to the other if we are outside that range. + var n12 = n1 * n1; + var discriminant = n2 * n2 * n12 + n12 * n12 - n12 * n4 * n4; + if (discriminant < 0) { + // No real solution which would make sense in LatLng-space. + return null; + } + var b = n2 * n4 + Math.sqrt(discriminant); + b /= n1 * n1 + n2 * n2; + var a = (n4 - n2 * b) / n1; + var fromLatRadians = Math.atan2(a, b); + if (fromLatRadians < -Math.PI / 2 || fromLatRadians > Math.PI / 2) { + b = n2 * n4 - Math.sqrt(discriminant); + b /= n1 * n1 + n2 * n2; + fromLatRadians = Math.atan2(a, b); + } + if (fromLatRadians < -Math.PI / 2 || fromLatRadians > Math.PI / 2) { + // No solution which would make sense in LatLng-space. + return null; + } + var fromLngRadians = toRadians(to.lng) - + Math.atan2(n3, n1 * Math.cos(fromLatRadians) - n2 * Math.sin(fromLatRadians)); + return new LatLng(toDegrees(fromLatRadians), toDegrees(fromLngRadians)); +} + +/** + * Returns the LatLng which lies the given fraction of the way between the + * origin LatLng and the destination LatLng. + * @param from The LatLng from which to start. + * @param to The LatLng toward which to travel. + * @param fraction A fraction of the distance to travel. + * @return The interpolated LatLng. + */ +function interpolate(from, to, fraction) { + // http://en.wikipedia.org/wiki/Slerp + var fromLat = toRadians(from.lat); + var fromLng = toRadians(from.lng); + var toLat = toRadians(to.lat); + var toLng = toRadians(to.lng); + var cosFromLat = Math.cos(fromLat); + var cosToLat = Math.cos(toLat); + + // Computes Spherical interpolation coefficients. + var angle = computeAngleBetween(from, to); + var sinAngle = Math.sin(angle); + if (sinAngle < 1E-6) { + return from; + } + var a = Math.sin((1 - fraction) * angle) / sinAngle; + var b = Math.sin(fraction * angle) / sinAngle; + + // Converts from polar to vector and interpolate. + var x = a * cosFromLat * Math.cos(fromLng) + b * cosToLat * Math.cos(toLng); + var y = a * cosFromLat * Math.sin(fromLng) + b * cosToLat * Math.sin(toLng); + var z = a * Math.sin(fromLat) + b * Math.sin(toLat); + + // Converts interpolated vector back to polar. + var lat = Math.atan2(z, Math.sqrt(x * x + y * y)); + var lng = Math.atan2(y, x); + return new LatLng(toDegrees(lat), toDegrees(lng)); +} + +/** + * Returns the length of the given path, in meters, on Earth. + */ +function computeLength(path) { + path = common.convertToPositionArray(path); + if (path.length < 2) { + return 0; + } + var length = 0; + var prev = path[0]; + var prevLat = toRadians(prev.lat); + var prevLng = toRadians(prev.lng); + path.forEach(function (point) { + var lat = toRadians(point.lat); + var lng = toRadians(point.lng); + length += distanceRadians(prevLat, prevLng, lat, lng); + prevLat = lat; + prevLng = lng; + }); + return length * EARTH_RADIUS; +} +module.exports = { + computeDistanceBetween: computeDistanceBetween, + computeOffset: computeOffset, + computeOffsetOrigin: computeOffsetOrigin, + computeArea: computeArea, + computeSignedArea: computeSignedArea, + computeHeading: computeHeading, + interpolate: interpolate, + computeLength: computeLength +}; + +}); diff --git a/docs/plugins/cordova-plugin-ionic-webview/src/www/util.js b/docs/plugins/cordova-plugin-ionic-webview/src/www/util.js new file mode 100644 index 0000000..aa1103b --- /dev/null +++ b/docs/plugins/cordova-plugin-ionic-webview/src/www/util.js @@ -0,0 +1,31 @@ +cordova.define("cordova-plugin-ionic-webview.IonicWebView", function(require, exports, module) { var exec = require('cordova/exec'); + +var WebView = { + convertFileSrc: function(url) { + if (!url) { + return url; + } + if (url.startsWith('/')) { + return window.WEBVIEW_SERVER_URL + '/_app_file_' + url; + } + if (url.startsWith('file://')) { + return window.WEBVIEW_SERVER_URL + url.replace('file://', '/_app_file_'); + } + if (url.startsWith('content://')) { + return window.WEBVIEW_SERVER_URL + url.replace('content:/', '/_app_content_'); + } + return url; + }, + setServerBasePath: function(path) { + exec(null, null, 'IonicWebView', 'setServerBasePath', [path]); + }, + getServerBasePath: function(callback) { + exec(callback, null, 'IonicWebView', 'getServerBasePath', []); + }, + persistServerBasePath: function() { + exec(null, null, 'IonicWebView', 'persistServerBasePath', []); + } +} + +module.exports = WebView; +}); diff --git a/docs/plugins/cordova-plugin-splashscreen/src/browser/SplashScreenProxy.js b/docs/plugins/cordova-plugin-splashscreen/src/browser/SplashScreenProxy.js new file mode 100644 index 0000000..5f6782f --- /dev/null +++ b/docs/plugins/cordova-plugin-splashscreen/src/browser/SplashScreenProxy.js @@ -0,0 +1,172 @@ +cordova.define("cordova-plugin-splashscreen.SplashScreenProxy", function(require, exports, module) { /* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +// Default parameter values including image size can be changed in `config.xml` +var splashImageWidth = 170; +var splashImageHeight = 200; +var position = { x: 0, y: 0, width: splashImageWidth, height: splashImageHeight }; +var localSplash; // the image to display +var localSplashImage; +var bgColor = "#464646"; +var imageSrc = '/img/logo.png'; +var splashScreenDelay = 3000; // in milliseconds +var showSplashScreen = true; // show splashcreen by default +var cordova = require('cordova'); +var configHelper = cordova.require('cordova/confighelper'); +var autoHideSplashScreen = true; + +function updateImageLocation() { + position.width = Math.min(splashImageWidth, window.innerWidth); + position.height = position.width * (splashImageHeight / splashImageWidth); + + localSplash.style.width = window.innerWidth + "px"; + localSplash.style.height = window.innerHeight + "px"; + localSplash.style.top = "0px"; + localSplash.style.left = "0px"; + + localSplashImage.style.top = "50%"; + localSplashImage.style.left = "50%"; + localSplashImage.style.height = position.height + "px"; + localSplashImage.style.width = position.width + "px"; + localSplashImage.style.marginTop = (-position.height / 2) + "px"; + localSplashImage.style.marginLeft = (-position.width / 2) + "px"; +} + +function onResize() { + updateImageLocation(); +} + +var SplashScreen = { + setBGColor: function (cssBGColor) { + bgColor = cssBGColor; + if (localSplash) { + localSplash.style.backgroundColor = bgColor; + } + }, + show: function () { + if(!localSplash) { + window.addEventListener("resize", onResize, false); + localSplash = document.createElement("div"); + localSplash.style.backgroundColor = bgColor; + localSplash.style.position = "absolute"; + localSplash.style["z-index"] = "99999"; + + localSplashImage = document.createElement("img"); + localSplashImage.src = imageSrc; + localSplashImage.style.position = "absolute"; + + updateImageLocation(); + + localSplash.appendChild(localSplashImage); + document.body.appendChild(localSplash); + + // deviceready fires earlier than the plugin init on cold-start + if (SplashScreen.shouldHideImmediately) { + SplashScreen.shouldHideImmediately = false; + window.setTimeout(function () { + SplashScreen.hide(); + }, 1000); + } + } + }, + hide: function () { + if(localSplash) { + var innerLocalSplash = localSplash; + localSplash = null; + window.removeEventListener("resize", onResize, false); + + innerLocalSplash.style.opacity = '0'; + innerLocalSplash.style["-webkit-transition"] = "opacity 1s ease-in-out"; + innerLocalSplash.style["-moz-transition"] = "opacity 1s ease-in-out"; + innerLocalSplash.style["-ms-transition"] = "opacity 1s ease-in-out"; + innerLocalSplash.style["-o-transition"] = "opacity 1s ease-in-out"; + + window.setTimeout(function () { + document.body.removeChild(innerLocalSplash); + innerLocalSplash = null; + }, 1000); + } else { + SplashScreen.shouldHideImmediately = true; + } + } +}; + +/** + * Reads preferences via ConfigHelper and substitutes default parameters. + */ +function readPreferencesFromCfg(cfg) { + try { + var value = cfg.getPreferenceValue('ShowSplashScreen'); + if(typeof value != 'undefined') { + showSplashScreen = value === 'true'; + } + + splashScreenDelay = cfg.getPreferenceValue('SplashScreenDelay') || splashScreenDelay; + splashScreenDelay = parseInt(splashScreenDelay, 10); + + imageSrc = cfg.getPreferenceValue('SplashScreen') || imageSrc; + bgColor = cfg.getPreferenceValue('SplashScreenBackgroundColor') || bgColor; + splashImageWidth = cfg.getPreferenceValue('SplashScreenWidth') || splashImageWidth; + splashImageHeight = cfg.getPreferenceValue('SplashScreenHeight') || splashImageHeight; + autoHideSplashScreen = cfg.getPreferenceValue('AutoHideSplashScreen') || autoHideSplashScreen; + autoHideSplashScreen = (autoHideSplashScreen === true || autoHideSplashScreen.toLowerCase() === 'true'); + } catch(e) { + var msg = '[Browser][SplashScreen] Error occurred on loading preferences from config.xml: ' + JSON.stringify(e); + console.error(msg); + } +} + +/** + * Shows and hides splashscreen if it is enabled, with a delay according the current preferences. + */ +function showAndHide() { + if(showSplashScreen) { + SplashScreen.show(); + + window.setTimeout(function() { + SplashScreen.hide(); + }, splashScreenDelay); + } +} + +/** + * Tries to read config.xml and override default properties and then shows and hides splashscreen if it is enabled. + */ +(function initAndShow() { + configHelper.readConfig(function(config) { + readPreferencesFromCfg(config); + if (autoHideSplashScreen) { + showAndHide(); + } else { + SplashScreen.show(); + } + + }, function(err) { + console.error(err); + }); +})(); + +module.exports = SplashScreen; + +require("cordova/exec/proxy").add("SplashScreen", SplashScreen); + + +}); diff --git a/docs/plugins/cordova-plugin-splashscreen/www/splashscreen.js b/docs/plugins/cordova-plugin-splashscreen/www/splashscreen.js new file mode 100644 index 0000000..0e6a10a --- /dev/null +++ b/docs/plugins/cordova-plugin-splashscreen/www/splashscreen.js @@ -0,0 +1,35 @@ +cordova.define("cordova-plugin-splashscreen.SplashScreen", function(require, exports, module) { /* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +var exec = require('cordova/exec'); + +var splashscreen = { + show:function() { + exec(null, null, "SplashScreen", "show", []); + }, + hide:function() { + exec(null, null, "SplashScreen", "hide", []); + } +}; + +module.exports = splashscreen; + +}); diff --git a/docs/plugins/cordova-plugin-statusbar/src/browser/StatusBarProxy.js b/docs/plugins/cordova-plugin-statusbar/src/browser/StatusBarProxy.js new file mode 100644 index 0000000..e6e41ec --- /dev/null +++ b/docs/plugins/cordova-plugin-statusbar/src/browser/StatusBarProxy.js @@ -0,0 +1,52 @@ +cordova.define("cordova-plugin-statusbar.StatusBarProxy", function(require, exports, module) { /* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +function notSupported(win,fail) { + // + console.log('StatusBar is not supported'); + setTimeout(function(){ + if (win) { + win(); + } + // note that while it is not explicitly supported, it does not fail + // this is really just here to allow developers to test their code in the browser + // and if we fail, then their app might as well. -jm + },0); +} + +module.exports = { + isVisible: false, + styleBlackTranslucent:notSupported, + styleDefault:notSupported, + styleLightContent:notSupported, + styleBlackOpaque:notSupported, + overlaysWebView:notSupported, + styleLightContect: notSupported, + backgroundColorByName: notSupported, + backgroundColorByHexString: notSupported, + hide: notSupported, + show: notSupported, + _ready:notSupported +}; + +require("cordova/exec/proxy").add("StatusBar", module.exports); + + +}); diff --git a/docs/plugins/cordova-plugin-statusbar/www/statusbar.js b/docs/plugins/cordova-plugin-statusbar/www/statusbar.js new file mode 100644 index 0000000..9684d23 --- /dev/null +++ b/docs/plugins/cordova-plugin-statusbar/www/statusbar.js @@ -0,0 +1,115 @@ +cordova.define("cordova-plugin-statusbar.statusbar", function(require, exports, module) { /* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * +*/ + +/* global cordova */ + +var exec = require('cordova/exec'); + +var namedColors = { + "black": "#000000", + "darkGray": "#A9A9A9", + "lightGray": "#D3D3D3", + "white": "#FFFFFF", + "gray": "#808080", + "red": "#FF0000", + "green": "#00FF00", + "blue": "#0000FF", + "cyan": "#00FFFF", + "yellow": "#FFFF00", + "magenta": "#FF00FF", + "orange": "#FFA500", + "purple": "#800080", + "brown": "#A52A2A" +}; + +var StatusBar = { + + isVisible: true, + + overlaysWebView: function (doOverlay) { + exec(null, null, "StatusBar", "overlaysWebView", [doOverlay]); + }, + + styleDefault: function () { + // dark text ( to be used on a light background ) + exec(null, null, "StatusBar", "styleDefault", []); + }, + + styleLightContent: function () { + // light text ( to be used on a dark background ) + exec(null, null, "StatusBar", "styleLightContent", []); + }, + + styleBlackTranslucent: function () { + // #88000000 ? Apple says to use lightContent instead + exec(null, null, "StatusBar", "styleBlackTranslucent", []); + }, + + styleBlackOpaque: function () { + // #FF000000 ? Apple says to use lightContent instead + exec(null, null, "StatusBar", "styleBlackOpaque", []); + }, + + backgroundColorByName: function (colorname) { + return StatusBar.backgroundColorByHexString(namedColors[colorname]); + }, + + backgroundColorByHexString: function (hexString) { + if (hexString.charAt(0) !== "#") { + hexString = "#" + hexString; + } + + if (hexString.length === 4) { + var split = hexString.split(""); + hexString = "#" + split[1] + split[1] + split[2] + split[2] + split[3] + split[3]; + } + + exec(null, null, "StatusBar", "backgroundColorByHexString", [hexString]); + }, + + hide: function () { + exec(null, null, "StatusBar", "hide", []); + StatusBar.isVisible = false; + }, + + show: function () { + exec(null, null, "StatusBar", "show", []); + StatusBar.isVisible = true; + } + +}; + +// prime it. setTimeout so that proxy gets time to init +window.setTimeout(function () { + exec(function (res) { + if (typeof res == 'object') { + if (res.type == 'tap') { + cordova.fireWindowEvent('statusTap'); + } + } else { + StatusBar.isVisible = res; + } + }, null, "StatusBar", "_ready", []); +}, 0); + +module.exports = StatusBar; + +});