MEGAINFRA-WEBAPP/scripts/site-model/test_alignment.py

52 lines
1.9 KiB
Python

import importlib.util
import unittest
from pathlib import Path
import numpy as np
spec = importlib.util.spec_from_file_location("alignment", Path(__file__).with_name("alignment.py"))
alignment = importlib.util.module_from_spec(spec)
spec.loader.exec_module(alignment)
def straight(ch):
"""Alignment along +e from (0, 0); chainage == e."""
return np.array([float(ch), 0.0]), np.array([1.0, 0.0])
def area(ring):
a = 0.0
for i in range(len(ring)):
x1, y1 = ring[i]; x2, y2 = ring[(i + 1) % len(ring)]
a += x1 * y2 - x2 * y1
return abs(a) / 2
class AlignmentTests(unittest.TestCase):
def test_band_key(self):
self.assertEqual(alignment.band_key(240, 260), "ch240-260")
def test_bands_cover_range_in_20m_steps(self):
self.assertEqual(alignment.bands(235.0, 281.0), [(220, 240), (240, 260), (260, 280), (280, 300)])
def test_clip_square_into_bands(self):
ring = [(0, -5), (50, -5), (50, 5), (0, 5)] # 50 m long, 10 m wide
parts = [alignment.clip_ring_to_band(ring, straight, lo, hi, lo == 0, hi == 60)
for lo, hi in [(0, 20), (20, 40), (40, 60)]]
self.assertAlmostEqual(area(parts[0]), 200)
self.assertAlmostEqual(area(parts[1]), 200)
self.assertAlmostEqual(area(parts[2]), 100)
def test_first_band_keeps_area_before_alignment_start(self):
ring = [(-10, -5), (10, -5), (10, 5), (-10, 5)]
part = alignment.clip_ring_to_band(ring, straight, 0, 20, True, False)
self.assertAlmostEqual(area(part), 200) # nothing lost before ch 0
def test_last_band_keeps_area_after_alignment_end(self):
ring = [(30, -5), (70, -5), (70, 5), (30, 5)]
part = alignment.clip_ring_to_band(ring, straight, 20, 40, False, True)
self.assertAlmostEqual(area(part), 400) # 30..70 all kept
if __name__ == "__main__":
unittest.main()