65.9K
CodeProject 正在变化。 阅读更多。
Home

从 Bing 地图获取高程数据

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2018 年 7 月 5 日

CPOL

2分钟阅读

viewsIcon

10402

downloadIcon

210

使用 HTTP 与 Bing 地图获取高程数据

引言

本文详细介绍了一个 C# 类,可用于从 Bing 地图获取高程数据。

背景

在开发一个地图项目时,我们正在寻找一种获取指定位置(们)的高程信息的方法。在探索了一些替代方案后,我们决定从 Bing 获取此信息。但是,Bing 地图库似乎没有一种获取特定位置高程信息的方法,因此需要进行 HTTP 查询。

类描述

下图显示了 BingMapElevation 类的图表

  • 类构造函数要求您指定 Bing 地图密钥。此 链接 描述了如何获取密钥。
  • 用于获取高程的两个 public 方法名为 getElevation。一个用于获取单个高程,另一个用于获取高程列表。
  • 实际工作由两个 protected 异步方法完成
    • FormatURI 根据位置或位置返回一个格式化的 string
    • GetElevationsFromHTTP 使用格式化的 string 获取高程列表。
  • 可以使用 EARTH_MODEL 枚举指定用于高程的地球模型。可以在 此处 找到这些模型的说明。

该类适用于 UWP 和 .NET 项目(注意:对于 .NET 项目,我们必须显式添加 System.Net.Http 程序集)。

代码描述

在类中,protected FormatURIGetElevationsFromHTTP 方法协同工作以下载高程。FormatURI 方法生成一个包含指定位置、密钥和地球模型的 string

// Format the URI from a list of locations.
protected string FormatURI(List<location> locList) 
{ 
   // The base URI string. Fill in: 
   // {0}: The lat/lon list, comma separated. 
   // {1}: The heights: datum string, lower case. 
   // {2}: The key. 
   const string BASE_URI_STRING = 
     "http://dev.virtualearth.net/REST/v1/Elevation/List?points={0}&heights={1}&key={2}"; 
   string retVal = string.Empty; 
   string locString = string.Empty; 
   for (int ndx = 0; ndx < locList.Count; ++ndx) 
   { 
      if (ndx != 0) 
      { 
        locString += ","; 
      } 
      locString += locList[ndx].latitude.ToString() + "," + locList[ndx].longitude.ToString(); 
   } 
   retVal = string.Format(BASE_URI_STRING, locString, Model.ToString().ToLower(), Key); 
   return retVal; 
} 

GetElevationsFromHTTP 方法使用 FormatURI 生成的 string 进行 HTTP 调用并下载高程信息。

/// Format the URI from a list of locations.
protected async Task<List<double>> GetElevationsFromHTTP(string url)
{
   List<double> retVal = new List<double>();
   try
   {
     HttpClient httpClient = new HttpClient();
     HttpResponseMessage msg = await httpClient.GetAsync(url);
        
     //Check the status code. Throw an exception on error. 
     if (!msg.IsSuccessStatusCode)
     {
       string errMsg = "HTTP Response Error: [" + msg + "]";
       throw new Exception(errMsg);
     }

     Stream inStream = await msg.Content.ReadAsStreamAsync();

     using (StreamReader reader = new StreamReader(inStream))
     {
       //Get the string from the HTTP stream, find the index of the
       //substring where the altitudes are enumerated.
       string readString = reader.ReadToEnd();
       int ndx = readString.IndexOf(targetString);

       //Check to see if the substring has been found.
       if (ndx >= 0)
       {
         string elevationListStr = 
            readString.Substring(ndx + targetString.Length);
         ndx = elevationListStr.IndexOf(']');

         if (ndx > 0)
         {
           elevationListStr = elevationListStr.Substring(0, ndx);

           //Split the comma delimited list into doubles.
           char[] parm = { ',' };
           string[] result = elevationListStr.Split(parm);   

           //Add the strings to the list.
           foreach (string dbl in result)
           {
             retVal.Add(double.Parse(dbl));
           }
         }
         else
         {
           string errMsg = "Format Error: [" + readString + "]";
           throw new Exception(errMsg);
         }
       }
       else
       {
          string errMsg = "No elevations found in the return string: [" +
              readString + "]";
          throw new Exception(errMsg);
       }
     }
   }
   catch (Exception e)
   {
     throw new Exception(e.Message, e);
   }
   return retVal;
 }

调用两个 getElevation 方法以获取特定位置的高程。

此处显示了 BingMapElevation 用法的示例

//Test Method
static async Task Test()
{
  string key = "Your Bing Map Key Here";
  BingMapElevation mapElevation = new BingMapElevation(key);

  double lat = 35.89431;
  double lon = -110.72522;
  List<location>locList = new List<location>();
    
  //Load 10 lat/lon values
  for (int ndx = 0; ndx < 10; ++ndx)
  {
    locList.Add(new Location() { latitude = lat, longitude = lon });
    lat += 0.1;
    lon -= 0.1;
  }
   
  List<double> dList = await mapElevation.getElevation(locList);
  Debug.WriteLine("List:");
  foreach (double d in dList)
  {
    Debug.WriteLine(d.ToString()); 
  }

  Debug.WriteLine("Single Location Test:");
  foreach (Location loc in locList)
  {
    Debug.WriteLine(loc.latitude.ToString() + "," + loc.longitude.ToString());
    double dbl = await mapElevation.getElevation(loc.latitude, loc.longitude);
    Debug.WriteLine(dbl.ToString());
  }
}

可能的扩展

Bing 地图 HTTP 接口支持至少其他两个函数(在 此处 解释)

  1. 沿多段线路径等距位置处获取高程。
  2. 在地球上由边界框定义的区域内等距位置处获取高程。

可以轻松扩展此类以适应这些函数。

历史

  • 2018 年 7 月 5 日:发布初始版本
© . All rights reserved.