public List <GeoPoint> GetLineGeometryElevation(IGeometry lineStringGeometry, DEMDataSet dataSet, InterpolationMode interpolationMode = InterpolationMode.Bilinear) { if (lineStringGeometry == null || lineStringGeometry.IsEmpty) { return(null); } if (lineStringGeometry.OgcGeometryType != OgcGeometryType.LineString) { throw new Exception("Geometry must be a linestring"); } if (lineStringGeometry.SRID != 4326) { throw new Exception("Geometry SRID must be set to 4326 (WGS 84)"); } BoundingBox bbox = lineStringGeometry.GetBoundingBox(); List <FileMetadata> tiles = this.GetCoveringFiles(bbox, dataSet); // Init interpolator IInterpolator interpolator = GetInterpolator(interpolationMode); var ptStart = lineStringGeometry.Coordinates[0]; var ptEnd = lineStringGeometry.Coordinates.Last(); GeoPoint start = new GeoPoint(ptStart.Y, ptStart.X); GeoPoint end = new GeoPoint(ptEnd.Y, ptEnd.X); double lengthMeters = start.DistanceTo(end); int demResolution = dataSet.ResolutionMeters; int totalCapacity = 2 * (int)(lengthMeters / demResolution); List <GeoPoint> geoPoints = new List <GeoPoint>(totalCapacity); using (RasterFileDictionary adjacentRasters = new RasterFileDictionary()) { bool isFirstSegment = true; // used to return first point only for first segments, for all other segments last point will be returned foreach (GeoSegment segment in lineStringGeometry.Segments()) { List <FileMetadata> segTiles = this.GetCoveringFiles(segment.GetBoundingBox(), dataSet, tiles); // Find all intersection with segment and DEM grid IEnumerable <GeoPoint> intersections = this.FindSegmentIntersections(segment.Start.Longitude , segment.Start.Latitude , segment.End.Longitude , segment.End.Latitude , segTiles , isFirstSegment , true); // Get elevation for each point intersections = this.GetElevationData(intersections, adjacentRasters, segTiles, interpolator); // Add to output list geoPoints.AddRange(intersections); isFirstSegment = false; } //Debug.WriteLine(adjacentRasters.Count); } // Ensures all rasters are properly closed return(geoPoints); }
public List <GeoPoint> GetLineGeometryElevation(IEnumerable <GeoPoint> lineGeoPoints, DEMDataSet dataSet, InterpolationMode interpolationMode = InterpolationMode.Bilinear) { if (lineGeoPoints == null) { throw new ArgumentNullException(nameof(lineGeoPoints), "Point list is null"); } IGeometry geometry = GeometryService.ParseGeoPointAsGeometryLine(lineGeoPoints); return(GetLineGeometryElevation(geometry, dataSet, interpolationMode)); }
public IntervisibilityReport GetIntervisibilityReport(GeoPoint source, GeoPoint target, DEMDataSet dataSet , bool downloadMissingFiles = true , double sourceVerticalOffset = 0d , InterpolationMode interpolationMode = InterpolationMode.Bilinear) { try { var elevationLine = GeometryService.ParseGeoPointAsGeometryLine(source, target); if (downloadMissingFiles) { this.DownloadMissingFiles(dataSet, elevationLine.GetBoundingBox()); } var geoPoints = this.GetLineGeometryElevation(elevationLine, dataSet); var metrics = geoPoints.ComputeVisibilityMetrics(sourceVerticalOffset, dataSet.NoDataValue); return(new IntervisibilityReport(geoPoints, metrics, originVerticalOffset: sourceVerticalOffset)); } catch (Exception ex) { _logger.LogError($"{nameof(GetIntervisibilityReport)} error: {ex.Message}"); throw; } }
public void DownloadRasterFile(DemFileReport report, DEMDataSet dataset) { throw new NotImplementedException(); }
public HeightMap GetHeightMap(ref BoundingBox bbox, DEMDataSet dataSet) { DownloadMissingFiles(dataSet, bbox); // Locate which files are needed // Find files matching coords List <FileMetadata> bboxMetadata = GetCoveringFiles(bbox, dataSet); if (bboxMetadata.Count == 0) { string errorMessage = $"Dataset {dataSet.Name} has no coverage for provided bounding box."; this._logger.LogWarning(errorMessage); throw new Exception(errorMessage); } else { // Check if bounding box is fully covered (will result in invalid models without any error being thrown) bool covered = this.IsBoundingBoxCovered(bbox, bboxMetadata.Select(m => m.BoundingBox)); if (!covered) { const string errorMessage = "Bounding box is partially covered by DEM dataset. Heightmap in its current state supports only full data tiles."; this._logger.LogWarning(errorMessage); throw new Exception(errorMessage); } else { // get height map for each file at bbox List <HeightMap> tilesHeightMap = new List <HeightMap>(bboxMetadata.Count); foreach (FileMetadata metadata in bboxMetadata) { using (IRasterFile raster = _IRasterService.OpenFile(metadata.Filename, dataSet.FileFormat.Type)) { tilesHeightMap.Add(raster.GetHeightMapInBBox(bbox, metadata, NO_DATA_OUT)); } } HeightMap heightMap; if (tilesHeightMap.Count == 1) { heightMap = tilesHeightMap.First(); bbox = heightMap.BoundingBox; } else { // Merge height maps int totalHeight = tilesHeightMap.GroupBy(h => h.BoundingBox.xMin).Select(g => g.Sum(v => v.Height)).First(); int totalWidth = tilesHeightMap.GroupBy(h => h.BoundingBox.yMin).Select(g => g.Sum(v => v.Width)).First(); heightMap = new HeightMap(totalWidth, totalHeight); heightMap.BoundingBox = new BoundingBox(xmin: tilesHeightMap.Min(h => h.BoundingBox.xMin) , xmax: tilesHeightMap.Max(h => h.BoundingBox.xMax) , ymin: tilesHeightMap.Min(h => h.BoundingBox.yMin) , ymax: tilesHeightMap.Max(h => h.BoundingBox.yMax)); bbox = heightMap.BoundingBox; heightMap.Coordinates = tilesHeightMap.SelectMany(hmap => hmap.Coordinates).Sort(); heightMap.Count = totalWidth * totalHeight; heightMap.Minimum = tilesHeightMap.Min(hmap => hmap.Minimum); heightMap.Maximum = tilesHeightMap.Max(hmap => hmap.Maximum); } System.Diagnostics.Debug.Assert(heightMap.Count == tilesHeightMap.Sum(h => h.Count)); return(heightMap); } } }
private void DownloadMissingFiles_FromReport(IEnumerable <DemFileReport> report, DEMDataSet dataSet) { // Generate metadata files if missing foreach (var file in report.Where(r => r.IsMetadataGenerated == false && r.IsExistingLocally == true)) { _IRasterService.GenerateFileMetadata(file.LocalName, dataSet.FileFormat, false); } List <DemFileReport> filesToDownload = new List <DemFileReport>(report.Where(kvp => kvp.IsExistingLocally == false)); if (filesToDownload.Count == 0) { _logger?.LogTrace("No missing file(s)."); } else { _logger?.LogInformation($"Downloading {filesToDownload.Count} missing file(s)."); try { Parallel.ForEach(filesToDownload, file => { _IRasterService.DownloadRasterFile(file, dataSet); } ); _IRasterService.GenerateDirectoryMetadata(dataSet, false, false); _IRasterService.LoadManifestMetadata(dataSet, true); } catch (AggregateException ex) { _logger?.LogError(ex, $"Error downloading missing files. Check internet connection or retry later. {ex.GetInnerMostException().Message}"); throw; } } }
public string GetLocalDEMFilePath(DEMDataSet dataset, string fileTitle) { return(Path.Combine(GetLocalDEMPath(dataset), fileTitle)); }
private IEnumerable <DEMFileSource> GetSources(DEMDataSet dataSet, string vrtFileName) { Uri localVrtUri = new Uri(Path.GetFullPath(vrtFileName), UriKind.Absolute); Uri remoteVrtUri = new Uri(dataSet.DataSource.IndexFilePath, UriKind.Absolute); double[] geoTransform; var registration = dataSet.FileFormat.Registration; Dictionary <string, string> properties; // Create an XmlReader using (FileStream fileStream = new FileStream(vrtFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (XmlReader reader = XmlReader.Create(fileStream)) { if (reader.ReadToFollowing("GeoTransform")) { geoTransform = ParseGeoTransform(reader.ReadElementContentAsString()); } else { throw new Exception("GeoTransform element not found!"); } string sourceName = ""; if (reader.ReadToFollowing("VRTRasterBand")) { properties = new Dictionary <string, string>(); while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { if (reader.Name == "ComplexSource" || reader.Name == "SimpleSource") { sourceName = reader.Name; break; } properties[reader.Name] = reader.ReadElementContentAsString(); } } bool isOnFirstSource = true; while (isOnFirstSource || reader.ReadToFollowing(sourceName)) { DEMFileSource source = ParseGDALSource(reader); // SetLocalFileName source.SourceFileNameAbsolute = new Uri(remoteVrtUri, source.SourceFileName).ToString(); source.LocalFileName = new Uri(localVrtUri, source.SourceFileName).LocalPath; // Transform origin // Xp = padfTransform[0] + P * padfTransform[1] + L * padfTransform[2]; // Yp = padfTransform[3] + P * padfTransform[4] + L * padfTransform[5]; source.OriginLon = geoTransform[0] + source.DstxOff * geoTransform[1] + source.DstyOff * geoTransform[2]; source.OriginLat = geoTransform[3] + source.DstxOff * geoTransform[4] + source.DstyOff * geoTransform[5]; source.DestLon = geoTransform[0] + (source.DstxOff + source.DstxSize) * geoTransform[1] + (source.DstyOff + source.DstySize) * geoTransform[2]; source.DestLat = geoTransform[3] + (source.DstxOff + source.DstxSize) * geoTransform[4] + (source.DstyOff + source.DstySize) * geoTransform[5]; if (registration == DEMFileRegistrationMode.Grid) { source.BBox = new BoundingBox(Math.Round(source.OriginLon + geoTransform[1] / 2, 10), Math.Round(source.DestLon - +geoTransform[1] / 2, 10), Math.Round(source.DestLat - geoTransform[5] / 2, 10), Math.Round(source.OriginLat + geoTransform[5] / 2, 10)); } else { source.OriginLon = Math.Round(source.OriginLon, 10); source.OriginLat = Math.Round(source.OriginLat, 10); source.DestLon = Math.Round(source.DestLon, 10); source.DestLat = Math.Round(source.DestLat, 10); source.BBox = new BoundingBox(source.OriginLon, source.DestLon, source.DestLat, source.OriginLat); } isOnFirstSource = false; yield return(source); } } } }
public void Setup(DEMDataSet dataset, string dataSetLocalDir) { this.dataset = dataset; this.localDir = dataSetLocalDir; }
public string GetLocalDEMPath(DEMDataSet dataset) { return(dataset.DataSource.IsGlobalFile ? Path.GetDirectoryName(dataset.DataSource.IndexFilePath) : Path.Combine(_localDirectory, dataset.Name)); }
public IEnumerable <DEMFileSource> GetCoveredFileSources(DEMDataSet dataset, BoundingBox bbox) { throw new NotImplementedException(nameof(NasaGranuleFileService)); }
public static FileMetadata Migrate(IRasterService rasterService, ILogger logger, FileMetadata oldMetadata, string dataRootDirectory, DEMDataSet dataSet) { if (oldMetadata != null) { logger.LogInformation($"Migration metadata file {oldMetadata.Filename} from {oldMetadata.Version} to {FileMetadata.FILEMETADATA_VERSION}"); // 2.2 version requires regeneration oldMetadata = rasterService.ParseMetadata(Path.Combine(rasterService.LocalDirectory, oldMetadata.Filename), dataSet.FileFormat); //switch (oldMetadata.Version) //{ // case "2.0": // // 2.1 : relative path // // Find dataset root within path // DirectoryInfo dir = new DirectoryInfo(Path.GetDirectoryName(oldMetadata.Filename)); // while (dir.Name != dataSet.Name) // { // dir = dir.Parent; // } // dir = dir.Parent; // // replace directory // oldMetadata.Filename = oldMetadata.Filename.Replace(dir.FullName, dataRootDirectory); // Uri fullPath = new Uri(oldMetadata.Filename, UriKind.Absolute); // if (!(dataRootDirectory.Last() == Path.DirectorySeparatorChar)) // dataRootDirectory += Path.DirectorySeparatorChar; // Uri relRoot = new Uri(dataRootDirectory, UriKind.Absolute); // oldMetadata.Filename = Uri.UnescapeDataString(relRoot.MakeRelativeUri(fullPath).ToString()); // oldMetadata.FileFormat = dataSet.FileFormat; // break; // case "2.1": // // 2.2 : [Metadata regneration required] file format is now mapped to DEMFileDefinition, lat/lon bounds names changed for clarity, file format changed from DEMFileFormat (name + file extenstion) // // // // to DEMFileDefinition // oldMetadata.FileFormat = dataSet.FileFormat; // break; // default: // // DEMFileFormat // oldMetadata.FileFormat = dataSet.FileFormat; // break; //} // set version and fileFormat oldMetadata.Version = FileMetadata.FILEMETADATA_VERSION; } return(oldMetadata); }
/// <summary> /// Ensures local directories are created and download VRT file if needed /// </summary> void IDEMDataSetIndex.Setup(DEMDataSet dataSet, string dataSetLocalDir) { try { if (dataSet == null) { throw new ArgumentNullException(nameof(dataSet), "Dataset is null."); } if (_cacheByDemName.ContainsKey(dataSet.Name)) { return; } _logger?.LogInformation($"Setup for {dataSet.Name} dataset."); if (!Directory.Exists(dataSetLocalDir)) { Directory.CreateDirectory(dataSetLocalDir); } string vrtFileName = Path.Combine(dataSetLocalDir, UrlHelper.GetFileNameFromUrl(dataSet.DataSource.IndexFilePath)); bool download = true; if (File.Exists(vrtFileName)) { // Download if too old file if ((DateTime.Now - File.GetLastWriteTime(vrtFileName)).TotalDays > MAX_AGE_DAYS) { _logger?.LogInformation("VRT file is too old."); } else if (IsCorrupted(dataSet, vrtFileName)) { _logger?.LogInformation("VRT file is corrupted."); } else { download = false; } } if (download) { lock (DOWNLOAD_LOCKER) { if (download) { _logger?.LogInformation($"Downloading index file from {dataSet.DataSource.IndexFilePath}... This file will be downloaded once and stored locally."); HttpClient client = _httpClientFactory.CreateClient(); using (HttpResponseMessage response = client.GetAsync(dataSet.DataSource.IndexFilePath).Result) using (FileStream fs = new FileStream(vrtFileName, FileMode.Create, FileAccess.Write)) { var contentbytes = client.GetByteArrayAsync(dataSet.DataSource.IndexFilePath).Result; fs.Write(contentbytes, 0, contentbytes.Length); } download = false; } } } // Cache if (_cacheByDemName == null) { _cacheByDemName = new ConcurrentDictionary <string, List <DEMFileSource> >(); } if (_cacheByDemName.ContainsKey(vrtFileName) == false) { _cacheByDemName[dataSet.Name] = this.GetSources(dataSet, vrtFileName).ToList(); } } catch (Exception ex) { _logger?.LogError("Unhandled exception: " + ex.Message); _logger?.LogInformation(ex.ToString()); throw; } }
public IEnumerable <GeoPoint> GetPointsElevation(IEnumerable <GeoPoint> points, DEMDataSet dataSet, InterpolationMode interpolationMode = InterpolationMode.Bilinear) { if (points == null) { return(null); } IEnumerable <GeoPoint> pointsWithElevation; BoundingBox bbox = points.GetBoundingBox(); DownloadMissingFiles(dataSet, bbox); List <FileMetadata> tiles = this.GetCoveringFiles(bbox, dataSet); if (tiles.Count == 0) { return(null); } else { // Init interpolator IInterpolator interpolator = GetInterpolator(interpolationMode); using (RasterFileDictionary adjacentRasters = new RasterFileDictionary()) { // Get elevation for each point pointsWithElevation = this.GetElevationData(points, adjacentRasters, tiles, interpolator); //Debug.WriteLine(adjacentRasters.Count); } // Ensures all rasters are properly closed } return(pointsWithElevation); }
public GeoPoint GetPointElevation(GeoPoint location, DEMDataSet dataSet, InterpolationMode interpolationMode = InterpolationMode.Bilinear) { return(GetPointElevation(location.Latitude, location.Longitude, dataSet, interpolationMode)); }
public string GetDEMLocalPath(DEMDataSet dataSet) { return(_IRasterService.GetLocalDEMPath(dataSet)); }
public string GetLocalDEMPath(DEMDataSet dataset) { return(dataset.DataSource.DataSourceType == Datasets.DEMDataSourceType.LocalFileSystem ? Path.GetFullPath(dataset.DataSource.IndexFilePath) : Path.Combine(_localDirectory, dataset.Name)); }