I know about using ogr2ogr, and also about the nodejs module osm_geojson. However, I would like to convert GeoJSON to OSM XML from Python. Is there a library which has this capability built in? Or would I have to write custom code based on the OSM XML specification? I am processing the GeoJSON using geopandas, so exporting directly from geopandas to OSM would also work.

I have looked at the GDAL/OGR Python library. It may be able to do what I want, but the documentation is impenetrable. The Cookbook has something similar to what I am looking for, but I can't quite seem to piece it together.

My code currently looks like this:

from osgeo import ogr
import os

# Read GeoJSON file
geojson_file = 'file.geojson'
GeoJSON_driver = ogr.GetDriverByName('GeoJSON')
data = GeoJSON_driver.Open(geojson_file, 0)
layer = data.GetLayer()

# OSM file to write
osm_file = 'file.osm'
OSM_driver = ogr.GetDriverByName('OSM')

# Remove output file if it already exists
if os.path.exists(osm_file):

# Export data to OSM file
# This is where I'm stuck

There is a Python tool ogr2osm.py available here https://github.com/pnorman/ogr2osm.


I wrote some code to create OSM XML from a geopandas dataframe. Note that my use case only required conversion of GeoJSON points to OSM nodes. More complex use cases should consider adapting code from ogr2osm as mentioned in the other answer.

For future reference, here is the code I used. (This assumes geopandas column names are valid OSM tags):

import xml.etree.ElementTree as ET

def export_geopandas_to_osm_xml(geopandas_data_frame):
    osm_root = ET.Element('osm', attrib={
        'version': '0.6',
        'generator': 'custom python script'

    i = -1
    for index, row in geopandas_data_frame.iterrows():
        current_node = ET.SubElement(osm_root, 'node', attrib={
            'id': str(i),
            'lat': str(row.geometry.y),
            'lon': str(row.geometry.x),
            'changeset': 'false'})
        for column in geopandas_data_frame.loc[:, ['addr:housenumber', 'addr:street']]:
            ET.SubElement(current_node, 'tag', attrib={
                'k': column,
                'v': row[column]})
        i -= 1
    output_file = ET.ElementTree(element=osm_root)

Your Answer

