cordova-plugin-googlemaps
Version:
Google Maps native SDK for Android and iOS, and Google Maps JavaScript API v3 for browser.
177 lines (162 loc) • 5.98 kB
JavaScript
var BaseArrayClass = require('cordova-plugin-googlemaps.BaseArrayClass');
var geocoder = null;
var lastRequestTime = 0;
var QUEUE = new BaseArrayClass();
QUEUE.on('insert_at', function() {
if (QUEUE.getLength() === 1) {
this.trigger('next');
}
});
QUEUE.one('insert_at', function() {
geocoder = new google.maps.Geocoder();
this.trigger('next');
});
QUEUE.on('next', function() {
var self = QUEUE;
if (!geocoder || self._executing || QUEUE.getLength() === 0) {
return;
}
if (Date.now() - lastRequestTime < 300) {
setTimeout(function() {
self.trigger('next');
}, 300 + Math.floor(Math.random() * 200));
return;
}
lastRequestTime = Date.now();
self._executing = true;
var cmd = QUEUE.removeAt(0, true);
geocoder.geocode(cmd.geocoderRequest, function(results, status) {
switch(status) {
case google.maps.GeocoderStatus.ERROR:
cmd.onError('[geocoding] Cannot connect to Google servers');
return;
case google.maps.GeocoderStatus.INVALID_REQUEST:
cmd.onError('[geocoding] Invalid request for geocoder');
return;
case google.maps.GeocoderStatus.OVER_QUERY_LIMIT:
QUEUE.insertAt(0, cmd);
console.warn('[geocoding] Due to the OVER_QUERY_LIMIT error, wait 3 sec, then try again.');
setTimeout(function() {
self._executing = false;
self.trigger('next');
}, 3000 + Math.floor(Math.random() * 200));
return;
case google.maps.GeocoderStatus.REQUEST_DENIED:
cmd.onError('[geocoding] Google denited your geocoding request.');
return;
case google.maps.GeocoderStatus.UNKNOWN_ERROR:
cmd.onError('[geocoding] There was an unknown error. Please try again.');
return;
}
var pluginResults = results.map(function(geocoderResult) {
var result = {
'position': {
'lat': geocoderResult.geometry.location.lat(),
'lng': geocoderResult.geometry.location.lng()
},
extra: {
lines: []
}
};
if (geocoderResult.place_id) {
result.extra.place_id = geocoderResult.place_id;
}
if (geocoderResult.plus_code) {
result.extra.plus_code = geocoderResult.plus_code;
}
if (geocoderResult.types) {
result.extra.types = geocoderResult.types;
}
var administrative_area = [];
var sublocality_area = [];
geocoderResult.address_components.forEach(function(addrComp) {
result.extra.lines.push(addrComp.long_name);
if (!result.locality && addrComp.types.indexOf('locality') > -1) {
result.locality = addrComp.short_name;
}
if (addrComp.types.indexOf('administrative_area_level_1') > -1 ||
addrComp.types.indexOf('administrative_area_level_2') > -1 ||
addrComp.types.indexOf('administrative_area_level_3') > -1 ||
addrComp.types.indexOf('administrative_area_level_4') > -1) {
addrComp.types.forEach(function(type) {
if (type.indexOf('administrative_area_level_') === 0) {
var idx = parseInt(type.replace('administrative_area_level_', ''), 10);
administrative_area[idx - 1] = addrComp.long_name;
}
});
}
if (addrComp.types.indexOf('sublocality_level_1') > -1 ||
addrComp.types.indexOf('sublocality_level_2') > -1 ||
addrComp.types.indexOf('sublocality_level_3') > -1 ||
addrComp.types.indexOf('sublocality_level_4') > -1 ||
addrComp.types.indexOf('sublocality_level_5') > -1) {
addrComp.types.forEach(function(type) {
if (type.indexOf('sublocality_level_') === 0) {
var idx = parseInt(type.replace('sublocality_level_', ''), 10);
sublocality_area[idx - 1] = addrComp.long_name;
}
});
}
if (!result.country && addrComp.types.indexOf('country') > -1) {
result.country = addrComp.long_name;
result.countryCode = addrComp.short_name;
}
if (!result.postalCode && addrComp.types.indexOf('postal_code') > -1) {
result.postalCode = addrComp.long_name;
}
if (!result.thoroughfare && addrComp.types.indexOf('street_address') > -1) {
result.thoroughfare = addrComp.long_name;
}
});
if (administrative_area.length > 0) {
result.adminArea = administrative_area.shift();
result.subAdminArea = administrative_area.join(',');
}
if (sublocality_area.length > 0) {
result.subLocality = sublocality_area.join(',');
}
//result.extra = geocoderResult.address_components; // for debug
return result;
});
self._executing = false;
cmd.onSuccess({
'idx': cmd.pluginRequest.idx,
'results': pluginResults
});
// Insert delay to prevent the OVER_QUERY_LIMIT error.
var delay = 300 + Math.floor(Math.random() * 200);
setTimeout(function() {
self._executing = false;
self.trigger('next');
}, delay);
});
});
module.exports = {
'geocode': function(onSuccess, onError, args) {
var request = args[0];
var geocoderRequest = {};
if (!request.position && request.address) {
//---------------------
// Geocoding
//---------------------
if (request.bounds && Array.isArray(request.bounds)) {
var bounds = new google.maps.LatLngBounds();
request.bounds.forEach(function(position) {
bounds.extend(position);
});
geocoderRequest.bounds = bounds;
}
geocoderRequest.address = request.address;
}
if (request.position && !request.address) {
geocoderRequest.location = request.position;
}
QUEUE.push({
'geocoderRequest': geocoderRequest,
'pluginRequest': request,
'onSuccess': onSuccess,
'onError': onError
});
}
};
require('cordova/exec/proxy').add('PluginGeocoder', module.exports);