graphhopper / graphhopper

Open source routing engine for OpenStreetMap. Use it as Java library or standalone web server.

Home Page:https://www.graphhopper.com/open-source/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Custom vehicle doesn't work after update to 8.0

Coneys opened this issue · comments

Describe the bug
After update to 8.0 from 5.3 I tried to rewrite one of our custom encoder to TagParsers. There had to be an internal change in graphhopper or I made some weird mistake

To Reproduce

Old encoder:

class PisteEncoder : AbstractFlagEncoder(4, 1.0, 0) {

    init {
        avgSpeedEnc = DecimalEncodedValueImpl(EncodingManager.getKey(name, "average_speed"), speedBits, speedFactor, false)
        restrictedValues.clear()
        blockFords(false)
    }

    override fun createEncodedValues(registerNewEncodedValue: MutableList<EncodedValue?>) {
        super.createEncodedValues(registerNewEncodedValue)
        registerNewEncodedValue.add(avgSpeedEnc)
    }

    override fun getTransportationMode(): TransportationMode = TransportationMode.FOOT

    override fun getAccess(way: ReaderWay): EncodingManager.Access {
        return EncodingManager.Access.WAY
    }

    override fun applyWayTags(way: ReaderWay?, edge: EdgeIteratorState?) {
    }

    override fun handleWayTags(edgeFlags: IntsRef, way: ReaderWay): IntsRef {
        if (way.isPisteNordic()) {
            avgSpeedEnc.setDecimal(false, edgeFlags, 5.0)
            accessEnc.setBool(false, edgeFlags, way.isPisteNordic())
            accessEnc.setBool(true, edgeFlags, way.isPisteNordic())
        }

        return edgeFlags
    }

    private fun ReaderWay.isPisteNordic(): Boolean {
        return getTag("piste:type") == "nordic"
    }

}

New approach:

Access:

class PisteAccessParser(lookup: EncodedValueLookup, properties: PMap) : TagParser {

    private val accessEnc = lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "piste")))

    private fun ReaderWay.isPisteNordic(): Boolean {
        return getTag("piste:type") == "nordic"
    }

    override fun handleWayTags(edgeId: Int, edgeIntAccess: EdgeIntAccess?, way: ReaderWay, relationFlags: IntsRef?) {
        if (way.isPisteNordic()) {
            accessEnc.setBool(false, edgeId, edgeIntAccess, true)
            accessEnc.setBool(true, edgeId, edgeIntAccess, true)
        }
    }
}

Priority:

class PistePriorityParser(lookup: EncodedValueLookup, properties: PMap) : TagParser {

    private fun ReaderWay.isPisteNordic(): Boolean {
        return getTag("piste:type") == "nordic"
    }

    private val priorityWayEncoder = lookup.getDecimalEncodedValue(VehiclePriority.key(properties.getString("name", "piste")))

    override fun handleWayTags(edgeId: Int, edgeIntAccess: EdgeIntAccess, way: ReaderWay, relationFlags: IntsRef) {
        if (way.isPisteNordic()) {
            priorityWayEncoder.setDecimal(false, edgeId, edgeIntAccess, PriorityCode.getValue(PriorityCode.BEST.value))
        } else
            priorityWayEncoder.setDecimal(false, edgeId, edgeIntAccess, PriorityCode.getValue(PriorityCode.EXCLUDE.value))
    }
}

Average speed:

class PisteAverageSpeedParser(lookup: EncodedValueLookup, properties: PMap) : AbstractAverageSpeedParser(
    lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "piste"))),
    lookup.getDecimalEncodedValue(FerrySpeed.KEY),
) {
    override fun handleWayTags(edgeId: Int, edgeIntAccess: EdgeIntAccess, way: ReaderWay) {
        if (way.isPisteNordic()) {
            setSpeed(false, edgeId, edgeIntAccess, 5.0)
        }
    }

    private fun ReaderWay.isPisteNordic(): Boolean {
        return getTag("piste:type") == "nordic"
    }
}

EncodedValues are created as foot with name change:

  configuration.putObject("name", "piste")
  VehicleEncodedValues.foot(configuration)

VehicleTagParsers:

 configuration.putObject("name", "piste")
        VehicleTagParsers(
            PisteAccessParser(lookup, configuration),
            PistePriorityParser(lookup, configuration),
            PisteAverageSpeedParser(lookup, configuration),
        )

Expected behavior

Graph should be able to find route for custom vehicle

System Information

JVM 21, Graphhopper 8.0

I did rewrite other custom vehicles and all which were based on highway tags works perfectly. Only this one is not working

I recommend to use our forum so that we can find out if it is an issue or maybe some migration mistake.

In general it looks like you should try to use a piste_nordic boolean encoded value and use this in a custom model instead of these many encoded values and parsers. It is also more flexible and you could let users decide about the speed or priority per request.

Regarding this problem here: what is the exact problem you are facing? "Connection not found" or "route not found" or something else? Ensure that the access encoded value is set to true and also the speed encoded value is set to some positive value for the same way. You can put a break point with the debugger and see if it is called at all.

I was printing those values and both encoded value is set to true and speed is always 5.0 for this tag.
Exact problem is "PointNotFoundException". "lookup" method in ViaRouting cannot find any snap (and I am sure that in this area there is possible piste route, I have saved coordinates from graphhopper 5.3)

Hard to tell without a reproducer. You need to debug if the parser is actually called.

Did you modify the config import.osm.ignored_highways accordingly? Let's move to the forum: https://discuss.graphhopper.com/

Maybe the new way filtering is too strict. Have a look here: #2448 (comment)

I did create topic: https://discuss.graphhopper.com/t/custom-vehicle-doesnt-work-after-update-to-8-0/8449
I am sure that TagParsers are called correctly, if I remove all "way.isPiste()" calls and just set speed and access then it works.
I have no idea what "import.osm.ignored_highways" are. Piste tag is set on ways which are not highways, that is the point of this custom vehicle, so maybe some code inside graphhopper is strictly allowing only highway tags?