diff --git a/vector/v.proj/main.c b/vector/v.proj/main.c index cce7f5d59bf..1a4da0f2d6a 100644 --- a/vector/v.proj/main.c +++ b/vector/v.proj/main.c @@ -289,8 +289,13 @@ int main(int argc, char *argv[]) int first = 1, counter = 0; struct Cell_head inwindow; - G_unset_window(); - G_get_window(&inwindow); + // Initialize from the source projects's default region, not the + // current region, because G_get_window() honors WIND_OVERRIDE / + // GRASS_REGION, but those refer to a region in the target's mapset, + // not in the source project we just switched into. Every spatial + // field below is overwritten from the input vector's extent anyway, + // so the default window is a sufficient and side-effect-free seed. + G_get_default_window(&inwindow); /* Cycle through all lines */ Vect_rewind(&Map); diff --git a/vector/v.proj/tests/v_proj_wind_override_test.py b/vector/v.proj/tests/v_proj_wind_override_test.py new file mode 100644 index 00000000000..d4fc21011ec --- /dev/null +++ b/vector/v.proj/tests/v_proj_wind_override_test.py @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +"""Regression test for v.proj run with a region override set.""" + +import os +from io import StringIO + +import pytest + +import grass.script as gs +from grass.tools import Tools + + +@pytest.fixture +def source_and_target(tmp_path): + """Two projects with different CRS. + + The source (lon/lat) holds a vector map in PERMANENT; the target + (NC State Plane, meters) is where v.proj runs. + """ + source = tmp_path / "source" + target = tmp_path / "target" + gs.create_project(source, epsg="4326") + gs.create_project(target, epsg="3358") + with gs.setup.init(source, env=os.environ.copy()) as session: + Tools(session=session).v_in_ascii( + input=StringIO("-78.6|35.7\n-78.5|35.8\n"), + output="points", + separator="|", + format="point", + ) + return source, target + + +def test_vproj_succeeds_with_wind_override(source_and_target): + """v.proj imports a map while WIND_OVERRIDE names a region only in the + target mapset.""" + source, target = source_and_target + with gs.setup.init(target, env=os.environ.copy()) as session: + # A named region that exists only in the target's current mapset. + gs.run_command( + "g.region", + n=300000, + s=200000, + e=700000, + w=600000, + res=10, + save="local_region", + env=session.env, + ) + # Set the override after init so it is not stripped by runtime setup; + # this mirrors a caller running under a temporary named region. + session.env["WIND_OVERRIDE"] = "local_region" + Tools(session=session).v_proj( + project=source.name, + mapset="PERMANENT", + input="points", + output="points", + ) + assert gs.find_file("points", element="vector", env=session.env)["name"]