# Integration Test: Coordinate Transformer

## Summary
Validate the Coordinate Transformer component for accurate conversion between GPS coordinates (WGS84), Web Mercator projections (EPSG:3857), and pixel coordinates in satellite tiles.

## Component Under Test
**Component**: Coordinate Transformer
**Location**: `gps_denied_12_coordinate_transformer`
**Dependencies**:
- Python libraries: pyproj or similar
- Mathematical projection formulas
- None (standalone utility component)

## Detailed Description
This test validates that the Coordinate Transformer can:
1. Convert GPS coordinates (lat/lon) to Web Mercator (x/y meters)
2. Convert Web Mercator to GPS coordinates (inverse projection)
3. Calculate pixel coordinates within satellite tiles at various zoom levels
4. Compute meters-per-pixel (GSD) accurately for different latitudes
5. Handle edge cases (poles, dateline, etc.)
6. Maintain numerical precision to avoid GPS drift errors
7. Calculate haversine distances between GPS points

This component is critical for georeferencing satellite tiles and converting between different coordinate systems used throughout ASTRAL-Next.

## Input Data

### Test Case 1: GPS to Mercator Conversion
- **Input GPS**: 48.275292, 37.385220 (AD000001)
- **Expected Mercator**: Calculated using Web Mercator formula
- **Validation**: Inverse conversion should return original GPS

### Test Case 2: Mercator to GPS Conversion
- **Input Mercator**: Result from Test Case 1
- **Expected GPS**: 48.275292, 37.385220
- **Tolerance**: < 0.000001° (≈0.1m)

### Test Case 3: Meters-Per-Pixel Calculation
- **Inputs**: Various latitudes and zoom levels
  - Lat 48°N, Zoom 19: Expected ~0.30 m/px
  - Lat 48°N, Zoom 18: Expected ~0.60 m/px
  - Lat 48°N, Zoom 17: Expected ~1.20 m/px
  - Lat 0° (Equator), Zoom 19: Expected 0.298 m/px
- **Formula**: `156543.03392 * cos(lat * π/180) / 2^zoom`

### Test Case 4: Pixel to GPS Conversion
- **Satellite Tile**: Center at 48.260117, 37.353469, Zoom 19, Size 640x640
- **Pixel Coordinate**: (320, 320) - center pixel
- **Expected GPS**: 48.260117, 37.353469
- **Tolerance**: < 0.00001° (≈1m)

### Test Case 5: GPS to Pixel Conversion
- **Satellite Tile**: Same as Test Case 4
- **Input GPS**: 48.260117, 37.353469
- **Expected Pixel**: (320, 320)
- **Tolerance**: < 1 pixel

### Test Case 6: Haversine Distance Calculation
- **Point A**: 48.275292, 37.385220 (AD000001)
- **Point B**: 48.275001, 37.382922 (AD000002)
- **Expected Distance**: ~150-200m (verified by external tool)
- **Tolerance**: < 1m

### Test Case 7: Boundary Calculations
- **Center GPS**: 48.256246, 37.357485 (AD000060)
- **Tile Size**: 640x640 pixels, Zoom 19
- **Calculate**: NW and SE corner coordinates
- **Validation**: Center should be equidistant from corners

### Test Case 8: Precision Test
- **Round Trip**: GPS → Mercator → Pixel → GPS
- **Input**: All 60 test images GPS coordinates
- **Expected**: Final GPS within 0.1m of original

## Expected Output

For each test case:
```json
{
  "test_case": "GPS_to_Mercator",
  "input": {"lat": 48.275292, "lon": 37.385220},
  "output": {"x_meters": <float>, "y_meters": <float>},
  "expected": {"x_meters": <float>, "y_meters": <float>},
  "error": <float>,
  "success": true/false,
  "processing_time_us": <float>
}
```

## Success Criteria

**Test Case 1 (GPS to Mercator)**:
- Conversion completes without error
- Output values are finite and reasonable
- processing_time_us < 100

**Test Case 2 (Mercator to GPS)**:
- Round-trip error < 0.000001° (≈0.1m)
- success = true

**Test Case 3 (Meters-Per-Pixel)**:
- All calculated m/px within 1% of expected values
- Correct relationship: m/px doubles when zoom decreases by 1

**Test Case 4 (Pixel to GPS)**:
- Error < 0.00001° (≈1m at 48°N)
- Center pixel correctly maps to center GPS

**Test Case 5 (GPS to Pixel)**:
- Pixel coordinate error < 1.0 pixel
- Result is within tile bounds (0-640)

**Test Case 6 (Haversine)**:
- Distance calculation error < 1m
- Consistent with external validation

**Test Case 7 (Boundaries)**:
- NW corner has smaller lat/lon than center
- SE corner has larger lat/lon than center
- Distances from center to corners are equal (within 1%)

**Test Case 8 (Precision)**:
- All 60 coordinates survive round-trip with < 0.1m error
- No accumulation of errors

## Maximum Expected Time
- **Per conversion**: < 100 microseconds
- **Haversine distance**: < 50 microseconds
- **Complex transformation chain**: < 500 microseconds
- **Total test suite**: < 1 second

## Test Execution Steps

1. **Setup Phase**:
   a. Initialize Coordinate Transformer
   b. Load test GPS coordinates from coordinates.csv
   c. Pre-calculate expected values for validation

2. **Test Case 1 - GPS to Mercator**:
   a. Convert test GPS coordinates to Mercator
   b. Verify output is reasonable
   c. Store for inverse test

3. **Test Case 2 - Mercator to GPS**:
   a. Take output from Test Case 1
   b. Convert back to GPS
   c. Compare with original input
   d. Calculate round-trip error

4. **Test Case 3 - Meters-Per-Pixel**:
   a. Calculate m/px for various lat/zoom combinations
   b. Compare with expected formula results
   c. Verify zoom level relationships

5. **Test Case 4 & 5 - Pixel Conversions**:
   a. Set up test satellite tile parameters
   b. Convert between pixel and GPS coordinates
   c. Validate both directions

6. **Test Case 6 - Haversine**:
   a. Calculate distances between all consecutive image pairs
   b. Verify distance statistics (mean ~120m)
   c. Check specific known distances

7. **Test Case 7 - Boundaries**:
   a. Calculate tile boundaries for test locations
   b. Verify geometric consistency
   c. Check corner relationships

8. **Test Case 8 - Precision**:
   a. Run all 60 test coordinates through full transformation chain
   b. Measure accumulated errors
   c. Verify no systematic bias

## Pass/Fail Criteria

**Overall Test Passes If**:
- All 8 test cases meet their success criteria
- No numerical errors (NaN, Inf)
- Performance meets timing constraints
- Round-trip precision < 0.1m for all test cases
- No memory leaks

**Test Fails If**:
- Any round-trip error > 1m
- Meters-per-pixel calculation error > 5%
- Haversine distance error > 10m
- Any conversion produces NaN or Inf
- Performance degrades over repeated calls

## Additional Validation

**Edge Cases**:
1. **North Pole** (lat = 90°): Should handle or reject gracefully
2. **South Pole** (lat = -90°): Should handle or reject gracefully
3. **Dateline Crossing** (lon ≈ ±180°): Should handle correctly
4. **Prime Meridian** (lon = 0°): Should work normally
5. **Equator** (lat = 0°): Should calculate m/px correctly

**Numerical Stability**:
- Test with very small angles (< 0.0001°)
- Test with coordinates close to each other (< 1m apart)
- Test with maximum zoom level (23)
- Test with minimum zoom level (0)

**Consistency Checks**:
- Distance from A to B equals distance from B to A
- Triangle inequality: dist(A,C) ≤ dist(A,B) + dist(B,C)
- Midpoint calculation: dist(A,mid) = dist(mid,B) = dist(A,B)/2

**Performance Benchmarks**:
- 10,000 GPS to Mercator conversions in < 1 second
- 10,000 Haversine distance calculations in < 500ms
- No performance degradation over 1,000,000 calls

## Reference Values

For validation, pre-calculated values:

**Reference Point 1** (AD000001):
- GPS: 48.275292°N, 37.385220°E
- Web Mercator X: ~4,161,880 meters
- Web Mercator Y: ~6,125,450 meters

**Reference Point 2** (AD000030):
- GPS: 48.259677°N, 37.352165°E
- Distance from Point 1: ~2,865 meters (haversine)

**Meters-per-pixel at 48°N**:
- Zoom 17: ~1.195 m/px
- Zoom 18: ~0.597 m/px
- Zoom 19: ~0.299 m/px
- Zoom 20: ~0.149 m/px

## Error Analysis

If test fails, analyze:
- Which conversion direction has larger errors
- Whether errors accumulate in round-trips
- If errors are latitude-dependent
- Whether zoom level affects accuracy
- If there's systematic bias (always over/under)

