mirror of
https://github.com/azaion/satellite-provider.git
synced 2026-06-22 21:31:14 +00:00
[AZ-366] Refactor C13: consolidate Haversine + tile-coord parsing
RouteProcessingService.CalculateDistance(double, double, double, double)
re-implemented Haversine using EARTH_RADIUS=6371000 alongside the
canonical GeoUtils.CalculateDistance(GeoPoint, GeoPoint) which uses
EARTH_RADIUS=6378137. Two implementations of the same formula for the
same problem.
Separately, ExtractTileCoordinatesFromFilename in RouteProcessingService
parsed the tile_{z}_{x}_{y}_{ts}.jpg filename pattern that's *generated*
by StorageConfig.GetTileFilePath in another assembly — the writer and
parser were coupled by string convention only and a format change in
one would silently break the other.
Both fixes:
(a) Deleted the duplicate Haversine in RouteProcessingService. The
single call site (region-matching nearest-neighbor OrderBy) now uses
GeoUtils.CalculateDistance with GeoPoint instances. The constant
difference is monotonic-equivalent for OrderBy purposes — same region
is picked.
(b) Added static StorageConfig.TryExtractTileCoordinates(string, out
int, out int): bool — pure parser, co-located with GetTileFilePath so
the inverse-pair invariant is structural, not by-convention.
RouteProcessingService.ExtractTileCoordinatesFromFilename becomes a
thin wrapper that delegates to the helper and emits the existing
warning log on malformed input — the AZ-352 tests for warning behavior
all still pass.
Verification:
- 77/77 unit tests green (was 71 → +6 new StorageConfigTests including
a writer/parser round-trip test for AC-2).
- Smoke + full integration suite green.
- AC-1 grep verification: Math.Sin/EARTH_RADIUS patterns are now
confined to GeoUtils.cs only.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
using FluentAssertions;
|
||||
using SatelliteProvider.Common.Configs;
|
||||
|
||||
namespace SatelliteProvider.Tests;
|
||||
|
||||
public class StorageConfigTests
|
||||
{
|
||||
[Fact]
|
||||
public void TryExtractTileCoordinates_ValidFilename_ReturnsTrue_AZ366()
|
||||
{
|
||||
var ok = StorageConfig.TryExtractTileCoordinates(
|
||||
"/tiles/18/158/90/tile_18_158292_90821_20260510022758.jpg",
|
||||
out var x,
|
||||
out var y);
|
||||
|
||||
ok.Should().BeTrue();
|
||||
x.Should().Be(158292);
|
||||
y.Should().Be(90821);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryExtractTileCoordinates_FilenameWithoutDirectory_ReturnsTrue_AZ366()
|
||||
{
|
||||
var ok = StorageConfig.TryExtractTileCoordinates(
|
||||
"tile_1700000000_42_99.jpg",
|
||||
out var x,
|
||||
out var y);
|
||||
|
||||
ok.Should().BeTrue();
|
||||
x.Should().Be(42);
|
||||
y.Should().Be(99);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryExtractTileCoordinates_NonTilePrefix_ReturnsFalseAndSentinel_AZ366()
|
||||
{
|
||||
var ok = StorageConfig.TryExtractTileCoordinates(
|
||||
"/tmp/not_a_tile_filename.jpg",
|
||||
out var x,
|
||||
out var y);
|
||||
|
||||
ok.Should().BeFalse();
|
||||
x.Should().Be(-1);
|
||||
y.Should().Be(-1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryExtractTileCoordinates_NonNumericCoords_ReturnsFalseAndSentinel_AZ366()
|
||||
{
|
||||
var ok = StorageConfig.TryExtractTileCoordinates(
|
||||
"/tiles/tile_1700000000_alpha_beta.jpg",
|
||||
out var x,
|
||||
out var y);
|
||||
|
||||
ok.Should().BeFalse();
|
||||
x.Should().Be(-1);
|
||||
y.Should().Be(-1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TryExtractTileCoordinates_NullPath_ThrowsArgumentNullException_AZ366()
|
||||
{
|
||||
Action act = () => StorageConfig.TryExtractTileCoordinates(null!, out _, out _);
|
||||
|
||||
act.Should().Throw<ArgumentNullException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetTileFilePath_RoundTrip_ParserRecoversOriginalCoordinates_AZ366_AC2()
|
||||
{
|
||||
// Arrange
|
||||
var config = new StorageConfig();
|
||||
const int zoom = 18;
|
||||
const int writtenX = 158_292;
|
||||
const int writtenY = 90_821;
|
||||
|
||||
// Act
|
||||
var path = config.GetTileFilePath(zoom, writtenX, writtenY, "20260510022758");
|
||||
var ok = StorageConfig.TryExtractTileCoordinates(path, out var parsedX, out var parsedY);
|
||||
|
||||
// Assert
|
||||
ok.Should().BeTrue();
|
||||
parsedX.Should().Be(writtenX, "writer-parser pair must be inverse — same module per AZ-366 AC-2");
|
||||
parsedY.Should().Be(writtenY);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user