/// <summary> /// Constructor. /// </summary> /// <param name="tile">TerrainTile to be cached.</param> public TerrainTileCacheEntry(TerrainTile tile) { m_terrainTile = tile; }
/// <summary> /// Builds a terrain array with specified boundaries /// </summary> /// <param name="north">North edge in decimal degrees.</param> /// <param name="south">South edge in decimal degrees.</param> /// <param name="west">West edge in decimal degrees.</param> /// <param name="east">East edge in decimal degrees.</param> /// <param name="samples"></param> public override TerrainTile GetElevationArray(double north, double south, double west, double east, int samples) { TerrainTile res = null; if (m_higherResolutionSubsets != null) { // TODO: Support more than 1 level of higher resolution sets and allow user selections foreach (TerrainAccessor higherResSub in m_higherResolutionSubsets) { if (!higherResSub.IsOn) { continue; } if (north <= higherResSub.North && south >= higherResSub.South && west >= higherResSub.West && east <= higherResSub.East) { res = higherResSub.GetElevationArray(north, south, west, east, samples); return(res); } } } res = new TerrainTile(m_terrainTileService); res.North = north; res.South = south; res.West = west; res.East = east; res.SamplesPerTile = samples; res.IsInitialized = true; res.IsValid = true; double samplesPerDegree = (double)samples / (double)(north - south); double latrange = Math.Abs(north - south); double lonrange = Math.Abs(east - west); TerrainTileCacheEntry ttce = null; float[,] data = new float[samples, samples]; if (samplesPerDegree < World.Settings.MinSamplesPerDegree) { res.ElevationData = data; return(res); } double scaleFactor = (double)1 / (samples - 1); for (int x = 0; x < samples; x++) { for (int y = 0; y < samples; y++) { double curLat = north - scaleFactor * latrange * x; double curLon = west + scaleFactor * lonrange * y; // Wrap lat/lon to fit range 90/-90 and -180/180 (PM 2006-11-17) if (curLat > 90) { curLat = 90 - (curLat - 90); curLon += 180; } if (curLat < -90) { curLat = -90 - (curLat + 90); curLon += 180; } if (curLon > 180) { curLon -= 360; } if (curLon < -180) { curLon += 360; } 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); } } res.ElevationData = data; return(res); }