Repository: geofileops/geofileops
Pull request #632 (2025-02-14 10:40:14)

BUG: GDAL input open options are ignored in `copy_layer`

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/geofileops/geofileops/pull/632?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=geofileops) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 86.27%. Comparing base [(`5f08842`)](https://app.codecov.io/gh/geofileops/geofileops/commit/5f08842e475a5aaff2f4ace75e7bc77c9c2fe023?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=geofileops) to head [(`717dfc1`)](https://app.codecov.io/gh/geofileops/geofileops/commit/717dfc1cab2583f8b74820359f69a44bb277bce1?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=geofileops).
> Report is 108 commits behind head on main.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #632      +/-   ##
==========================================
- Coverage   93.11%   86.27%   -6.85%     
==========================================
  Files          21       22       +1     
  Lines        4113     4489     +376     
==========================================
+ Hits         3830     3873      +43     
- Misses        283      616     +333     
```

</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/geofileops/geofileops/pull/632?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=geofileops).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=geofileops).


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3379c33..e866fbb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,9 +17,11 @@
   `symmetric_difference` and `union`. (#585, #601, #591, #614)
 - Add support to rename columns and layers with only a difference in casing (#549, #593)
 - Avoid integer overflow when gpkg written by geofileops is read from .NET (#612)
-- Speed up two layer operations: explicitly start transactions in sqlite3 code, don't 
-  create obsolete triggers and use a memory temp file where possible (#626, #628, #630)
-- Speed up processing many small files: reduce calls to `gdal.OpenEx` (#622, #625)
+- Speed up processing many small files, mainly on windows:
+    - reduce calls to `gdal.OpenEx` (#622, #625)
+    - improvements in sqlite3 code for 2 layer operations: start transactions
+      explicitly, remove obsolete GPKG triggers, use a :memory: temp file where possible
+      (#626, #628, #630)
 - Add support to pass a single string for all `column` type parameters if a single
   column should be retained (#523)
 - Enable "CURVE" geometrytype files to be processed in the general file and
@@ -31,6 +33,7 @@
 ### Bugs fixed
 
 - Fix `copy_layer` to a gpkg.zip file (#604)
+- Fix GDAL input open options being ignored in `copy_layer` (#632)
 - Fix `missing_ok` parameter in `remove` being ~ignored (#605)
 
 ## 0.9.1 (2024-07-18)
diff --git a/geofileops/util/_ogr_util.py b/geofileops/util/_ogr_util.py
index 75ddc44..e782bb5 100644
--- a/geofileops/util/_ogr_util.py
+++ b/geofileops/util/_ogr_util.py
@@ -330,8 +330,9 @@ def vector_translate(
             raise ValueError(f"unsupported warp algorithm: {algorithm}")
 
     # Input dataset open options
+    input_open_options = []
     for option_name, value in gdal_options["INPUT_OPEN"].items():
-        args.extend(["-oo", f"{option_name}={value}"])
+        input_open_options.append(f"{option_name}={value!s}")
 
     # Output file parameters
     # Get driver for the output_path
@@ -457,6 +458,7 @@ def vector_translate(
             input_ds = gdal.OpenEx(
                 str(input_path),
                 nOpenFlags=gdal.OF_VECTOR | gdal.OF_READONLY | gdal.OF_SHARED,
+                open_options=input_open_options,
             )
 
             # If output_srs is not specified and the result has 0 rows, gdal creates the


Test patch:
diff --git a/tests/test_geofile.py b/tests/test_geofile.py
index 7e9d6ec..957ae69 100644
--- a/tests/test_geofile.py
+++ b/tests/test_geofile.py
@@ -345,6 +345,34 @@ def test_copy_layer_invalid_params(tmp_path):
         gfo.copy_layer(src, dst)
 
 
+def test_copy_layer_input_open_options(tmp_path):
+    # Prepare test data
+    src = tmp_path / "input.csv"
+    dst = tmp_path / "output.gpkg"
+    with open(src, "w") as srcfile:
+        srcfile.write("POINT_ID, POINT_LAT, POINT_LON, POINT_NAME\n")
+        srcfile.write('1, 50.939972761,3.888498686, "random spot"\n')
+
+    # copy_layer with open_options
+    gfo.copy_layer(
+        src,
+        dst,
+        options={
+            "INPUT_OPEN.X_POSSIBLE_NAMES": "POINT_LON",
+            "INPUT_OPEN.Y_POSSIBLE_NAMES": "POINT_LAT",
+        },
+        dst_crs="EPSG:4326",
+    )
+
+    # Check result
+    assert dst.exists()
+    result_gdf = gfo.read_file(dst)
+    assert len(result_gdf) == 1
+    assert "geometry" in result_gdf.columns
+    assert result_gdf.geometry[0].x == 3.888498686
+    assert result_gdf.geometry[0].y == 50.939972761
+
+
 @pytest.mark.parametrize(
     "src_suffix, dst_suffix, preserve_fid, exp_preserved_fids",
     [