# Interoperability and export

    library(osmnxr)
    g <- ox_example("olinda") # a small real network bundled with the package

An `osm_graph` is deliberately thin: tidy `sf` nodes and edges. That makes it easy to hand off to the rest of the R spatial-network ecosystem, or to export for other tools.

## sf

The nodes and edges are always available as `sf`:

    parts <- ox_as_sf(g)
    parts$edges
    #> Simple feature collection with 1191 features and 5 fields
    #> Geometry type: LINESTRING
    #> Dimension:     XY
    #> Bounding box:  xmin: -34.86427 ymin: -8.019512 xmax: -34.84686 ymax: -7.999988
    #> Geodetic CRS:  WGS 84
    #> First 10 features:
    #>             u          v     length     highway                           name
    #> 1  3567235794  655141381 143.059872       trunk         Avenida Pan Nordestina
    #> 2   655141381 1572683340  39.206250       trunk         Avenida Pan Nordestina
    #> 3   655141381 1572703444 108.819636 residential Rua Honorato do Espírito Santo
    #> 4  1572703444  655141381 108.819636 residential Rua Honorato do Espírito Santo
    #> 5   655144602  655144717  47.559016    tertiary             Rua Lucilo Varejão
    #> 6   655144717  655144602  47.559016    tertiary             Rua Lucilo Varejão
    #> 7   655144602 1446749601  94.315783    tertiary  Rua Manuel Clementino Marques
    #> 8  1446749601  655144602  94.315783    tertiary  Rua Manuel Clementino Marques
    #> 9   655144602 7271784016   2.199505    tertiary  Rua Manuel Clementino Marques
    #> 10 7271784016  655144602   2.199505    tertiary  Rua Manuel Clementino Marques
    #>                          geometry
    #> 1  LINESTRING (-34.85776 -8.00...
    #> 2  LINESTRING (-34.85716 -8.00...
    #> 3  LINESTRING (-34.85716 -8.00...
    #> 4  LINESTRING (-34.85675 -8.00...
    #> 5  LINESTRING (-34.85867 -8.00...
    #> 6  LINESTRING (-34.85889 -8.00...
    #> 7  LINESTRING (-34.85867 -8.00...
    #> 8  LINESTRING (-34.8595 -8.007...
    #> 9  LINESTRING (-34.85867 -8.00...
    #> 10 LINESTRING (-34.85865 -8.00...

## sfnetworks and tidygraph

Convert to an `sfnetwork` for the `tidygraph` verb workflow, or to a bare `tbl_graph`:

    net <- ox_as_sfnetwork(g)
    net

    tg <- ox_as_tidygraph(g)
    tg

## dodgr

`ox_as_dodgr()` returns the column layout `dodgr` expects, so you can use its highly optimised routing directly:

    library(dodgr)
    graph <- ox_as_dodgr(g)
    dodgr_dists(graph, from = graph$from_id[1], to = graph$to_id[10])

## GeoJSON and MapLibre

Export edges to GeoJSON, or build a MapLibre GL style fragment that points at the written data:

    gj <- tempfile(fileext = ".geojson")
    ox_to_geojson(g, gj)

    style <- ox_to_maplibre(g, tempfile(fileext = ".geojson"))
    str(style, max.level = 2)
    #> List of 2
    #>  $ sources:List of 1
    #>   ..$ osmnxr:List of 2
    #>  $ layers :List of 1
    #>   ..$ :List of 4

## GraphML round-trip

`ox_save_graphml()` / `ox_load_graphml()` persist the graph in a format compatible with OSMnx, NetworkX and Gephi. Edge geometry is stored as WKT, so the round-trip is lossless:

    f <- tempfile(fileext = ".graphml")
    ox_save_graphml(g, f)
    g2 <- ox_load_graphml(f)
    ox_basic_stats(g2)
    #> # A tibble: 1 × 7
    #>   n_nodes n_edges total_length mean_length mean_out_degree self_loops circuity
    #>     <int>   <int>        <dbl>       <dbl>           <dbl>      <int>    <dbl>
    #> 1     498    1191       95484.        80.2            2.39          1     1.06