Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add kwargs config option to turn off mitiff corner correction #2713

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions satpy/tests/writer_tests/test_mitiff.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python

Check notice on line 1 in satpy/tests/writer_tests/test_mitiff.py

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

ℹ Getting worse: Lines of Code in a Single File

The lines of code increases from 920 to 950, improve code health by reducing it to 600. The number of Lines of Code in a single file. More Lines of Code lowers the code health.

Check notice on line 1 in satpy/tests/writer_tests/test_mitiff.py

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

ℹ Getting worse: Low Cohesion

The number of different responsibilities increases from 7 to 8, threshold = 4. Cohesion is calculated using the LCOM4 metric. Low cohesion means that the module/class has multiple unrelated responsibilities, doing too many things and breaking the Single Responsibility Principle.
# -*- coding: utf-8 -*-
# Copyright (c) 2018-2020 Satpy developers
#
Expand Down Expand Up @@ -879,6 +879,40 @@
proj4_string = w._add_proj4_string(ds1, ds1)
assert proj4_string == check["proj4"]

def test_correction_proj4_string(self):
"""Test correction of proj4 lower left coordinate."""
import dask.array as da
import xarray as xr
from pyresample.geometry import AreaDefinition

from satpy.writers.mitiff import MITIFFWriter
area_def = AreaDefinition(
"test",
"test",
"test",
"+proj=merc",
100,
200,
(-1000., -1500., 1000., 1500.),
)

ds1 = xr.DataArray(
da.zeros((10, 20), chunks=20),
dims=("y", "x"),
attrs={"area": area_def}
)
default_expected_correction = (20.0, 15.0)
w = MITIFFWriter(filename="dummy.tif", base_dir=self.base_dir)
mitiff_pixel_adjustment = True
correction = w._set_correction_size(ds1, mitiff_pixel_adjustment)
assert correction == default_expected_correction

mitiff_pixel_adjustment = False
new_expected_correction = (0, 0)
w = MITIFFWriter(filename="dummy.tif", base_dir=self.base_dir)
correction = w._set_correction_size(ds1, mitiff_pixel_adjustment)
assert correction == new_expected_correction

def test_save_dataset_palette(self):
"""Test writer operation as palette."""
from satpy.writers.mitiff import MITIFFWriter
Expand Down
46 changes: 30 additions & 16 deletions satpy/writers/mitiff.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env python

Check notice on line 1 in satpy/writers/mitiff.py

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

✅ Getting better: Overall Code Complexity

The mean cyclomatic complexity decreases from 6.15 to 5.82, threshold = 4. This file has many conditional statements (e.g. if, for, while) across its implementation, leading to lower code health. Avoid adding more conditionals.
# -*- coding: utf-8 -*-
# Copyright (c) 2018, 2019 Satpy developers
#
Expand Down Expand Up @@ -220,72 +220,86 @@

return _image_description

def _add_proj4_string(self, datasets, first_dataset):
def _add_proj4_string(self, datasets, first_dataset, **kwargs):
import warnings

proj4_string = " Proj string: "

if isinstance(datasets, list):
area = first_dataset.attrs["area"]
else:
area = datasets.attrs["area"]
# Use pyproj's CRS object to get a valid EPSG code if possible
# only in newer pyresample versions with pyproj 2.0+ installed
if hasattr(area, "crs") and area.crs.to_epsg() is not None:
proj4_string += "+init=EPSG:{}".format(area.crs.to_epsg())
else:
# Filter out the PROJ warning of losing projection information
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=UserWarning,
message=r"You will likely lose important projection information")
proj4_string += area.proj_str

x_0 = 0
y_0 = 0
# FUTURE: Use pyproj 2.0+ to convert EPSG to PROJ4 if possible
proj4_string, x_0 = self._convert_epsg_to_proj(proj4_string, x_0)

proj4_string = self._special_correction_of_proj_string(proj4_string)

if isinstance(datasets, list):
_dataset = first_dataset
else:
_dataset = datasets
mitiff_pixel_adjustment = kwargs.get("mitiff_pixel_adjustment", True)
proj4_string = self._append_projection_center(proj4_string, _dataset, x_0, y_0, mitiff_pixel_adjustment)
LOG.debug("proj4_string: %s", proj4_string)
proj4_string += "\n"

return proj4_string

def _special_correction_of_proj_string(self, proj4_string):
if "geos" in proj4_string:
proj4_string = proj4_string.replace("+sweep=x ", "")
if "+a=6378137.0 +b=6356752.31414" in proj4_string:
proj4_string = proj4_string.replace("+a=6378137.0 +b=6356752.31414",
"+ellps=WGS84")
if "+units=m" in proj4_string:
proj4_string = proj4_string.replace("+units=m", "+units=km")

if not any(datum in proj4_string for datum in ["datum", "towgs84"]):
proj4_string += " +towgs84=0,0,0"

if "units" not in proj4_string:
proj4_string += " +units=km"

Check notice on line 274 in satpy/writers/mitiff.py

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (main)

✅ No longer an issue: Complex Method

MITIFFWriter._add_proj4_string is no longer above the threshold for cyclomatic complexity. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.

proj4_string = self._append_projection_center(proj4_string, datasets, first_dataset, x_0, y_0)
LOG.debug("proj4_string: %s", proj4_string)
proj4_string += "\n"

return proj4_string

def _append_projection_center(self, proj4_string, datasets, first_dataset, x_0, y_0):
if isinstance(datasets, list):
dataset = first_dataset
else:
dataset = datasets
def _append_projection_center(self, proj4_string, dataset, x_0, y_0, mitiff_pixel_adjustment):
corner_correction_x, corner_correction_y = self._set_correction_size(dataset, mitiff_pixel_adjustment)
if "x_0" not in proj4_string:
proj4_string += " +x_0=%.6f" % (
(-dataset.attrs["area"].area_extent[0] +
dataset.attrs["area"].pixel_size_x) + x_0)
corner_correction_x) + x_0)
proj4_string += " +y_0=%.6f" % (
(-dataset.attrs["area"].area_extent[1] +
dataset.attrs["area"].pixel_size_y) + y_0)
corner_correction_y) + y_0)
elif "+x_0=0" in proj4_string and "+y_0=0" in proj4_string:
proj4_string = proj4_string.replace("+x_0=0", "+x_0=%.6f" % (
(-dataset.attrs["area"].area_extent[0] +
dataset.attrs["area"].pixel_size_x) + x_0))
corner_correction_x) + x_0))
proj4_string = proj4_string.replace("+y_0=0", "+y_0=%.6f" % (
(-dataset.attrs["area"].area_extent[1] +
dataset.attrs["area"].pixel_size_y) + y_0))
corner_correction_y) + y_0))
return proj4_string

def _set_correction_size(self, dataset, mitiff_pixel_adjustment):
corner_correction_x = dataset.attrs["area"].pixel_size_x
corner_correction_y = dataset.attrs["area"].pixel_size_y
if not mitiff_pixel_adjustment:
corner_correction_x = 0
corner_correction_y = 0
return corner_correction_x,corner_correction_y

def _convert_epsg_to_proj(self, proj4_string, x_0):
if "EPSG:32631" in proj4_string:
proj4_string = proj4_string.replace("+init=EPSG:32631",
Expand Down Expand Up @@ -563,7 +577,7 @@

_image_description += " Map projection: Stereographic\n"

_image_description += self._add_proj4_string(datasets, first_dataset)
_image_description += self._add_proj4_string(datasets, first_dataset, **kwargs)
TAlonglong marked this conversation as resolved.
Show resolved Hide resolved

_image_description += " TrueLat: 60N\n"
_image_description += " GridRot: 0\n"
Expand Down
Loading