2

I am using Osm2PO for route finding which reads a graph file created from a pbf file downloaded from OpenStreetMap.

I have my own GIS database where updates may be applied to the data. I would like Osm2PO to be able to generate a graph based on this DB.

Does anyone know how I can generate a osm pbf file from a database created using Osm2Pgsql? I have tried using Osmosis with commands like:

osmosis --read-pgsql host="localhost" database="gis" user="username" --write-pbf file="OSMDump" 

but it gives an error saying Task 2-write-pbf does not support data provided by default pipe stored at level 1 in the default pipe stack.

Thanks

Relations table schame

Table "public.planet_osm_rels"
 Column  |   Type   | Modifiers 
---------+----------+-----------
 id      | bigint   | not null
 way_off | smallint | 
 rel_off | smallint | 
 parts   | bigint[] | 
 members | text[]   | 
 tags    | text[]   | 
 pending | boolean  | not null

Code: Here are the classes (I'll leave out the getters/setters): Node class:

private long id;
private int lat;
private int lon;
private String[] tags;

Way class:

private long id;
private Long[] nodes;
private String[] tags;

Relation:

private long id;
private String[] members;
private String[] tags;

parse method (gets data from DB and stores in the collections):

ArrayList<Node> nodes = getNodes();
ArrayList<Way> ways = getWays();
ArrayList<Relation> relations = getRelations();

// Process all nodes
for(Node n : nodes) {
    this.gisHandler.onNode(n.getId(), n.getLat(), n.getLon());
    if(n.getTags() !=null) {
        for(int i = 0; i < n.getTags().length-1; i+=2) {
            this.gisHandler.onNodeTag(n.getTags()[i], n.getTags()[i+1]);
        }   
    }
    this.gisHandler.onNodeComplete();
    this.gisHandler.closeNodeProcessing();
}


// Process all ways
for(Way w : ways) {
    this.gisHandler.onWay(w.getId());
    // Node refs
    for(Long l : w.getNodes()) {
        this.gisHandler.onWayNdRef(l);  
    }
    // Node tags
    if(w.getTags() != null) {
        for(int i = 0; i < w.getTags().length-1; i+=2) {
            this.gisHandler.onNodeTag(w.getTags()[i], w.getTags()[i+1]);
        }
    }
    this.gisHandler.onWayComplete();
    this.gisHandler.closeWayProcessing();
}

// Process all Relations
for(Relation rel : relations) {
    this.gisHandler.onRelation(rel.getId());
    for(int i = 0; i < rel.getMembers().length-1; i+=2) {
        this.gisHandler.onRelationMember("relation", rel.getId(), "multipolygon");
    }

    for(int i = 0; i < rel.getTags().length-1; i+=2) {
        this.gisHandler.onNodeTag(rel.getTags()[i], rel.getTags()[i+1]);
    }
    this.gisHandler.onRelationComplete();
    this.gisHandler.closeRelationProcessing();
}

Log output

ESTABLISHED CONNETION TO GIS DB
INFO   460,001 of 460,001 nodes extracted - 782M
INFO   33,582 of 66,118 ways extracted - 796M
INFO   43 of 827 relations extracted - 796M
INFO   Tiler finished at Mon Mar 04 16:16:42 GMT 2013
INFO   Starting Joiner at Mon Mar 04 16:16:42 GMT 2013
INFO   Caching relations from tr_raw.2po - 864M
INFO   0 of 43 relations cached - 864M
INFO   460,001 of 460,001 nodes cached (n034-e145) - 853M
INFO   33,582 of 33,582 ways read, 33,582 written
       Total 33,582 tiled, 0 shared
INFO   Joiner finished at Mon Mar 04 16:16:43 GMT 2013
INFO   Starting Segmenter at Mon Mar 04 16:16:43 GMT 2013
INFO   0 of 0 nodes cached (shared) - 863M
INFO   175,929 of 222,327 nodes cached (n034-e145) - 830M
INFO   33,582 ways analyzed, 67,881 segments created (n034-e145) - 798M
INFO   55,065 vertices of 175,929 written - 853M
INFO   0 ways analyzed, 0 segments created (shared) - 853M
INFO   0 vertices of 0 written - 853M
INFO   Segmenter finished at Mon Mar 04 16:16:43 GMT 2013
INFO   Starting GraphBuilder at Mon Mar 04 16:16:43 GMT 2013
INFO   Transforming Ways - 853M
INFO   33,582 Ways read, 135,764 Edges cached - 817M  
INFO   Transforming Vertices - 817M
INFO   55,065 Vertices read, 0 Restrictions cached - 814M
INFO   Finding SourceVertex EntryPoints - 814M
INFO   135,764 Edges analyzed
INFO   Creating NoTurnBits - 804M
INFO   135,764 Edges analyzed, 0 Crossings checked
INFO   Writing GraphFile
       gis_2po.gph - 804M
INFO   55,065 entries written     
INFO   135,764 edges written
INFO   GraphBuilder finished at Mon Mar 04 16:16:45 GMT 2013
INFO   Starting PostProccessor at Mon Mar 04 16:16:45 GMT 2013
       [de.cm.osm2po.converter.PgRoutingWriter]
INFO   Creating sql file gis/gis_2po_4pgr.sql
INFO   67,881 Segments written.
INFO   commandline template:
       psql -U [username] -d [dbname] -q -f "/home/sam/src/osm2po/gis/gis_2po_4pgr.sql"
INFO   PostProcessor finished at Mon Mar 04 16:16:46 GMT 2013
INFO   Loading Graph File
       /home/sam/src/osm2po/gis/gis_2po.gph
INFO   Created with Version 4.6.9.4
INFO   Loading SourceVertex-EntryPoints
INFO   55,065 Vertices loaded. - 863M
INFO   Memory for 135,764 edges reserved. - 862M
INFO   135,764 Edges loaded. - 861M
INFO   55,065 Classes loaded. - 861M  
INFO   Memory for 55,065 coords reserved. - 861M
INFO   55,065 Coords loaded.   
INFO   Graph is in memory - 859M free
INFO   Services started. Waiting for requests at
       http://localhost:8888/Osm2poService

1 Answer 1

1

Why the detour via pbf? osm2po allows you to write your own Reader and to inject it into the processing chain. All you need is a Java-Class which implements OsmParser.

@Override
public void open(InputStream inputStream,
        OsmParserHandler osmParserHandler, Config config) {
    this.handler = osmParserHandler;
    this.log = config.getLog();
    // inputStream is not needed, open your DB here instead.
    // db-params can be set via config
}

@Override
public void close() {
    // close your db here.
}

@Override
public void parse() {
    // Read your table here and call back

    // 1) All Nodes first
    this.handler.onNode(long id, double lat, double lon);
    this.handler.onNodeTag(String key, String value);
    this.handler.onNodeComplete();
    this.handler.closeNodeProcessing();

    // 2) Then all Ways
    this.handler.onWay(long id);
    this.handler.onWayNdRef(long ndRefId);
    this.handler.onWayTag(String key, String value);
    this.handler.onWayComplete();
    this.handler.closeWayProcessing();

    // 3) Finally all Relations
    this.handler.onRelation(long id);
    this.handler.onRelationMember(String type, long ref, String role);
    this.handler.onRelationTag(String key, String value);
    this.handler.onRelationComplete();
    this.handler.closeRelationProcessing();
}
18
  • Do I need to implement my own OsmParserHandler?
    – sam
    Commented Feb 18, 2013 at 23:54
  • No. The OsmParser is the key interface which I use to implement different readers for e.g pbf, o5m, plain xml, etc.
    – Carsten
    Commented Feb 19, 2013 at 18:08
  • In order to trigger it and to chain it into the default mechanism, you must pass an input file (though a db does not need one) Have look into the config where each file extension is associated with a special parser. So associate sth. like *.db with your parser implementation. One idea would be to put all your connection parameters in there instead of declaring them in the osm2po.config.
    – Carsten
    Commented Feb 19, 2013 at 18:17
  • Hi, Ok so I have created most of the parser class although I am stuck at the this.handler.onRelationMember(String type, long ref, String role); what is the ref variable here? I'll post my relations table schema in the original post
    – sam
    Commented Feb 22, 2013 at 0:55
  • This corresponds to a native OSM-relation. Each member of a relation references either a node, a way or another relation. So for the type parameter pass "node", "way" or "relation". An OSM-role can be everything, even self-invented stuff. The ref-parameter is the ID of the element (e.g. ID of the node).
    – Carsten
    Commented Feb 22, 2013 at 17:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.