37

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

4

7 回答 7

39

我的方法是使用USGS 高程查询网络服务

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;
            }
        });
    }
于 2010-01-03T19:30:40.060 回答
24

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

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

使用限制:使用 Google 地理编码 API 的查询限制为每天 2,500 个地理定位请求。(Google Maps API Premier 的用户每天最多可以执行 100,000 个请求。)强制执行此限制是为了防止滥用和/或重新利用 Geocoding API,并且此限制将来可能会更改,恕不另行通知。此外,我们强制执行请求速率限制以防止滥用服务。如果您超过 24 小时限制或以其他方式滥用服务,Geocoding API 可能会暂时停止为您工作。如果您继续超过此限制,您对 Geocoding API 的访问可能会被阻止。注意:Geocoding 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;
    }
于 2011-04-15T04:06:20.207 回答
4

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

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

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

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

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

于 2017-06-02T19:41:21.407 回答
2

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

于 2012-11-12T04:38:43.300 回答
2

试试我构建的这个: 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());
于 2016-07-30T12:36:15.290 回答
0

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

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;
}
于 2015-12-09T15:48:04.703 回答
-1

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

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

于 2015-06-20T08:46:46.863 回答