321 строка
11 KiB
Python
321 строка
11 KiB
Python
#!/usr/bin/env pytest
|
|
# -*- coding: utf-8 -*-
|
|
###############################################################################
|
|
# $Id$
|
|
#
|
|
# Project: GDAL/OGR Test Suite
|
|
# Purpose: gdal2tiles.py testing
|
|
# Author: Gregory Bataille <gregory.bataille@gmail.com>
|
|
#
|
|
###############################################################################
|
|
# Copyright (c) 2017, Gregory Bataille <gregory.bataille@gmail.com>
|
|
# Copyright (c) 2021, Idan Miara <idan@miara.com>
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
# copy of this software and associated documentation files (the "Software"),
|
|
# to deal in the Software without restriction, including without limitation
|
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
# and/or sell copies of the Software, and to permit persons to whom the
|
|
# Software is furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included
|
|
# in all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
# DEALINGS IN THE SOFTWARE.
|
|
###############################################################################
|
|
|
|
import os
|
|
import tempfile
|
|
from unittest import TestCase, mock
|
|
|
|
import pytest
|
|
|
|
from osgeo import gdal
|
|
from osgeo_utils import gdal2tiles
|
|
|
|
|
|
class AttrDict(dict):
|
|
def __init__(self, *args, **kwargs):
|
|
super(AttrDict, self).__init__(*args, **kwargs)
|
|
self.__dict__ = self
|
|
|
|
|
|
class OptionParserInputOutputTest(TestCase):
|
|
def test_vanilla_input_output(self):
|
|
_, input_file = tempfile.mkstemp()
|
|
output_folder = tempfile.mkdtemp()
|
|
parsed_input, parsed_output, options = gdal2tiles.process_args(
|
|
[input_file, output_folder]
|
|
)
|
|
|
|
self.assertEqual(parsed_input, input_file)
|
|
self.assertEqual(parsed_output, output_folder)
|
|
self.assertNotEqual(options, {})
|
|
|
|
def test_output_folder_is_the_input_file_folder_when_none_passed(self):
|
|
_, input_file = tempfile.mkstemp()
|
|
_, parsed_output, _ = gdal2tiles.process_args([input_file])
|
|
|
|
self.assertEqual(parsed_output, os.path.basename(input_file))
|
|
|
|
def _asserts_exits_with_code_2(self, params):
|
|
with self.assertRaises(SystemExit) as cm:
|
|
gdal2tiles.process_args(params)
|
|
|
|
e = cm.exception
|
|
self.assertEqual(str(e), "2")
|
|
|
|
def test_exits_when_0_args_passed(self):
|
|
self._asserts_exits_with_code_2([])
|
|
|
|
def test_exits_when_more_than_2_free_parameters(self):
|
|
self._asserts_exits_with_code_2(["input1.tiff", "input2.tiff", "output_folder"])
|
|
|
|
def test_exits_when_input_file_does_not_exist(self):
|
|
self._asserts_exits_with_code_2(["foobar.tiff"])
|
|
|
|
def test_exits_when_first_param_is_not_a_file(self):
|
|
folder = tempfile.gettempdir()
|
|
self._asserts_exits_with_code_2([folder])
|
|
|
|
|
|
def mock_GetDriverByName_wo_webp(name, orig_GetDriverByName=gdal.GetDriverByName):
|
|
if name == "WEBP":
|
|
return None
|
|
return orig_GetDriverByName(name)
|
|
|
|
|
|
# pylint:disable=E1101
|
|
class OptionParserPostProcessingTest(TestCase):
|
|
def setUp(self):
|
|
self.DEFAULT_OPTIONS = {
|
|
"verbose": True,
|
|
"resampling": "near",
|
|
"title": "",
|
|
"url": "",
|
|
"tiledriver": "PNG",
|
|
}
|
|
self.DEFAULT_ATTRDICT_OPTIONS = AttrDict(self.DEFAULT_OPTIONS)
|
|
|
|
def _setup_gdal_patch(self, mock_gdal):
|
|
mock_gdal.TermProgress_nocb = True
|
|
mock_gdal.RegenerateOverview = True
|
|
mock_gdal.GetCacheMax = lambda: 1024 * 1024
|
|
return mock_gdal
|
|
|
|
def test_title_is_untouched_if_set(self):
|
|
title = "fizzbuzz"
|
|
self.DEFAULT_ATTRDICT_OPTIONS["title"] = title
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "bar.tiff", "baz"
|
|
)
|
|
|
|
self.assertEqual(options.title, title)
|
|
|
|
def test_title_default_to_input_filename_if_not_set(self):
|
|
input_file = "foo/bar/fizz/buzz.tiff"
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, input_file, "baz"
|
|
)
|
|
|
|
self.assertEqual(options.title, os.path.basename(input_file))
|
|
|
|
def test_url_stays_empty_if_not_passed(self):
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "baz"
|
|
)
|
|
|
|
self.assertEqual(options.url, "")
|
|
|
|
def test_url_ends_with_the_output_folder_last_component(self):
|
|
output_folder = "foo/bar/fizz"
|
|
url = "www.mysite.com/storage"
|
|
self.DEFAULT_ATTRDICT_OPTIONS["url"] = url
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", output_folder
|
|
)
|
|
|
|
self.assertEqual(options.url, url + "/fizz/")
|
|
|
|
# With already present trailing slashes
|
|
output_folder = "foo/bar/fizz/"
|
|
url = "www.mysite.com/storage/"
|
|
self.DEFAULT_ATTRDICT_OPTIONS["url"] = url
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", output_folder
|
|
)
|
|
|
|
self.assertEqual(options.url, url + "fizz/")
|
|
|
|
@mock.patch("osgeo_utils.gdal2tiles.gdal", spec=AttrDict())
|
|
def test_average_resampling_supported_with_latest_gdal(self, mock_gdal):
|
|
self._setup_gdal_patch(mock_gdal)
|
|
self.DEFAULT_ATTRDICT_OPTIONS["resampling"] = "average"
|
|
|
|
gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
|
|
)
|
|
# No error means it worked as expected
|
|
|
|
def test_antialias_resampling_supported_with_numpy(self):
|
|
gdal2tiles.numpy_available = True
|
|
self.DEFAULT_ATTRDICT_OPTIONS["resampling"] = "antialias"
|
|
|
|
gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
|
|
)
|
|
# No error means it worked as expected
|
|
|
|
def test_antialias_resampling_not_supported_wout_numpy(self):
|
|
gdal2tiles.numpy_available = False
|
|
if hasattr(gdal2tiles, "numpy"):
|
|
del gdal2tiles.numpy
|
|
|
|
self.DEFAULT_ATTRDICT_OPTIONS["resampling"] = "antialias"
|
|
|
|
with self.assertRaises(SystemExit):
|
|
gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
|
|
)
|
|
|
|
def test_zoom_option_not_specified(self):
|
|
self.DEFAULT_ATTRDICT_OPTIONS["zoom"] = None
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "baz"
|
|
)
|
|
|
|
self.assertEqual(options.zoom, [None, None])
|
|
|
|
def test_zoom_option_single_level(self):
|
|
self.DEFAULT_ATTRDICT_OPTIONS["zoom"] = "10"
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "baz"
|
|
)
|
|
|
|
self.assertEqual(options.zoom, [10, 10])
|
|
|
|
def test_zoom_option_two_levels(self):
|
|
self.DEFAULT_ATTRDICT_OPTIONS["zoom"] = "14-24"
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "baz"
|
|
)
|
|
|
|
self.assertEqual(options.zoom, [14, 24])
|
|
|
|
def test_zoom_option_two_levels_automatic_max(self):
|
|
self.DEFAULT_ATTRDICT_OPTIONS["zoom"] = "14-"
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "baz"
|
|
)
|
|
|
|
self.assertEqual(options.zoom, [14, None])
|
|
|
|
@mock.patch(
|
|
"osgeo_utils.gdal2tiles.gdal.GetDriverByName",
|
|
side_effect=mock_GetDriverByName_wo_webp,
|
|
)
|
|
def test_tiledriver_wout_webp(self, mock_GetDriverByName_wo_webp):
|
|
self.DEFAULT_ATTRDICT_OPTIONS["tiledriver"] = "WEBP"
|
|
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 70
|
|
|
|
with self.assertRaises(SystemExit):
|
|
gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
|
|
)
|
|
|
|
@mock.patch(
|
|
"osgeo_utils.gdal2tiles.gdal.GetDriverByName",
|
|
side_effect=mock_GetDriverByName_wo_webp,
|
|
)
|
|
def test_tiledriver_wout_webp_png_accepted(self, mock_GetDriverByName_wo_webp):
|
|
self.DEFAULT_ATTRDICT_OPTIONS["tiledriver"] = "PNG"
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
|
|
)
|
|
|
|
self.assertEqual(options.tiledriver, "PNG")
|
|
|
|
def test_tiledriver_webp_quality_option_valid(self):
|
|
if gdal.GetDriverByName("WEBP") is None:
|
|
pytest.skip()
|
|
|
|
self.DEFAULT_ATTRDICT_OPTIONS["tiledriver"] = "WEBP"
|
|
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 1
|
|
self.DEFAULT_ATTRDICT_OPTIONS["webp_lossless"] = False
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
|
|
)
|
|
|
|
self.assertEqual(options.tiledriver, "WEBP")
|
|
self.assertEqual(options.webp_quality, 1)
|
|
|
|
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 100
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
|
|
)
|
|
|
|
self.assertEqual(options.tiledriver, "WEBP")
|
|
self.assertEqual(options.webp_quality, 100)
|
|
|
|
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 50
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
|
|
)
|
|
|
|
self.assertEqual(options.tiledriver, "WEBP")
|
|
self.assertEqual(options.webp_quality, 50)
|
|
|
|
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 10.5
|
|
|
|
options = gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
|
|
)
|
|
|
|
self.assertEqual(options.tiledriver, "WEBP")
|
|
self.assertEqual(options.webp_quality, 10)
|
|
|
|
def test_tiledriver_webp_quality_option_invalid(self):
|
|
if gdal.GetDriverByName("WEBP") is None:
|
|
pytest.skip()
|
|
|
|
self.DEFAULT_ATTRDICT_OPTIONS["tiledriver"] = "WEBP"
|
|
self.DEFAULT_ATTRDICT_OPTIONS["webp_lossless"] = False
|
|
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = -20
|
|
|
|
with self.assertRaises(SystemExit):
|
|
gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
|
|
)
|
|
|
|
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 0
|
|
|
|
with self.assertRaises(SystemExit):
|
|
gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
|
|
)
|
|
|
|
self.DEFAULT_ATTRDICT_OPTIONS["webp_quality"] = 140
|
|
|
|
with self.assertRaises(SystemExit):
|
|
gdal2tiles.options_post_processing(
|
|
self.DEFAULT_ATTRDICT_OPTIONS, "foo.tiff", "/bar/"
|
|
)
|