All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.graphhopper.routing.util.CarFlagEncoder Maven / Gradle / Ivy

/*
 *  Licensed to GraphHopper GmbH under one or more contributor
 *  license agreements. See the NOTICE file distributed with this work for 
 *  additional information regarding copyright ownership.
 * 
 *  GraphHopper GmbH licenses this file to you under the Apache License, 
 *  Version 2.0 (the "License"); you may not use this file except in 
 *  compliance with the License. You may obtain a copy of the License at
 * 
 *       http://www.apache.org/licenses/LICENSE-2.0
 * 
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.graphhopper.routing.util;

import com.graphhopper.reader.OSMRelation;
import com.graphhopper.reader.OSMWay;
import com.graphhopper.reader.osm.conditional.ConditionalTagsInspector;
import com.graphhopper.reader.osm.conditional.DateRangeParser;
import com.graphhopper.util.Helper;
import com.graphhopper.util.PMap;

import java.util.*;

/**
 * Defines bit layout for cars. (speed, access, ferries, ...)
 * 

* @author Peter Karich * @author Nop */ public class CarFlagEncoder extends AbstractFlagEncoder { protected final Map trackTypeSpeedMap = new HashMap(); protected final Set badSurfaceSpeedMap = new HashSet(); /** * A map which associates string to speed. Get some impression: * http://www.itoworld.com/map/124#fullscreen * http://wiki.openstreetmap.org/wiki/OSM_tags_for_routing/Maxspeed */ protected final Map defaultSpeedMap = new HashMap(); public CarFlagEncoder() { this(5, 5, 0); } public CarFlagEncoder( PMap properties ) { this((int) properties.getLong("speed_bits", 5), properties.getDouble("speed_factor", 5), properties.getBool("turn_costs", false) ? 1 : 0); this.properties = properties; this.setBlockFords(properties.getBool("block_fords", true)); } public CarFlagEncoder( String propertiesStr ) { this(new PMap(propertiesStr)); } public CarFlagEncoder( int speedBits, double speedFactor, int maxTurnCosts ) { super(speedBits, speedFactor, maxTurnCosts); restrictions.addAll(Arrays.asList("motorcar", "motor_vehicle", "vehicle", "access")); restrictedValues.add("private"); restrictedValues.add("agricultural"); restrictedValues.add("forestry"); restrictedValues.add("no"); restrictedValues.add("restricted"); restrictedValues.add("delivery"); restrictedValues.add("military"); restrictedValues.add("emergency"); intendedValues.add("yes"); intendedValues.add("permissive"); potentialBarriers.add("gate"); potentialBarriers.add("lift_gate"); potentialBarriers.add("kissing_gate"); potentialBarriers.add("swing_gate"); absoluteBarriers.add("bollard"); absoluteBarriers.add("stile"); absoluteBarriers.add("turnstile"); absoluteBarriers.add("cycle_barrier"); absoluteBarriers.add("motorcycle_barrier"); absoluteBarriers.add("block"); absoluteBarriers.add("bus_trap"); absoluteBarriers.add("sump_buster"); trackTypeSpeedMap.put("grade1", 20); // paved trackTypeSpeedMap.put("grade2", 15); // now unpaved - gravel mixed with ... trackTypeSpeedMap.put("grade3", 10); // ... hard and soft materials trackTypeSpeedMap.put("grade4", 5); // ... some hard or compressed materials trackTypeSpeedMap.put("grade5", 5); // ... no hard materials. soil/sand/grass badSurfaceSpeedMap.add("cobblestone"); badSurfaceSpeedMap.add("grass_paver"); badSurfaceSpeedMap.add("gravel"); badSurfaceSpeedMap.add("sand"); badSurfaceSpeedMap.add("paving_stones"); badSurfaceSpeedMap.add("dirt"); badSurfaceSpeedMap.add("ground"); badSurfaceSpeedMap.add("grass"); maxPossibleSpeed = 140; // autobahn defaultSpeedMap.put("motorway", 100); defaultSpeedMap.put("motorway_link", 70); defaultSpeedMap.put("motorroad", 90); // bundesstraße defaultSpeedMap.put("trunk", 70); defaultSpeedMap.put("trunk_link", 65); // linking bigger town defaultSpeedMap.put("primary", 65); defaultSpeedMap.put("primary_link", 60); // linking towns + villages defaultSpeedMap.put("secondary", 60); defaultSpeedMap.put("secondary_link", 50); // streets without middle line separation defaultSpeedMap.put("tertiary", 50); defaultSpeedMap.put("tertiary_link", 40); defaultSpeedMap.put("unclassified", 30); defaultSpeedMap.put("residential", 30); // spielstraße defaultSpeedMap.put("living_street", 5); defaultSpeedMap.put("service", 20); // unknown road defaultSpeedMap.put("road", 20); // forestry stuff defaultSpeedMap.put("track", 15); conditionalTagsInspector = new ConditionalTagsInspector(DateRangeParser.createCalendar(), restrictions, restrictedValues, intendedValues); } @Override public int getVersion() { return 1; } /** * Define the place of the speedBits in the edge flags for car. */ @Override public int defineWayBits( int index, int shift ) { // first two bits are reserved for route handling in superclass shift = super.defineWayBits(index, shift); speedEncoder = new EncodedDoubleValue("Speed", shift, speedBits, speedFactor, defaultSpeedMap.get("secondary"), maxPossibleSpeed); return shift + speedEncoder.getBits(); } protected double getSpeed( OSMWay way ) { String highwayValue = way.getTag("highway"); Integer speed = defaultSpeedMap.get(highwayValue); if (speed == null) throw new IllegalStateException(toString() + ", no speed found for: " + highwayValue + ", tags: " + way); if (highwayValue.equals("track")) { String tt = way.getTag("tracktype"); if (!Helper.isEmpty(tt)) { Integer tInt = trackTypeSpeedMap.get(tt); if (tInt != null) speed = tInt; } } return speed; } @Override public long acceptWay( OSMWay way ) { // TODO: Ferries have conditionals, like opening hours or are closed during some time in the year String highwayValue = way.getTag("highway"); if (highwayValue == null) { if (way.hasTag("route", ferries)) { String motorcarTag = way.getTag("motorcar"); if (motorcarTag == null) motorcarTag = way.getTag("motor_vehicle"); if (motorcarTag == null && !way.hasTag("foot") && !way.hasTag("bicycle") || "yes".equals(motorcarTag)) return acceptBit | ferryBit; } return 0; } if ("track".equals(highwayValue)) { String tt = way.getTag("tracktype"); if (tt != null && !tt.equals("grade1") && !tt.equals("grade2") && !tt.equals("grade3")) return 0; } if (!defaultSpeedMap.containsKey(highwayValue)) return 0; if (way.hasTag("impassable", "yes") || way.hasTag("status", "impassable")) return 0; // multiple restrictions needs special handling compared to foot and bike, see also motorcycle String firstValue = way.getFirstPriorityTag(restrictions); if (!firstValue.isEmpty()) { if (restrictedValues.contains(firstValue) && !conditionalTagsInspector.isRestrictedWayConditionallyPermitted(way)) return 0; if (intendedValues.contains(firstValue)) return acceptBit; } // do not drive street cars into fords if (isBlockFords() && ("ford".equals(highwayValue) || way.hasTag("ford"))) return 0; if (conditionalTagsInspector.isPermittedWayConditionallyRestricted(way)) return 0; else return acceptBit; } @Override public long handleRelationTags( OSMRelation relation, long oldRelationFlags ) { return oldRelationFlags; } @Override public long handleWayTags( OSMWay way, long allowed, long relationFlags ) { if (!isAccept(allowed)) return 0; long flags = 0; if (!isFerry(allowed)) { // get assumed speed from highway type double speed = getSpeed(way); speed = applyMaxSpeed(way, speed); // limit speed to max 30 km/h if bad surface if (speed > 30 && way.hasTag("surface", badSurfaceSpeedMap)) speed = 30; flags = setSpeed(flags, speed); boolean isRoundabout = way.hasTag("junction", "roundabout"); if (isRoundabout) flags = setBool(flags, K_ROUNDABOUT, true); if (isOneway(way) || isRoundabout) { if (isBackwardOneway(way)) flags |= backwardBit; if (isForwardOneway(way)) flags |= forwardBit; } else flags |= directionBitMask; } else { double ferrySpeed = getFerrySpeed(way, defaultSpeedMap.get("living_street"), defaultSpeedMap.get("service"), defaultSpeedMap.get("residential")); flags = setSpeed(flags, ferrySpeed); flags |= directionBitMask; } return flags; } /** * make sure that isOneway is called before */ protected boolean isBackwardOneway( OSMWay way ) { return way.hasTag("oneway", "-1") || way.hasTag("vehicle:forward", "no") || way.hasTag("motor_vehicle:forward", "no"); } /** * make sure that isOneway is called before */ protected boolean isForwardOneway( OSMWay way ) { return !way.hasTag("oneway", "-1") && !way.hasTag("vehicle:forward", "no") && !way.hasTag("motor_vehicle:forward", "no"); } protected boolean isOneway( OSMWay way ) { return way.hasTag("oneway", oneways) || way.hasTag("vehicle:backward") || way.hasTag("vehicle:forward") || way.hasTag("motor_vehicle:backward") || way.hasTag("motor_vehicle:forward"); } public String getWayInfo( OSMWay way ) { String str = ""; String highwayValue = way.getTag("highway"); // for now only motorway links if ("motorway_link".equals(highwayValue)) { String destination = way.getTag("destination"); if (!Helper.isEmpty(destination)) { int counter = 0; for (String d : destination.split(";")) { if (d.trim().isEmpty()) continue; if (counter > 0) str += ", "; str += d.trim(); counter++; } } } if (str.isEmpty()) return str; // I18N if (str.contains(",")) return "destinations: " + str; else return "destination: " + str; } @Override public String toString() { return "car"; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy