use of org.opentripplanner.common.model.P2 in project OpenTripPlanner by opentripplanner.
the class CompositeStreetTraversalPermissionConverter method convert.
/**
* use the permission combination strategy to combine the results of the list of converters
*/
@Override
public P2<StreetTraversalPermission> convert(SimpleFeature feature) {
P2<StreetTraversalPermission> result = null;
for (SimpleFeatureConverter<P2<StreetTraversalPermission>> converter : converters) {
P2<StreetTraversalPermission> value = converter.convert(feature);
if (result == null) {
result = value;
} else {
StreetTraversalPermission first, second;
if (orPermissions) {
first = result.first.add(value.first);
second = result.second.add(value.second);
} else {
first = StreetTraversalPermission.get(result.first.code & value.first.code);
second = StreetTraversalPermission.get(result.second.code & value.second.code);
}
result = new P2<StreetTraversalPermission>(first, second);
}
}
return result;
}
use of org.opentripplanner.common.model.P2 in project OpenTripPlanner by opentripplanner.
the class GeometryUtils method splitGeometryAtFraction.
/**
* Splits the input geometry into two LineStrings at a fraction of the distance covered.
*/
public static P2<LineString> splitGeometryAtFraction(Geometry geometry, double fraction) {
LineString empty = new LineString(null, gf);
Coordinate[] coordinates = geometry.getCoordinates();
CoordinateSequence sequence = gf.getCoordinateSequenceFactory().create(coordinates);
LineString total = new LineString(sequence, gf);
if (coordinates.length < 2)
return new P2<LineString>(empty, empty);
if (fraction <= 0)
return new P2<LineString>(empty, total);
if (fraction >= 1)
return new P2<LineString>(total, empty);
double totalDistance = total.getLength();
double requestedDistance = totalDistance * fraction;
// An index in JTS can actually refer to any point along the line. It is NOT an array index.
LocationIndexedLine line = new LocationIndexedLine(geometry);
LinearLocation l = LengthLocationMap.getLocation(geometry, requestedDistance);
LineString beginning = (LineString) line.extractLine(line.getStartIndex(), l);
LineString ending = (LineString) line.extractLine(l, line.getEndIndex());
return new P2<LineString>(beginning, ending);
}
use of org.opentripplanner.common.model.P2 in project OpenTripPlanner by opentripplanner.
the class WalkableAreaBuilder method buildWithoutVisibility.
/**
* For all areas just use outermost rings as edges so that areas can be routable without visibility calculations
* @param group
*/
public void buildWithoutVisibility(AreaGroup group) {
Set<Edge> edges = new HashSet<Edge>();
// create polygon and accumulate nodes for area
for (Ring ring : group.outermostRings) {
AreaEdgeList edgeList = new AreaEdgeList();
// the points corresponding to concave or hole vertices
// or those linked to ways
HashSet<P2<OSMNode>> alreadyAddedEdges = new HashSet<P2<OSMNode>>();
// and to avoid the numerical problems that they tend to cause
for (Area area : group.areas) {
if (!ring.toJtsPolygon().contains(area.toJTSMultiPolygon())) {
continue;
}
for (Ring outerRing : area.outermostRings) {
for (int i = 0; i < outerRing.nodes.size(); ++i) {
createEdgesForRingSegment(edges, edgeList, area, outerRing, i, alreadyAddedEdges);
}
// TODO: is this actually needed?
for (Ring innerRing : outerRing.holes) {
for (int j = 0; j < innerRing.nodes.size(); ++j) {
createEdgesForRingSegment(edges, edgeList, area, innerRing, j, alreadyAddedEdges);
}
}
}
}
}
}
use of org.opentripplanner.common.model.P2 in project OpenTripPlanner by opentripplanner.
the class WalkableAreaBuilder method buildWithVisibility.
public void buildWithVisibility(AreaGroup group, boolean platformEntriesLinking) {
Set<OSMNode> startingNodes = new HashSet<OSMNode>();
Set<Vertex> startingVertices = new HashSet<Vertex>();
Set<Edge> edges = new HashSet<Edge>();
// create polygon and accumulate nodes for area
for (Ring ring : group.outermostRings) {
AreaEdgeList edgeList = new AreaEdgeList();
// the points corresponding to concave or hole vertices
// or those linked to ways
ArrayList<VLPoint> visibilityPoints = new ArrayList<VLPoint>();
ArrayList<OSMNode> visibilityNodes = new ArrayList<OSMNode>();
HashSet<P2<OSMNode>> alreadyAddedEdges = new HashSet<P2<OSMNode>>();
// and to avoid the numerical problems that they tend to cause
for (Area area : group.areas) {
// parameter is true
if (platformEntriesLinking && "platform".equals(area.parent.getTag("public_transport"))) {
continue;
}
if (!ring.toJtsPolygon().contains(area.toJTSMultiPolygon())) {
continue;
}
// Add stops from public transit relations into the area
Collection<OSMNode> nodes = osmdb.getStopsInArea(area.parent);
if (nodes != null) {
for (OSMNode node : nodes) {
addtoVisibilityAndStartSets(startingNodes, visibilityPoints, visibilityNodes, node);
}
}
for (Ring outerRing : area.outermostRings) {
for (int i = 0; i < outerRing.nodes.size(); ++i) {
OSMNode node = outerRing.nodes.get(i);
createEdgesForRingSegment(edges, edgeList, area, outerRing, i, alreadyAddedEdges);
addtoVisibilityAndStartSets(startingNodes, visibilityPoints, visibilityNodes, node);
}
for (Ring innerRing : outerRing.holes) {
for (int j = 0; j < innerRing.nodes.size(); ++j) {
OSMNode node = innerRing.nodes.get(j);
createEdgesForRingSegment(edges, edgeList, area, innerRing, j, alreadyAddedEdges);
addtoVisibilityAndStartSets(startingNodes, visibilityPoints, visibilityNodes, node);
}
}
}
}
List<OSMNode> nodes = new ArrayList<OSMNode>();
List<VLPoint> vertices = new ArrayList<VLPoint>();
accumulateRingNodes(ring, nodes, vertices);
VLPolygon polygon = makeStandardizedVLPolygon(vertices, nodes, false);
accumulateVisibilityPoints(ring.nodes, polygon, visibilityPoints, visibilityNodes, false);
ArrayList<VLPolygon> polygons = new ArrayList<VLPolygon>();
polygons.add(polygon);
// holes
for (Ring innerRing : ring.holes) {
ArrayList<OSMNode> holeNodes = new ArrayList<OSMNode>();
vertices = new ArrayList<VLPoint>();
accumulateRingNodes(innerRing, holeNodes, vertices);
VLPolygon hole = makeStandardizedVLPolygon(vertices, holeNodes, true);
accumulateVisibilityPoints(innerRing.nodes, hole, visibilityPoints, visibilityNodes, true);
nodes.addAll(holeNodes);
polygons.add(hole);
}
Environment areaEnv = new Environment(polygons);
// areas to prevent way explosion
if (visibilityPoints.size() > MAX_AREA_NODES) {
LOG.warn("Area " + group.getSomeOSMObject() + " is too complicated (" + visibilityPoints.size() + " > " + MAX_AREA_NODES);
continue;
}
if (!areaEnv.is_valid(VISIBILITY_EPSILON)) {
LOG.warn("Area " + group.getSomeOSMObject() + " is not epsilon-valid (epsilon = " + VISIBILITY_EPSILON + ")");
continue;
}
edgeList.setOriginalEdges(ring.toJtsPolygon());
createNamedAreas(edgeList, ring, group.areas);
OSMWithTags areaEntity = group.getSomeOSMObject();
for (int i = 0; i < visibilityNodes.size(); ++i) {
OSMNode nodeI = visibilityNodes.get(i);
VisibilityPolygon visibilityPolygon = new VisibilityPolygon(visibilityPoints.get(i), areaEnv, VISIBILITY_EPSILON);
Polygon poly = toJTSPolygon(visibilityPolygon);
for (int j = 0; j < visibilityNodes.size(); ++j) {
OSMNode nodeJ = visibilityNodes.get(j);
P2<OSMNode> nodePair = new P2<OSMNode>(nodeI, nodeJ);
if (alreadyAddedEdges.contains(nodePair))
continue;
IntersectionVertex startEndpoint = __handler.getVertexForOsmNode(nodeI, areaEntity);
IntersectionVertex endEndpoint = __handler.getVertexForOsmNode(nodeJ, areaEntity);
Coordinate[] coordinates = new Coordinate[] { startEndpoint.getCoordinate(), endEndpoint.getCoordinate() };
GeometryFactory geometryFactory = GeometryUtils.getGeometryFactory();
LineString line = geometryFactory.createLineString(coordinates);
if (poly != null && poly.contains(line)) {
createSegments(nodeI, nodeJ, startEndpoint, endEndpoint, group.areas, edgeList, edges);
if (startingNodes.contains(nodeI)) {
startingVertices.add(startEndpoint);
}
if (startingNodes.contains(nodeJ)) {
startingVertices.add(endEndpoint);
}
}
}
}
}
pruneAreaEdges(startingVertices, edges);
}
use of org.opentripplanner.common.model.P2 in project OpenTripPlanner by opentripplanner.
the class ShapefileStreetModule method buildGraph.
@Override
public void buildGraph(Graph graph, HashMap<Class<?>, Object> extra) {
try {
FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = _featureSourceFactory.getFeatureSource();
CoordinateReferenceSystem sourceCRS = featureSource.getInfo().getCRS();
Hints hints = new Hints(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
CRSAuthorityFactory factory = ReferencingFactoryFinder.getCRSAuthorityFactory("EPSG", hints);
CoordinateReferenceSystem worldCRS = factory.createCoordinateReferenceSystem("EPSG:4326");
Query query = new Query();
query.setCoordinateSystem(sourceCRS);
query.setCoordinateSystemReproject(worldCRS);
FeatureCollection<SimpleFeatureType, SimpleFeature> features = featureSource.getFeatures(query);
features = featureSource.getFeatures(query);
HashMap<String, HashMap<Coordinate, Integer>> intersectionNameToId = new HashMap<String, HashMap<Coordinate, Integer>>();
SimpleFeatureConverter<String> streetIdConverter = _schema.getIdConverter();
SimpleFeatureConverter<String> streetNameConverter = _schema.getNameConverter();
SimpleFeatureConverter<P2<StreetTraversalPermission>> permissionConverter = _schema.getPermissionConverter();
SimpleFeatureConverter<String> noteConverter = _schema.getNoteConverter();
HashMap<Coordinate, IntersectionVertex> intersectionsByLocation = new HashMap<Coordinate, IntersectionVertex>();
SimpleFeatureConverter<P2<Double>> safetyConverter = _schema.getBicycleSafetyConverter();
SimpleFeatureConverter<Boolean> slopeOverrideCoverter = _schema.getSlopeOverrideConverter();
SimpleFeatureConverter<Boolean> featureSelector = _schema.getFeatureSelector();
// Keep track of features that are duplicated so we don't have duplicate streets
Set<Object> seen = new HashSet<Object>();
List<SimpleFeature> featureList = new ArrayList<SimpleFeature>();
FeatureIterator<SimpleFeature> it2 = features.features();
while (it2.hasNext()) {
SimpleFeature feature = it2.next();
if (featureSelector != null && !featureSelector.convert(feature)) {
continue;
}
featureList.add(feature);
}
it2.close();
it2 = null;
HashMap<Coordinate, TreeSet<String>> coordinateToStreetNames = getCoordinatesToStreetNames(featureList);
for (SimpleFeature feature : featureList) {
if (feature.getDefaultGeometry() == null) {
log.warn("feature has no geometry: " + feature.getIdentifier());
continue;
}
LineString geom = toLineString((Geometry) feature.getDefaultGeometry());
Object o = streetIdConverter.convert(feature);
String label = "" + o;
if (o != null && seen.contains(label)) {
continue;
}
seen.add(label);
String name = streetNameConverter.convert(feature);
Coordinate[] coordinates = geom.getCoordinates();
if (coordinates.length < 2) {
// not a real linestring
log.warn("Bad geometry for street with label " + label + " name " + name);
continue;
}
// this rounding is a total hack, to work around
// http://jira.codehaus.org/browse/GEOT-2811
Coordinate startCoordinate = new Coordinate(Math.round(coordinates[0].x * 1048576) / 1048576.0, Math.round(coordinates[0].y * 1048576) / 1048576.0);
Coordinate endCoordinate = new Coordinate(Math.round(coordinates[coordinates.length - 1].x * 1048576) / 1048576.0, Math.round(coordinates[coordinates.length - 1].y * 1048576) / 1048576.0);
String startIntersectionName = getIntersectionName(coordinateToStreetNames, intersectionNameToId, startCoordinate);
if (startIntersectionName == "null") {
log.warn("No intersection name for " + name);
}
String endIntersectionName = getIntersectionName(coordinateToStreetNames, intersectionNameToId, endCoordinate);
IntersectionVertex startIntersection = intersectionsByLocation.get(startCoordinate);
if (startIntersection == null) {
startIntersection = new IntersectionVertex(graph, startIntersectionName, startCoordinate.x, startCoordinate.y, new NonLocalizedString(startIntersectionName));
intersectionsByLocation.put(startCoordinate, startIntersection);
}
IntersectionVertex endIntersection = intersectionsByLocation.get(endCoordinate);
if (endIntersection == null) {
endIntersection = new IntersectionVertex(graph, endIntersectionName, endCoordinate.x, endCoordinate.y, new NonLocalizedString(endIntersectionName));
intersectionsByLocation.put(endCoordinate, endIntersection);
}
double length = 0;
for (int i = 0; i < coordinates.length - 1; ++i) {
length += JTS.orthodromicDistance(coordinates[i], coordinates[i + 1], worldCRS);
}
P2<StreetTraversalPermission> permissions = permissionConverter.convert(feature);
// TODO Set appropriate car speed from shapefile source.
StreetEdge street = edgeFactory.createEdge(startIntersection, endIntersection, geom, new NonLocalizedString(name), length, permissions.first, false);
LineString reversed = (LineString) geom.reverse();
StreetEdge backStreet = edgeFactory.createEdge(endIntersection, startIntersection, reversed, new NonLocalizedString(name), length, permissions.second, true);
backStreet.shareData(street);
if (noteConverter != null) {
String note = noteConverter.convert(feature);
if (note != null && note.length() > 0) {
Alert noteAlert = Alert.createSimpleAlerts(note);
graph.streetNotesService.addStaticNote(street, noteAlert, StreetNotesService.ALWAYS_MATCHER);
graph.streetNotesService.addStaticNote(backStreet, noteAlert, StreetNotesService.ALWAYS_MATCHER);
}
}
boolean slopeOverride = slopeOverrideCoverter.convert(feature);
street.setSlopeOverride(slopeOverride);
backStreet.setSlopeOverride(slopeOverride);
if (safetyConverter != null) {
P2<Double> safetyFactors = safetyConverter.convert(feature);
if (safetyFactors != null) {
street.setBicycleSafetyFactor(safetyFactors.first.floatValue());
backStreet.setBicycleSafetyFactor(safetyFactors.second.floatValue());
}
}
}
} catch (Exception ex) {
throw new IllegalStateException("error loading shapefile street data", ex);
} finally {
_featureSourceFactory.cleanup();
}
}
Aggregations