Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
xfischer committed Nov 1, 2020
2 parents 1675fd0 + abedff8 commit 3be014f
Show file tree
Hide file tree
Showing 30 changed files with 1,123 additions and 219 deletions.
1 change: 1 addition & 0 deletions DEM.Net.Core/Configuration/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public static IServiceCollection AddDemNetCore(this IServiceCollection services)
.AddSingleton<RasterService>()
.AddTransient<ElevationService>()
.AddTransient<MeshService>()
.AddTransient<AdornmentsService>()
.AddTransient<ImageryCache>()
.AddSingleton<ImageryService>();

Expand Down
254 changes: 128 additions & 126 deletions DEM.Net.Core/DEM.Net.Core.csproj

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion DEM.Net.Core/Helpers/HeightMapExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ public static HeightMap CenterOnOrigin(this HeightMap heightMap, BoundingBox bbo

heightMap.BoundingBox = new BoundingBox(bbox.xMin - xOriginOffset, bbox.xMax - xOriginOffset
, bbox.yMin - yOriginOffset, bbox.yMax - yOriginOffset
, 0, bbox.zMax - bbox.zMin);
, 0, bbox.zMax - bbox.zMin)
{ SRID = bbox.SRID };
return heightMap;
}

Expand Down
30 changes: 30 additions & 0 deletions DEM.Net.Core/Helpers/MetadataExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DEM.Net.Core
{
public static class MetadataExtensions
{
public static BoundingBox BoundingBox(this IEnumerable<FileMetadata> fileMetadatas)
{
double xmin = double.MaxValue,
ymin = double.MaxValue,
zmin = double.MaxValue,
xmax = double.MinValue,
ymax = double.MinValue,
zmax = double.MinValue;

foreach (var metadata in fileMetadatas)
{
xmin = Math.Min(xmin, metadata.BoundingBox.xMin);
xmax = Math.Max(xmax, metadata.BoundingBox.xMax);

ymin = Math.Min(ymin, metadata.BoundingBox.yMin);
ymax = Math.Max(ymax, metadata.BoundingBox.yMax);
}
return new BoundingBox(xmin, xmax, ymin, ymax, zmin, zmax);
}
}
}
9 changes: 9 additions & 0 deletions DEM.Net.Core/Helpers/Reprojection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public static class Reprojection
public const int SRID_GEODETIC = 4326;
public const int SRID_PROJECTED_LAMBERT_93 = 2154;
public const int SRID_PROJECTED_MERCATOR = 3857;
public const int SRID_NAD83 = 4269;

public static HeightMap ReprojectGeodeticToCartesian(this HeightMap heightMap)
{
Expand Down Expand Up @@ -142,6 +143,14 @@ public static TriangulationList<Vector3> ZScale(this TriangulationList<Vector3>
}
return triangulation;
}
public static TriangulationList<Vector3> Scale(this TriangulationList<Vector3> triangulation, float factor)
{
return triangulation.Transform(Matrix4x4.CreateScale(factor));
}
public static TriangulationList<Vector3> Scale(this TriangulationList<Vector3> triangulation, Vector3 scales)
{
return triangulation.Transform(Matrix4x4.CreateScale(scales));
}
public static TriangulationList<Vector3> ToGlTFSpace(this TriangulationList<Vector3> triangulation)
{
for (int i = 0; i < triangulation.NumPositions; i++)
Expand Down
27 changes: 27 additions & 0 deletions DEM.Net.Core/Helpers/VectorsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ public static Vector4 CreateColor(byte r, byte g, byte b, byte a = 255)
{
return new Vector4(r / 255f, g / 255f, b / 255f, a / 255f);
}
public static Vector3 AtZ(this Vector3 vector3, float newZ)
{
vector3.Z = newZ;
return vector3;
}
public static IEnumerable<Vector3> ToQuadPoints(this Vector3 vertex, float pointSize)
{
float halfSize = pointSize / 2f;
Expand Down Expand Up @@ -141,6 +146,9 @@ public static TriangulationList<Vector3> Translate(this TriangulationList<Vector
Matrix4x4 translate = Matrix4x4.CreateTranslation(vector);
return Transform(triangulation, translate);
}
public static TriangulationList<Vector3> RotateX(this TriangulationList<Vector3> triangulation, float radians) => Transform(triangulation, Matrix4x4.CreateRotationX(radians));
public static TriangulationList<Vector3> RotateY(this TriangulationList<Vector3> triangulation, float radians) => Transform(triangulation, Matrix4x4.CreateRotationY(radians));
public static TriangulationList<Vector3> RotateZ(this TriangulationList<Vector3> triangulation, float radians) => Transform(triangulation, Matrix4x4.CreateRotationZ(radians));
public static TriangulationList<Vector3> Transform(this TriangulationList<Vector3> triangulation, Matrix4x4 matrix4x4)
{
for (int i = 0; i < triangulation.NumPositions; i++)
Expand Down Expand Up @@ -173,7 +181,26 @@ public static TriangulationList<Vector3> CenterOnOrigin(this TriangulationList<V

return triangulation;
}
public static TriangulationList<Vector3> CenterOnOrigin(this TriangulationList<Vector3> triangulation)
{
return triangulation.CenterOnOrigin(triangulation.GetBoundingBox(), true);
}

public static BoundingBox GetBoundingBox(this TriangulationList<Vector3> triangulation)
{
var bbox = new BoundingBox() { zMin = double.MaxValue, zMax = double.MinValue };
for (int i = 0; i < triangulation.NumPositions; i++)
{
bbox.xMin = Math.Min(bbox.xMin, triangulation.Positions[i].X);
bbox.xMax = Math.Max(bbox.xMax, triangulation.Positions[i].X);
bbox.yMin = Math.Min(bbox.yMin, triangulation.Positions[i].Y);
bbox.yMax = Math.Max(bbox.yMax, triangulation.Positions[i].Y);
bbox.zMin = Math.Min(bbox.zMin, triangulation.Positions[i].Z);
bbox.zMax = Math.Max(bbox.zMax, triangulation.Positions[i].Z);
}

return bbox;
}

}
}
139 changes: 111 additions & 28 deletions DEM.Net.Core/IO/Raster/AsciiGridFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ public class ASCIIGridFile : IRasterFile
private readonly string _filename;
private static char[] SEPARATOR = new char[] { ' ' };

List<string> _scanLines = null;
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 @@ -36,33 +37,58 @@ public ASCIIGridFile(string fileName)
}
public float GetElevationAtPoint(FileMetadata metadata, int x, int y)
{
if (_data == null)
{
ReadAllFile(metadata);
}

string strXValue = _data[y][x];

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

}

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

// skip header
for (int i = 1; i <= 6 /* + (y - 1)*/; i++)
{
curLine = _streamReader.ReadLine();
}
// skip header
for (int i = 1; i <= 6 /* + (y - 1)*/; i++)
{
curLine = _streamReader.ReadLine();
}

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

var values = new List<string>(metadata.Width);
var current = string.Empty;
foreach (char c in line)
{
_scanLines.Add(_streamReader.ReadLine());
if (c == ' ')
{
values.Add(current);
current = string.Empty;
}
else
{
current += c;
}
}

values.Add(current);
Debug.Assert(values.Count == metadata.Width);
_data.Add(values);
}

string strXValue = _scanLines[y].Split(SEPARATOR, x + 2, StringSplitOptions.RemoveEmptyEntries)[x];

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

_tempCache[_filename] = _data;
}

public HeightMap GetHeightMap(FileMetadata metadata)
Expand All @@ -72,7 +98,61 @@ public HeightMap GetHeightMap(FileMetadata metadata)

public HeightMap GetHeightMapInBBox(BoundingBox bbox, FileMetadata metadata, float noDataValue = float.MinValue)
{
throw new NotImplementedException();
if (_data == null)
{
ReadAllFile(metadata);
}
int registrationOffset = metadata.FileFormat.Registration == DEMFileRegistrationMode.Grid ? 1 : 0;

int yNorth = (int)Math.Floor((bbox.yMax - metadata.PhysicalEndLat) / metadata.pixelSizeY);
int ySouth = (int)Math.Ceiling((bbox.yMin - metadata.PhysicalEndLat) / metadata.pixelSizeY);
int xWest = (int)Math.Floor((bbox.xMin - metadata.PhysicalStartLon) / metadata.pixelSizeX);
int xEast = (int)Math.Ceiling((bbox.xMax - metadata.PhysicalStartLon) / metadata.pixelSizeX);

xWest = Math.Max(0, xWest);
xEast = Math.Min(metadata.Width - 1 - registrationOffset, xEast);
yNorth = Math.Max(0, yNorth);
ySouth = Math.Min(metadata.Height - 1 - registrationOffset, ySouth);

HeightMap heightMap = new HeightMap(xEast - xWest + 1, ySouth - yNorth + 1);
heightMap.Count = heightMap.Width * heightMap.Height;
var coords = new List<GeoPoint>(heightMap.Count);
heightMap.BoundingBox = new BoundingBox(0, 0, 0, 0);

for (int y = yNorth; y <= ySouth; y++)
{
double latitude = metadata.DataEndLat + (metadata.pixelSizeY * y);

// bounding box
if (y == yNorth)
{
heightMap.BoundingBox.yMax = latitude;
heightMap.BoundingBox.xMin = metadata.DataStartLon + (metadata.pixelSizeX * xWest);
heightMap.BoundingBox.xMax = metadata.DataStartLon + (metadata.pixelSizeX * xEast);
}
if (y == ySouth)
{
heightMap.BoundingBox.yMin = latitude;
}

for (int x = xWest; x <= xEast; x++)
{
double longitude = metadata.DataStartLon + (metadata.pixelSizeX * x);

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

coords.Add(new GeoPoint(latitude, longitude, heightValue));

}
}
heightMap.BoundingBox.zMin = heightMap.Minimum;
heightMap.BoundingBox.zMax = heightMap.Maximum;
Debug.Assert(heightMap.Width * heightMap.Height == coords.Count);

heightMap.Coordinates = coords;
return heightMap;
}

public FileMetadata ParseMetaData(DEMFileDefinition fileFormat)
Expand Down Expand Up @@ -101,8 +181,8 @@ public FileMetadata ParseMetaData(DEMFileDefinition fileFormat)
metadata.Width = ncols;
metadata.PixelScaleX = cellsize;
metadata.PixelScaleY = cellsize;
metadata.pixelSizeX = metadata.PixelScaleX;
metadata.pixelSizeY = metadata.PixelScaleY;
metadata.pixelSizeX = cellsize;
metadata.pixelSizeY = -cellsize;

if (fileFormat.Registration == DEMFileRegistrationMode.Grid)
{
Expand All @@ -115,18 +195,21 @@ public FileMetadata ParseMetaData(DEMFileDefinition fileFormat)
metadata.PhysicalStartLon = xllcorner;
metadata.PhysicalEndLat = metadata.DataEndLat;
metadata.PhysicalEndLon = metadata.DataEndLon;

}
else
{
metadata.DataStartLat = Math.Round(yllcorner + (metadata.PixelScaleY / 2.0), 10);
metadata.DataStartLon = Math.Round(xllcorner + (metadata.PixelScaleX / 2.0), 10);
metadata.DataStartLat = Math.Round(yllcorner + (metadata.pixelSizeY / 2.0), 10);
metadata.DataStartLon = Math.Round(xllcorner - (metadata.PixelScaleX / 2.0), 10);
metadata.DataEndLat = yllcorner + metadata.Height * cellsize;
metadata.DataEndLon = xllcorner + metadata.Width * cellsize;
metadata.DataEndLat = Math.Round(metadata.DataEndLat - (metadata.PixelScaleY / 2.0), 10);
metadata.DataEndLon = Math.Round(metadata.DataEndLon - (metadata.PixelScaleX / 2.0), 10);

metadata.PhysicalStartLat = metadata.DataStartLat;
metadata.PhysicalStartLon = metadata.DataStartLon;
metadata.DataEndLat = yllcorner + metadata.Height * metadata.pixelSizeY;
metadata.DataEndLon = xllcorner + metadata.Width * metadata.pixelSizeX;
metadata.PhysicalEndLat = metadata.DataEndLat;
metadata.PhysicalEndLon = metadata.DataEndLon;
}

metadata.SampleFormat = RasterSampleFormat.FLOATING_POINT;
Expand Down Expand Up @@ -162,8 +245,8 @@ protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_scanLines?.Clear();
_scanLines = null;
//_data?.Clear();
//_data = null;
_streamReader?.Dispose();
_fileStream?.Dispose();
}
Expand Down

0 comments on commit 3be014f

Please sign in to comment.