Skip to content

Commit 39dce02

Browse files
committed
feat: add parameter to support both AND and OR combinations of tags_filter.
1 parent ca3e233 commit 39dce02

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

quackosm/functions.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ def convert_pbf_to_duckdb(
5151
ignore_cache: bool = False,
5252
filter_osm_ids: Optional[list[str]] = None,
5353
custom_sql_filter: Optional[str] = None,
54+
filter_logical_operator: str = "OR",
5455
duckdb_table_name: str = "quackosm",
5556
working_directory: Union[str, Path] = "files",
5657
osm_way_polygon_features_config: Optional[Union[OsmWayPolygonConfig, dict[str, Any]]] = None,
@@ -108,6 +109,10 @@ def convert_pbf_to_duckdb(
108109
custom_sql_filter (str, optional): Allows users to pass custom SQL conditions used
109110
to filter OSM features. It will be embedded into predefined queries and requires
110111
DuckDB syntax to operate on tags map object. Defaults to None.
112+
filter_logical_operator (str, optional): Logical operator used to join positive tag filter
113+
conditions. Either "OR" (default) or "AND". With "OR", objects matching any
114+
of the tag conditions are included. With "AND", objects must match all tag
115+
conditions. Defaults to "OR".
111116
duckdb_table_name (str): Table in which to store the OSM data inside the DuckDB database.
112117
working_directory (Union[str, Path], optional): Directory where to save
113118
the parsed `*.parquet` files. Defaults to "files".
@@ -269,6 +274,7 @@ def convert_pbf_to_duckdb(
269274
tags_filter=tags_filter,
270275
geometry_filter=geometry_filter,
271276
custom_sql_filter=custom_sql_filter,
277+
filter_logical_operator=filter_logical_operator,
272278
working_directory=working_directory,
273279
osm_way_polygon_features_config=osm_way_polygon_features_config,
274280
compression=compression,
@@ -306,6 +312,7 @@ def convert_geometry_to_duckdb(
306312
ignore_cache: bool = False,
307313
filter_osm_ids: Optional[list[str]] = None,
308314
custom_sql_filter: Optional[str] = None,
315+
filter_logical_operator: str = "OR",
309316
duckdb_table_name: str = "quackosm",
310317
working_directory: Union[str, Path] = "files",
311318
osm_way_polygon_features_config: Optional[Union[OsmWayPolygonConfig, dict[str, Any]]] = None,
@@ -368,6 +375,10 @@ def convert_geometry_to_duckdb(
368375
custom_sql_filter (str, optional): Allows users to pass custom SQL conditions used
369376
to filter OSM features. It will be embedded into predefined queries and requires
370377
DuckDB syntax to operate on tags map object. Defaults to None.
378+
filter_logical_operator (str, optional): Logical operator used to join positive tag filter
379+
conditions. Either "OR" (default) or "AND". With "OR", objects matching any
380+
of the tag conditions are included. With "AND", objects must match all tag
381+
conditions. Defaults to "OR".
371382
duckdb_table_name (str): Table in which to store the OSM data inside the DuckDB database.
372383
working_directory (Union[str, Path], optional): Directory where to save
373384
the parsed `*.parquet` files. Defaults to "files".
@@ -492,6 +503,7 @@ def convert_geometry_to_duckdb(
492503
tags_filter=tags_filter,
493504
geometry_filter=geometry_filter,
494505
custom_sql_filter=custom_sql_filter,
506+
filter_logical_operator=filter_logical_operator,
495507
working_directory=working_directory,
496508
osm_way_polygon_features_config=osm_way_polygon_features_config,
497509
compression=compression,
@@ -532,6 +544,7 @@ def convert_osm_extract_to_duckdb(
532544
ignore_cache: bool = False,
533545
filter_osm_ids: Optional[list[str]] = None,
534546
custom_sql_filter: Optional[str] = None,
547+
filter_logical_operator: str = "OR",
535548
duckdb_table_name: str = "quackosm",
536549
working_directory: Union[str, Path] = "files",
537550
osm_way_polygon_features_config: Optional[Union[OsmWayPolygonConfig, dict[str, Any]]] = None,
@@ -592,6 +605,10 @@ def convert_osm_extract_to_duckdb(
592605
custom_sql_filter (str, optional): Allows users to pass custom SQL conditions used
593606
to filter OSM features. It will be embedded into predefined queries and requires
594607
DuckDB syntax to operate on tags map object. Defaults to None.
608+
filter_logical_operator (str, optional): Logical operator used to join positive tag filter
609+
conditions. Either "OR" (default) or "AND". With "OR", objects matching any
610+
of the tag conditions are included. With "AND", objects must match all tag
611+
conditions. Defaults to "OR".
595612
duckdb_table_name (str): Table in which to store the OSM data inside the DuckDB database.
596613
working_directory (Union[str, Path], optional): Directory where to save
597614
the parsed `*.parquet` files. Defaults to "files".
@@ -672,6 +689,7 @@ def convert_osm_extract_to_duckdb(
672689
tags_filter=tags_filter,
673690
geometry_filter=geometry_filter,
674691
custom_sql_filter=custom_sql_filter,
692+
filter_logical_operator=filter_logical_operator,
675693
working_directory=working_directory,
676694
osm_way_polygon_features_config=osm_way_polygon_features_config,
677695
compression=compression,
@@ -709,6 +727,7 @@ def convert_pbf_to_parquet(
709727
ignore_cache: bool = False,
710728
filter_osm_ids: Optional[list[str]] = None,
711729
custom_sql_filter: Optional[str] = None,
730+
filter_logical_operator: str = "OR",
712731
working_directory: Union[str, Path] = "files",
713732
osm_way_polygon_features_config: Optional[Union[OsmWayPolygonConfig, dict[str, Any]]] = None,
714733
save_as_wkt: bool = False,
@@ -766,6 +785,10 @@ def convert_pbf_to_parquet(
766785
custom_sql_filter (str, optional): Allows users to pass custom SQL conditions used
767786
to filter OSM features. It will be embedded into predefined queries and requires
768787
DuckDB syntax to operate on tags map object. Defaults to None.
788+
filter_logical_operator (str, optional): Logical operator used to join positive tag filter
789+
conditions. Either "OR" (default) or "AND". With "OR", objects matching any
790+
of the tag conditions are included. With "AND", objects must match all tag
791+
conditions. Defaults to "OR".
769792
working_directory (Union[str, Path], optional): Directory where to save
770793
the parsed `*.parquet` files. Defaults to "files".
771794
osm_way_polygon_features_config (Union[OsmWayPolygonConfig, dict[str, Any]], optional):
@@ -927,6 +950,7 @@ def convert_pbf_to_parquet(
927950
tags_filter=tags_filter,
928951
geometry_filter=geometry_filter,
929952
custom_sql_filter=custom_sql_filter,
953+
filter_logical_operator=filter_logical_operator,
930954
working_directory=working_directory,
931955
osm_way_polygon_features_config=osm_way_polygon_features_config,
932956
compression=compression,
@@ -964,6 +988,7 @@ def convert_geometry_to_parquet(
964988
ignore_cache: bool = False,
965989
filter_osm_ids: Optional[list[str]] = None,
966990
custom_sql_filter: Optional[str] = None,
991+
filter_logical_operator: str = "OR",
967992
working_directory: Union[str, Path] = "files",
968993
osm_way_polygon_features_config: Optional[Union[OsmWayPolygonConfig, dict[str, Any]]] = None,
969994
save_as_wkt: bool = False,
@@ -1026,6 +1051,10 @@ def convert_geometry_to_parquet(
10261051
custom_sql_filter (str, optional): Allows users to pass custom SQL conditions used
10271052
to filter OSM features. It will be embedded into predefined queries and requires
10281053
DuckDB syntax to operate on tags map object. Defaults to None.
1054+
filter_logical_operator (str, optional): Logical operator used to join positive tag filter
1055+
conditions. Either "OR" (default) or "AND". With "OR", objects matching any
1056+
of the tag conditions are included. With "AND", objects must match all tag
1057+
conditions. Defaults to "OR".
10291058
working_directory (Union[str, Path], optional): Directory where to save
10301059
the parsed `*.parquet` files. Defaults to "files".
10311060
osm_way_polygon_features_config (Union[OsmWayPolygonConfig, dict[str, Any]], optional):
@@ -1149,6 +1178,7 @@ def convert_geometry_to_parquet(
11491178
tags_filter=tags_filter,
11501179
geometry_filter=geometry_filter,
11511180
custom_sql_filter=custom_sql_filter,
1181+
filter_logical_operator=filter_logical_operator,
11521182
working_directory=working_directory,
11531183
osm_way_polygon_features_config=osm_way_polygon_features_config,
11541184
compression=compression,
@@ -1189,6 +1219,7 @@ def convert_osm_extract_to_parquet(
11891219
ignore_cache: bool = False,
11901220
filter_osm_ids: Optional[list[str]] = None,
11911221
custom_sql_filter: Optional[str] = None,
1222+
filter_logical_operator: str = "OR",
11921223
working_directory: Union[str, Path] = "files",
11931224
osm_way_polygon_features_config: Optional[Union[OsmWayPolygonConfig, dict[str, Any]]] = None,
11941225
save_as_wkt: bool = False,
@@ -1249,6 +1280,10 @@ def convert_osm_extract_to_parquet(
12491280
custom_sql_filter (str, optional): Allows users to pass custom SQL conditions used
12501281
to filter OSM features. It will be embedded into predefined queries and requires
12511282
DuckDB syntax to operate on tags map object. Defaults to None.
1283+
filter_logical_operator (str, optional): Logical operator used to join positive tag filter
1284+
conditions. Either "OR" (default) or "AND". With "OR", objects matching any
1285+
of the tag conditions are included. With "AND", objects must match all tag
1286+
conditions. Defaults to "OR".
12521287
working_directory (Union[str, Path], optional): Directory where to save
12531288
the parsed `*.parquet` files. Defaults to "files".
12541289
osm_way_polygon_features_config (Union[OsmWayPolygonConfig, dict[str, Any]], optional):
@@ -1330,6 +1365,7 @@ def convert_osm_extract_to_parquet(
13301365
tags_filter=tags_filter,
13311366
geometry_filter=geometry_filter,
13321367
custom_sql_filter=custom_sql_filter,
1368+
filter_logical_operator=filter_logical_operator,
13331369
working_directory=working_directory,
13341370
osm_way_polygon_features_config=osm_way_polygon_features_config,
13351371
compression=compression,
@@ -1367,6 +1403,7 @@ def convert_pbf_to_geodataframe(
13671403
ignore_cache: bool = False,
13681404
filter_osm_ids: Optional[list[str]] = None,
13691405
custom_sql_filter: Optional[str] = None,
1406+
filter_logical_operator: str = "OR",
13701407
working_directory: Union[str, Path] = "files",
13711408
osm_way_polygon_features_config: Optional[Union[OsmWayPolygonConfig, dict[str, Any]]] = None,
13721409
verbosity_mode: VERBOSITY_MODE = "transient",
@@ -1423,6 +1460,10 @@ def convert_pbf_to_geodataframe(
14231460
custom_sql_filter (str, optional): Allows users to pass custom SQL conditions used
14241461
to filter OSM features. It will be embedded into predefined queries and requires
14251462
DuckDB syntax to operate on tags map object. Defaults to None.
1463+
filter_logical_operator (str, optional): Logical operator used to join positive tag filter
1464+
conditions. Either "OR" (default) or "AND". With "OR", objects matching any
1465+
of the tag conditions are included. With "AND", objects must match all tag
1466+
conditions. Defaults to "OR".
14261467
working_directory (Union[str, Path], optional): Directory where to save
14271468
the parsed `*.parquet` files. Defaults to "files".
14281469
osm_way_polygon_features_config (Union[OsmWayPolygonConfig, dict[str, Any]], optional):
@@ -1558,6 +1599,7 @@ def convert_pbf_to_geodataframe(
15581599
tags_filter=tags_filter,
15591600
geometry_filter=geometry_filter,
15601601
custom_sql_filter=custom_sql_filter,
1602+
filter_logical_operator=filter_logical_operator,
15611603
working_directory=working_directory,
15621604
osm_way_polygon_features_config=osm_way_polygon_features_config,
15631605
compression=compression,
@@ -1591,6 +1633,7 @@ def convert_geometry_to_geodataframe(
15911633
ignore_cache: bool = False,
15921634
filter_osm_ids: Optional[list[str]] = None,
15931635
custom_sql_filter: Optional[str] = None,
1636+
filter_logical_operator: str = "OR",
15941637
working_directory: Union[str, Path] = "files",
15951638
osm_way_polygon_features_config: Optional[Union[OsmWayPolygonConfig, dict[str, Any]]] = None,
15961639
verbosity_mode: VERBOSITY_MODE = "transient",
@@ -1649,6 +1692,10 @@ def convert_geometry_to_geodataframe(
16491692
custom_sql_filter (str, optional): Allows users to pass custom SQL conditions used
16501693
to filter OSM features. It will be embedded into predefined queries and requires
16511694
DuckDB syntax to operate on tags map object. Defaults to None.
1695+
filter_logical_operator (str, optional): Logical operator used to join positive tag filter
1696+
conditions. Either "OR" (default) or "AND". With "OR", objects matching any
1697+
of the tag conditions are included. With "AND", objects must match all tag
1698+
conditions. Defaults to "OR".
16521699
working_directory (Union[str, Path], optional): Directory where to save
16531700
the parsed `*.parquet` files. Defaults to "files".
16541701
osm_way_polygon_features_config (Union[OsmWayPolygonConfig, dict[str, Any]], optional):
@@ -1729,6 +1776,7 @@ def convert_geometry_to_geodataframe(
17291776
tags_filter=tags_filter,
17301777
geometry_filter=geometry_filter,
17311778
custom_sql_filter=custom_sql_filter,
1779+
filter_logical_operator=filter_logical_operator,
17321780
working_directory=working_directory,
17331781
osm_way_polygon_features_config=osm_way_polygon_features_config,
17341782
compression=compression,
@@ -1765,6 +1813,7 @@ def convert_osm_extract_to_geodataframe(
17651813
ignore_cache: bool = False,
17661814
filter_osm_ids: Optional[list[str]] = None,
17671815
custom_sql_filter: Optional[str] = None,
1816+
filter_logical_operator: str = "OR",
17681817
working_directory: Union[str, Path] = "files",
17691818
osm_way_polygon_features_config: Optional[Union[OsmWayPolygonConfig, dict[str, Any]]] = None,
17701819
verbosity_mode: VERBOSITY_MODE = "transient",
@@ -1821,6 +1870,10 @@ def convert_osm_extract_to_geodataframe(
18211870
custom_sql_filter (str, optional): Allows users to pass custom SQL conditions used
18221871
to filter OSM features. It will be embedded into predefined queries and requires
18231872
DuckDB syntax to operate on tags map object. Defaults to None.
1873+
filter_logical_operator (str, optional): Logical operator used to join positive tag filter
1874+
conditions. Either "OR" (default) or "AND". With "OR", objects matching any
1875+
of the tag conditions are included. With "AND", objects must match all tag
1876+
conditions. Defaults to "OR".
18241877
working_directory (Union[str, Path], optional): Directory where to save
18251878
the parsed `*.parquet` files. Defaults to "files".
18261879
osm_way_polygon_features_config (Union[OsmWayPolygonConfig, dict[str, Any]], optional):
@@ -1892,6 +1945,7 @@ def convert_osm_extract_to_geodataframe(
18921945
tags_filter=tags_filter,
18931946
geometry_filter=geometry_filter,
18941947
custom_sql_filter=custom_sql_filter,
1948+
filter_logical_operator=filter_logical_operator,
18951949
working_directory=working_directory,
18961950
osm_way_polygon_features_config=osm_way_polygon_features_config,
18971951
compression=compression,

quackosm/pbf_file_reader.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ def __init__(
143143
tags_filter: Optional[Union[OsmTagsFilter, GroupedOsmTagsFilter]] = None,
144144
geometry_filter: Optional[BaseGeometry] = None,
145145
custom_sql_filter: Optional[str] = None,
146+
filter_logical_operator: str = "OR",
146147
working_directory: Union[str, Path] = "files",
147148
osm_way_polygon_features_config: Optional[
148149
Union[OsmWayPolygonConfig, dict[str, Any]]
@@ -177,6 +178,10 @@ def __init__(
177178
custom_sql_filter (str, optional): Allows users to pass custom SQL conditions used
178179
to filter OSM features. It will be embedded into predefined queries and requires
179180
DuckDB syntax to operate on tags map object. Defaults to `None`.
181+
filter_logical_operator (str, optional): Logical operator used to join positive tag
182+
filter conditions. Either "OR" (default) or "AND". With "OR", objects matching any
183+
of the tag conditions are included. With "AND", objects must match all tag
184+
conditions. Defaults to "OR".
180185
working_directory (Union[str, Path], optional): Directory where to save
181186
the parsed `*.parquet` files. Defaults to "files".
182187
osm_way_polygon_features_config (Union[OsmWayPolygonConfig, dict[str, Any]], optional):
@@ -229,6 +234,9 @@ def __init__(
229234
self.merged_tags_filter: Optional[Union[GroupedOsmTagsFilter, OsmTagsFilter]] = None
230235

231236
self.custom_sql_filter = custom_sql_filter
237+
self.filter_logical_operator = filter_logical_operator.upper()
238+
if self.filter_logical_operator not in ("OR", "AND"):
239+
raise ValueError("filter_logical_operator must be either 'OR' or 'AND'")
232240

233241
self.geometry_coverage_iou_threshold = geometry_coverage_iou_threshold
234242
self.allow_uncovered_geometry = allow_uncovered_geometry
@@ -1809,7 +1817,7 @@ def _generate_osm_tags_sql_filter(self) -> str:
18091817
if not positive_filter_clauses:
18101818
positive_filter_clauses.append("(1=1)")
18111819

1812-
joined_filter_clauses = " OR ".join(positive_filter_clauses)
1820+
joined_filter_clauses = f" {self.filter_logical_operator} ".join(positive_filter_clauses)
18131821
if negative_filter_clauses:
18141822
joined_filter_clauses = (
18151823
f"({joined_filter_clauses}) AND ({' AND '.join(negative_filter_clauses)})"

0 commit comments

Comments
 (0)