在Android中获取经度和纬度的海拔高度

时间:2021-05-15 16:01:54

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

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

7 个解决方案

#1


37  

elevation app screen http://img509.imageshack.us/img509/4848/elevationc.jpg

提升应用程序屏幕http://img509.imageshack.us/img509/4848/elevationc.jpg

My approach is to use USGS Elevation Query Web Service:

我的方法是使用USGS Elevation Query Web服务:

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):

和使用示例(在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;
            }
        });
    }

#2


22  

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

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

Please note the following from the above API page:

请从以上API页面中注意以下内容:

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.

使用限制:使用Google地理编码API每天的查询限制为2,500个地理定位请求。 (Google Maps API Premier的用户每天最多可执行100,000次请求。)此限制的使用是为了防止滥用和/或重新使用地理编码API,此限制可能会在将来更改,恕不另行通知。此外,我们强制执行请求速率限制以防止滥用服务。如果您超过24小时限制或以其他方式滥用服务,Geocoding API可能会暂时停止为您工作。如果您继续超出此限制,则可能会阻止您访问地理编码API。注意:地理编码API只能与Google地图结合使用;禁止在地图上显示地理编码结果。有关允许使用的完整详细信息,请参阅Maps API服务条款许可限制。

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

改变Max Gontar上面的Google API代码给出了以下内容,返回的高程以英尺为单位:

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;
    }

#3


2  

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.

如果您正在使用具有GPS Recever的Android设备,那么有一个方法getAltitude()使用它可以通过高程获得高度。

#4


1  

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.

可以使用Location.getAltitude()函数获取海拔高度。

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.

话虽如此,对于美国,USGS提供了一个较新的HTTP POST和GET查询,可以返回任何英尺或米的高程的XML或JSON值。对于全球范围的提升,您可以使用Google Elevation API。

#5


0  

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;
}

#6


0  

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

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

here is example for Java:

这是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());

#7


-2  

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.

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

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

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

#1


37  

elevation app screen http://img509.imageshack.us/img509/4848/elevationc.jpg

提升应用程序屏幕http://img509.imageshack.us/img509/4848/elevationc.jpg

My approach is to use USGS Elevation Query Web Service:

我的方法是使用USGS Elevation Query Web服务:

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):

和使用示例(在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;
            }
        });
    }

#2


22  

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

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

Please note the following from the above API page:

请从以上API页面中注意以下内容:

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.

使用限制:使用Google地理编码API每天的查询限制为2,500个地理定位请求。 (Google Maps API Premier的用户每天最多可执行100,000次请求。)此限制的使用是为了防止滥用和/或重新使用地理编码API,此限制可能会在将来更改,恕不另行通知。此外,我们强制执行请求速率限制以防止滥用服务。如果您超过24小时限制或以其他方式滥用服务,Geocoding API可能会暂时停止为您工作。如果您继续超出此限制,则可能会阻止您访问地理编码API。注意:地理编码API只能与Google地图结合使用;禁止在地图上显示地理编码结果。有关允许使用的完整详细信息,请参阅Maps API服务条款许可限制。

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

改变Max Gontar上面的Google API代码给出了以下内容,返回的高程以英尺为单位:

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;
    }

#3


2  

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.

如果您正在使用具有GPS Recever的Android设备,那么有一个方法getAltitude()使用它可以通过高程获得高度。

#4


1  

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.

可以使用Location.getAltitude()函数获取海拔高度。

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.

话虽如此,对于美国,USGS提供了一个较新的HTTP POST和GET查询,可以返回任何英尺或米的高程的XML或JSON值。对于全球范围的提升,您可以使用Google Elevation API。

#5


0  

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;
}

#6


0  

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

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

here is example for Java:

这是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());

#7


-2  

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.

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

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

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