1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.rugged.intersection.duvenhage;
18
19 import org.hipparchus.random.RandomGenerator;
20 import org.hipparchus.random.Well1024a;
21 import org.hipparchus.util.FastMath;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.lang.reflect.Field;
26
27 import org.junit.jupiter.api.Assertions;
28 import org.junit.jupiter.api.Test;
29 import org.junit.jupiter.api.io.TempDir;
30
31 public class MinMaxTreeTileTest {
32
33 @Test
34 public void testSizeTall()
35 throws SecurityException, NoSuchFieldException,
36 IllegalArgumentException, IllegalAccessException {
37 MinMaxTreeTile tile = createTile(107, 19);
38 Assertions.assertEquals(9, tile.getLevels());
39
40 Field startField = MinMaxTreeTile.class.getDeclaredField("start");
41 startField.setAccessible(true);
42 int[] start = (int[]) startField.get(tile);
43 Assertions.assertEquals( 0, start[ 0]);
44 Assertions.assertEquals( 7, start[ 1]);
45 Assertions.assertEquals( 21, start[ 2]);
46 Assertions.assertEquals( 49, start[ 3]);
47 Assertions.assertEquals( 91, start[ 4]);
48 Assertions.assertEquals( 172, start[ 5]);
49 Assertions.assertEquals( 307, start[ 6]);
50 Assertions.assertEquals( 577, start[ 7]);
51 Assertions.assertEquals(1117, start[ 8]);
52
53 Assertions.assertTrue(tile.isColumnMerging(9));
54 Assertions.assertFalse(tile.isColumnMerging(8));
55 Assertions.assertTrue(tile.isColumnMerging(7));
56 Assertions.assertFalse(tile.isColumnMerging(6));
57 Assertions.assertTrue(tile.isColumnMerging(5));
58 Assertions.assertFalse(tile.isColumnMerging(4));
59 Assertions.assertTrue(tile.isColumnMerging(3));
60 Assertions.assertFalse(tile.isColumnMerging(2));
61 Assertions.assertTrue(tile.isColumnMerging(1));
62
63 Field minTreeField = MinMaxTreeTile.class.getDeclaredField("minTree");
64 minTreeField.setAccessible(true);
65 Assertions.assertEquals(2187, ((double[]) minTreeField.get(tile)).length);
66 Field maxTreeField = MinMaxTreeTile.class.getDeclaredField("maxTree");
67 maxTreeField.setAccessible(true);
68 Assertions.assertEquals(2187, ((double[]) maxTreeField.get(tile)).length);
69
70 }
71
72 @Test
73 public void testSizeFat()
74 throws SecurityException, NoSuchFieldException,
75 IllegalArgumentException, IllegalAccessException {
76 MinMaxTreeTile tile = createTile(4, 7);
77 Assertions.assertEquals(4, tile.getLevels());
78
79 Field startField = MinMaxTreeTile.class.getDeclaredField("start");
80 startField.setAccessible(true);
81 int[] start = (int[]) startField.get(tile);
82 Assertions.assertEquals( 0, start[ 0]);
83 Assertions.assertEquals( 2, start[ 1]);
84 Assertions.assertEquals( 6, start[ 2]);
85 Assertions.assertEquals(14, start[ 3]);
86
87 Assertions.assertTrue(tile.isColumnMerging(4));
88 Assertions.assertFalse(tile.isColumnMerging(3));
89 Assertions.assertTrue(tile.isColumnMerging(2));
90 Assertions.assertFalse(tile.isColumnMerging(1));
91
92 Field minTreeField = MinMaxTreeTile.class.getDeclaredField("minTree");
93 minTreeField.setAccessible(true);
94 Assertions.assertEquals(30, ((double[]) minTreeField.get(tile)).length);
95 Field maxTreeField = MinMaxTreeTile.class.getDeclaredField("maxTree");
96 maxTreeField.setAccessible(true);
97 Assertions.assertEquals(30, ((double[]) maxTreeField.get(tile)).length);
98
99 }
100
101 @Test
102 public void testSinglePixel() {
103 Assertions.assertEquals(0, createTile(1, 1).getLevels());
104 }
105
106 @Test
107 public void testMinMax() {
108 for (int nbRows = 1; nbRows < 25; nbRows++) {
109 for (int nbColumns = 1; nbColumns < 25; nbColumns++) {
110
111 MinMaxTreeTile tile = createTile(nbRows, nbColumns);
112
113 for (int level = 0; level < tile.getLevels(); level++) {
114 for (int row = 0; row < nbRows; row++) {
115 for (int column = 0; column < nbColumns; column++) {
116
117
118 int[] neighbors = neighbors(row, column, nbRows, nbColumns, tile.getLevels() - level);
119 double min = Double.POSITIVE_INFINITY;
120 double max = Double.NEGATIVE_INFINITY;
121 for (int i = neighbors[0]; i < FastMath.min(neighbors[1] + 1, nbRows); ++i) {
122 for (int j = neighbors[2]; j < FastMath.min(neighbors[3] + 1, nbColumns); ++j) {
123 double cellValue = tile.getElevationAtIndices(i, j);
124 min = FastMath.min(min, cellValue);
125 max = FastMath.max(max, cellValue);
126 }
127 }
128
129 Assertions.assertEquals(min, tile.getMinElevation(row, column, level), 1.0e-10 * min);
130 Assertions.assertEquals(max, tile.getMaxElevation(row, column, level), 1.0e-10 * max);
131 }
132 }
133 }
134 }
135 }
136 }
137
138 @Test
139 public void testLocateMinMax() {
140 RandomGenerator random = new Well1024a(0xca9883209c6e740cl);
141 for (int nbRows = 1; nbRows < 25; nbRows++) {
142 for (int nbColumns = 1; nbColumns < 25; nbColumns++) {
143
144 MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
145 tile.setGeometry(1.0, 2.0, 0.1, 0.2, nbRows, nbColumns);
146 for (int i = 0; i < nbRows; ++i) {
147 for (int j = 0; j < nbColumns; ++j) {
148 final double e = 1000.0 * random.nextDouble();
149 tile.setElevation(i, j, e);
150 }
151 }
152 tile.tileUpdateCompleted();
153
154 for (int i = 0; i < tile.getLatitudeRows(); ++i) {
155 for (int j = 0; j < tile.getLongitudeColumns(); ++j) {
156 for (int l = 0; l < tile.getLevels(); ++l) {
157 int[] min = tile.locateMin(i, j, l);
158 Assertions.assertEquals(tile.getMinElevation(i, j, l),
159 tile.getElevationAtIndices(min[0], min[1]),
160 1.0e-10);
161 int[] max = tile.locateMax(i, j, l);
162 Assertions.assertEquals(tile.getMaxElevation(i, j, l),
163 tile.getElevationAtIndices(max[0], max[1]),
164 1.0e-10);
165 }
166 }
167 }
168 }
169 }
170 }
171
172 @Test
173 public void testIssue189() {
174 MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
175 tile.setGeometry(1.0, 2.0, 0.1, 0.2, 2, 2);
176 tile.setElevation(0, 0, 1.0);
177 tile.setElevation(0, 1, 2.0);
178 tile.setElevation(1, 0, 3.0);
179 tile.setElevation(1, 1, 4.0);
180 tile.tileUpdateCompleted();
181 Assertions.assertEquals(1.0, tile.getMinElevation(0, 0, 0), 1.0e-10);
182 Assertions.assertEquals(3.0, tile.getMinElevation(1, 0, 0), 1.0e-10);
183 Assertions.assertEquals(4.0, tile.getMaxElevation(0, 0, 0), 1.0e-10);
184 Assertions.assertEquals(4.0, tile.getMaxElevation(1, 0, 0), 1.0e-10);
185 }
186
187 @Test
188 public void testMergeLarge() {
189 MinMaxTreeTile tile = createTile(1201, 1201);
190 Assertions.assertEquals(21, tile.getLevels());
191 Assertions.assertEquals( 7, tile.getMergeLevel(703, 97, 765, 59));
192 }
193
194 @Test
195 public void testMergeLevel() {
196 for (int nbRows = 1; nbRows < 20; nbRows++) {
197 for (int nbColumns = 1; nbColumns < 20; nbColumns++) {
198
199 MinMaxTreeTile tile = createTile(nbRows, nbColumns);
200
201 for (int i1 = 0; i1 < nbRows; i1++) {
202 for (int j1 = 0; j1 < nbColumns; j1++) {
203 for (int i2 = 0; i2 < nbRows; i2++) {
204 for (int j2 = 0; j2 < nbColumns; j2++) {
205
206 int level = tile.getMergeLevel(i1, j1, i2, j2);
207 if (level > 0) {
208 int[] neighbors1 = neighbors(i1, j1, nbRows, nbColumns, tile.getLevels() - level);
209 int[] neighbors2 = neighbors(i2, j2, nbRows, nbColumns, tile.getLevels() - level);
210 for (int k = 0; k < neighbors1.length; ++k) {
211 Assertions.assertTrue(neighbors1[0] == neighbors2[0] &&
212 neighbors1[1] == neighbors2[1] &&
213 neighbors1[2] == neighbors2[2] &&
214 neighbors1[3] == neighbors2[3]);
215 }
216 }
217 if (level + 1 < tile.getLevels()) {
218 int[] neighbors1 = neighbors(i1, j1, nbRows, nbColumns, tile.getLevels() - (level + 1));
219 int[] neighbors2 = neighbors(i2, j2, nbRows, nbColumns, tile.getLevels() - (level + 1));
220 for (int k = 0; k < neighbors1.length; ++k) {
221 if ((neighbors1[0] == neighbors2[0] &&
222 neighbors1[1] == neighbors2[1] &&
223 neighbors1[2] == neighbors2[2] &&
224 neighbors1[3] == neighbors2[3])) {
225 tile.getMergeLevel(i1, j1, i2, j2);
226 }
227 Assertions.assertFalse(neighbors1[0] == neighbors2[0] &&
228 neighbors1[1] == neighbors2[1] &&
229 neighbors1[2] == neighbors2[2] &&
230 neighbors1[3] == neighbors2[3]);
231 }
232 }
233 }
234 }
235 }
236 }
237 }
238 }
239 }
240
241 @Test
242 public void testSubTilesLimits() {
243 for (int nbRows = 1; nbRows < 25; nbRows++) {
244 for (int nbColumns = 1; nbColumns < 25; nbColumns++) {
245
246 MinMaxTreeTile tile = createTile(nbRows, nbColumns);
247
248 for (int level = 0; level < tile.getLevels(); ++level) {
249 int[] neighbors = neighbors(0, 0, nbRows, nbColumns, tile.getLevels() - level);
250 int subTileRows = neighbors[1] - neighbors[0];
251 int subTileCols = neighbors[3] - neighbors[2];
252 for (int i1 = 0; i1 < nbRows; ++i1) {
253 for (int i2 = 0; i2 < nbRows; ++i2) {
254 int[] crossings = tile.getCrossedBoundaryRows(i1, i2, level);
255 int[] ref = multiples(i1, i2, subTileRows);
256 Assertions.assertArrayEquals(ref, crossings);
257 }
258 }
259 for (int j1 = 0; j1 < nbColumns; ++j1) {
260 for (int j2 = 0; j2 < nbColumns; ++j2) {
261 int[] crossings = tile.getCrossedBoundaryColumns(j1, j2, level);
262 int[] ref = multiples(j1, j2, subTileCols);
263 Assertions.assertArrayEquals(ref, crossings);
264 }
265 }
266 }
267 }
268 }
269 }
270
271 @Test
272 public void testForCoverage() throws IOException {
273
274 org.orekit.rugged.errors.DumpManager.activate(File.createTempFile("junit", null, tempFolder));
275
276 MinMaxTreeTile tile = createTile(1201, 1201);
277 tile.getMinElevation(100, 100, 0);
278
279 org.orekit.rugged.errors.DumpManager.deactivate();
280 }
281
282 private int[] neighbors(int row, int column, int nbRows, int nbColumns, int stages) {
283
284
285
286
287 int rMin = row;
288 int rN = 1;
289 int rMask = -1;
290 int cMin = column;
291 int cMask = -1;
292 int cN = 1;
293
294 boolean mergeColumns = true;
295 for (int i = 0; i < stages; ++i) {
296 if (mergeColumns) {
297 cMask = cMask << 1;
298 cMin = cMin & cMask;
299 cN = cN * 2;
300 } else {
301 rMask = rMask << 1;
302 rMin = rMin & rMask;
303 rN = rN * 2;
304 }
305 mergeColumns = !mergeColumns;
306 }
307
308 return new int[] {
309 rMin, FastMath.min(rMin + rN, nbRows),
310 cMin, FastMath.min(cMin + cN, nbColumns)
311 };
312
313 }
314
315 private int[] multiples(int k1, int k2, int n) {
316
317
318
319
320
321
322 int kS = FastMath.min(k1, k2);
323 int kE = FastMath.max(k1, k2) + 1;
324 int count = 0;
325 for (int k = kS; k < kE; ++k) {
326 if (k % n == 0) {
327 ++count;
328 }
329 }
330
331 int[] multiples = new int[count];
332 int index = 0;
333 for (int k = kS; k < kE; ++k) {
334 if (k % n == 0) {
335 multiples[index++] = k;
336 }
337 }
338
339 if (k1 > k2) {
340
341 for (int i = 0; i < count / 2; ++i) {
342 int tmp = multiples[i];
343 multiples[i] = multiples[count - 1 - i];
344 multiples[count - 1 - i] = tmp;
345 }
346 }
347
348 return multiples;
349
350 }
351
352 private MinMaxTreeTile createTile(int nbRows, int nbColumns) {
353 MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
354 tile.setGeometry(1.0, 2.0, 0.1, 0.2, nbRows, nbColumns);
355 for (int i = 0; i < nbRows; ++i) {
356 for (int j = 0; j < nbColumns; ++j) {
357 tile.setElevation(i, j, i + 0.01 * j);
358 }
359 }
360 tile.tileUpdateCompleted();
361 return tile;
362 }
363
364 @TempDir
365 public File tempFolder;
366
367 }