Get OSM node ID from getAdjNode and getBaseNode

Hello everyone,

I would like to know if there was a way to get the OSM node IDs matching to the node IDs returned by getAdjNode and getBaseNode. To make it simpler, I just would like to know how to get an OSM Node ID out of a “Graphhopper” node ID.

Thank you in advance!

GraphHopper does not store the OSM node IDs so far. What do you need them for? It would certainly possible to store them but this would require changes in the Java code.

Thank you for your quick answer!

Without going into too much details, I have a bunch of OSM Node IDs stored in a database and some values associated to them. I’m doing requests to that database at each calcEdgeWeight method call, to get the node’s associated value and return a weight based on that number. Therefore this system doesn’t work if I can’t access OSM Node IDs from calcEdgeWeight

Note: As the values stored in the database constantly change, I can’t set encoded values for them as recommended in the docs because, as I understood, they are loaded at the graph generation.

Take a look at the WaySegmentParser.java/Pass2Handler/handleSegment method in OSMReader.java where there is code:

 if (i == 0)
   from = nodeData.idToTowerNode(id);
 else if (i == segment.size() - 1)
   to = nodeData.idToTowerNode(id);

You can get the OSM node IDs corresponding to the ‘from’- and ‘to’- GraphHopper node IDs by calling segment.get(0).osmNodeId and segment.get(segment.size() - 1).osmNodeId. You could use this data to store the mapping between OSM and GH node IDs and later use it in your weighting function.

Hi.

I added a method call (in handeSegment method definition) that writes OSM node IDs and GH node IDs in database (see below) but it doesn’t seem to work. In fact, I added a System.out.println() to check if the handleSegment is called but it doesn’t print anything.

You said that handleSegment is called in OSMReader.java but I don’t see it there.

I don’t really know if I modified the wrong code snippet, and if so, where I should perform modifications, could you please help me with that?

Also, is handleSegment called at the graph generation?

Thank you in advance!

//My modified code

void handleSegment(List<SegmentNode> segment, ReaderWay way) {
            final PointList pointList = new PointList(segment.size(), nodeData.is3D());
            final List<Map<String, Object>> nodeTags = new ArrayList<>(segment.size());
            int from = -1;
            int to = -1;
            


            System.out.println("****************");
            System.out.println("HandleSegmentCalled");

            Postgres postgres = new Postgres();
            for (int i = 0; i < segment.size(); i++) {
                SegmentNode node = segment.get(i);
                long id = node.id;
                if (!isNodeId(id))
                    throw new IllegalStateException("Invalid id for node: " + node.osmNodeId + " when handling segment " + segment + " for way: " + way.getId());
                if (isPillarNode(id) && (i == 0 || i == segment.size() - 1)) {
                    id = nodeData.convertPillarToTowerNode(id, node.osmNodeId);
                    node.id = id;
                }

                if (i == 0)
                    from = nodeData.idToTowerNode(id);
                else if (i == segment.size() - 1)
                    to = nodeData.idToTowerNode(id);
                else if (isTowerNode(id))
                    throw new IllegalStateException("Tower nodes should only appear at the end of segments, way: " + way.getId());

                //Postgres.writeData() takes in parameter a long (OSM Node ID), an int (Graphhopper Node ID) and a default value (0) and write them in database.
                postgres.writeData(segment.get(0).osmNodeId, from, 0);
                postgres.writeData(segment.get(segment.size() - 1).osmNodeId, to, 0);
                nodeData.addCoordinatesToPointList(id, pointList);
                nodeTags.add(node.tags);
            }
            if (from < 0 || to < 0)
                throw new IllegalStateException("The first and last nodes of a segment must be tower nodes, way: " + way.getId());
            edgeHandler.handleEdge(from, to, pointList, way, nodeTags);
        }

I’m doing requests to that database at each calcEdgeWeight method call, to get the node’s associated value and return a weight based on that number.

This might be relative slow doing these external calls million times per request (depends on the route length). Also the easier way to integrate this in GraphHopper could be to create encoded values that you feed from your database after the import using the LocationIndex or even modifying the source PBF.

1 Like

Yes, it is only called during graph generation, so you might have to delete the graph-cache folder (or whatever the GraphHopper folder is called in your case) and run the import again. Then it should definitely be called.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.