google-apps-script - 提供 API key 以避免 Apps 脚本中的 map 服务出现命中限制错误

标签 google-apps-script google-sheets google-directions-api custom-function

我有一个 Google 表格,我们通过 Maps Service 获取两个纬度/经度之间的行驶距离。下面的函数可以工作,但矩阵有 4,500 个单元格,因此我收到“Hit Limit”错误。

如何在此处提供我的付费帐户的 API key ?

自定义函数

function drivingMeters(origin, destination) {
  if (origin=='' || destination==''){return ''}
  var directions = Maps.newDirectionFinder()
  .setOrigin(origin)
  .setDestination(destination)
  .getDirections();
  return directions.routes[0].legs[0].distance.value ;
}

使用示例:

A1: =drivingMeters($E10,G$9)

Where E10 = 42.771328,-91.902281
  and G9  = 42.490390,-91.1626620

最佳答案

根据文档,您应该 initialize the Maps service with your authentication details在调用其他方法之前:

Your client ID and signing key can be obtained from the Google Enterprise Support Portal. Set these values to null to go back to using the default quota allowances.

我建议将这些值存储在 PropertiesService 中并使用CacheService ,提供快速访问。使用这种方法,而不是将它们写入脚本项目的主体中,意味着它们不会被其他编辑器无意中复制,推送到共享代码存储库,或者如果您的脚本作为库发布,则它们不会对其他开发人员可见。

此外,我建议重写您的自定义函数以接受数组输入并返回适当的数组输出 - 这将有助于加快其执行速度。 Google 在自定义函数页面上提供了这样的示例:https://developers.google.com/apps-script/guides/sheets/functions#optimization

使用 props/cache 的示例: example props

function authenticateMaps_() {
  // Try to get values from cache:
  const cache = CacheService.getScriptCache();
  var props = cache.getAll(['mapsClientId', 'mapsSigningKey']);
  // If it wasn't there, read it from PropertiesService.
  if (!props || !props.mapsClientId || !props.mapsSigningKey) {
    const allProps = PropertiesService.getScriptProperties().getProperties();
    props = {
      'mapsClientId': allProps.mapsClientId,
      'mapsSigningKey': allProps.mapsSigningKey
    };
    // Cache these values for faster access (max 6hrs)
    cache.putAll(props, 21600);
  }
  // Apply these keys to the Maps Service. If they don't exist, this is the
  // same as being a default user (i.e. no paid quota).
  Maps.setAuthentication(props.mapsClientId, props.mapsSigningKey);
}
function deauthMaps_() {
  Maps.setAuthentication(null, null);
}

// Your called custom function. First tries without authentication,
// and then if an error occurs, assumes it was a quota limit error
// and retries. Other errors do exist (like no directions, etc)...
function DRIVINGMETERS(origin, dest) {
  if (!origin || !destination)
    return;
  try {
    return drivingMeters_(origin, dest);
  } catch (e) {
    console.error({
      message: "Error when computing directions: " + e.message,
      error: e
    });
    // One of the possible errors is a quota limit, so authenticate and retry:
    // (Business code should handle other errors instead of simply assuming this :) )
    authenticateMaps_();
    var result = drivingMeters_(origin, dest);
    deauthMaps_();
    return result;
  }
}

// Your implementation function.
function drivingMeters_(origin, dest) {
  var directions = Maps.newDirectionFinder()
  ...
}

关于google-apps-script - 提供 API key 以避免 Apps 脚本中的 map 服务出现命中限制错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50703364/

相关文章:

javascript - 如何从 Google Sheet 列获取值

google-apps-script - UrlFetchApp 在脚本编辑器中工作,而不在文档中工作

ios - 在创建新 key 并删除旧 key 后,我在我的 iOS Xcode 项目中使用适用于 iOS 的 Google Maps SDK 的不受限制的 api key

android - Google 从当前位置到已知位置的定向路线

javascript - 谷歌脚本电子邮件表单接受/拒绝

google-apps-script - 类型错误 : Cannot call method "getActiveSheet" of null

google-apps-script - Google Apps 脚本 - 如何将一列复制到下一个可用列的另一工作表

javascript - 谷歌表格脚本 : Passing function as a parameter

javascript - 如何让 Google 文件选取器脚本在公开共享的 Google 工作表上启动?

java - 如何获取 Google 返回的 JSON 对象中的持续时间和距离?