Skip to content

handler_for_filtered not behaving as expected. #293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
knaveofdiamonds opened this issue May 22, 2025 · 4 comments
Closed

handler_for_filtered not behaving as expected. #293

knaveofdiamonds opened this issue May 22, 2025 · 4 comments

Comments

@knaveofdiamonds
Copy link

If I have code like the following:

writer = osmium.SimpleWriter(output_pbf, overwrite=True)

 fp = osmium.FileProcessor(input_pbf).with_filter(
    osmium.filter.IdFilter([1,2,3]).enable_for(osmium.osm.WAY)
).with_filter(
    osmium.filter.IdFilter([1,2,3]).enable_for(osmium.osm.NODE)
).handler_for_filtered(writer)

for o in fp:
    # ... process nodes and ways

I would have expected that the relations would just get passed through to the output via the handler_for_filtered method, however this is not the case. I need to add something with a filter that filters everything in order to get them to show, like:

with_filter(
            osmium.filter.IdFilter([-1]).enable_for(osmium.osm.RELATION)
        )

This feels unexpected - is this a bug, or intended, or am I just missing passing a parameter somewhere? If intended is it possible to configure this behavior, so you don't need to add spurious filters?

@lonvia
Copy link
Member

lonvia commented May 22, 2025

This is intended behaviour.

The FileProcessor will initially forward every single object it encounters in the file to the body of the for loop. When you add a filter, then some objects are dropped. The enable_for() function ensures that whatever the filter drops is of a certain OSM type. So your example expresses to drop some ways and some nodes but it says nothing at all about filtering relations. Therefore all relations end up being presented to the for loop and not to the handler for objects that have been filtered.

If you know that you are only interested in ways and nodes, use an EntityFilter to filter out relations right away:

fp = osmium.FileProcessor(input_pbf)\
        .with_filter(osmium.filter.EntityFilter(osmium.osm.NODE | osmium.osm.WAY)
        .with_filter(osmium.filter.IdFilter([1,2,3]).enable_for(osmium.osm.WAY))\
        .with_filter(osmium.filter.IdFilter([1,2,3]).enable_for(osmium.osm.NODE))\
        .handler_for_filtered(writer)

@knaveofdiamonds
Copy link
Author

If you know that you are only interested in ways and nodes, use an EntityFilter to filter out relations right away

So my use case is that I want to modify a file, but I only care about modifying ways & nodes, and just want to pass through relations. With your last example will adding a .with_filter(osmium.filter.EntityFilter(osmium.osm.ALL) do that for me? This seems marginally cleaner than filtering on a non-existent id, just to get relations in the output.

@lonvia
Copy link
Member

lonvia commented May 22, 2025

Please read the code I provided.

@knaveofdiamonds
Copy link
Author

Ok - I see now, I was getting confused about what was being filtered in vs being filtered out. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants