diff --git a/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java b/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java
index 006e5935fb20b3803a3c9d1c907dc5f42e84346d..21fa38e3507ba94c2b49610c274c7a52d9d5a633 100644
--- a/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java
+++ b/rugged-core/src/main/java/org/orekit/rugged/core/duvenhage/MinMaxTreeTile.java
@@ -69,6 +69,7 @@ public class MinMaxTreeTile extends SimpleTile {
      * @return number of kd-tree levels
      * @see #getMinElevation(int, int, int)
      * @see #getMaxElevation(int, int, int)
+     * @see #getMergeLevel(int, int, int, int)
      */
     public int getLevels() {
         return start.length;
@@ -81,6 +82,7 @@ public class MinMaxTreeTile extends SimpleTile {
      * @return minimum elevation
      * @see #getLevels()
      * @see #getMaxElevation(int, int, int)
+     * @see #getMergeLevel(int, int, int, int)
      */
     public double getMinElevation(final int i, final int j, final int level) {
 
@@ -103,6 +105,7 @@ public class MinMaxTreeTile extends SimpleTile {
      * @return maximum elevation
      * @see #getLevels()
      * @see #getMinElevation(int, int, int)
+     * @see #getMergeLevel(int, int, int, int)
      */
     public double getMaxElevation(final int i, final int j, final int level) {
 
@@ -118,6 +121,40 @@ public class MinMaxTreeTile extends SimpleTile {
 
     }
 
+    /** Get the largest level at which two pixels are merged in the same min/max sub-tile.
+     * @param i1 row index of first pixel
+     * @param j1 column index of first pixel
+     * @param i2 row index of second pixel
+     * @param j2 column index of sedonc pixel
+     * @return largest level at which two pixels are merged in the same min/max sub-tile,
+     * or negative if they are never merged in the same sub-tile
+     * @see #getLevels()
+     * @see #getMinElevation(int, int, int)
+     * @see #getMaxElevation(int, int, int)
+     */
+    public int getMergeLevel(final int i1, final int j1, final int i2, final int j2) {
+
+        int largest = -1;
+
+        for (int level = 0; level < start.length; ++level) {
+            // compute indices in level merged array
+            final int k        = start.length - level;
+            final int rowShift = k / 2;
+            final int colShift = (k + 1) / 2;
+            final int levelI1  = i1 >> rowShift;
+            final int levelJ1  = j1 >> colShift;
+            final int levelI2  = i2 >> rowShift;
+            final int levelJ2  = j2 >> colShift;
+            if (levelI1 != levelI2 || levelJ1 != levelJ2) {
+                return largest;
+            }
+            largest = level;
+        }
+
+        return largest;
+
+    }
+
     /** Recursive setting of tree levels.
      * <p>
      * The following algorithms works for any array shape, even with
diff --git a/rugged-core/src/test/java/orekit/rugged/core/duvenhage/MinMaxTreeTileTest.java b/rugged-core/src/test/java/orekit/rugged/core/duvenhage/MinMaxTreeTileTest.java
index 7b69d6f6c74940f4ab789b84af705589963de60e..55261ebe0c72959c13e28ee871adcef522877f6b 100644
--- a/rugged-core/src/test/java/orekit/rugged/core/duvenhage/MinMaxTreeTileTest.java
+++ b/rugged-core/src/test/java/orekit/rugged/core/duvenhage/MinMaxTreeTileTest.java
@@ -31,9 +31,7 @@ public class MinMaxTreeTileTest {
     public void testSizeTall()
         throws RuggedException, SecurityException, NoSuchFieldException,
                IllegalArgumentException, IllegalAccessException {
-        MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
-        tile.setGeometry(1.0, 2.0, 0.1, 0.2, 107, 19);
-        tile.tileUpdateCompleted();
+        MinMaxTreeTile tile = createTile(107, 19);
         Assert.assertEquals(9, tile.getLevels());
 
         Field startField = MinMaxTreeTile.class.getDeclaredField("start");
@@ -62,9 +60,7 @@ public class MinMaxTreeTileTest {
     public void testSizeFat()
         throws RuggedException, SecurityException, NoSuchFieldException,
                IllegalArgumentException, IllegalAccessException {
-        MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
-        tile.setGeometry(1.0, 2.0, 0.1, 0.2, 4, 7);
-        tile.tileUpdateCompleted();
+        MinMaxTreeTile tile = createTile(4, 7);
         Assert.assertEquals(4, tile.getLevels());
 
         Field startField = MinMaxTreeTile.class.getDeclaredField("start");
@@ -86,61 +82,100 @@ public class MinMaxTreeTileTest {
 
     @Test
     public void testSinglePixel() throws RuggedException {
-        MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
-        tile.setGeometry(1.0, 2.0, 0.1, 0.2, 1, 1);
-        tile.setElevation(0, 0, 2.5);
-        tile.tileUpdateCompleted();
-        Assert.assertEquals(0, tile.getLevels());
+        Assert.assertEquals(0, createTile(1, 1).getLevels());
     }
 
     @Test
     public void testMinMax() throws RuggedException {
         for (int nbRows = 1; nbRows < 25; nbRows++) {
             for (int nbColumns = 1; nbColumns < 25; nbColumns++) {
-                checkMinMax(nbRows, nbColumns);
+
+                MinMaxTreeTile tile = createTile(nbRows, nbColumns);
+
+                for (int level = 0; level < tile.getLevels(); level++) {
+                    for (int row = 0; row < nbRows; row++) {
+                        for (int column = 0; column < nbColumns; column++) {
+
+                            // reference min and max
+                            int[] neighbors = neighbors(row, column, nbRows, nbColumns, tile.getLevels() - level);
+                            double min = Double.POSITIVE_INFINITY;
+                            double max = Double.NEGATIVE_INFINITY;
+                            for (int i = neighbors[0]; i < neighbors[1]; ++i) {
+                                for (int j = neighbors[2]; j < neighbors[3]; ++j) {
+                                    double pixelValue = tile.getElevationAtIndices(i, j);
+                                    min = FastMath.min(min, pixelValue);
+                                    max = FastMath.max(max, pixelValue);
+                                }
+                            }
+
+                            Assert.assertEquals(min, tile.getMinElevation(row, column, level), 1.0e-10 * min);
+                            Assert.assertEquals(max, tile.getMaxElevation(row, column, level), 1.0e-10 * max);
+                        }
+                    }
+                }
             }
         }
     }
 
-    private void checkMinMax(int nbRows, int nbColumns)
-        throws RuggedException {
-
-        MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
-        tile.setGeometry(1.0, 2.0, 0.1, 0.2, nbRows, nbColumns);
-        for (int i = 0; i < nbRows; ++i) {
-            for (int j = 0; j < nbColumns; ++j) {
-                tile.setElevation(i, j, i + 0.01 * j);
-            }
-        }
-        tile.tileUpdateCompleted();
+    @Test
+    public void testMergeLarge() throws RuggedException {
+        MinMaxTreeTile tile = createTile(1201, 1201);
+        Assert.assertEquals(21, tile.getLevels());
+        Assert.assertEquals( 7, tile.getMergeLevel(703, 97, 765, 59));
+    }
 
-        for (int level = 0; level < tile.getLevels(); level++) {
-            for (int row = 0; row < nbRows; row++) {
-                for (int column = 0; column < nbColumns; column++) {
-
-                    // reference min and max
-                    int[] neighbors = neighbors(row, column, nbRows, nbColumns, tile.getLevels() - level);
-                    double min = Double.POSITIVE_INFINITY;
-                    double max = Double.NEGATIVE_INFINITY;
-                    for (int i = neighbors[0]; i < neighbors[1]; ++i) {
-                        for (int j = neighbors[2]; j < neighbors[3]; ++j) {
-                            double pixelValue = tile.getElevationAtIndices(i, j);
-                            min = FastMath.min(min, pixelValue);
-                            max = FastMath.max(max, pixelValue);
+    @Test
+    public void testMergeLevel() throws RuggedException {
+        for (int nbRows = 1; nbRows < 20; nbRows++) {
+            for (int nbColumns = 1; nbColumns < 20; nbColumns++) {
+
+                MinMaxTreeTile tile = createTile(nbRows, nbColumns);
+
+                for (int i1 = 0; i1 < nbRows; i1++) {
+                    for (int j1 = 0; j1 < nbColumns; j1++) {
+                        for (int i2 = 0; i2 < nbRows; i2++) {
+                            for (int j2 = 0; j2 < nbColumns; j2++) {
+
+                                int level = tile.getMergeLevel(i1, j1, i2, j2);
+                                if (level > 0) {
+                                    int[] neighbors1 = neighbors(i1, j1, nbRows, nbColumns, tile.getLevels() - level);
+                                    int[] neighbors2 = neighbors(i2, j2, nbRows, nbColumns, tile.getLevels() - level);
+                                    for (int k = 0; k < neighbors1.length; ++k) {
+                                        Assert.assertTrue(neighbors1[0] == neighbors2[0] &&
+                                                          neighbors1[1] == neighbors2[1] &&
+                                                          neighbors1[2] == neighbors2[2] &&
+                                                          neighbors1[3] == neighbors2[3]);
+                                    }
+                                }
+                                if (level + 1 < tile.getLevels()) {
+                                    int[] neighbors1 = neighbors(i1, j1, nbRows, nbColumns, tile.getLevels() - (level + 1));
+                                    int[] neighbors2 = neighbors(i2, j2, nbRows, nbColumns, tile.getLevels() - (level + 1));
+                                    for (int k = 0; k < neighbors1.length; ++k) {
+                                        if ((neighbors1[0] == neighbors2[0] &&
+                                                neighbors1[1] == neighbors2[1] &&
+                                                neighbors1[2] == neighbors2[2] &&
+                                                neighbors1[3] == neighbors2[3])) {
+                                            tile.getMergeLevel(i1, j1, i2, j2);
+                                        }
+                                        Assert.assertFalse(neighbors1[0] == neighbors2[0] &&
+                                                           neighbors1[1] == neighbors2[1] &&
+                                                           neighbors1[2] == neighbors2[2] &&
+                                                           neighbors1[3] == neighbors2[3]);
+                                    }
+                                }
+                            }
                         }
                     }
-
-                    Assert.assertEquals(min, tile.getMinElevation(row, column, level), 1.0e-10 * min);
-                    Assert.assertEquals(max, tile.getMaxElevation(row, column, level), 1.0e-10 * max);
                 }
             }
         }
-
     }
 
     private int[] neighbors(int row, int column, int nbRows, int nbColumns, int stages) {
 
         // poor man identification of neighbors cells merged together with specified cell
+        // this identification is intentionally independent of the MinMaxTreeTile class,
+        // for testing purposes
         int rMin  = row;
         int rN    = 1;
         int rMask = -1;
@@ -169,4 +204,16 @@ public class MinMaxTreeTileTest {
 
     }
 
+    private MinMaxTreeTile createTile(int nbRows, int nbColumns) throws RuggedException {
+        MinMaxTreeTile tile = new MinMaxTreeTileFactory().createTile();
+        tile.setGeometry(1.0, 2.0, 0.1, 0.2, nbRows, nbColumns);
+        for (int i = 0; i < nbRows; ++i) {
+            for (int j = 0; j < nbColumns; ++j) {
+                tile.setElevation(i, j, i + 0.01 * j);
+            }
+        }
+        tile.tileUpdateCompleted();
+        return tile;
+    }
+
 }