WorldWind学习系列:7、 高程数据访问类

World类中包含高程访问器类对象TerrainAccessor _terrainAccessor 来访问本地或网络上的高程数据,通过读取地球配置文件中的TerrainAccessor 字段,构建一个高程访问器类NltTerrainAccessor 对象(列表)。

<TerrainAccessor Name="SRTM">
	<TerrainTileService>
		<ServerUrl>http://worldwind25.arc.nasa.gov/wwelevation/wwelevation.aspx</ServerUrl>
		<DataSetName>srtm30pluszip</DataSetName>
		<LevelZeroTileSizeDegrees>20.0</LevelZeroTileSizeDegrees>
		<NumberLevels>12</NumberLevels>
		<SamplesPerTile>150</SamplesPerTile>
		<DataFormat>Int16</DataFormat>
		<FileExtension>bil</FileExtension>
		<CompressonType>zip</CompressonType>
	</TerrainTileService>
	<LatLonBoundingBox>
		<North>
			<Value>90.0</Value>
		</North>
		<South>
			<Value>-90.0</Value>
		</South>
		<West>
			<Value>-180.0</Value>
		</West>
		<East>
			<Value>180.0</Value>
		</East>
	</LatLonBoundingBox>
</TerrainAccessor>

高程访问器类包含一个高程瓦片服务对象: TerrainTileService tts,用于管理地形瓦片。其中包含访问的网址,瓦片的层级,每个瓦片的高程点数量等信息。0级瓦片的分辨率最低,瓦片跨度20*20度,150*150个点,总共12层,上一层分辨率是下一层的4倍,每个瓦片的点数不变,1级瓦片跨度为5*5°。首先根据需要的分辨率(每度的点数)获得对应的层级,再计算在该层的行和列号,访问具体的瓦片数据。

其类关系图如下:

一、TerrainAccessor

TerrainAccessor 类是基类,主要包括四角点经纬度,名字等信息。

主要函数:

float GetElevationAt(double latitude, double longitude, double targetSamplesPerDegree),是一个抽象虚函数,获取给定经纬度,一定采样精度(每度的采样点数量)下的高程值。

virtual TerrainTile GetElevationArray(double north, double south, double west, double east, int samples)  获取给定地理范围和采样精度下的高程数组。首先构造一个给定地理范围和精度的TerrainTile res 对象,samples表示这个瓦片总共samples行,samples列。从西北到东南的顺序设置每个点的高程值(通过GetElevationAt(curLat, curLon, 0)获取)。

二、NltTerrainAccessor类

NltTerrainAccessor访问器访问具体的地形数据,数据采用 BIL 格式。它通过Hash表可缓存100个瓦片数据,包含一个TerrainTileService地形瓦片服务对象和WmsImageStore 图片存储管理对象。还可以包含一个更高精度的地形数据访问器数组。

主要成员变量包括:

public static int CacheSize = 100;
protected TerrainTileService m_terrainTileService;
protected WmsImageStore m_wmsElevationSet;
protected TerrainAccessor[] m_higherResolutionSubsets;
protected Hashtable m_tileCache = new Hashtable();

主要函数:

virtual TerrainTile GetElevationArray(double north, double south, double west, double east, int samples)  重载函数,首先检查定地理范围 是否包含在某个更高精度地形访问器的范围内,如果存在,则递归调用更高精度地形访问器的函数,获取地形瓦片。每度的采样点数量需要大于设定的最小值才能读取高程数据。读取高程数据的主要方法:

double curLat = north - scaleFactor * latrange * x;
double curLon = west + scaleFactor * lonrange * y;

if (ttce == null ||
		curLat < ttce.TerrainTile.South ||
		curLat > ttce.TerrainTile.North ||
		curLon < ttce.TerrainTile.West ||
		curLon > ttce.TerrainTile.East)
{
		TerrainTile tt = m_terrainTileService.GetTerrainTile(curLat, curLon, samplesPerDegree);
		ttce = (TerrainTileCacheEntry)m_tileCache[tt.TerrainTileFilePath];
		if (ttce == null)
		{
			ttce = new TerrainTileCacheEntry(tt);
			AddToCache(ttce);
		}
		if (!ttce.TerrainTile.IsInitialized)
				ttce.TerrainTile.Initialize();
		ttce.LastAccess = DateTime.Now;
		if (!tt.IsValid)
					res.IsValid = false;
}
data[x, y] = ttce.TerrainTile.GetElevationAt(curLat, curLon);

ttce是高程瓦片缓存,如果为空,或当前瓦片不在缓存的范围内,通过瓦片服务器的GetTerrainTile方法获取对应的瓦片,如果瓦片没有缓冲过,则创建缓存条目,并添加到缓存区中。对高程瓦片进行初始化。最后,给定经纬度的高程值通过获取瓦片的GetElevationAt函数获取。

float GetElevationAt(double latitude, double longitude, double targetSamplesPerDegree)重载函数, targetSamplesPerDegree为每度拥有的采用点数,为m_terrainTileService.SamplesPerTile / m_terrainTileService.LevelZeroTileSizeDegrees 。瓦片的采样点数除以0级瓦片的经度范围。首先检查定地理范围 是否包含在某个更高精度地形访问器的范围内,如果存在,则递归调用更高精度地形访问器的函数,获取地形瓦片。实际是通过高程瓦片服务获取对应的瓦片TerrainTile ,然后调用瓦片TerrainTile 的TerrainTileGetElevationAt(latitude, longitude);

三、TerrainTileService类

TerrainTileService负责读取和管理高程瓦片数据。主要功能是根据经纬度和每度采样点数,构造一个高程瓦片对象。类图如下所示:

主要变量:

		string m_serverUrl;
		string m_dataSet;
		double m_levelZeroTileSizeDegrees;
		int m_samplesPerTile;
		int m_numberLevels;
		string m_fileExtension;
		string m_terrainTileDirectory;
		TimeSpan m_terrainTileRetryInterval;
		string m_dataType;

主要函数: 

public static int GetColFromLongitude(double longitude, double tileSize)
{
return (int)System.Math.Floor((System.Math.Abs(-180.0 - longitude)%360)/tileSize);
}

public static int GetRowFromLatitude(double latitude, double tileSize)
{
	return (int)System.Math.Floor((System.Math.Abs(-90.0 - latitude)%180)/tileSize);
}

 TerrainTile GetTerrainTile(double latitude, double longitude, double samplesPerDegree): 构造一个新的TerrainTile对象,其中samplesPerDegree决定了瓦片的层级。从最高层级开始往下,直到找到满足精度要求的层级。

四、TerrainTile 类

TerrainTile 对应一个高程瓦片。类图如下所示:

主要属性:

protected TerrainDownloadRequest request; 为一个下载请求,可以从网络上下载高程文件,目前使用的是直接通过http下载,下载路径为:(现在流行的是通过WMS服务提供下载

download.Url = String.Format(CultureInfo.InvariantCulture,
"{0}?T={1}&L={2}&X={3}&Y={4}",
owner.ServerUrl,
owner.DataSet,
targetLevel, col, row);

public float GetElevationAt(double latitude, double longitude):在瓦片数据中,通过插值计算给定经纬度的高程值。

public void Initialize() :初始化瓦片的高程数据,如果文件不存在,通过request请求下载一个高程文件到缓存目录,然后读取缓存文件到ElevationData二维数组,行为经度,列为纬度。bil高程文件有两个格式,一种Int16 每个高程值2个字节短整形,一种是32位float类型。

for (int y = 0; y < SamplesPerTile; y++)
    for (int x = 0; x < SamplesPerTile; x++)
        ElevationData[x, y] = reader.ReadInt16();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值