首页 > 解决方案 > 谷歌地图高程 API 安卓工作室

问题描述

我正在创建一个 android 应用程序来使用 Google Maps SDK 和 Google Play Services Location API 记录用户的活动。我正在尝试根据给定的纬度和经度检索用户的海拔高度。我最初使用 Location#getAltitude() 但后来意识到这并没有给出海拔高度。

我使用以下查询字符串继续使用开放式高程 API:

String url = "https://api.open-elevation.com/api/v1/lookup?locations=" + latLng.latitude + "," + latLng.longitude;

但是,该 API 在生成响应方面似乎太慢了。然后我找到了 Google Maps Elevation API,我们也可以使用 URL 发出请求。但是,我们需要传递一个 API 密钥,我不想在 URL 字符串中传递这个 API 密钥并最终将其提交到远程存储库。

在这个 repo (https://github.com/googlemaps/google-maps-services-java)中,我找到了这个类:/src/main/java/com/google/maps/ElevationApi.java 我认为我可以用来避免弄乱http请求。

在我的 gradle 中,我包含了这个依赖项:

implementation 'com.google.maps:google-maps-services:0.18.0'

目前,检索高程的代码如下:

ElevationApi.getByPoint(new GeoApiContext.Builder().apiKey(API_KEY).build(), latLng)
            .setCallback(new PendingResult.Callback<ElevationResult>() {
                @Override
                public void onResult(ElevationResult result) {
                    consumer.doAction(result.elevation);
                }

                @Override
                public void onFailure(Throwable e) {
                    e.printStackTrace();
                }
            });

既然我不想将它提交到存储库,我应该在这里为 API_KEY 传递什么?我在 local.properties 中为地图定义了一个 api 键,但是,如下所示:

MAPS_API_KEY=<API_KEY_HERE>

基本上,我的问题是,我可以在未提交到 GitHub 的属性文件中定义 API 密钥,然后在代码中引用它吗?

谢谢你的帮助。

更新: 我已经设法使用 gradle 从 local.properties 读取 API 密钥,但从 ElevationApi 得到一个异常,说 API 21+ 预期,但是 30 ......奇怪。因此,我使用以下 Volley 请求回到开放高度 API:

/**
 * Calculates elevation gain for the provided recording service
 * @param recordingService the recording service to calculate elevation gain for
 * @param response the handler to consume the elevation gain with
 */
public static void calculateElevationGain(RecordingService recordingService, ActionHandlerConsumer<Double> response) {
    ArrayList<Location> locations = recordingService.getLocations();
    JSONArray array = constructLocations(locations);

    try {
        if (array != null) {
            RequestQueue requestQueue = Volley.newRequestQueue(recordingService);
            String url = "https://api.open-elevation.com/api/v1/lookup";
            JSONObject requestHeader = new JSONObject(); // TODO this seems very slow
            requestHeader.put("locations", array);
            JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, requestHeader,
                    response1 -> handleSuccessfulResponse(response1, response), RecordingUtils::handleErrorResponse);
            request.setRetryPolicy(new DefaultRetryPolicy(500000, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
            requestQueue.add(request);
        }
    } catch (JSONException ex) {
        ex.printStackTrace();
    }
}

我不得不将超时设置为一个很大的数字,不确定它应该有多高,因为由于响应时间慢,我收到了 Volley 超时错误。

还有其他方法可以检索有关海平面的高度吗?

标签: javaandroidmapsgoogle-elevation-api

解决方案


是的,open-elevation.com 在超时和延迟方面存在间歇性问题。

此 GIS 堆栈交换问题Seeking Alternative to Google Maps Elevation API中列出了一些替代方案。我是Open Topo Data的开发人员,这是那里投票最多的答案。你可以用 docker 托管你自己的服务器,我也有一个免费的公共 API,它有很好的延迟和正常运行时间。

还有GPXZ作为具有更高质量数据的 Google Elevation API 的替代品,但它需要 API 密钥,因此与 Google Maps 存在相同的问题。


推荐阅读