Android中通过经度和纬度获取海拔高度

发布于 2024-08-16 20:32:00 字数 53 浏览 4 评论 0原文

Android平台上有没有一种快速高效的通过经纬度获取海拔高度(elevation)的方法?

Is there a quick and efficient way to get altitude (elevation) by longitude and latitude on the Android platform?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

当爱已成负担 2024-08-23 20:32:00

我的方法是使用 USGS Elevation Query Web Service

private double getAltitude(Double longitude, Double latitude) {
    double result = Double.NaN;
    HttpClient httpClient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    String url = "http://gisdata.usgs.gov/"
            + "xmlwebservices2/elevation_service.asmx/"
            + "getElevation?X_Value=" + String.valueOf(longitude)
            + "&Y_Value=" + String.valueOf(latitude)
            + "&Elevation_Units=METERS&Source_Layer=-1&Elevation_Only=true";
    HttpGet httpGet = new HttpGet(url);
    try {
        HttpResponse response = httpClient.execute(httpGet, localContext);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream instream = entity.getContent();
            int r = -1;
            StringBuffer respStr = new StringBuffer();
            while ((r = instream.read()) != -1)
                respStr.append((char) r);
            String tagOpen = "<double>";
            String tagClose = "</double>";
            if (respStr.indexOf(tagOpen) != -1) {
                int start = respStr.indexOf(tagOpen) + tagOpen.length();
                int end = respStr.indexOf(tagClose);
                String value = respStr.substring(start, end);
                result = Double.parseDouble(value);
            }
            instream.close();
        }
    } catch (ClientProtocolException e) {} 
    catch (IOException e) {}
    return result;
}

以及使用示例(就在HelloMapView 类):

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        linearLayout = (LinearLayout) findViewById(R.id.zoomview);
        mapView = (MapView) findViewById(R.id.mapview);
        mZoom = (ZoomControls) mapView.getZoomControls();
        linearLayout.addView(mZoom);
        mapView.setOnTouchListener(new OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == 1) {
                    final GeoPoint p = mapView.getProjection().fromPixels(
                            (int) event.getX(), (int) event.getY());
                    final StringBuilder msg = new StringBuilder();
                    new Thread(new Runnable() {
                        public void run() {
                            final double lon = p.getLongitudeE6() / 1E6;
                            final double lat = p.getLatitudeE6() / 1E6;
                            final double alt = getAltitude(lon, lat);
                            msg.append("Lon: ");
                            msg.append(lon);
                            msg.append(" Lat: ");
                            msg.append(lat);
                            msg.append(" Alt: ");
                            msg.append(alt);
                        }
                    }).run();
                    Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT)
                            .show();
                }
                return false;
            }
        });
    }

My approach is to use USGS Elevation Query Web Service:

private double getAltitude(Double longitude, Double latitude) {
    double result = Double.NaN;
    HttpClient httpClient = new DefaultHttpClient();
    HttpContext localContext = new BasicHttpContext();
    String url = "http://gisdata.usgs.gov/"
            + "xmlwebservices2/elevation_service.asmx/"
            + "getElevation?X_Value=" + String.valueOf(longitude)
            + "&Y_Value=" + String.valueOf(latitude)
            + "&Elevation_Units=METERS&Source_Layer=-1&Elevation_Only=true";
    HttpGet httpGet = new HttpGet(url);
    try {
        HttpResponse response = httpClient.execute(httpGet, localContext);
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream instream = entity.getContent();
            int r = -1;
            StringBuffer respStr = new StringBuffer();
            while ((r = instream.read()) != -1)
                respStr.append((char) r);
            String tagOpen = "<double>";
            String tagClose = "</double>";
            if (respStr.indexOf(tagOpen) != -1) {
                int start = respStr.indexOf(tagOpen) + tagOpen.length();
                int end = respStr.indexOf(tagClose);
                String value = respStr.substring(start, end);
                result = Double.parseDouble(value);
            }
            instream.close();
        }
    } catch (ClientProtocolException e) {} 
    catch (IOException e) {}
    return result;
}

And example of use (right in HelloMapView class):

public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        linearLayout = (LinearLayout) findViewById(R.id.zoomview);
        mapView = (MapView) findViewById(R.id.mapview);
        mZoom = (ZoomControls) mapView.getZoomControls();
        linearLayout.addView(mZoom);
        mapView.setOnTouchListener(new OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == 1) {
                    final GeoPoint p = mapView.getProjection().fromPixels(
                            (int) event.getX(), (int) event.getY());
                    final StringBuilder msg = new StringBuilder();
                    new Thread(new Runnable() {
                        public void run() {
                            final double lon = p.getLongitudeE6() / 1E6;
                            final double lat = p.getLatitudeE6() / 1E6;
                            final double alt = getAltitude(lon, lat);
                            msg.append("Lon: ");
                            msg.append(lon);
                            msg.append(" Lat: ");
                            msg.append(lat);
                            msg.append(" Alt: ");
                            msg.append(alt);
                        }
                    }).run();
                    Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT)
                            .show();
                }
                return false;
            }
        });
    }
沫离伤花 2024-08-23 20:32:00

您还可以使用 Google Elevation API。它的在线文档位于:
https://developers.google.com/maps/documentation/elevation/

请注意以下来自上述 API 页面:

使用限制:Google 的使用
地理编码 API 需要查询
最多 2,500 个地理定位请求
每天。 (Google 地图 API 用户
Premier 最多可执行 100,000 次
每天的请求数。)此限制是
强制执行以防止滥用和/或
地理编码 API 的重新利用,以及
这个限制可能会改变
未来恕不另行通知。此外,
我们强制执行请求速率限制
防止滥用服务。如果你
超过24小时限制或其他
滥用地理编码 API 服务
可能会暂时停止为您工作。
如果您继续超过此限制,
您对地理编码 API 的访问可能会
被封锁。注意:地理编码 API
只能与
谷歌地图;地理编码结果无
在地图上显示它们是
禁止。有关完整详细信息
允许使用,请参阅地图 API
服务条款许可限制。

更改上面的 Google API 的 Max Gontar 代码可得到以下结果,返回的海拔高度以英尺为单位:

private double getElevationFromGoogleMaps(double longitude, double latitude) {
        double result = Double.NaN;
        HttpClient httpClient = new DefaultHttpClient();
        HttpContext localContext = new BasicHttpContext();
        String url = "http://maps.googleapis.com/maps/api/elevation/"
                + "xml?locations=" + String.valueOf(latitude)
                + "," + String.valueOf(longitude)
                + "&sensor=true";
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse response = httpClient.execute(httpGet, localContext);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                InputStream instream = entity.getContent();
                int r = -1;
                StringBuffer respStr = new StringBuffer();
                while ((r = instream.read()) != -1)
                    respStr.append((char) r);
                String tagOpen = "<elevation>";
                String tagClose = "</elevation>";
                if (respStr.indexOf(tagOpen) != -1) {
                    int start = respStr.indexOf(tagOpen) + tagOpen.length();
                    int end = respStr.indexOf(tagClose);
                    String value = respStr.substring(start, end);
                    result = (double)(Double.parseDouble(value)*3.2808399); // convert from meters to feet
                }
                instream.close();
            }
        } catch (ClientProtocolException e) {} 
        catch (IOException e) {}

        return result;
    }

You can also use the Google Elevation API. The online documentation for it is located at:
https://developers.google.com/maps/documentation/elevation/

Please note the following from the above API page:

Usage Limits: Use of the Google
Geocoding API is subject to a query
limit of 2,500 geolocation requests
per day. (User of Google Maps API
Premier may perform up to 100,000
requests per day.) This limit is
enforced to prevent abuse and/or
repurposing of the Geocoding API, and
this limit may be changed in the
future without notice. Additionally,
we enforce a request rate limit to
prevent abuse of the service. If you
exceed the 24-hour limit or otherwise
abuse the service, the Geocoding API
may stop working for you temporarily.
If you continue to exceed this limit,
your access to the Geocoding API may
be blocked. Note: the Geocoding API
may only be used in conjunction with a
Google map; geocoding results without
displaying them on a map is
prohibited. For complete details on
allowed usage, consult the Maps API
Terms of Service License Restrictions.

Altering Max Gontar's code above for the Google API gives the following, with the returned elevation given in feet:

private double getElevationFromGoogleMaps(double longitude, double latitude) {
        double result = Double.NaN;
        HttpClient httpClient = new DefaultHttpClient();
        HttpContext localContext = new BasicHttpContext();
        String url = "http://maps.googleapis.com/maps/api/elevation/"
                + "xml?locations=" + String.valueOf(latitude)
                + "," + String.valueOf(longitude)
                + "&sensor=true";
        HttpGet httpGet = new HttpGet(url);
        try {
            HttpResponse response = httpClient.execute(httpGet, localContext);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                InputStream instream = entity.getContent();
                int r = -1;
                StringBuffer respStr = new StringBuffer();
                while ((r = instream.read()) != -1)
                    respStr.append((char) r);
                String tagOpen = "<elevation>";
                String tagClose = "</elevation>";
                if (respStr.indexOf(tagOpen) != -1) {
                    int start = respStr.indexOf(tagOpen) + tagOpen.length();
                    int end = respStr.indexOf(tagClose);
                    String value = respStr.substring(start, end);
                    result = (double)(Double.parseDouble(value)*3.2808399); // convert from meters to feet
                }
                instream.close();
            }
        } catch (ClientProtocolException e) {} 
        catch (IOException e) {}

        return result;
    }
感性 2024-08-23 20:32:00

首先区分海拔高度很重要。

高度是从一点到当地表面的距离;无论是土地还是水。该测量主要用于航空。

可以使用 Location.getAltitude() 函数。

高程是当地表面到海平面的距离;更常用,并且经常被错误地称为海拔。

尽管如此,对于美国来说,USGS 提供了更新的 HTTP POST 和 GET 查询,可以返回以英尺或米为单位的海拔的 XML 或 JSON 值。对于全球海拔高度,您可以使用 Google Elevation API

It's important to first differentiate altitude from elevation.

Altitude is the distance from a point down to the local surface; whether that be land or water. This measurement is mainly used for aviation.

Altitude can be obtained by using the Location.getAltitude() function.

Elevation is the distance from the local surface to the sea level; much more often used, and often mistakenly referred to as altitude.

With that said, for the US, USGS has provided a newer HTTP POST and GET queries that can return XML or JSON values for elevation in either feet or meters. For worldwide elevation, you could use the Google Elevation API.

长不大的小祸害 2024-08-23 20:32:00

如果您使用具有 GPS 接收器的 Android 设备,那么有一个方法 getAltitude() 通过使用您可以通过海拔高度获取海拔高度。

If u are using android device which has GPS Recever then there is a method getAltitude() by using that u can get the altitude by elevation.

鯉魚旗 2024-08-23 20:32:00

试试我构建的这个:https://algorithmia.com/algorithms/Gaploid/Elevation

这是 Java 的示例:

import com.algorithmia.*;
import com.algorithmia.algo.*;

String input = "{\"lat\": \"50.2111\", \"lon\": \"18.1233\"}";
AlgorithmiaClient client = Algorithmia.client("YOUR_API_KEY");
Algorithm algo = client.algo("algo://Gaploid/Elevation/0.3.0");
AlgoResponse result = algo.pipeJson(input);
System.out.println(result.asJson());

Try this one that I`v built: https://algorithmia.com/algorithms/Gaploid/Elevation

here is example for Java:

import com.algorithmia.*;
import com.algorithmia.algo.*;

String input = "{\"lat\": \"50.2111\", \"lon\": \"18.1233\"}";
AlgorithmiaClient client = Algorithmia.client("YOUR_API_KEY");
Algorithm algo = client.algo("algo://Gaploid/Elevation/0.3.0");
AlgoResponse result = algo.pipeJson(input);
System.out.println(result.asJson());
雨轻弹 2024-08-23 20:32:00

谷歌地图有海拔高度,你需要的是这个代码

altitude="";
var init = function() {
        var elevator = new google.maps.ElevationService;
        map.on('mousemove', function(event) {
            getLocationElevation(event.latlng, elevator);
            document.getElementsByClassName("altitudeClass")[0].innerHTML = "Altitude: "+ getAltitude();
            //console.debug(getAltitude());
        });
}

var getLocationElevation = function (location, elevator){
  // Initiate the location request
  elevator.getElevationForLocations({
    'locations': [location]
  }, function(results, status) {
    if (status === google.maps.ElevationStatus.OK) {
      // Retrieve the first result
      if (results[0]) {
        // Open the infowindow indicating the elevation at the clicked position.
        setAltitude(parseFloat(results[0].elevation).toFixed(2));
      } else {
        setAltitude('No results found');
      }
    } else {
      setAltitude('Elevation service failed due to: ' + status);
    }
  });
}
function setAltitude(a){
    altitude = a;
}
function getAltitude(){
    return altitude;
}

Google maps have the altitude, what you need is this code

altitude="";
var init = function() {
        var elevator = new google.maps.ElevationService;
        map.on('mousemove', function(event) {
            getLocationElevation(event.latlng, elevator);
            document.getElementsByClassName("altitudeClass")[0].innerHTML = "Altitude: "+ getAltitude();
            //console.debug(getAltitude());
        });
}

var getLocationElevation = function (location, elevator){
  // Initiate the location request
  elevator.getElevationForLocations({
    'locations': [location]
  }, function(results, status) {
    if (status === google.maps.ElevationStatus.OK) {
      // Retrieve the first result
      if (results[0]) {
        // Open the infowindow indicating the elevation at the clicked position.
        setAltitude(parseFloat(results[0].elevation).toFixed(2));
      } else {
        setAltitude('No results found');
      }
    } else {
      setAltitude('Elevation service failed due to: ' + status);
    }
  });
}
function setAltitude(a){
    altitude = a;
}
function getAltitude(){
    return altitude;
}
香草可樂 2024-08-23 20:32:00

使用 Google Elevation API 的想法很好,但使用字符串函数解析 XML 则不然。此外,HttpClient 现在已被弃用,因为它使用不安全的连接。

请参阅此处以获得更好的解决方案:
https://github .com/M66B/BackPackTrackII/blob/master/app/src/main/java/eu/faircode/backpacktrack2/GoogleElevationApi.java

The idea to use the Google Elevation API is good, but parsing XML using string functions is not. Also, HttpClient is deprecated now, as using insecure connections.

See here for a better solution:
https://github.com/M66B/BackPackTrackII/blob/master/app/src/main/java/eu/faircode/backpacktrack2/GoogleElevationApi.java

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文