Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
# Conflicts:
#	DEM.Net.Core/IO/Raster/AsciiGridFile.cs
  • Loading branch information
xfischer committed Mar 12, 2021
2 parents 0df845f + d1cb413 commit 46c8546
Show file tree
Hide file tree
Showing 18 changed files with 364 additions and 71 deletions.
5 changes: 4 additions & 1 deletion DEM.Net.Core/Helpers/HeightMapExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
using DEM.Net.Core.Gpx;
using SixLabors.ImageSharp.ColorSpaces;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
Expand Down Expand Up @@ -211,8 +212,10 @@ public static GeoPoint Translate(this GeoPoint point, double x, double y, double
/// <returns></returns>
public static HeightMap BakeCoordinates(this HeightMap heightMap)
{
heightMap.Coordinates = heightMap.Coordinates.ToList();
if (heightMap.Coordinates is IList)
return heightMap;

heightMap.Coordinates = heightMap.Coordinates.ToList();
return heightMap;
}

Expand Down
36 changes: 36 additions & 0 deletions DEM.Net.Core/Helpers/Reprojection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ public static HeightMap ReprojectGeodeticToCartesian(this HeightMap heightMap)
heightMap.BoundingBox = heightMap.BoundingBox.ReprojectTo(SRID_GEODETIC, SRID_PROJECTED_MERCATOR);
return heightMap;
}
public static HeightMap ReprojectGeodeticToTileSystem(this HeightMap heightMap, int zoomLevel, int tileSize)
{
heightMap.Coordinates = heightMap.Coordinates.ReprojectGeodeticToTileSystem(zoomLevel, tileSize);
heightMap.BoundingBox = heightMap.BoundingBox.ReprojectToTileSystem(zoomLevel, tileSize);
return heightMap;
}

public static HeightMap ReprojectTo(this HeightMap heightMap, int sourceEpsgCode, int destinationEpsgCode)
{
Expand All @@ -61,6 +67,16 @@ public static HeightMap ReprojectTo(this HeightMap heightMap, int sourceEpsgCode
return heightMap;
}

public static IEnumerable<GeoPoint> ReprojectGeodeticToTileSystem(this IEnumerable<GeoPoint> points, int zoomLevel, int tileSize)
{
foreach (var p in points)
{
var newPt = TileUtils.PositionToGlobalPixel(new LatLong(p.Latitude, p.Longitude), zoomLevel, tileSize);

yield return new GeoPoint(newPt.Y, newPt.X, p.Elevation);
}
}

public static IEnumerable<GeoPoint> ReprojectGeodeticToCartesian(this IEnumerable<GeoPoint> points, int? count = null)
{
return points.ReprojectTo(SRID_GEODETIC, SRID_PROJECTED_MERCATOR, count);
Expand Down Expand Up @@ -237,6 +253,26 @@ public static BoundingBox ReprojectTo(this BoundingBox bbox, int sourceEpsgCode,

return outBbox;

}
public static BoundingBox ReprojectToTileSystem(this BoundingBox bbox, int zoomLevel, int tileSize)
{

var minmin = TileUtils.PositionToGlobalPixel(new LatLong(bbox.yMin, bbox.xMin), zoomLevel, tileSize);
var minmax = TileUtils.PositionToGlobalPixel(new LatLong(bbox.yMin, bbox.xMax), zoomLevel, tileSize);
var maxmax = TileUtils.PositionToGlobalPixel(new LatLong(bbox.yMax, bbox.xMax), zoomLevel, tileSize);
var maxmin = TileUtils.PositionToGlobalPixel(new LatLong(bbox.yMax, bbox.xMin), zoomLevel, tileSize);

var outBbox = GeometryService.GetBoundingBox(new GeoPoint[] { new GeoPoint(minmin.Y, minmin.X),
new GeoPoint(minmax.Y,minmax.X),
new GeoPoint(maxmax.Y,maxmax.X),
new GeoPoint(maxmin.Y,maxmin.X)
});
outBbox.zMin = bbox.zMin;
outBbox.zMax = bbox.zMax;
outBbox.SRID = 3857;

return outBbox;

}

public static GeoPoint ReprojectTo(this GeoPoint point, int sourceEpsgCode, int destinationEpsgCode)
Expand Down
46 changes: 23 additions & 23 deletions DEM.Net.Core/IO/Raster/AsciiGridFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public class ASCIIGridFile : IRasterFile
private readonly string _filename;
private static char[] SEPARATOR = new char[] { ' ' };

List<List<float>> _data = null;
private static Dictionary<string, List<List<float>>> _tempCache = new Dictionary<string, List<List<float>>>();
List<List<string>> _data = null;
private static Dictionary<string, List<List<string>>> _tempCache = new Dictionary<string, List<List<string>>>();

public ASCIIGridFile(string fileName)
{
Expand All @@ -42,18 +42,20 @@ public float GetElevationAtPoint(FileMetadata metadata, int x, int y)
ReadAllFile(metadata);
}

float elevation = _data[y][x];
string strXValue = _data[y][x];

float elevation = float.Parse(strXValue, CultureInfo.InvariantCulture);
return elevation;

}

private void ReadAllFile(FileMetadata metadata)
{
//if (_tempCache.ContainsKey(_filename))
//{
// _data = _tempCache[_filename];
// return;
//}
if (_tempCache.ContainsKey(_filename))
{
_data = _tempCache[_filename];
return;
}
string curLine = null;
_fileStream.Seek(0, SeekOrigin.Begin);

Expand All @@ -63,33 +65,30 @@ private void ReadAllFile(FileMetadata metadata)
curLine = _streamReader.ReadLine();
}

_data = new List<List<float>>(metadata.Height);
_data = new List<List<string>>(metadata.Height);
while (!_streamReader.EndOfStream)
{
var line = _streamReader.ReadLine();
var line = _streamReader.ReadLine().Trim();

var values = new List<float>(metadata.Width);
var values = new List<string>(metadata.Width);
var current = string.Empty;
foreach (char c in line)
{
if (c == ' ')
{
if (current != string.Empty)
{
values.Add(float.Parse(current, CultureInfo.InvariantCulture));
}
values.Add(current);
current = string.Empty;
}
else
{
current += c;
}
}
values.Add(float.Parse(current, CultureInfo.InvariantCulture));
Debug.Assert(values.Count == metadata.Width);
values.Add(current);
//Debug.Assert(values.Count == metadata.Width);
_data.Add(values);
}
//_tempCache[_filename] = _data;
_tempCache[_filename] = _data;
}

public HeightMap GetHeightMap(FileMetadata metadata)
Expand Down Expand Up @@ -140,7 +139,8 @@ public HeightMap GetHeightMapInBBox(BoundingBox bbox, FileMetadata metadata, flo
{
double longitude = metadata.DataStartLon + (metadata.pixelSizeX * x);

float heightValue = _data[y][x];
float heightValue = float.Parse(_data[y][x], CultureInfo.InvariantCulture);
if (heightValue == metadata.NoDataValueFloat) heightValue = noDataValue;
heightMap.Minimum = Math.Min(heightMap.Minimum, heightValue);
heightMap.Maximum = Math.Max(heightMap.Maximum, heightValue);

Expand Down Expand Up @@ -183,7 +183,7 @@ public FileMetadata ParseMetaData(DEMFileDefinition fileFormat)
metadata.PixelScaleX = cellsize;
metadata.PixelScaleY = cellsize;
metadata.pixelSizeX = cellsize;
metadata.pixelSizeY = cellsize; // Y direction here (may be detected somehow)
metadata.pixelSizeY = -cellsize;

if (fileFormat.Registration == DEMFileRegistrationMode.Grid)
{
Expand Down Expand Up @@ -233,7 +233,7 @@ private void DebugCheckRegistrationType(DEMFileRegistrationMode registration, st
DEMFileRegistrationMode xModeFromFile = xRegFromFile.ToLower().EndsWith("corner") ? DEMFileRegistrationMode.Grid : DEMFileRegistrationMode.Cell;
DEMFileRegistrationMode yModeFromFile = yRegFromFile.ToLower().EndsWith("corner") ? DEMFileRegistrationMode.Grid : DEMFileRegistrationMode.Cell;

Debug.Assert(registration == xModeFromFile && registration == yModeFromFile, "Registration mode mismatch between file and dataset.");
//Debug.Assert(registration == xModeFromFile && registration == yModeFromFile, "Registration mode mismatch between file and dataset.");

}

Expand All @@ -246,8 +246,8 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_data?.Clear();
_data = null;
//_data?.Clear();
//_data = null;
_streamReader?.Dispose();
_fileStream?.Dispose();
}
Expand Down
67 changes: 50 additions & 17 deletions DEM.Net.Core/Model/Datasets/DEMDataSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,34 @@ public override string ToString()
Attribution = new Attribution(ATTRIBUTION_SUBJECT, "ETOPO1 - NOAA", "https://www.ngdc.noaa.gov/mgg/global/"
, "Amante, C. and B.W. Eakins, 2009. ETOPO1 1 Arc-Minute Global Relief Model: Procedures, Data Sources and Analysis. NOAA Technical Memorandum NESDIS NGDC-24. National Geophysical Data Center, NOAA. doi:10.7289/V5C8276M")
});
datasets.Add("IGN_5m", new DEMDataSet()
{
Name = nameof(IGN_5m),
Description = "IGN RGE Alti 5 meter",
PublicUrl = "https://ign.fr",
DataSource = new LocalFileSystem(localDirectory: Path.Combine("Data", "IGN_5m")),
FileFormat = new DEMFileDefinition("Esri Ascii Grid", DEMFileType.ASCIIGrid, ".asc", DEMFileRegistrationMode.Cell),
ResolutionMeters = 5,
PointsPerDegree = 21600,
NoDataValue = -99999,
SRID = 2154,
Attribution = new Attribution(ATTRIBUTION_SUBJECT, "IGN", "https://ign.fr"
, "TO BE DEFINED")
});
datasets.Add("IGN_1m", new DEMDataSet()
{
Name = nameof(IGN_1m),
Description = "IGN RGE Alti 1 meter",
PublicUrl = "https://ign.fr",
DataSource = new LocalFileSystem(localDirectory: Path.Combine("Data", "IGN_1m")),
FileFormat = new DEMFileDefinition("Esri Ascii Grid", DEMFileType.ASCIIGrid, ".asc", DEMFileRegistrationMode.Cell),
ResolutionMeters = 1,
PointsPerDegree = 108000,
NoDataValue = -99999,
SRID = 2154,
Attribution = new Attribution(ATTRIBUTION_SUBJECT, "IGN", "https://ign.fr"
, "TO BE DEFINED")
});
datasets.Add("ASTER_GDEMV3", new DEMDataSet()
{
Name = nameof(ASTER_GDEMV3),
Expand Down Expand Up @@ -168,22 +196,22 @@ public override string ToString()
Attribution = new Attribution(ATTRIBUTION_SUBJECT, "GEBCO Compilation Group (2019) GEBCO 2019 Grid (doi:10.5285/836f016a-33be-6ddc-e053-6c86abc0788e)",
"https://www.gebco.net/data_and_products/gridded_bathymetry_data/gebco_2019/gebco_2019_info.html",
"GEBCO Compilation Group (2019) GEBCO 2019 Grid (doi:10.5285/836f016a-33be-6ddc-e053-6c86abc0788e)")
});
//datasets.Add("GEBCO_2020", new DEMDataSet()
//{
// Name = nameof(GEBCO_2020),
// Description = "GEBCO’s gridded bathymetric data set, a global terrain model for ocean and land at 15 arc-second intervals",
// PublicUrl = "https://www.gebco.net/data_and_products/gridded_bathymetry_data/gebco_2020/",
// DataSource = new LocalFileSystem(localDirectory: Path.Combine("Data", "GEBCO_2020")),
// FileFormat = new DEMFileDefinition("netCDF file", DEMFileType.CF_NetCDF, ".nc", DEMFileRegistrationMode.Cell),
// ResolutionMeters = 464,
// ResolutionArcSeconds = 15,
// PointsPerDegree = 240,
// NoDataValue = -9999,
// Attribution = new Attribution(ATTRIBUTION_SUBJECT, "GEBCO Compilation Group (2020) GEBCO 2020 Grid (doi:10.5285/a29c5465-b138-234d-e053-6c86abc040b9)",
// "https://www.gebco.net/data_and_products/gridded_bathymetry_data/gebco_2020/",
// "GEBCO Compilation Group (2020) GEBCO 2020 Grid (doi:10.5285/a29c5465-b138-234d-e053-6c86abc040b9)")
//});
});
datasets.Add("GEBCO_2020", new DEMDataSet()
{
Name = nameof(GEBCO_2020),
Description = "GEBCO’s gridded bathymetric data set, a global terrain model for ocean and land at 15 arc-second intervals",
PublicUrl = "https://www.gebco.net/data_and_products/gridded_bathymetry_data/gebco_2020/",
DataSource = new LocalFileSystem(localDirectory: "GEBCO_2020"),
FileFormat = new DEMFileDefinition("GeoTiff file", DEMFileType.GEOTIFF, ".tif", DEMFileRegistrationMode.Grid),
ResolutionMeters = 464,
ResolutionArcSeconds = 15,
PointsPerDegree = 240,
NoDataValue = -9999,
Attribution = new Attribution(ATTRIBUTION_SUBJECT, "GEBCO Compilation Group (2020) GEBCO 2020 Grid (doi:10.5285/a29c5465-b138-234d-e053-6c86abc040b9)",
"https://www.gebco.net/data_and_products/gridded_bathymetry_data/gebco_2020/",
"GEBCO Compilation Group (2020) GEBCO 2020 Grid (doi:10.5285/a29c5465-b138-234d-e053-6c86abc040b9)")
});

return datasets;
}
Expand Down Expand Up @@ -216,7 +244,7 @@ public override string ToString()
/// Global medium res coverage with bathymetry (500m resolution)
/// </summary>
public static DEMDataSet GEBCO_2019 => Datasets.Value[nameof(GEBCO_2019)];
//public static DEMDataSet GEBCO_2020 => Datasets.Value[nameof(GEBCO_2020)];
public static DEMDataSet GEBCO_2020 => Datasets.Value[nameof(GEBCO_2020)];

/// <summary>
/// ASTER GDEM V3 https://cmr.earthdata.nasa.gov/search/concepts/C1575726572-LPDAAC_ECS/11
Expand All @@ -229,6 +257,11 @@ public override string ToString()
/// API: https://cmr.earthdata.nasa.gov/search/site/docs/search/api.html
/// </summary>
public static DEMDataSet NASADEM => Datasets.Value[nameof(NASADEM)];
public static DEMDataSet IGN_5m => Datasets.Value[nameof(IGN_5m)];
public static DEMDataSet IGN_1m => Datasets.Value[nameof(IGN_1m)];





}
Expand Down
2 changes: 1 addition & 1 deletion DEM.Net.Core/Model/GeoPoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public GeoPoint(double latitude, double longitude, double? altitude)
{
this.Latitude = latitude;
this.Longitude = longitude;
this.Elevation = altitude;
this.Elevation = (altitude.HasValue && double.IsNaN(altitude.Value)) ? null : altitude;
this.DistanceFromOriginMeters = null;
}

Expand Down
22 changes: 21 additions & 1 deletion DEM.Net.Core/Model/Imagery/ImageryProviders.Predefined.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
namespace DEM.Net.Core.Imagery
using System.Linq;

namespace DEM.Net.Core.Imagery
{
public partial class ImageryProvider
{
public const string ATTRIBUTION_SUBJECT = "Imagery";
#if DEBUG
public static readonly ImageryProvider DebugProvider = new TileDebugProvider(null);
#endif
//https://t0.tiles.virtualearth.net/tiles/a1202221311130.jpeg?g=990&mkt=en-us&n=z
public static readonly ImageryProvider BingMapsSatellite = new ImageryProvider
{
Name = "MapTiler-Satellite",
Attribution = new Attribution(ATTRIBUTION_SUBJECT, "Bing Maps", "https://www.microsoft.com/en-us/maps/product/terms-april-2011", "© Bing Maps"),
UrlModel = new UrlModel("https://t{s}.tiles.virtualearth.net/tiles/a{quadkey}.jpeg?g=990&mkt=en-us&n=z", new[] { "0", "1", "2", "3", "4", "5", "6", "7" }),
TileSize = 256,
MaxZoom = 19
};
public static readonly ImageryProvider MapTilerSatellite = new ImageryProvider
{
Name = "MapTiler-Satellite",
Attribution = new Attribution(ATTRIBUTION_SUBJECT, "MapTiler Cloud Satellite", "https://www.maptiler.com", "© MapTiler- © OpenStreetMap and contributors"),
UrlModel = new UrlModel("https://api.maptiler.com/tiles/satellite/{z}/{x}/{y}.jpg?key={t}", null),
TokenUserSecretsKey = "MapTilerKey",
TileSize = 256,
MaxZoom = 20
};
public static readonly ImageryProvider MapBoxSatellite = new ImageryProvider
{
Name = "MapBox-Satellite",
Expand Down
5 changes: 5 additions & 0 deletions DEM.Net.Core/Model/Imagery/PointInt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,10 @@ public override string ToString()
{
return $"x={X}, y={Y}";
}

public static bool IsDefault(Point<T> point)
{
return point.X.Equals(default(T)) && point.Y.Equals(default(T));
}
}
}
2 changes: 2 additions & 0 deletions DEM.Net.Core/Model/Imagery/TileRange.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ public TileRange ZoomOut()
public int NumCols => End.X - Start.X + 1;
public int NumRows => End.Y - Start.Y + 1;
public int Count => NumCols * NumRows;
public int Width => NumCols * TileSize;
public int Height => NumRows * TileSize;

public int Zoom => Start.Zoom;

Expand Down
3 changes: 2 additions & 1 deletion DEM.Net.Core/Services/DemProviders/LocalFileSystemIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ public IEnumerable<DEMFileSource> GetCoveredFileSources(DEMDataSet dataset, Boun

public IEnumerable<DEMFileSource> GetFileSources(DEMDataSet dataset)
{
foreach (var file in Directory.GetFiles(dataset.DataSource.IndexFilePath, "*" + dataset.FileFormat.FileExtension, SearchOption.AllDirectories))
string datasetPath = _rasterService.GetLocalDEMPath(dataset);
foreach (var file in Directory.GetFiles(datasetPath, "*" + dataset.FileFormat.FileExtension, SearchOption.AllDirectories))
{
var metadataPath = Path.Combine(Path.GetDirectoryName(file), RasterService.MANIFEST_DIR, Path.ChangeExtension(Path.GetFileName(file), ".json"));
if (!File.Exists(metadataPath))
Expand Down

0 comments on commit 46c8546

Please sign in to comment.