Skip to content

Commit f88c844

Browse files
Some refactoring (#1767)
2 parents 8900275 + 3114fd4 commit f88c844

File tree

15 files changed

+107
-87
lines changed

15 files changed

+107
-87
lines changed

src/api/BoreholeGeometry/AzIncFormat.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ internal sealed class AzIncFormat : IBoreholeGeometryFormat
1414

1515
public string Name => "Azimuth Inclination";
1616

17-
private Lazy<string> expectedCsvHeader = new(Helper.GetCSVHeader<Geometry>);
17+
private Lazy<string> expectedCsvHeader = new(CsvConfigHelper.GetCsvHeader<Geometry>);
1818

1919
public string CsvHeader => expectedCsvHeader.Value;
2020

2121
public IList<BoreholeGeometryElement> ReadCsv(IFormFile file, int boreholeId)
2222
{
2323
using var reader = new StreamReader(file.OpenReadStream());
24-
using var csv = new CsvReader(reader, Helper.CsvConfig);
24+
using var csv = new CsvReader(reader, CsvConfigHelper.CsvConfig);
2525

2626
var data = csv.GetRecords<Geometry>().ToList();
2727

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using BDMS.Models;
2+
using CsvHelper;
3+
using CsvHelper.Configuration;
4+
using Humanizer;
5+
using NetTopologySuite.Mathematics;
6+
using NetTopologySuite.Utilities;
7+
using System.Globalization;
8+
9+
namespace BDMS.BoreholeGeometry;
10+
11+
public static class CsvConfigHelper
12+
{
13+
internal static readonly CsvConfiguration CsvConfig = new(new CultureInfo("de-CH"))
14+
{
15+
Delimiter = ";",
16+
IgnoreReferences = true,
17+
PrepareHeaderForMatch = args => args.Header.Humanize(LetterCasing.Title),
18+
MissingFieldFound = null,
19+
};
20+
21+
/// <summary>
22+
/// Get the CSV header <see cref="CsvHelper"/> for a class of type <typeparamref name="T"/>.
23+
/// Uses the map generated by <see cref="CsvHelper.CsvContext.AutoMap{T}()"/>.
24+
/// If a property has multiple possible column names only the first is considered.
25+
/// </summary>
26+
/// <typeparam name="T">The class to get the header for.</typeparam>
27+
internal static string GetCsvHeader<T>()
28+
{
29+
var context = new CsvContext(CsvConfig);
30+
var map = context.AutoMap<T>();
31+
return string.Join("; ", map.MemberMaps
32+
.Select(m =>
33+
{
34+
var name = m.Data.Names.FirstOrDefault(m.Data.Member.Name);
35+
return m.Data.IsOptional ? $"[{name}]" : name;
36+
}));
37+
}
38+
}

src/api/BoreholeGeometry/PitchRollFormat.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ internal sealed class PitchRollFormat : IBoreholeGeometryFormat
1414

1515
public string Name => "Pitch Roll";
1616

17-
private Lazy<string> expectedCsvHeader = new(Helper.GetCSVHeader<Geometry>);
17+
private Lazy<string> expectedCsvHeader = new(CsvConfigHelper.GetCsvHeader<Geometry>);
1818

1919
public string CsvHeader => expectedCsvHeader.Value;
2020

2121
public IList<BoreholeGeometryElement> ReadCsv(IFormFile file, int boreholeId)
2222
{
2323
using var reader = new StreamReader(file.OpenReadStream());
24-
using var csv = new CsvReader(reader, Helper.CsvConfig);
24+
using var csv = new CsvReader(reader, CsvConfigHelper.CsvConfig);
2525

2626
var data = csv.GetRecords<Geometry>().ToList();
2727

src/api/BoreholeGeometry/XYZFormat.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@ internal sealed class XYZFormat : IBoreholeGeometryFormat
1313

1414
public string Name => "X Y Z";
1515

16-
private Lazy<string> expectedCsvHeader = new(Helper.GetCSVHeader<Geometry>);
16+
private Lazy<string> expectedCsvHeader = new(CsvConfigHelper.GetCsvHeader<Geometry>);
1717

1818
public string CsvHeader => expectedCsvHeader.Value;
1919

2020
public IList<BoreholeGeometryElement> ReadCsv(IFormFile file, int boreholeId)
2121
{
2222
using var reader = new StreamReader(file.OpenReadStream());
23-
using var csv = new CsvReader(reader, Helper.CsvConfig);
23+
using var csv = new CsvReader(reader, CsvConfigHelper.CsvConfig);
2424

2525
var data = csv.GetRecords<Geometry>();
2626
return ToBoreholeGeometry(data, boreholeId);

src/api/BoreholeGeometry/Helper.cs renamed to src/api/BoreholeGeometryExtensions.cs

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,41 @@
11
using BDMS.Models;
2-
using CsvHelper;
3-
using CsvHelper.Configuration;
4-
using Humanizer;
52
using NetTopologySuite.Mathematics;
63
using NetTopologySuite.Utilities;
7-
using System.Globalization;
84

9-
namespace BDMS.BoreholeGeometry;
5+
namespace BDMS;
106

11-
public static class Helper
7+
public static class BoreholeGeometryExtensions
128
{
13-
internal static readonly CsvConfiguration CsvConfig = new(new CultureInfo("de-CH"))
14-
{
15-
Delimiter = ";",
16-
IgnoreReferences = true,
17-
PrepareHeaderForMatch = args => args.Header.Humanize(LetterCasing.Title),
18-
MissingFieldFound = null,
19-
};
20-
219
/// <summary>
22-
/// Get the CSV header <see cref="CsvHelper"/> expects to read a class <typeparamref name="T"/>.
23-
/// Uses the map generated by <see cref="CsvHelper.CsvContext.AutoMap{T}()"/>.
24-
/// If a property has multiple possible column names only the first is considered.
10+
/// Get the TVD of <paramref name="depthMD"/> according to the <paramref name="geometry"/> if the geometry exists.
2511
/// </summary>
26-
/// <typeparam name="T">The class to get the header for.</typeparam>
27-
internal static string GetCSVHeader<T>()
12+
/// <param name="geometry">The list of <see cref="BoreholeGeometryElement"/> representing the borehole's path geometry.</param>
13+
/// <param name="depthMD">The measured depth (MD) at which to calculate the TVD.</param>
14+
/// <returns>The TVD at <paramref name="depthMD"/> if the geometry exists; otherwise <see langword="null"/>.</returns>
15+
internal static double? GetTVDIfGeometryExists(this List<BoreholeGeometryElement> geometry, double? depthMD)
2816
{
29-
var context = new CsvContext(CsvConfig);
30-
var map = context.AutoMap<T>();
31-
return string.Join("; ", map.MemberMaps
32-
.Select(m =>
17+
if (geometry == null || geometry.Count < 2)
18+
{
19+
if (depthMD != null && depthMD >= 0)
3320
{
34-
var name = m.Data.Names.FirstOrDefault(m.Data.Member.Name);
35-
return m.Data.IsOptional ? $"[{name}]" : name;
36-
}));
37-
}
21+
// Return the depthMD unchanged as if the borehole is perfectly vertical and infinitely long.
22+
return depthMD;
23+
}
24+
}
25+
else if (depthMD != null)
26+
{
27+
try
28+
{
29+
return geometry.GetDepthTVD(depthMD.Value);
30+
}
31+
catch (ArgumentOutOfRangeException)
32+
{
33+
// Exception is ignored so that the method returns null in case the input was invalid.
34+
}
35+
}
3836

39-
private static readonly IComparer<BoreholeGeometryElement> geometryMDComparer = Comparer<BoreholeGeometryElement>.Create((a, b) => a.MD.CompareTo(b.MD));
37+
return null;
38+
}
4039

4140
/// <summary>
4241
/// Get the TVD of <paramref name="depthMD"/> according to the <paramref name="geometry"/>.
@@ -130,6 +129,8 @@ private static double InterpolateDepthTVD(List<BoreholeGeometryElement> geometry
130129
}
131130
}
132131

132+
private static readonly IComparer<BoreholeGeometryElement> geometryMDComparer = Comparer<BoreholeGeometryElement>.Create((a, b) => a.MD.CompareTo(b.MD));
133+
133134
internal static Vector3D ToVector3D(this BoreholeGeometryElement element)
134135
=> new Vector3D(element.X, element.Y, element.Z);
135136

src/api/Controllers/BoreholeGeometryController.cs

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -118,28 +118,13 @@ public async Task<IActionResult> GetDepthTVD([FromQuery] int boreholeId, [FromQu
118118
{
119119
var geometry = await GetBoreholeGeometry(boreholeId).ConfigureAwait(false);
120120

121-
if (geometry.Count < 2)
121+
var tvd = geometry.GetTVDIfGeometryExists(depthMD);
122+
if (tvd == null)
122123
{
123-
if (depthMD >= 0)
124-
{
125-
// Return the depthMD unchanged as if the borehole is perfectly vertical and infinitely long.
126-
return Ok(depthMD);
127-
}
128-
}
129-
else
130-
{
131-
try
132-
{
133-
return Ok(geometry.GetDepthTVD(depthMD));
134-
}
135-
catch (ArgumentOutOfRangeException)
136-
{
137-
// Exception is ignored so that the action returns an empty response in case the input was invalid.
138-
}
124+
logger?.LogInformation($"Invalid input, could not calculate true vertical depth from measured depth of {depthMD}");
139125
}
140126

141-
logger?.LogInformation($"Invalid input, could not calculate true vertical depth from measured depth of {depthMD}");
142-
return Ok();
127+
return Ok(tvd);
143128
}
144129

145130
private async Task<List<BoreholeGeometryElement>> GetBoreholeGeometry(int boreholeId)

src/api/Controllers/UploadController.cs renamed to src/api/Controllers/ImportController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace BDMS.Controllers;
1414

1515
[ApiController]
1616
[Route("api/v{version:apiVersion}/[controller]")]
17-
public class UploadController : ControllerBase
17+
public class ImportController : ControllerBase
1818
{
1919
private const int MaxFileSize = 210_000_000; // 1024 x 1024 x 200 = 209715200 bytes
2020
private readonly BdmsContext context;
@@ -35,7 +35,7 @@ public class UploadController : ControllerBase
3535

3636
private static readonly JsonSerializerOptions jsonImportOptions = new() { PropertyNameCaseInsensitive = true };
3737

38-
public UploadController(BdmsContext context, ILogger<UploadController> logger, LocationService locationService, CoordinateService coordinateService, BoreholeFileCloudService boreholeFileCloudService)
38+
public ImportController(BdmsContext context, ILogger<ImportController> logger, LocationService locationService, CoordinateService coordinateService, BoreholeFileCloudService boreholeFileCloudService)
3939
{
4040
this.context = context;
4141
this.logger = logger;

src/client/cypress/e2e/helpers/testHelpers.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ export const interceptApiCalls = () => {
109109
cy.intercept("dataextraction/api/V1/extract_data").as("extract-data");
110110

111111
cy.intercept("https://api3.geo.admin.ch/rest/services/height*").as("height");
112+
113+
cy.intercept("/api/v2/import*").as("borehole-upload");
112114
};
113115

114116
/**

src/client/cypress/e2e/mainPage/import.cy.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ describe("Test for importing boreholes.", () => {
4242
});
4343
});
4444

45-
// Intercept upload request
46-
cy.intercept("/api/v2/upload?workgroupId=1").as("borehole-upload");
47-
4845
// Import boreholes and attachments
4946
cy.get('[data-cy="import-button"]').click();
5047
cy.wait("@borehole-upload");
@@ -75,9 +72,6 @@ describe("Test for importing boreholes.", () => {
7572
});
7673
});
7774
});
78-
79-
cy.intercept("/api/v2/upload?workgroupId=1").as("borehole-upload");
80-
8175
cy.get('[data-cy="import-button"]').click();
8276

8377
cy.wait("@borehole-upload");

src/client/cypress/fixtures/import/boreholes-missing-fields-and-duplicates.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
alternate_name;original_name;location_x;location_y
1+
name;original_name;location_x;location_y
22
BH-1001;Wellington 1;
33
BH-1002;Wellington 2;
44
BH-1003;Wellington 3;2189456;1334567

0 commit comments

Comments
 (0)