public void NextInsideBoxTest() { Assert.Equal(27UL, ZCurve.NextInsideBox(0, 27, 102)); Assert.Equal(74UL, ZCurve.NextInsideBox(58, 27, 102)); Assert.Equal(74UL, ZCurve.NextInsideBox(67, 27, 102)); Assert.Equal(96UL, ZCurve.NextInsideBox(79, 27, 102)); Assert.Equal(74UL, ZCurve.NextInsideBox(61, 27, 102)); // What if z is within box(qlo,qhi)? Drill down, cutting // off parts of the box, until a single cell remains. Assert.Equal(6UL, ZCurve.NextInsideBox(3, 3, 49)); Assert.Equal(11UL, ZCurve.NextInsideBox(9, 3, 49)); Assert.Equal(14UL, ZCurve.NextInsideBox(13, 3, 49)); Assert.Equal(19UL, ZCurve.NextInsideBox(18, 3, 49)); Assert.Equal(49UL, ZCurve.NextInsideBox(48, 3, 49)); Assert.Equal(0UL, ZCurve.NextInsideBox(49, 3, 49)); Assert.Equal(0UL, ZCurve.NextInsideBox(54, 54, 54)); // What if z > qhi? Only keys 000 or 100 or 101 can occur, // drilling down (possibly cutting off lower parts of the // query box) until the box is below and z is above the // dividing line (key 100) and we return the result so far, // which is zero (result's initial value). Assert.Equal(0UL, ZCurve.NextInsideBox(50, 3, 49, 5)); // x within, y beyond Assert.Equal(0UL, ZCurve.NextInsideBox(51, 3, 49, 5)); // x within, y beyond Assert.Equal(0UL, ZCurve.NextInsideBox(52, 3, 49, 5)); // x beyond, y within Assert.Equal(0UL, ZCurve.NextInsideBox(53, 3, 49, 5)); // x beyond, y within Assert.Equal(0UL, ZCurve.NextInsideBox(54, 3, 49, 5)); // both x and y beyond // Enumerate cells within query box qlo..qhi: var result = new List <ulong>(); var expected = new ulong[] { 3, 6, 7, 9, 11, 12, 13, 14, 15, 18, 19, 24, 25, 26, 27, 33, 36, 37, 48, 49 }; ulong qlo = ZCurve.Encode(1U, 1U); // 3 ulong qhi = ZCurve.Encode(5U, 4U); // 49 ulong cur = qlo; while (true) { result.Add(cur); cur += 1; if (cur > qhi) { break; } const int starti = 5; if (!ZCurve.IsInsideBox(cur, qlo, qhi)) { cur = ZCurve.NextInsideBox(cur, qlo, qhi, starti); } } Assert.Equal(expected, result); }
public void IsInsideBoxTest() { ulong min = ZCurve.Encode(1U, 1U); // 3 ulong max = ZCurve.Encode(5U, 4U); // 49 Assert.False(ZCurve.IsInsideBox(0, min, max)); Assert.True(ZCurve.IsInsideBox(3, min, max)); Assert.True(ZCurve.IsInsideBox(19, min, max)); Assert.False(ZCurve.IsInsideBox(20, min, max)); Assert.False(ZCurve.IsInsideBox(8, min, max)); Assert.True(ZCurve.IsInsideBox(15, min, max)); Assert.True(ZCurve.IsInsideBox(49, min, max)); Assert.False(ZCurve.IsInsideBox(50, min, max)); min = ZCurve.Encode(int.MaxValue - 1, int.MaxValue - 1); max = ZCurve.Encode(int.MaxValue, int.MaxValue); Assert.False(ZCurve.IsInsideBox(ZCurve.Encode(int.MaxValue - 2, int.MaxValue - 2), min, max)); Assert.True(ZCurve.IsInsideBox(ZCurve.Encode(int.MaxValue - 1, int.MaxValue - 1), min, max)); Assert.True(ZCurve.IsInsideBox(ZCurve.Encode(int.MaxValue, int.MaxValue), min, max)); Assert.False(ZCurve.IsInsideBox(ZCurve.Encode(1U + int.MaxValue, 1U + int.MaxValue), min, max)); }
public void QueryBlocksTrial() { // Expect shortest ordered sequence of blocks covering query box // Query box: ulong qlo = ZCurve.Encode(1U, 1U); // 3 ulong qhi = ZCurve.Encode(5U, 4U); // 49 // Expected result: 3 6 7 9 11 (12..15) 18 19 (24..27) 33 36 37 48 49 var starts = new ulong[] { 3, 6, 7, 9, 11, 12, 18, 19, 24, 33, 36, 37, 48, 49 }; var levels = new[] { 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0 }; var expected = starts.Zip(levels, (s, l) => new ZCurve.Block(s, l)).ToList(); var actual = new List <ZCurve.Block>(); ulong first = ZCurve.FirstInBlock(qlo, 0); ulong last = ZCurve.FirstInBlock(qhi, 0); for (ulong cursor = first; ;) { int level = ZCurve.LargestLevel(cursor, last); ulong increment = ZCurve.CellsPerBlock(level); actual.Add(new ZCurve.Block(cursor, level)); cursor += increment; if (cursor > last) { break; } if (!ZCurve.IsInsideBox(cursor, first, last)) { cursor = ZCurve.NextInsideBox(cursor, first, last); } } Assert.Equal(expected, actual); }