int addEdge(int fromIndex, int toIndex, PointList pointList, int flags) { double towerNodeDistance = 0; double prevLat = pointList.latitude(0); double prevLon = pointList.longitude(0); double lat; double lon; PointList pillarNodes = new PointList(pointList.size() - 2); int nodes = pointList.size(); for (int i = 1; i < nodes; i++) { lat = pointList.latitude(i); lon = pointList.longitude(i); towerNodeDistance += callback.calcDist(prevLat, prevLon, lat, lon); prevLat = lat; prevLon = lon; if (nodes > 2 && i < nodes - 1) pillarNodes.add(lat, lon); } if (towerNodeDistance == 0) { // As investigation shows often two paths should have crossed via one identical point // but end up in two very close points. later this will be removed/fixed while // removing short edges where one node is of degree 2 zeroCounter++; towerNodeDistance = 0.0001; } EdgeIterator iter = g.edge(fromIndex, toIndex, towerNodeDistance, flags); if (nodes > 2) iter.wayGeometry(pillarNodes); return nodes; }
@Test public void testBoth() throws Exception { PointList list = Helper.createPointList( 38.5, -120.2, 43.252, -126.453, 40.7, -120.95, 50.3139, 10.612793, 50.04303, 9.497681); String str = WebHelper.encodePolyline(list); assertEquals(list, WebHelper.decodePolyline(str, list.size())); list = Helper.createPointList(38.5, -120.2, 43.252, -126.453, 40.7, -120.95, 40.70001, -120.95001); str = WebHelper.encodePolyline(list); assertEquals(list, WebHelper.decodePolyline(str, list.size())); }
@Override public int addEdge(TLongList osmIds, int flags) { PointList pointList = new PointList(osmIds.size()); int successfullyAdded = 0; int firstNode = -1; int lastIndex = osmIds.size() - 1; int lastInBoundsPillarNode = -1; for (int i = 0; i < osmIds.size(); i++) { long osmId = osmIds.get(i); int tmpNode = osmIdToIndexMap.get(osmId); if (tmpNode == EMPTY) continue; // skip osmIds with no associated pillar or tower id (e.g. !OSMReader.isBounds) if (tmpNode == TOWER_NODE) continue; if (tmpNode == PILLAR_NODE) { // In some cases no node information is saved for the specified osmId. // ie. a way references a <node> which does not exist in the current file. // => if the node before was a pillar node then convert into to tower node (as it is also // end-standing). if (!pointList.isEmpty() && lastInBoundsPillarNode > -TOWER_NODE) { // transform the pillar node to a tower node tmpNode = lastInBoundsPillarNode; tmpNode = handlePillarNode(tmpNode, osmId, null, true); tmpNode = -tmpNode - 3; if (pointList.size() > 1 && firstNode >= 0) { // TOWER node successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags); pointList.clear(); pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode)); } firstNode = tmpNode; lastInBoundsPillarNode = -1; } continue; } if (tmpNode <= -TOWER_NODE && tmpNode >= TOWER_NODE) throw new AssertionError("Mapped index not in correct bounds " + tmpNode + ", " + osmId); if (tmpNode > -TOWER_NODE) { boolean convertToTowerNode = i == 0 || i == lastIndex; if (!convertToTowerNode) lastInBoundsPillarNode = tmpNode; // PILLAR node, but convert to towerNode if end-standing tmpNode = handlePillarNode(tmpNode, osmId, pointList, convertToTowerNode); } if (tmpNode < TOWER_NODE) { // TOWER node tmpNode = -tmpNode - 3; pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode)); if (firstNode >= 0) { successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags); pointList.clear(); pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode)); } firstNode = tmpNode; } } return successfullyAdded; }
@Override public int addEdge(TLongList nodes, int flags) { PointList pointList = new PointList(nodes.size()); int successfullyAdded = 0; int firstNode = -1; int lastIndex = nodes.size() - 1; int lastInBoundsPillarNode = -1; for (int i = 0; i < nodes.size(); i++) { long osmId = nodes.get(i); int tmpNode = osmIdToIndexMap.get(osmId); if (tmpNode == EMPTY) continue; // skip osmIds with no associated pillar or tower id (e.g. !OSMReader.isBounds) if (tmpNode == TOWER_NODE) continue; if (tmpNode == PILLAR_NODE) { // no pillarLats,pillarLons was saved for tmpNode // so if there are any existing pillar nodes we need to create an edge out of them if (!pointList.isEmpty() && lastInBoundsPillarNode >= 3) { // transform the pillar node to a tower node tmpNode = lastInBoundsPillarNode; tmpNode = handlePillarNode(tmpNode, osmId, null, true); tmpNode = -tmpNode - 3; if (pointList.size() > 1 && firstNode >= 0) { // TOWER node successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags); pointList.clear(); pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode)); } firstNode = tmpNode; lastInBoundsPillarNode = -1; } continue; } if (tmpNode <= -TOWER_NODE && tmpNode >= TOWER_NODE) throw new AssertionError("Mapped index not in correct bounds " + tmpNode); if (tmpNode > -TOWER_NODE) { lastInBoundsPillarNode = tmpNode; // PILLAR node, but convert to towerNode if end-standing tmpNode = handlePillarNode(tmpNode, osmId, pointList, i == 0 || i == lastIndex); } if (tmpNode < TOWER_NODE) { // TOWER node tmpNode = -tmpNode - 3; pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode)); if (firstNode >= 0) { successfullyAdded += addEdge(firstNode, tmpNode, pointList, flags); pointList.clear(); pointList.add(g.getLatitude(tmpNode), g.getLongitude(tmpNode)); } firstNode = tmpNode; } } return successfullyAdded; }
public void suggest(File locationFile, int locationListSize, File outputFile, int hubSize) { // WARNING: this code is VERY DIRTY. // It's JUST good enough to generate the hubs for Belgium once (because we only need to // determine them once). // Further research to generate good hubs is needed. List<AirLocation> locationList = readAirLocationFile(locationFile); if (locationListSize > locationList.size()) { throw new IllegalArgumentException( "The locationListSize (" + locationListSize + ") is larger than the locationList size (" + locationList.size() + ")."); } locationList = subselectLocationList(locationListSize, locationList); Map<Point, Point> fromPointMap = new LinkedHashMap<Point, Point>(locationListSize * 10); Map<Point, Point> toPointMap = new LinkedHashMap<Point, Point>(locationListSize * 10); int rowIndex = 0; double maxAirDistance = 0.0; for (AirLocation fromAirLocation : locationList) { for (AirLocation toAirLocation : locationList) { double airDistance = fromAirLocation.getAirDistanceDouble(toAirLocation); if (airDistance > maxAirDistance) { maxAirDistance = airDistance; } } } double airDistanceThreshold = maxAirDistance / 10.0; for (AirLocation fromAirLocation : locationList) { for (AirLocation toAirLocation : locationList) { double distance; if (fromAirLocation != toAirLocation) { GHRequest request = new GHRequest( fromAirLocation.getLatitude(), fromAirLocation.getLongitude(), toAirLocation.getLatitude(), toAirLocation.getLongitude()) .setVehicle("car"); GHResponse response = graphHopper.route(request); if (response.hasErrors()) { throw new IllegalStateException( "GraphHopper gave " + response.getErrors().size() + " errors. First error chained.", response.getErrors().get(0)); } // Distance should be in km, not meter distance = response.getDistance() / 1000.0; if (distance == 0.0) { throw new IllegalArgumentException( "The fromAirLocation (" + fromAirLocation + ") and toAirLocation (" + toAirLocation + ") are the same."); } PointList ghPointList = response.getPoints(); PointPart previousFromPointPart = null; PointPart previousToPointPart = null; double previousLatitude = Double.NaN; double previousLongitude = Double.NaN; for (int i = 0; i < ghPointList.size(); i++) { double latitude = ghPointList.getLatitude(i); double longitude = ghPointList.getLongitude(i); if (latitude == previousLatitude && longitude == previousLongitude) { continue; } if (calcAirDistance( latitude, longitude, fromAirLocation.getLatitude(), fromAirLocation.getLongitude()) < airDistanceThreshold) { Point fromPoint = new Point(latitude, longitude); Point oldFromPoint = fromPointMap.get(fromPoint); if (oldFromPoint == null) { // Initialize fromPoint instance fromPoint.pointPartMap = new LinkedHashMap<AirLocation, PointPart>(); fromPointMap.put(fromPoint, fromPoint); } else { // Reuse existing fromPoint instance fromPoint = oldFromPoint; } PointPart fromPointPart = fromPoint.pointPartMap.get(fromAirLocation); if (fromPointPart == null) { fromPointPart = new PointPart(fromPoint, fromAirLocation); fromPoint.pointPartMap.put(fromAirLocation, fromPointPart); fromPointPart.previousPart = previousFromPointPart; } fromPointPart.count++; previousFromPointPart = fromPointPart; } if (calcAirDistance( latitude, longitude, toAirLocation.getLatitude(), toAirLocation.getLongitude()) < airDistanceThreshold) { Point toPoint = new Point(latitude, longitude); Point oldToPoint = toPointMap.get(toPoint); if (oldToPoint == null) { // Initialize toPoint instance toPoint.pointPartMap = new LinkedHashMap<AirLocation, PointPart>(); toPointMap.put(toPoint, toPoint); } else { // Reuse existing toPoint instance toPoint = oldToPoint; } // Basically do the same as fromPointPart, but while traversing in the other direction PointPart toPointPart = toPoint.pointPartMap.get(toAirLocation); boolean newToPointPart = false; if (toPointPart == null) { toPointPart = new PointPart(toPoint, toAirLocation); toPoint.pointPartMap.put(toAirLocation, toPointPart); newToPointPart = true; } if (previousToPointPart != null) { previousToPointPart.previousPart = toPointPart; } toPointPart.count++; if (newToPointPart) { previousToPointPart = toPointPart; } else { previousToPointPart = null; } } previousLatitude = latitude; previousLongitude = longitude; } } } logger.debug(" Finished routes for rowIndex {}/{}", rowIndex, locationList.size()); rowIndex++; } Set<Point> hubPointList = new LinkedHashSet<Point>(20); extractFromHubs(new ArrayList<Point>(fromPointMap.values()), hubPointList, (hubSize + 1) / 2); extractFromHubs(new ArrayList<Point>(toPointMap.values()), hubPointList, hubSize / 2); logger.info("Writing hubs..."); BufferedWriter vrpWriter = null; try { vrpWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile), "UTF-8")); vrpWriter.write("HUB_COORD_SECTION\n"); int id = 0; for (Point point : hubPointList) { vrpWriter.write("" + id + " " + point.latitude + " " + point.longitude + " " + id + "\n"); id++; } vrpWriter.write("\n\nGOOGLE MAPS\n"); for (Point point : hubPointList) { vrpWriter.write("" + id + "\t0\t" + point.latitude + "," + point.longitude + "\n"); id++; } } catch (IOException e) { throw new IllegalArgumentException( "Could not read the locationFile (" + locationFile.getName() + ") or write the vrpOutputFile (" + outputFile.getName() + ").", e); } finally { IOUtils.closeQuietly(vrpWriter); } // Throw in google docs spreadsheet and use add-on Mapping Sheets to visualize. }