Skip to content

Handler-based Processing🔗

All examples so far have used the FileProcessor for reading files. It provides an iterative way of working through the data, which comes quite natural to a Python programmer. This chapter shows a different way of processing a file. It shows how to create one or more handler classes and apply those to an input file.

Note: handler classes used to be the only way of processing data in older pyosimum versions. You may therefore find them in many tutorials and examples. There is no disadvantage in using FileProcessors instead. Handlers simply provide a different syntax for achieving a similar goal.

The handler object and osmium.apply🔗

A pyosmium handler object is simply a Python object that implements callbacks to handle the different types of entities (node, way, relation, area, changeset). Usually you would define a class with your handler functions and instantiate it. A complete handler class that prints out each object in the file would look like this:

Example

class PrintHandler:
    def node(self, n):
        print(n)

    def way(self, w):
        print(w)

    def relation(self, r):
        print(r)

    def area(self, a):
        print(a)

    def changeset(self, c):
        print(c)

Such a handler is applied to an OSM file with the function osmium.apply(). The function takes a single file as an argument and then an arbitrary number of handlers:

Example

import osmium

my_handler = PrintHandler()

osmium.apply('buildings.opl', my_handler)
n1: location=45.0000000/13.0000000 tags={}
n2: location=45.0001000/13.0000000 tags={}
n3: location=45.0001000/13.0001000 tags={}
n4: location=45.0000000/13.0001000 tags={entrance=yes}
n11: location=45.0000100/13.0000100 tags={}
n12: location=45.0000500/13.0000100 tags={}
n13: location=45.0000500/13.0000500 tags={}
n14: location=45.0000100/13.0000500 tags={}
w1: nodes=[1,2,3,4,1] tags={amenity=restaurant}
w2: nodes=[11,12,13,14,11] tags={}
r1: members=[w1,w2], tags={type=multipolygon,building=yes}

Using filters with apply🔗

Filter functions are also recognised as handlers by the apply functions. They have the same effect as when used in FileProcessors: when they signal to filter out an object, then the processing is stopped for that object and the next object is processed. You can arbitrarily mix filters and custom-made handlers. They are sequentially executed in the order in which they appear in the apply function:

Example

osmium.apply('buildings.opl',
             osmium.filter.EntityFilter(osmium.osm.RELATION),
             my_handler,
             osmium.filter.KeyFilter('route')),
             my_other_handler

The osmium.SimpleHandler class🔗

The apply function is a very low-level function for processing. It will only apply the handler functions to the input and be done with it. It will in particular not care about providing the necessary building blocks for geometry processing. If you need to work with geometries, you can derive your handler class from osmium.SimpleHandler. This mix-in class adds two convenience functions to your handler : apply_file() and apply_buffer(). These functions apply the handler itself to a file or buffer but come with additional parameter to enable location. If the handler implements an area callback, then they automatically enable area processing as well.