Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.opentripplanner.graph_builder.module.osm;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.opentripplanner.common.model.P2;
import org.opentripplanner.common.model.T2;
import org.opentripplanner.openstreetmap.model.OSMWithTags;
import org.opentripplanner.routing.alertpatch.Alert;
import org.opentripplanner.routing.edgetype.StreetTraversalPermission;
import org.opentripplanner.routing.services.notes.NoteMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.opentripplanner.util.I18NString;
/**
* Information given to the GraphBuilder about how to assign permissions, safety values, names, etc. to edges based on OSM tags.
* TODO rename so that the connection with OSM tags is obvious
*
* WayPropertyPickers, CreativeNamePickers, SlopeOverridePickers, and SpeedPickers are applied to ways based on how well
* their OSMSpecifiers match a given OSM way. Generally one OSMSpecifier will win out over all the others based on the
* number of exact, partial, and wildcard tag matches. See OSMSpecifier for more details on the matching process.
*/
public class WayPropertySet {
private static Logger LOG = LoggerFactory.getLogger(WayPropertySet.class);
private List wayProperties;
/** Assign names to ways that do not have them based on OSM tags. */
private List creativeNamers;
private List slopeOverrides;
/** Assign automobile speeds based on OSM tags. */
private List speedPickers;
/** The automobile speed for street segments that do not match any SpeedPicker. */
public Float defaultSpeed;
private List notes;
private Pattern maxSpeedPattern;
/** The WayProperties applied to all ways that do not match any WayPropertyPicker. */
public WayProperties defaultProperties;
public WayPropertySetSource base;
public WayPropertySet() {
/* sensible defaults */
defaultProperties = new WayProperties();
defaultProperties.setSafetyFeatures(new P2(1.0, 1.0));
defaultProperties.setPermission(StreetTraversalPermission.ALL);
defaultSpeed = 11.2f; // 11.2 m/s ~= 25 mph ~= 40 kph, standard speed limit in the US
wayProperties = new ArrayList();
creativeNamers = new ArrayList();
slopeOverrides = new ArrayList();
speedPickers = new ArrayList();
notes = new ArrayList();
// regex courtesy http://wiki.openstreetmap.org/wiki/Key:maxspeed
// and edited
maxSpeedPattern = Pattern.compile("^([0-9][\\.0-9]+?)(?:[ ]?(kmh|km/h|kmph|kph|mph|knots))?$");
}
/**
* Applies the WayProperties whose OSMPicker best matches this way. In addition, WayProperties that are mixins
* will have their safety values applied if they match at all.
*/
public WayProperties getDataForWay(OSMWithTags way) {
WayProperties leftResult = defaultProperties;
WayProperties rightResult = defaultProperties;
int bestLeftScore = 0;
int bestRightScore = 0;
List leftMixins = new ArrayList();
List rightMixins = new ArrayList();
for (WayPropertyPicker picker : wayProperties) {
OSMSpecifier specifier = picker.getSpecifier();
WayProperties wayProperties = picker.getProperties();
P2 score = specifier.matchScores(way);
int leftScore = score.first;
int rightScore = score.second;
if (picker.isSafetyMixin()) {
if (leftScore > 0) {
leftMixins.add(wayProperties);
}
if (rightScore > 0) {
rightMixins.add(wayProperties);
}
} else {
if (leftScore > bestLeftScore) {
leftResult = wayProperties;
bestLeftScore = leftScore;
}
if (rightScore > bestRightScore) {
rightResult = wayProperties;
bestRightScore = rightScore;
}
}
}
WayProperties result = rightResult.clone();
result.setSafetyFeatures(new P2(rightResult.getSafetyFeatures().first,
leftResult.getSafetyFeatures().second));
/* apply mixins */
if (leftMixins.size() > 0) {
applyMixins(result, leftMixins, false);
}
if (rightMixins.size() > 0) {
applyMixins(result, rightMixins, true);
}
if ((bestLeftScore == 0 || bestRightScore == 0)
&& (leftMixins.size() == 0 || rightMixins.size() == 0)) {
String all_tags = dumpTags(way);
LOG.debug("Used default permissions: " + all_tags);
}
return result;
}
private String dumpTags(OSMWithTags way) {
/* generate warning message */
String all_tags = null;
Map tags = way.getTags();
for (Entry entry : tags.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
String tag = key + "=" + value;
if (all_tags == null) {
all_tags = tag;
} else {
all_tags += "; " + tag;
}
}
return all_tags;
}
private void applyMixins(WayProperties result, List mixins, boolean right) {
P2 safetyFeatures = result.getSafetyFeatures();
double first = safetyFeatures.first;
double second = safetyFeatures.second;
for (WayProperties properties : mixins) {
if (right) {
second *= properties.getSafetyFeatures().second;
} else {
first *= properties.getSafetyFeatures().first;
}
}
result.setSafetyFeatures(new P2(first, second));
}
public I18NString getCreativeNameForWay(OSMWithTags way) {
CreativeNamer bestNamer = null;
int bestScore = 0;
for (CreativeNamerPicker picker : creativeNamers) {
OSMSpecifier specifier = picker.specifier;
CreativeNamer namer = picker.namer;
int score = specifier.matchScore(way);
if (score > bestScore) {
bestNamer = namer;
bestScore = score;
}
}
if (bestNamer == null) {
return null;
}
return bestNamer.generateCreativeName(way);
}
/**
* Calculate the automobile speed, in meters per second, for this way.
*/
public float getCarSpeedForWay(OSMWithTags way, boolean back) {
// first, check for maxspeed tags
Float speed = null;
Float currentSpeed;
if (way.hasTag("maxspeed:motorcar"))
speed = getMetersSecondFromSpeed(way.getTag("maxspeed:motorcar"));
if (speed == null && !back && way.hasTag("maxspeed:forward"))
speed = getMetersSecondFromSpeed(way.getTag("maxspeed:forward"));
if (speed == null && back && way.hasTag("maxspeed:reverse"))
speed = getMetersSecondFromSpeed(way.getTag("maxspeed:reverse"));
if (speed == null && way.hasTag("maxspeed:lanes")) {
for (String lane : way.getTag("maxspeed:lanes").split("\\|")) {
currentSpeed = getMetersSecondFromSpeed(lane);
// Pick the largest speed from the tag
// currentSpeed might be null if it was invalid, for instance 10|fast|20
if (currentSpeed != null && (speed == null || currentSpeed > speed))
speed = currentSpeed;
}
}
if (way.hasTag("maxspeed") && speed == null)
speed = getMetersSecondFromSpeed(way.getTag("maxspeed"));
// this would be bad, as the segment could never be traversed by an automobile
// The small epsilon is to account for possible rounding errors
if (speed != null && speed < 0.0001)
LOG.warn("Zero or negative automobile speed detected at {} based on OSM " +
"maxspeed tags; ignoring these tags", this);
// if there was a defined speed and it's not 0, we're done
if (speed != null)
return speed;
// otherwise, we use the speedPickers
int bestScore = 0;
Float bestSpeed = null;
int score;
// SpeedPickers are constructed in DefaultWayPropertySetSource with an OSM specifier
// (e.g. highway=motorway) and a default speed for that segment.
for (SpeedPicker picker : speedPickers) {
OSMSpecifier specifier = picker.specifier;
score = specifier.matchScore(way);
if (score > bestScore) {
bestScore = score;
bestSpeed = picker.speed;
}
}
if (bestSpeed != null)
return bestSpeed;
else
return this.defaultSpeed;
}
public Set> getNoteForWay(OSMWithTags way) {
HashSet> out = new HashSet<>();
for (NotePicker picker : notes) {
OSMSpecifier specifier = picker.specifier;
NoteProperties noteProperties = picker.noteProperties;
if (specifier.matchScore(way) > 0) {
out.add(noteProperties.generateNote(way));
}
}
if (out.size() == 0) {
return null;
}
return out;
}
public boolean getSlopeOverride(OSMWithTags way) {
boolean result = false;
int bestScore = 0;
for (SlopeOverridePicker picker : slopeOverrides) {
OSMSpecifier specifier = picker.getSpecifier();
int score = specifier.matchScore(way);
if (score > bestScore) {
result = picker.getOverride();
bestScore = score;
}
}
return result;
}
public void addProperties(OSMSpecifier spec, WayProperties properties, boolean mixin) {
wayProperties.add(new WayPropertyPicker(spec, properties, mixin));
}
public void addProperties(OSMSpecifier spec, WayProperties properties) {
wayProperties.add(new WayPropertyPicker(spec, properties, false));
}
public void addCreativeNamer(OSMSpecifier spec, CreativeNamer namer) {
creativeNamers.add(new CreativeNamerPicker(spec, namer));
}
public void addNote(OSMSpecifier osmSpecifier, NoteProperties properties) {
notes.add(new NotePicker(osmSpecifier, properties));
}
public void setSlopeOverride(OSMSpecifier spec, boolean override) {
slopeOverrides.add(new SlopeOverridePicker(spec, override));
}
public boolean equals(Object o) {
if (o instanceof WayPropertySet) {
WayPropertySet other = (WayPropertySet) o;
return (defaultProperties.equals(other.defaultProperties)
&& wayProperties.equals(other.wayProperties)
&& creativeNamers.equals(other.creativeNamers)
&& slopeOverrides.equals(other.slopeOverrides) && notes.equals(other.notes));
}
return false;
}
public int hashCode() {
return defaultProperties.hashCode() + wayProperties.hashCode() + creativeNamers.hashCode()
+ slopeOverrides.hashCode();
}
public void addSpeedPicker(SpeedPicker picker) {
this.speedPickers.add(picker);
}
public Float getMetersSecondFromSpeed(String speed) {
Matcher m = maxSpeedPattern.matcher(speed);
if (!m.matches())
return null;
float originalUnits;
try {
originalUnits = (float) Double.parseDouble(m.group(1));
} catch (NumberFormatException e) {
LOG.warn("Could not parse max speed {}", m.group(1));
return null;
}
String units = m.group(2);
if (units == null || units.equals(""))
units = "kmh";
// we'll be doing quite a few string comparisons here
units = units.intern();
float metersSecond;
if (units == "kmh" || units == "km/h" || units == "kmph" || units == "kph")
metersSecond = 0.277778f * originalUnits;
else if (units == "mph")
metersSecond = 0.446944f * originalUnits;
else if (units == "knots")
metersSecond = 0.514444f * originalUnits;
else
return null;
return metersSecond;
}
public void createNames(String spec, String patternKey) {
String pattern = patternKey;
CreativeNamer namer = new CreativeNamer(pattern);
addCreativeNamer(new OSMSpecifier(spec), namer);
}
public void createNotes(String spec, String patternKey, NoteMatcher matcher) {
String pattern = patternKey;
// TODO: notes aren't localized
NoteProperties properties = new NoteProperties(pattern, matcher);
addNote(new OSMSpecifier(spec), properties);
}
public void setProperties(String spec,
StreetTraversalPermission permission) {
setProperties( spec, permission, 1.0, 1.0);
}
/**
* Note that the safeties here will be adjusted such that the safest street
* has a safety value of 1, with all others scaled proportionately.
*/
public void setProperties(String spec,
StreetTraversalPermission permission, double safety, double safetyBack) {
setProperties(spec, permission, safety, safetyBack, false);
}
public void setProperties(String spec,
StreetTraversalPermission permission, double safety, double safetyBack, boolean mixin) {
WayProperties properties = new WayProperties();
properties.setPermission(permission);
properties.setSafetyFeatures(new P2(safety, safetyBack));
addProperties(new OSMSpecifier(spec), properties, mixin);
}
public void setCarSpeed(String spec, float speed) {
SpeedPicker picker = new SpeedPicker();
picker.specifier = new OSMSpecifier(spec);
picker.speed = speed;
addSpeedPicker(picker);
}
}