public ModelRoot Run(ModelRoot gltfModel, BoundingBox bbox, bool computeElevations, DEMDataSet dataSet, bool downloadMissingFiles) { #if TOLIST try { // Download buildings and convert them to GeoJson var features = _osmDataService.GetOsmDataAsGeoJson(bbox, DataSettings).ToList(); // Create internal building model var parsed = this.CreateModelsFromGeoJson <T>(features, ModelFactory).ToList(); //_logger.LogInformation($"Computing elevations ({parsed.Models.Count} lines, {parsed.TotalPoints} total points)..."); // Compute elevations (faster elevation when point count is known in advance) // Download elevation data if missing if (computeElevations && downloadMissingFiles) { _elevationService.DownloadMissingFiles(dataSet, bbox); } parsed = this.ComputeModelElevationsAndTransform(parsed, computeElevations, dataSet, downloadMissingFiles).ToList(); gltfModel = this.AddToModel(gltfModel, glTFNodeName, parsed); return(gltfModel); } catch (Exception ex) { _logger.LogError($"{typeof(T).Name} generator error: {ex.Message}"); throw; } #else try { // Download buildings and convert them to GeoJson IEnumerable <IFeature> features = _osmDataService.GetOsmDataAsGeoJson(bbox, DataSettings); // Create internal building model IEnumerable <T> parsed = this.CreateModelsFromGeoJson <T>(features, ModelFactory); //_logger.LogInformation($"Computing elevations ({parsed.Models.Count} lines, {parsed.TotalPoints} total points)..."); // Compute elevations (faster elevation when point count is known in advance) // Download elevation data if missing if (computeElevations && downloadMissingFiles) { _elevationService.DownloadMissingFiles(dataSet, bbox); } parsed = this.ComputeModelElevationsAndTransform(parsed, computeElevations, dataSet, downloadMissingFiles); gltfModel = this.AddToModel(gltfModel, glTFNodeName, parsed); return(gltfModel); } catch (Exception ex) { _logger.LogError($"{typeof(T).Name} generator error: {ex.Message}"); throw; } #endif }
public void Run() { try { // Sample testing bad calculation on tile edges with tile registration modes (cell/grid) double amountx = .00000000000004; double amounty = .000000000000007; double lat = 46; double lon = 10; LineSample(DEMDataSet.ASTER_GDEMV3, latStart: 45.9993826389, lonStart: 9.9997211693, latEnd: 46.00002905, lonEnd: 10.00063093); TestEdges(DEMDataSet.ASTER_GDEMV3, lat, lon, "ASTGTMV003_N45E009_dem.tif", "ASTGTMV003_N45E010_dem.tif", "ASTGTMV003_N46E009_dem.tif", "ASTGTMV003_N46E010_dem.tif"); TestEdges(DEMDataSet.SRTM_GL3, lat, lon, "N45E009.hgt", "N45E010.hgt", "N46E009.hgt", "N46E010.hgt"); TestEdges(DEMDataSet.SRTM_GL1, lat, lon, "N45E009.hgt", "N45E010.hgt", "N46E009.hgt", "N46E010.hgt"); TestEdges(DEMDataSet.AW3D30, lat, lon, "N045E009_AVE_DSM.tif", "N045E010_AVE_DSM.tif", "N046E009_AVE_DSM.tif", "N046E010_AVE_DSM.tif"); DEMDataSet dataSet = DEMDataSet.SRTM_GL1; //_rasterService.GenerateDirectoryMetadata(dataSet, true, false, 1); _elevationService.DownloadMissingFiles(dataSet, lat, lon); var tiles = _rasterService.GenerateReportForLocation(dataSet, lat, lon); Debug.Assert(tiles.Count == 4); //_rasterService.GenerateFileMetadata(tile.LocalName, dataSet.FileFormat, true); GeoPoint pt = null; pt = _elevationService.GetPointElevation(lat + amounty, lon + amountx, dataSet); pt = _elevationService.GetPointElevation(lat - amounty, lon + amountx, dataSet); pt = _elevationService.GetPointElevation(lat + amounty, lon - amountx, dataSet); pt = _elevationService.GetPointElevation(lat - amounty, lon - amountx, dataSet); pt = _elevationService.GetPointElevation(lat + (1 / 3600d) / 2d, lon + (1 / 3600d) / 2, dataSet); pt = _elevationService.GetPointElevation(lat + 0.5, lon + 0.5, dataSet); pt = _elevationService.GetPointElevation(lat, lon, dataSet); foreach (var dataset in DEMDataSet.RegisteredNonLocalDatasets) { _elevationService.DownloadMissingFiles(dataset, lat, lon); //foreach (var file in _rasterService.GenerateReportForLocation(dataset, lat, lon)) //{ // _rasterService.GenerateFileMetadata(file.LocalName, dataset.FileFormat, true); //} GeoPoint geoPoint = _elevationService.GetPointElevation(lat, lon, dataset); } } catch (Exception ex) { _logger.LogError(ex, ex.Message); } }
public void DownloadTile_Location() { double lat = 43.537854; double lon = 5.429993; DEMDataSet dataset = DEMDataSet.SRTM_GL3; _elevationService.DownloadMissingFiles(dataset, lat, lon); var report = _rasterService.GenerateReportForLocation(dataset, lat, lon); Assert.NotNull(report); Assert.NotEmpty(report); Assert.True(report.Count == 1); Assert.True(report.First().IsExistingLocally); }
private static void GeoTiffBenchmark() { DEMDataSet dataSet = DEMDataSet.AW3D30; ElevationService elevationServiceLibTiff = new ElevationService(new GeoTiffService(_DataDirectory)); string wkt = WKT_BREST_NICE; elevationServiceLibTiff.DownloadMissingFiles(dataSet, GetBoundingBox(wkt)); const int NUM_ITERATIONS = 10; Stopwatch swCoreTiff = new Stopwatch(); Stopwatch swGeoTiff = new Stopwatch(); for (int j = 0; j < 5; j++) { for (int i = 0; i < NUM_ITERATIONS; i++) { swGeoTiff.Start(); var lineElevationData = elevationServiceLibTiff.GetLineGeometryElevation(wkt, dataSet, InterpolationMode.Hyperbolic); swGeoTiff.Stop(); } } long geoTiffMs = swGeoTiff.ElapsedMilliseconds; long codeTiffMs = swCoreTiff.ElapsedMilliseconds; Console.WriteLine($"GeoTiff : {geoTiffMs} ms, Native : {codeTiffMs}"); }
public void Run(DEMDataSet specificDataset = null) { try { _logger.LogInformation($"Downloading all files to {_rasterService.LocalDirectory}"); Stopwatch sw = new Stopwatch(); var datasetsQuery = DEMDataSet.RegisteredNonLocalDatasets; if (specificDataset != null) { datasetsQuery = datasetsQuery.Where(d => d.Name == specificDataset.Name); } foreach (var dataset in datasetsQuery) //Parallel.ForEach(datasetsQuery, dataset => { _logger.LogInformation($"{dataset.Name}:"); _elevationService.DownloadMissingFiles(dataset); } //); } catch (Exception e) { _logger.LogError(e, e.Message); } }
public IHttpActionResult GetPathElevation(Location[] path, int samples = 100) { try { var geoPoints = ModelFactory.Create(path); var geom = GeometryService.ParseGeoPointAsGeometryLine(geoPoints); _elevationService.DownloadMissingFiles(DEMDataSet.AW3D30, geom.GetBoundingBox()); geoPoints = _elevationService.GetLineGeometryElevation(geom, DEMDataSet.AW3D30, InterpolationMode.Bilinear); ElevationMetrics metrics = GeometryService.ComputeMetrics(geoPoints); if (samples > 2) { double ratio = 4 / 2; double tolerance = (metrics.MaxElevation - metrics.MinElevation) / (samples / ratio); geoPoints = DouglasPeucker.DouglasPeuckerReduction(geoPoints, tolerance); } // Model ElevationMetricsModel metricsModel = ModelFactory.CreateElevationMetricsModel(geoPoints, metrics); var feature = ModelFactory.CreateFeature(geoPoints, metricsModel); return(Ok(feature)); } catch (Exception ex) { return(InternalServerError(new Exception(ex.Message))); } }
/// <summary> /// Generate an excel output of all nodes with /// - their computed coordinates relative to entry /// - their distance from entry /// - their distance from the ground surface above them /// </summary> /// <param name="visualTopoFile"></param> /// <param name="dataSet"></param> private void Run_ExcelExport(string visualTopoFile, DEMDataSet dataSet) { try { StopwatchLog timeLog = StopwatchLog.StartNew(_logger); //======================= // Generation params // string outputDir = Directory.GetCurrentDirectory(); VisualTopoModel model = _visualTopoService.LoadFile(visualTopoFile, Encoding.GetEncoding("ISO-8859-1") , decimalDegrees: true , ignoreRadialBeams: true); // for debug, //var b = GetBranches(model); // graph list of all nodes //var lowestPoint = model.Sets.Min(s => s.Data.Min(d => d.GlobalGeoPoint?.Elevation ?? 0)); BoundingBox bbox = model.BoundingBox // relative coords .Translate(model.EntryPoint.Longitude, model.EntryPoint.Latitude, model.EntryPoint.Elevation ?? 0) // absolute coords .Pad(50) // margin around model .ReprojectTo(model.SRID, dataSet.SRID); _elevationService.DownloadMissingFiles(dataSet, bbox); timeLog.LogTime("Terrain height map"); //======================= // Get entry elevation (need to reproject to DEM coordinate system first) // and sections entry elevations // _visualTopoService.ComputeFullCavityElevations(model, dataSet); // will add TerrainElevationAbove and entry elevations // CSV string csvFileName = Path.GetFileName(Path.ChangeExtension(visualTopoFile, ".csv")); File.WriteAllBytes(csvFileName, _visualTopoService.ExportToCsv(model, "\t").ToArray()); // Excel string xlsFileName = Path.GetFileName(Path.ChangeExtension(visualTopoFile, ".xlsx")); using (MemoryStream ms = _visualTopoService.ExportToExcel(model, autoFitColumns: false)) { File.WriteAllBytes(xlsFileName, ms.ToArray()); } timeLog.LogTime("Cavity points elevation"); timeLog.LogTime("3D model"); } catch (Exception ex) { _logger.LogError("Error :" + ex.Message); } }
static void PointDEMTest(ElevationService elevationService, DEMDataSet dataSet, double lat, double lon) { elevationService.DownloadMissingFiles(dataSet, lat, lon); var geoPoint_Bilinear = elevationService.GetPointElevation(lat, lon, dataSet, InterpolationMode.Bilinear); Console.WriteLine($"Elevation with Bilinear model : {geoPoint_Bilinear.Elevation}"); var geoPoint_Hyperbolic = elevationService.GetPointElevation(lat, lon, dataSet, InterpolationMode.Hyperbolic); Console.WriteLine($"Elevation with Hyperbolic model : {geoPoint_Hyperbolic.Elevation}"); }
static void LineDEMBenchmark(ElevationService elevationService, DEMDataSet dataSet, int numSamples) { Dictionary <string, string> dicWktByName = new Dictionary <string, string>(); //dicWktByName.Add(nameof(WKT_EXAMPLE_GOOGLE), WKT_EXAMPLE_GOOGLE); // Before GeoTiff window optim : 90s // After GeoTiff optim : 77s / release : 60s; dicWktByName.Add(nameof(WKT_BREST_NICE), WKT_BREST_NICE); dicWktByName.Add(nameof(WKT_HORIZONTAL_DEM_EDGE), WKT_HORIZONTAL_DEM_EDGE); dicWktByName.Add(nameof(WKT_VERTICAL_DEM_EDGE), WKT_VERTICAL_DEM_EDGE); dicWktByName.Add(nameof(WKT_MONACO), WKT_MONACO); dicWktByName.Add(nameof(WKT_TEST), WKT_TEST); dicWktByName.Add(nameof(WKT_NO_DEM), WKT_NO_DEM); dicWktByName.Add(nameof(WKT_ZERO), WKT_ZERO); dicWktByName.Add(nameof(WKT_NEG100), WKT_NEG100); dicWktByName.Add(nameof(WKT_BREST_SPAIN_OCEAN), WKT_BREST_SPAIN_OCEAN); dicWktByName.Add(nameof(WKT_EXAMPLE_GOOGLE), WKT_EXAMPLE_GOOGLE); dicWktByName.Add(nameof(WKT_PARIS_AIX), WKT_PARIS_AIX); dicWktByName.Add(nameof(WKT_PETITE_BOUCLE), WKT_PETITE_BOUCLE); dicWktByName.Add(nameof(WKT_GRAND_TRAJET), WKT_GRAND_TRAJET); dicWktByName.Add(nameof(WKT_GRAND_TRAJET_MARSEILLE_ALPES_MULTIPLE_TILES), WKT_GRAND_TRAJET_MARSEILLE_ALPES_MULTIPLE_TILES); dicWktByName.Add(nameof(WKT_BAYONNE_AIX_OUEST_EST), WKT_BAYONNE_AIX_OUEST_EST); dicWktByName.Add(nameof(WKT_AIX_BAYONNE_EST_OUEST), WKT_AIX_BAYONNE_EST_OUEST); dicWktByName.Add(nameof(WKT_BAYONNE_NICE_DIRECT), WKT_BAYONNE_NICE_DIRECT); dicWktByName.Add(nameof(WKT_DEM_INTERPOLATION_BUG), WKT_DEM_INTERPOLATION_BUG); Stopwatch sw = Stopwatch.StartNew(); InterpolationMode[] modes = { InterpolationMode.Bilinear, InterpolationMode.Hyperbolic }; for (int i = 0; i < 5; i++) { foreach (var wkt in dicWktByName) { elevationService.DownloadMissingFiles(dataSet, GetBoundingBox(wkt.Value)); foreach (InterpolationMode mode in modes) { var lineElevationData = elevationService.GetLineGeometryElevation(wkt.Value, dataSet, mode); ElevationMetrics metrics = GeometryService.ComputeMetrics(ref lineElevationData); //var sampledLineElevationData = ReduceList(lineElevationData, numSamples).ToList(); //File.WriteAllText($"ElevationData_{wkt.Key}_{mode}.txt", elevationService.ExportElevationTable(lineElevationData)); //File.WriteAllText($"ElevationData_{wkt.Key}_{mode}_{numSamples}samples.txt", elevationService.ExportElevationTable(sampledLineElevationData)); } } } sw.Stop(); Console.WriteLine($"LineDEMTests performed in {sw.Elapsed:g}."); }
static void LineDEMTest(ElevationService elevationService, DEMDataSet dataSet, string wkt, int numSamples) { Stopwatch sw = Stopwatch.StartNew(); elevationService.DownloadMissingFiles(dataSet, GetBoundingBox(wkt)); var lineElevationData = elevationService.GetLineGeometryElevation(wkt, dataSet, InterpolationMode.Bilinear); ElevationMetrics metrics = GeometryService.ComputeMetrics(ref lineElevationData); var lineElevationData_Reduced = DouglasPeucker.DouglasPeuckerReduction(lineElevationData, (metrics.MaxElevation - metrics.MinElevation) / numSamples); sw.Stop(); Console.WriteLine($"LineDEMTest performed in {sw.Elapsed:g}."); SpatialTrace.Enable(); SpatialTrace.Clear(); SpatialTraceLine(lineElevationData, $"Full resolution line ({lineElevationData.Count} points)"); SpatialTraceLine(lineElevationData_Reduced, $"Reduced line ({lineElevationData_Reduced.Count} points)"); SpatialTrace.ShowDialog(); }
public List <BeanPoint_internal> GetPointsTestsByBBox(string p_bbox, DEMDataSet dataset, int sridCible) { List <BeanPoint_internal> v_pointsToTest = new List <BeanPoint_internal>(); try { IRasterService v_rasterService = new RasterService(null); IElevationService v_elevationService = new ElevationService(v_rasterService, null); BoundingBox v_bbox = GeometryService.GetBoundingBox(p_bbox); v_elevationService.DownloadMissingFiles(dataset, v_bbox); // HeightMap v_hMap; v_hMap = v_elevationService.GetHeightMap(ref v_bbox, dataset); v_hMap = v_hMap.ReprojectTo(4326, sridCible); v_pointsToTest = GetGeoPointsByHMap(v_hMap, sridCible); } catch (Exception) { throw; } return(v_pointsToTest); }
public List <BeanPoint_internal> GetPointsTestsByBBox(string p_bbox, DEMDataSet dataset, int sridCible) { List <BeanPoint_internal> v_pointsToTest = new List <BeanPoint_internal>(); try { // fix issue #86 to work with opentopography files without proper DI injection RasterIndexServiceResolver rasterIndexServiceResolver = dataSourceType => { switch (dataSourceType) { case DEMDataSourceType.GDALVrt: return(new GDALVRTFileService(null, null)); default: throw new KeyNotFoundException(); // or maybe return null, up to you } }; RasterService v_rasterService = new RasterService(rasterIndexServiceResolver); ElevationService v_elevationService = new ElevationService(v_rasterService, null); BoundingBox v_bbox = GeometryService.GetBoundingBox(p_bbox); v_elevationService.DownloadMissingFiles(dataset, v_bbox); // HeightMap v_hMap; v_hMap = v_elevationService.GetHeightMap(ref v_bbox, dataset); v_hMap = v_hMap.ReprojectTo(4326, sridCible); v_pointsToTest = GetGeoPointsByHMap(v_hMap, sridCible); } catch (Exception) { throw; } return(v_pointsToTest); }
public void Run() { try { double lat1 = 46.00000000000004; double lon1 = 10.000000000000007; double lat2 = 45.212278; double lont2 = 5.468857; _logger.LogInformation($"Getting location elevation for each dataset (location lat: {lat1:N2}, lon: {lon1:N2})"); Stopwatch sw = new Stopwatch(); Parallel.ForEach(DEMDataSet.RegisteredNonLocalDatasets, (dataSet, loopState) => //foreach (var dataSet in DEMDataSet.RegisteredNonSingleFileDatasets) { sw.Restart(); _elevationService.DownloadMissingFiles(dataSet, lat1, lon1); GeoPoint geoPoint = _elevationService.GetPointElevation(lat1, lon1, dataSet); _logger.LogInformation($"{dataSet.Name} elevation: {geoPoint.Elevation:N2} (time taken: {sw.Elapsed.TotalMilliseconds:N1}ms)"); } ); _logger.LogInformation("Multiple point elevation"); sw.Restart(); GeoPoint pt1 = new GeoPoint(lat1, lon1); GeoPoint pt2 = new GeoPoint(lat2, lont2); GeoPoint[] points = { pt1, pt2 }; Parallel.ForEach(DEMDataSet.RegisteredNonLocalDatasets, (dataSet, loopState) => //foreach (var dataSet in DEMDataSet.RegisteredNonSingleFileDatasets) { sw.Restart(); var geoPoints = _elevationService.GetPointsElevation(points, dataSet); _logger.LogInformation($"{dataSet.Name} elevation: {string.Join(" / ", geoPoints.Select(e => e.Elevation.GetValueOrDefault().ToString("N2")))} (time taken: {sw.Elapsed.TotalMilliseconds:N1}ms)"); } ); _logger.LogInformation("Line elevation"); sw.Restart(); // Line passing by mont ventoux peak [5.144899, 44.078873], [5.351516, 44.225876] var elevationLine = GeometryService.ParseGeoPointAsGeometryLine(new GeoPoint(44.078873, 5.144899), new GeoPoint(44.225876, 5.351516)); Parallel.ForEach(DEMDataSet.RegisteredNonLocalDatasets, (dataSet, loopState) => //foreach (var dataSet in DEMDataSet.RegisteredNonSingleFileDatasets) { _elevationService.DownloadMissingFiles(dataSet, elevationLine.GetBoundingBox()); var geoPoints = _elevationService.GetLineGeometryElevation(elevationLine, dataSet); var metrics = geoPoints.ComputeMetrics(); _logger.LogInformation($"{dataSet.Name} metrics: {metrics.ToString()}"); var simplified = geoPoints.Simplify(50 /* meters */); _logger.LogInformation($"{dataSet.Name} after reduction : {simplified.Count} points"); var geoJson = ConvertLineElevationResultToGeoJson(simplified); } ); _logger.LogInformation($"Done in {sw.Elapsed.TotalMilliseconds:N1}ms"); } catch (Exception ex) { _logger.LogError(ex, ex.Message); } }
public void TestDownloadWithNoCoverage() { DEMDataSet dataSet = DEMDataSet.SRTM_GL3; // This one should run without error, but generating a warning, // as location is not covererd by dataset _elevationService.DownloadMissingFiles(dataSet, 31, -27); }
void TestEdges(string dataSetName, double lat, double lon , string rasterSouthWestName, string rasterSouthEastName , string rasterNorthWestName, string rasterNorthEastName) { DEMDataSet dataSet = DEMDataSet.RegisteredDatasets.FirstOrDefault(d => d.Name == dataSetName); Assert.NotNull(dataSet); DEMFileType fileType = dataSet.FileFormat.Type; int rasterSize = dataSet.PointsPerDegree; double amountx = (1d / rasterSize) / 4d; double amounty = (1d / rasterSize) / 4d; // Regenerates all metadata //_rasterService.GenerateDirectoryMetadata(dataSet // , force: true // , deleteOnError: false // , maxDegreeOfParallelism: 1); _elevationService.DownloadMissingFiles(dataSet, lat, lon); var tiles = _rasterService.GenerateReportForLocation(dataSet, lat, lon); Assert.True(tiles.Count == 4); Assert.Single(tiles, t => string.Equals(Path.GetFileName(t.LocalName), rasterSouthWestName, StringComparison.OrdinalIgnoreCase)); Assert.Single(tiles, t => string.Equals(Path.GetFileName(t.LocalName), rasterSouthEastName, StringComparison.OrdinalIgnoreCase)); Assert.Single(tiles, t => string.Equals(Path.GetFileName(t.LocalName), rasterNorthWestName, StringComparison.OrdinalIgnoreCase)); Assert.Single(tiles, t => string.Equals(Path.GetFileName(t.LocalName), rasterNorthEastName, StringComparison.OrdinalIgnoreCase)); if (dataSet.FileFormat.Registration == DEMFileRegistrationMode.Cell) { using (var rasterNW = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterNorthWestName, Path.GetFileName(t.LocalName))).LocalName, fileType)) using (var rasterNE = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterNorthEastName, Path.GetFileName(t.LocalName))).LocalName, fileType)) using (var rasterSW = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterSouthWestName, Path.GetFileName(t.LocalName))).LocalName, fileType)) using (var rasterSE = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterSouthEastName, Path.GetFileName(t.LocalName))).LocalName, fileType)) { var elevNW = rasterNW.GetElevationAtPoint(rasterNW.ParseMetaData(dataSet.FileFormat), rasterSize - 1, rasterSize - 1); var elevNE = rasterNE.GetElevationAtPoint(rasterNE.ParseMetaData(dataSet.FileFormat), 0, rasterSize - 1); var elevSW = rasterSW.GetElevationAtPoint(rasterSW.ParseMetaData(dataSet.FileFormat), rasterSize - 1, 0); var elevSE = rasterSE.GetElevationAtPoint(rasterSE.ParseMetaData(dataSet.FileFormat), 0, 0); BilinearInterpolator interpolator = new BilinearInterpolator(); var elev0 = interpolator.Interpolate(elevSW, elevSE, elevNW, elevNE, 0.25, 0.25); var apiElev0 = _elevationService.GetPointElevation(lat + amounty, lon - amountx, dataSet); Assert.True((elev0 - apiElev0.Elevation.Value) < double.Epsilon); var elev1 = interpolator.Interpolate(elevSW, elevSE, elevNW, elevNE, 0.75, 0.25); var apiElev1 = _elevationService.GetPointElevation(lat + amounty, lon + amountx, dataSet); Assert.True((elev1 - apiElev1.Elevation.Value) < double.Epsilon); var elev2 = interpolator.Interpolate(elevSW, elevSE, elevNW, elevNE, 0.25, 0.75); var apiElev2 = _elevationService.GetPointElevation(lat - amounty, lon - amountx, dataSet); Assert.True((elev2 - apiElev2.Elevation.Value) < double.Epsilon); var elev3 = interpolator.Interpolate(elevSW, elevSE, elevNW, elevNE, 0.75, 0.75); var apiElev3 = _elevationService.GetPointElevation(lat - amounty, lon + amountx, dataSet); Assert.True((elev3 - apiElev3.Elevation.Value) < double.Epsilon); } } else { using (var rasterNW = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterNorthWestName, Path.GetFileName(t.LocalName))).LocalName, fileType)) using (var rasterNE = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterNorthEastName, Path.GetFileName(t.LocalName))).LocalName, fileType)) using (var rasterSW = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterSouthWestName, Path.GetFileName(t.LocalName))).LocalName, fileType)) using (var rasterSE = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterSouthEastName, Path.GetFileName(t.LocalName))).LocalName, fileType)) { // Northen row, west to east var elevN0 = rasterNW.GetElevationAtPoint(rasterNW.ParseMetaData(dataSet.FileFormat), rasterSize - 1, rasterSize - 1); var elevN1 = rasterNW.GetElevationAtPoint(rasterNW.ParseMetaData(dataSet.FileFormat), rasterSize, rasterSize - 1); var elevN2 = rasterNE.GetElevationAtPoint(rasterNE.ParseMetaData(dataSet.FileFormat), 1, rasterSize - 1); // middle row, west to east var elevM0 = rasterNW.GetElevationAtPoint(rasterNW.ParseMetaData(dataSet.FileFormat), rasterSize - 1, rasterSize); var elevM1 = rasterNW.GetElevationAtPoint(rasterNW.ParseMetaData(dataSet.FileFormat), rasterSize, rasterSize); var elevM2 = rasterNE.GetElevationAtPoint(rasterNE.ParseMetaData(dataSet.FileFormat), 1, rasterSize); // Sourthen row, west to east var elevS0 = rasterSW.GetElevationAtPoint(rasterSW.ParseMetaData(dataSet.FileFormat), rasterSize - 1, 1); var elevS1 = rasterSW.GetElevationAtPoint(rasterSW.ParseMetaData(dataSet.FileFormat), rasterSize, 1); var elevS2 = rasterSE.GetElevationAtPoint(rasterSE.ParseMetaData(dataSet.FileFormat), 1, 1); BilinearInterpolator interpolator = new BilinearInterpolator(); var elev0 = interpolator.Interpolate(elevM0, elevM1, elevN0, elevN1, 0.75, 0.75); var apiElev0 = _elevationService.GetPointElevation(lat + amounty, lon - amountx, dataSet); Assert.True((elev0 - apiElev0.Elevation.Value) < double.Epsilon); var elev1 = interpolator.Interpolate(elevM1, elevM2, elevN1, elevN2, 0.25, 0.75); var apiElev1 = _elevationService.GetPointElevation(lat + amounty, lon + amountx, dataSet); Assert.True((elev1 - apiElev1.Elevation.Value) < double.Epsilon); var elev2 = interpolator.Interpolate(elevS0, elevS1, elevM0, elevM1, 0.75, 0.25); var apiElev2 = _elevationService.GetPointElevation(lat - amounty, lon - amountx, dataSet); Assert.True((elev2 - apiElev2.Elevation.Value) < double.Epsilon); var elev3 = interpolator.Interpolate(elevS1, elevS2, elevM1, elevM2, 0.25, 0.25); var apiElev3 = _elevationService.GetPointElevation(lat - amounty, lon + amountx, dataSet); Assert.True((elev3 - apiElev3.Elevation.Value) < double.Epsilon); } } }