Hello, I’m new of GrapHopper. Currently, I upgraded the version of the GrapHopper 0.9.0 to 7.0.0, so a lot of things changed. I was trying to build the profile for train. After several days, I still get the problem with drawing the railway shape.
My config.yml like that:
datareader.file: /Users/phamtai/sojo-project/graphhopper/vietosm/vietnam-latest.osm.pbf
graph.location: /Users/phamtai/sojo-project/graphhopper/traingdd
index.high_resolution: 300
index.max_region_search: 8
import.osm.ignored_highways:
graph.flag_encoders: train
graph.dataaccess: RAM_STORE
routing.instructions: true
TrainCommonParser
package com.axonvibe.vibe.transit.util.parsers;
import com.graphhopper.reader.ReaderWay;
import com.graphhopper.routing.util.WayAccess;
import com.graphhopper.storage.IntsRef;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
public class TrainCommonTagParser extends VibeTagParser {
protected String[] railValues = {"rail", "narrow_gauge", "tram", "subway", "light_rail", "level_crossing"};
protected String[] intendedValues = {"railway", "train"};
public TrainCommonTagParser() {
}
public void handleWayTags(IntsRef var1, ReaderWay var2, IntsRef var3) {
}
public WayAccess getAccess(ReaderWay readerWay) {
String railwayValue = readerWay.getTag("railway");
if (StringUtils.isEmpty(railwayValue)) {
if (readerWay.hasTag("route", intendedValues)) {
return WayAccess.WAY;
}
} else {
if (readerWay.hasTag("impassable", "yes") || readerWay.hasTag("status", "impassable")) {
return WayAccess.CAN_SKIP;
}
if (Arrays.asList(railValues).contains(railwayValue)) {
return WayAccess.WAY;
}
}
return WayAccess.CAN_SKIP;
}
}
TrainAccessParser
package com.axonvibe.vibe.transit.util.parsers.access;
import com.axonvibe.vibe.transit.util.parsers.TrainCommonTagParser;
import com.graphhopper.reader.ReaderWay;
import com.graphhopper.routing.ev.BooleanEncodedValue;
import com.graphhopper.routing.ev.EncodedValueLookup;
import com.graphhopper.routing.ev.Roundabout;
import com.graphhopper.routing.ev.VehicleAccess;
import com.graphhopper.routing.util.WayAccess;
import com.graphhopper.storage.IntsRef;
import com.graphhopper.util.PMap;
public class TrainAccessParser extends TrainCommonTagParser {
protected final BooleanEncodedValue roundaboutEnc;
protected final BooleanEncodedValue accessEnc;
public TrainAccessParser(EncodedValueLookup lookup, PMap properties) {
this(
lookup.getBooleanEncodedValue(VehicleAccess.key(properties.getString("name", "train"))),
lookup.getBooleanEncodedValue(Roundabout.KEY)
);
}
public TrainAccessParser(BooleanEncodedValue accessEnc, BooleanEncodedValue roundaboutEnc) {
super();
this.accessEnc = accessEnc;
this.roundaboutEnc = roundaboutEnc;
}
@Override
public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay, IntsRef relationFlags) {
this.handleWayTags(edgeFlags, readerWay);
}
public void handleWayTags(IntsRef edgeFlags, ReaderWay readerWay) {
WayAccess wayAccess = getAccess(readerWay);
if (!wayAccess.canSkip()) {
accessEnc.setBool(false, edgeFlags, true);
accessEnc.setBool(true, edgeFlags, true);
}
}
}
AverageSpeedParser
package com.axonvibe.vibe.transit.util.parsers.speed;
import com.axonvibe.vibe.transit.util.parsers.TrainCommonTagParser;
import com.graphhopper.reader.ReaderWay;
import com.graphhopper.routing.ev.DecimalEncodedValue;
import com.graphhopper.routing.ev.EncodedValueLookup;
import com.graphhopper.routing.ev.VehicleSpeed;
import com.graphhopper.routing.util.WayAccess;
import com.graphhopper.storage.IntsRef;
import com.graphhopper.util.PMap;
import org.apache.commons.lang3.StringUtils;
public class TrainAverageSpeedParser extends TrainCommonTagParser {
public static final double TRAIN_MAX_SPEED = 120.0;
private final DecimalEncodedValue avgSpeedEnc;
private final double maxPossibleSpeed;
public TrainAverageSpeedParser(EncodedValueLookup lookup, PMap properties) {
this(lookup.getDecimalEncodedValue(VehicleSpeed.key(properties.getString("name", "train"))));
}
public TrainAverageSpeedParser(DecimalEncodedValue avgSpeedEnc) {
super();
this.avgSpeedEnc = avgSpeedEnc;
this.maxPossibleSpeed = this.avgSpeedEnc.getNextStorableValue(TRAIN_MAX_SPEED);
}
public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) {
WayAccess wayAccess = getAccess(way);
double speed = 1.0;
if (WayAccess.WAY.equals(wayAccess)) {
String maxSpeed = way.getTag("maxspeed");
String railwayValue = way.getTag("railway");
if (railwayValue != null) {
switch (railwayValue) {
case "rail":
speed = 50.0D;
break;
case "tram":
speed = 20.0D;
break;
case "narrow_gauge":
speed = 30.0D;
break;
case "subway":
speed = 20.0D;
break;
}
}
if (!StringUtils.isEmpty(maxSpeed)) {
try {
speed = Double.parseDouble(maxSpeed);
} catch (NumberFormatException nfe) {
speed = 10.0; //everything else failed, so we just pick 35kph
}
}
}
if (!wayAccess.canSkip()) {
this.avgSpeedEnc.setDecimal(false, edgeFlags, speed);
this.avgSpeedEnc.setDecimal(true, edgeFlags, speed);
}
}
}
PriorityParser
package com.axonvibe.vibe.transit.util.parsers.priority;
import com.axonvibe.vibe.transit.util.parsers.TrainCommonTagParser;
import com.graphhopper.reader.ReaderWay;
import com.graphhopper.routing.ev.DecimalEncodedValue;
import com.graphhopper.routing.ev.EncodedValueLookup;
import com.graphhopper.routing.ev.VehiclePriority;
import com.graphhopper.routing.util.PriorityCode;
import com.graphhopper.routing.util.WayAccess;
import com.graphhopper.storage.IntsRef;
import com.graphhopper.util.PMap;
public class TrainPriorityParser extends TrainCommonTagParser {
protected final DecimalEncodedValue priorityEnc;
public TrainPriorityParser(EncodedValueLookup lookup, PMap properties) {
this(lookup.getDecimalEncodedValue(VehiclePriority.key(properties.getString("name", "train"))));
}
public TrainPriorityParser(DecimalEncodedValue priorityEnc) {
super();
this.priorityEnc = priorityEnc;
}
@Override
public void handleWayTags(IntsRef edgeFlags, ReaderWay way, IntsRef relationFlags) {
Integer priorityFromRelation;
WayAccess wayAccess = getAccess(way);
switch (wayAccess) {
case WAY -> {
priorityFromRelation = PriorityCode.BEST.getValue();
}
case OTHER -> {
priorityFromRelation = PriorityCode.SLIGHT_PREFER.getValue();
}
default -> {
priorityFromRelation = PriorityCode.REACH_DESTINATION.getValue();
}
}
if (!wayAccess.canSkip()) {
priorityEnc.setDecimal(false, edgeFlags, priorityFromRelation);
priorityEnc.setDecimal(true, edgeFlags, priorityFromRelation);
}
}
}
VehicleEncodedValues
public static VehicleEncodedValues train(PMap properties) {
String name = properties.getString("name", "train");
int speedBits = properties.getInt("speed_bits", 7);
double speedFactor = properties.getDouble("speed_factor", 1.0);
int maxTurnCosts = properties.getInt("max_turn_costs", 1);
BooleanEncodedValue accessEnc = VehicleAccess.create(name);
DecimalEncodedValue speedEnc = VehicleSpeed.create(name, speedBits, speedFactor, true);
DecimalEncodedValue priorityEnc = VehiclePriority.create(name, 7, speedFactor, true);
DecimalEncodedValue turnCostEnc = TurnCost.create(name, maxTurnCosts);
return new VehicleEncodedValues(name, accessEnc, speedEnc, priorityEnc, turnCostEnc);
}
My initing GrapHopper code
ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
ResourceLoader resourceLoader = new DefaultResourceLoader();
GraphHopperConfig graphHopperConfig = objectMapper.readValue(resourceLoader.getResource("classpath:config.yml").getInputStream(), GraphHopperConfig.class);
List<Profile> profiles = buildProfiles();
graphHopperConfig.setProfiles(profiles);
graphHopperConfig.setCHProfiles(buildCHProfiles(profiles));
graphHopper = new GraphHopper().init(graphHopperConfig);
graphHopper.setMinNetworkSize(0);
graphHopper.setEncodedValuesString("road_class,surface,road_environment,max_speed,max_width,max_height");
graphHopper.setVehicleTagParserFactory(new VibeVehicleTagParsersFactory());
graphHopper.setVehicleEncodedValuesFactory(new VibeVehicleEncodedValuesFactory());
graphHopper.importOrLoad();
Can any experts take care it? Thanks so much!