Repository: cogeotiff/rio-cogeo

Issue:
Update get_maximum_overview_level to use Rasterio dataset directly 
in https://github.com/cogeotiff/rio-cogeo/blob/fb9ceba8b00dae22bce68b196c47a88a62371b61/rio_cogeo/cogeo.py#L62-L66
we pass the dataset path and then open it in `get_maximum_overview_level` function. This means we have to open the dataset twice while it's not really necessary 

Discussion:

Patch:
diff --git a/CHANGES.txt b/CHANGES.txt
index bce8d83..34319c4 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,12 @@
+1.0b1 (2019-03-25)
+------------------
+
+Breacking Changes:
+
+- refactor utils.get_maximum_overview_level to get rasterio dataset 
+as input and reduce the number of dataset opennings (#61)
+
+
 1.0b0 (2019-03-15)
 ------------------
 - add more logging and `--quiet` option (#46)
diff --git a/rio_cogeo/__init__.py b/rio_cogeo/__init__.py
index d3a8d9f..798dca7 100644
--- a/rio_cogeo/__init__.py
+++ b/rio_cogeo/__init__.py
@@ -1,3 +1,3 @@
 """rio_cogeo"""
 
-__version__ = "1.0b0"
+__version__ = "1.0b1"
diff --git a/rio_cogeo/cogeo.py b/rio_cogeo/cogeo.py
index e14e52a..6339a8d 100644
--- a/rio_cogeo/cogeo.py
+++ b/rio_cogeo/cogeo.py
@@ -59,11 +59,6 @@ def cog_translate(
     """
     config = config or {}
 
-    if overview_level is None:
-        overview_level = get_maximum_overview_level(
-            src_path, min(int(dst_kwargs["blockxsize"]), int(dst_kwargs["blockysize"]))
-        )
-
     with rasterio.Env(**config):
         with rasterio.open(src_path) as src_dst:
             meta = src_dst.meta
@@ -82,6 +77,12 @@ def cog_translate(
                     LossyCompression,
                 )
 
+            if overview_level is None:
+                overview_level = get_maximum_overview_level(
+                    src_dst,
+                    min(int(dst_kwargs["blockxsize"]), int(dst_kwargs["blockysize"])),
+                )
+
             vrt_params = dict(add_alpha=True)
 
             if nodata is not None:
diff --git a/rio_cogeo/utils.py b/rio_cogeo/utils.py
index 44edb90..19eed74 100644
--- a/rio_cogeo/utils.py
+++ b/rio_cogeo/utils.py
@@ -1,14 +1,27 @@
 """rio_cogeo.utils: Utility functions."""
 
-import rasterio
 from rasterio.enums import MaskFlags, ColorInterp
 
 
-def get_maximum_overview_level(src_path, minsize=512):
-    """Calculate the maximum overview level."""
-    with rasterio.open(src_path) as src:
-        width = src.width
-        height = src.height
+def get_maximum_overview_level(src_dst, minsize=512):
+    """
+    Calculate the maximum overview level.
+
+    Attributes
+    ----------
+    src_dst : rasterio.io.DatasetReader
+        Rasterio io.DatasetReader object.
+    minsize : int (default: 512)
+        Minimum overview size.
+
+    Returns
+    -------
+    nlevel: int
+        overview level.
+
+    """
+    width = src_dst.width
+    height = src_dst.height
 
     nlevel = 0
     overview = 1


Test patch:
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 98e5bbd..d1b076b 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -2,6 +2,7 @@
 
 import os
 
+import rasterio
 from rio_cogeo.utils import get_maximum_overview_level
 
 raster_path_rgb = os.path.join(os.path.dirname(__file__), "fixtures", "image_rgb.tif")
@@ -9,4 +10,6 @@ raster_path_rgb = os.path.join(os.path.dirname(__file__), "fixtures", "image_rgb
 
 def test_overviewlevel_valid():
     """Should work as expected (return overview level)."""
-    assert get_maximum_overview_level(raster_path_rgb, 128) == 2
+    with rasterio.open(raster_path_rgb) as src_dst:
+        assert get_maximum_overview_level(src_dst, 128) == 2
+        assert get_maximum_overview_level(src_dst) == 0