@@ -771,6 +771,26 @@ cdef apply_geometry_filter(OGRLayerH ogr_layer, wkb):
771
771
OGR_G_DestroyGeometry(ogr_geometry)
772
772
773
773
774
+ cdef apply_skip_features(OGRLayerH ogr_layer, int skip_features):
775
+ """ Applies skip_features to layer.
776
+
777
+ Parameters
778
+ ----------
779
+ ogr_layer : pointer to open OGR layer
780
+ wskip_features : int
781
+ """
782
+ err = OGR_L_SetNextByIndex(ogr_layer, skip_features)
783
+ # GDAL can raise an error (depending on the format) for out-of-bound index,
784
+ # but `validate_feature_range()` should ensure we only pass a valid number
785
+ if err != OGRERR_NONE:
786
+ try :
787
+ check_last_error()
788
+ except CPLE_BaseError as exc:
789
+ raise ValueError (str (exc))
790
+
791
+ raise ValueError (f" Applying {skip_features=} raised an error" )
792
+
793
+
774
794
cdef validate_feature_range(
775
795
OGRLayerH ogr_layer, int skip_features = 0 , int max_features = 0
776
796
):
@@ -793,9 +813,9 @@ cdef validate_feature_range(
793
813
return 0 , 0
794
814
795
815
if skip_features >= feature_count:
796
- skip_features = feature_count
816
+ return 0 , 0
797
817
798
- elif max_features == 0 :
818
+ if max_features == 0 :
799
819
num_features = feature_count - skip_features
800
820
801
821
elif max_features > feature_count:
@@ -973,7 +993,7 @@ cdef get_features(
973
993
OGR_L_ResetReading(ogr_layer)
974
994
975
995
if skip_features > 0 :
976
- OGR_L_SetNextByIndex (ogr_layer, skip_features)
996
+ apply_skip_features (ogr_layer, skip_features)
977
997
978
998
if return_fids:
979
999
fid_data = np.empty(shape = (num_features), dtype = np.int64)
@@ -1148,7 +1168,7 @@ cdef get_bounds(OGRLayerH ogr_layer, int skip_features, int num_features):
1148
1168
OGR_L_ResetReading(ogr_layer)
1149
1169
1150
1170
if skip_features > 0 :
1151
- OGR_L_SetNextByIndex (ogr_layer, skip_features)
1171
+ apply_skip_features (ogr_layer, skip_features)
1152
1172
1153
1173
fid_data = np.empty(shape = (num_features), dtype = np.int64)
1154
1174
fid_view = fid_data[:]
@@ -1668,6 +1688,13 @@ def ogr_open_arrow(
1668
1688
elif mask is not None :
1669
1689
apply_geometry_filter(ogr_layer, mask)
1670
1690
1691
+ # Limit feature range to available range (cannot use logic of
1692
+ # `validate_feature_range` because max_features is not supported)
1693
+ if skip_features > 0 :
1694
+ feature_count = get_feature_count(ogr_layer, 1 )
1695
+ if skip_features >= feature_count:
1696
+ skip_features = feature_count
1697
+
1671
1698
# Limit to specified columns
1672
1699
if ignored_fields:
1673
1700
for field in ignored_fields:
@@ -1704,9 +1731,11 @@ def ogr_open_arrow(
1704
1731
if not OGR_L_GetArrowStream(ogr_layer, stream, options):
1705
1732
raise RuntimeError (" Failed to open ArrowArrayStream from Layer" )
1706
1733
1707
- if skip_features:
1734
+ if skip_features > 0 :
1708
1735
# only supported for GDAL >= 3.8.0; have to do this after getting
1709
1736
# the Arrow stream
1737
+ # use `OGR_L_SetNextByIndex` directly and not `apply_skip_features`
1738
+ # to ignore errors in case skip_features == feature_count
1710
1739
OGR_L_SetNextByIndex(ogr_layer, skip_features)
1711
1740
1712
1741
if use_pyarrow:
0 commit comments