-
Notifications
You must be signed in to change notification settings - Fork 94
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
192 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright (c) 2014-2023 Pyresample developers | ||
# | ||
# This program is free software: you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation, either version 3 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, | ||
# but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
# GNU General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
"""Define the BoundarySides class.""" | ||
|
||
import logging | ||
|
||
import numpy as np | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class BoundarySides: | ||
"""A class to represent the sides of an area boundary. | ||
The sides are stored as a tuple of 4 numpy arrays, each representing the | ||
coordinate (geographic or projected) of the vertices of the boundary side. | ||
The sides must be stored in the order (top, right, left, bottom), | ||
which refers to the side position with respect to the coordinate array. | ||
The first row of the coordinate array correspond to the top side, the last row to the bottom side, | ||
the first column to the left side and the last column to the right side. | ||
Please note that the last vertex of each side must be equal to the first vertex of the next side. | ||
""" | ||
__slots__ = ['_sides'] | ||
|
||
def __init__(self, sides): | ||
"""Initialize the BoundarySides object.""" | ||
if len(sides) != 4 or not all(isinstance(side, np.ndarray) and side.ndim == 1 for side in sides): | ||
raise ValueError("Sides must be a list of four numpy arrays.") | ||
|
||
if not all(np.array_equal(sides[i][-1], sides[(i + 1) % 4][0]) for i in range(4)): | ||
raise ValueError("The last element of each side must be equal to the first element of the next side.") | ||
|
||
self._sides = tuple(sides) # Store as a tuple | ||
|
||
@property | ||
def top(self): | ||
"""Return the vertices of the top side.""" | ||
return self._sides[0] | ||
|
||
@property | ||
def right(self): | ||
"""Return the vertices of the right side.""" | ||
return self._sides[1] | ||
|
||
@property | ||
def bottom(self): | ||
"""Return the vertices of the bottom side.""" | ||
return self._sides[2] | ||
|
||
@property | ||
def left(self): | ||
"""Return the vertices of the left side.""" | ||
return self._sides[3] | ||
|
||
@property | ||
def vertices(self): | ||
"""Return the vertices of the concatenated sides. | ||
Note that the last element of each side is discarded to avoid duplicates. | ||
""" | ||
return np.concatenate([side[:-1] for side in self._sides]) | ||
|
||
def __iter__(self): | ||
"""Return an iterator over the sides.""" | ||
return iter(self._sides) | ||
|
||
def __getitem__(self, index): | ||
"""Return the side at the given index.""" | ||
if not isinstance(index, int) or not 0 <= index < 4: | ||
raise IndexError("Index must be an integer from 0 to 3.") | ||
return self._sides[index] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# pyresample, Resampling of remote sensing image data in python | ||
# | ||
# Copyright (C) 2010-2022 Pyresample developers | ||
# | ||
# This program is free software: you can redistribute it and/or modify it under | ||
# the terms of the GNU Lesser General Public License as published by the Free | ||
# Software Foundation, either version 3 of the License, or (at your option) any | ||
# later version. | ||
# | ||
# This program is distributed in the hope that it will be useful, but WITHOUT | ||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more | ||
# details. | ||
# | ||
# You should have received a copy of the GNU Lesser General Public License | ||
# along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
"""Test the BoundarySides objects.""" | ||
|
||
import numpy as np | ||
import pytest | ||
|
||
from pyresample.boundary import BoundarySides | ||
|
||
|
||
class TestBoundarySides: | ||
"""Test suite for the BoundarySides class with 1D numpy arrays for sides.""" | ||
|
||
def test_initialization_valid_input(self): | ||
"""Test initialization with valid 1D numpy array inputs.""" | ||
sides = [np.array([1, 2, 3]), # top | ||
np.array([3, 4, 5]), # right | ||
np.array([5, 6, 7]), # bottom | ||
np.array([7, 8, 1])] # left | ||
boundary = BoundarySides(sides) | ||
assert all(np.array_equal(boundary[i], sides[i]) for i in range(4)) | ||
|
||
def test_initialization_invalid_input(self): | ||
"""Test initialization with invalid inputs, such as wrong number of sides or non-1D arrays.""" | ||
with pytest.raises(ValueError): | ||
BoundarySides([np.array([1, 2]), # Invalid number of sides | ||
np.array([2, 3])]) | ||
|
||
with pytest.raises(ValueError): | ||
BoundarySides([np.array([1, 2]), # Non-1D arrays | ||
np.array([[2, 3], [4, 5]]), | ||
np.array([5, 6]), | ||
np.array([6, 7])]) | ||
|
||
with pytest.raises(ValueError): | ||
BoundarySides([np.array([1, 2]), # Invalid side connection | ||
np.array([3, 4]), | ||
np.array([4, 6]), | ||
np.array([6, 1])]) | ||
|
||
def test_property_accessors(self): | ||
"""Test property accessors with 1D numpy arrays.""" | ||
sides = [np.array([1, 2, 3]), # top | ||
np.array([3, 4, 5]), # right | ||
np.array([5, 6, 7]), # bottom | ||
np.array([7, 8, 1])] # left | ||
boundary = BoundarySides(sides) | ||
assert np.array_equal(boundary.top, sides[0]) | ||
assert np.array_equal(boundary.right, sides[1]) | ||
assert np.array_equal(boundary.bottom, sides[2]) | ||
assert np.array_equal(boundary.left, sides[3]) | ||
|
||
def test_vertices_property(self): | ||
"""Test the vertices property with concatenated 1D numpy arrays.""" | ||
sides = [np.array([1, 2, 3]), # top | ||
np.array([3, 4, 5]), # right | ||
np.array([5, 6, 7]), # bottom | ||
np.array([7, 8, 1])] # left | ||
boundary = BoundarySides(sides) | ||
expected_vertices = np.array([1, 2, 3, 4, 5, 6, 7, 8]) | ||
assert np.array_equal(boundary.vertices, expected_vertices) | ||
|
||
def test_iteration(self): | ||
"""Test iteration over the 1D numpy array sides.""" | ||
sides = [np.array([1, 2, 3]), # top | ||
np.array([3, 4, 5]), # right | ||
np.array([5, 6, 7]), # bottom | ||
np.array([7, 8, 1])] # left | ||
boundary = BoundarySides(sides) | ||
for i, side in enumerate(boundary): | ||
assert np.array_equal(side, sides[i]) | ||
|
||
def test_indexing_valid(self): | ||
"""Test valid indexing with 1D numpy arrays.""" | ||
sides = [np.array([1, 2, 3]), # top | ||
np.array([3, 4, 5]), # right | ||
np.array([5, 6, 7]), # bottom | ||
np.array([7, 8, 1])] # left | ||
boundary = BoundarySides(sides) | ||
for i in range(4): | ||
assert np.array_equal(boundary[i], sides[i]) | ||
|
||
def test_indexing_invalid(self): | ||
"""Test indexing with invalid indices.""" | ||
sides = [np.array([1, 2, 3]), # top | ||
np.array([3, 4, 5]), # right | ||
np.array([5, 6, 7]), # bottom | ||
np.array([7, 8, 1])] # left | ||
boundary = BoundarySides(sides) | ||
with pytest.raises(IndexError): | ||
boundary[4] # Invalid index |