Skip to content

Commit 73e7b2f

Browse files
r.latlong: Add tests (#5523)
1 parent 0b3b2eb commit 73e7b2f

File tree

1 file changed

+175
-0
lines changed

1 file changed

+175
-0
lines changed
+175
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
import os
2+
import pytest
3+
import grass.script as gs
4+
5+
6+
def _init_session(tmp_path, epsg_code):
7+
"""
8+
Create a GRASS LOCATION and return its context manager.
9+
"""
10+
project = tmp_path / f"r_latlong_{epsg_code}_project"
11+
gs.create_project(project)
12+
return gs.setup.init(project, env=os.environ.copy())
13+
14+
15+
@pytest.fixture
16+
def setup_maps(tmp_path):
17+
"""Set up a GRASS session and create test raster maps in EPSG:4326."""
18+
with _init_session(tmp_path, "4326") as session:
19+
gs.run_command(
20+
"g.proj",
21+
flags="c",
22+
epsg="4326",
23+
env=session.env,
24+
)
25+
26+
# Define a 3×3 region in degrees
27+
gs.run_command(
28+
"g.region",
29+
n=3,
30+
s=0,
31+
e=3,
32+
w=0,
33+
res=1,
34+
env=session.env,
35+
)
36+
37+
# Dummy raster map (values are irrelevant to r.latlong)
38+
gs.mapcalc(
39+
"custom_map = 1",
40+
overwrite=True,
41+
env=session.env,
42+
)
43+
44+
yield session
45+
46+
47+
def clean_output(output):
48+
"""Normalize output by stripping whitespace from each line."""
49+
return "\n".join([line.strip() for line in output.strip().splitlines()])
50+
51+
52+
def test_latlong_lat(setup_maps):
53+
"""Test default r.latlong output (latitude)."""
54+
session = setup_maps
55+
56+
gs.run_command(
57+
"r.latlong",
58+
input="custom_map",
59+
output="latlong_output",
60+
env=session.env,
61+
)
62+
63+
ascii_output = gs.read_command(
64+
"r.out.ascii",
65+
input="latlong_output",
66+
env=session.env,
67+
)
68+
ascii_clean = clean_output(ascii_output)
69+
70+
expected_output = """north: 3N
71+
south: 0
72+
east: 3E
73+
west: 0
74+
rows: 3
75+
cols: 3
76+
3 3 3
77+
2 2 2
78+
1 1 1"""
79+
80+
assert ascii_clean == expected_output
81+
82+
83+
def test_l_flag(setup_maps):
84+
"""Test -l (longitude) flag output."""
85+
session = setup_maps
86+
87+
gs.run_command(
88+
"r.latlong",
89+
input="custom_map",
90+
output="latlong_output",
91+
flags="l",
92+
env=session.env,
93+
)
94+
95+
ascii_output = gs.read_command(
96+
"r.out.ascii",
97+
input="latlong_output",
98+
env=session.env,
99+
)
100+
ascii_clean = clean_output(ascii_output)
101+
102+
expected_output = """north: 3N
103+
south: 0
104+
east: 3E
105+
west: 0
106+
rows: 3
107+
cols: 3
108+
0 1 2
109+
0 1 2
110+
0 1 2"""
111+
112+
assert ascii_clean == expected_output
113+
114+
115+
def test_latlong_projected_epsg_3358(tmp_path):
116+
"""
117+
test r.latlong in a projected CRS (EPSG:3358),
118+
verify lat/long outputs stay within valid degree ranges.
119+
"""
120+
with _init_session(tmp_path, "3358") as session:
121+
gs.run_command(
122+
"g.proj",
123+
flags="c",
124+
epsg="3358",
125+
env=session.env,
126+
)
127+
128+
gs.run_command(
129+
"g.region",
130+
n=3,
131+
s=0,
132+
e=3,
133+
w=0,
134+
res=1,
135+
env=session.env,
136+
)
137+
138+
gs.mapcalc(
139+
"custom_map = 1",
140+
overwrite=True,
141+
env=session.env,
142+
)
143+
144+
# Test latitude output
145+
gs.run_command(
146+
"r.latlong",
147+
input="custom_map",
148+
output="latlong_proj",
149+
env=session.env,
150+
)
151+
info = gs.parse_command(
152+
"r.info",
153+
flags="r", # range: to get min/max
154+
map="latlong_proj",
155+
env=session.env,
156+
)
157+
lat_min, lat_max = float(info["min"]), float(info["max"])
158+
assert -90.0 <= lat_min < lat_max <= 90.0
159+
160+
# Test longitude output
161+
gs.run_command(
162+
"r.latlong",
163+
input="custom_map",
164+
output="lon_proj",
165+
flags="l",
166+
env=session.env,
167+
)
168+
info_lon = gs.parse_command(
169+
"r.info",
170+
flags="r",
171+
map="lon_proj",
172+
env=session.env,
173+
)
174+
lon_min, lon_max = float(info_lon["min"]), float(info_lon["max"])
175+
assert -180.0 <= lon_min < lon_max <= 180.0

0 commit comments

Comments
 (0)