Edge edge = (Edge) iterator.next();
Geometry edgeGeom = edge.getGeometry();
if (edgeGeom != null) { // make sure we get only real edges
if (edgeGeom instanceof LineString) {
// allConnectingEdges.add(edge); // instead of this, use a map now, so we don't have similar edge many times
connectingEdgesMap.put(new ReversibleLineStringWrapper(
(LineString) edgeGeom), edge);
}
}
}
Collection<Edge> vertexEdgesOut = state.getVertex().getOutgoing();
for (Iterator<Edge> iterator = vertexEdgesOut.iterator(); iterator.hasNext();) {
Edge edge = (Edge) iterator.next();
Geometry edgeGeom = edge.getGeometry();
if (edgeGeom != null) {
if (edgeGeom instanceof LineString) {
// allConnectingEdges.add(edge); // instead of this, use a map now, so we don't similar edge many times
connectingEdgesMap.put(new ReversibleLineStringWrapper(
(LineString) edgeGeom), edge);
}
}
}
}// end : if(et < maxTime)
}
// --
// points from list to array, for later
coords = new Coordinate[visitedCoords.size()];
int i = 0;
for (Coordinate c : visitedCoords)
coords[i++] = c;
// connection edges from Map to List
allConnectingEdges.clear();
for (Edge tedge : connectingEdgesMap.values())
allConnectingEdges.add(tedge);
}
StringWriter sw = new StringWriter();
GeometryJSON geometryJSON = new GeometryJSON();
//
// -- create the different outputs ---
//
try {
if (output.equals(SIsochrone.RESULT_TYPE_POINTS)) {
// in case there was no road we create a circle and
// and return those points
if (noRoadNearBy) {
Geometry circleShape = createCirle(dropPoint, pathToStreet);
coords = circleShape.getCoordinates();
}
// -- the states/nodes with time elapsed <= X min.
LOG.debug("write multipoint geom with {} points", coords.length);
geometryJSON.write(gf.createMultiPoint(coords), sw);
LOG.debug("done");
} else if (output.equals(SIsochrone.RESULT_TYPE_SHED)) {
Geometry geomsArray[] = null;
// in case there was no road we create a circle
if (noRoadNearBy) {
Geometry circleShape = createCirle(dropPoint, pathToStreet);
geometryJSON.write(circleShape, sw);
} else {
if (maxTime > shedCalcMethodSwitchTimeInSec) { // eg., walkshed > 20 min
// -- create a point-based walkshed
// less exact and should be used for large walksheds with many edges
LOG.debug("create point-based shed (not from edges)");
geomsArray = new Geometry[coords.length];
for (int j = 0; j < geomsArray.length; j++) {
geomsArray[j] = gf.createPoint(coords[j]);
}
} else {
// -- create an edge-based walkshed
// it is more exact and should be used for short walks
LOG.debug("create edge-based shed (not from points)");
Map<ReversibleLineStringWrapper, LineString> walkShedEdges = Maps
.newHashMap();
// add the walk from the pushpin to closest street point
walkShedEdges.put(new ReversibleLineStringWrapper(pathToStreet),
pathToStreet);
// get the edges and edge parts within time limits
ArrayList<LineString> withinTimeEdges = this
.getLinesAndSubEdgesWithinMaxTime(maxTime, allConnectingEdges,
sptA, angleLimitForUShapeDetection,
distanceToleranceForUShapeDetection, maxUserSpeed, usesCar,
doSpeedTest);
for (LineString ls : withinTimeEdges) {
walkShedEdges.put(new ReversibleLineStringWrapper(ls), ls);
}
geomsArray = new Geometry[walkShedEdges.size()];
int k = 0;
for (LineString ls : walkShedEdges.values())
geomsArray[k++] = ls;
} // end if-else: maxTime condition
GeometryCollection gc = gf.createGeometryCollection(geomsArray);
// create the concave hull, but in case it fails we just return the convex hull
Geometry outputHull = null;
LOG.debug(
"create concave hull from {} geoms with edge length limit of about {} m (distance on meridian)",
geomsArray.length, concaveHullAlpha * 111132);
// 1deg at Latitude phi = 45deg is about 111.132km
// (see wikipedia: http://en.wikipedia.org/wiki/Latitude#The_length_of_a_degree_of_latitude)
try {
ConcaveHull hull = new ConcaveHull(gc, concaveHullAlpha);
outputHull = hull.getConcaveHull();
} catch (Exception e) {
outputHull = gc.convexHull();
LOG.debug("Could not generate ConcaveHull for WalkShed, using ConvexHull instead.");
}
LOG.debug("write shed geom");
geometryJSON.write(outputHull, sw);
LOG.debug("done");
}
} else if (output.equals(SIsochrone.RESULT_TYPE_EDGES)) {
// in case there was no road we return only the suggested path to the street
if (noRoadNearBy) {
geometryJSON.write(pathToStreet, sw);
} else {
// -- if we would use only the edges from the paths to the origin we will miss
// some edges that will be never on the shortest path (e.g. loops/crescents).
// However, we can retrieve all edges by checking the times for each
// edge end-point
Map<ReversibleLineStringWrapper, LineString> walkShedEdges = Maps.newHashMap();
// add the walk from the pushpin to closest street point
walkShedEdges.put(new ReversibleLineStringWrapper(pathToStreet), pathToStreet);
// get the edges and edge parts within time limits
ArrayList<LineString> withinTimeEdges = this
.getLinesAndSubEdgesWithinMaxTime(maxTime, allConnectingEdges, sptA,
angleLimitForUShapeDetection,
distanceToleranceForUShapeDetection, maxUserSpeed, usesCar,
doSpeedTest);
for (LineString ls : withinTimeEdges) {
walkShedEdges.put(new ReversibleLineStringWrapper(ls), ls);
}
Geometry mls = null;
LineString edges[] = new LineString[walkShedEdges.size()];
int k = 0;
for (LineString ls : walkShedEdges.values())