📄 route.java
字号:
* 2. Return all but the last vertex, this is the route to the destination. * A boolean allows for two cases: heading towards a junction (the endpoint of the line) or heading away from the * endpoint of the line (this function can't be used to go to two midpoints on a line). * * * @param currentCoord * @param destinationCoord * @param road * @param toJunction whether or not we're travelling towards or away from a Junction * @return */ private ArrayList<Coordinate> getCoordsAlongRoad(Coordinate currentCoord, Coordinate destinationCoord, Road road, boolean toJunction) { // XXXX perform some checks to make sure coordinate and road etc are correct (e.g. coords are on a road). Coordinate[] roadCoords = this.roadGeography.getGeometry(road).getCoordinates(); ArrayList<Coordinate> routeCoords = new ArrayList<Coordinate>(); // The list of coordinates to return// // Check that the either the destination or current coordinate are actually part of the road boolean correct = false; for (int i=0; i<roadCoords.length; i++) { if (toJunction && roadCoords[i].equals(destinationCoord)) { correct = true; break; } else if (!toJunction && roadCoords[i].equals(currentCoord)) { correct = true; break; } } // for if (!correct) System.err.println("Route: getCoordsAlongRoad: Error, destiantion or current coordinate is not part" + "of road (person "+this.person.getName()+")"); // Might need to reverse the order of the road coordinates if (toJunction && !roadCoords[roadCoords.length-1].equals(destinationCoord)) { ArrayUtils.reverse(roadCoords); // If heading towards a junction, destination coordinate must be at end of road segment } else if (!toJunction && !roadCoords[0].equals(currentCoord)){ ArrayUtils.reverse(roadCoords); // If heading away form junction, current coord must be at beginning of road segment } Point destinationPointGeom = geomFac.createPoint(destinationCoord); Point currentPointGeom = geomFac.createPoint(currentCoord); for (int i=0; i<roadCoords.length-1; i++ ) { Coordinate[] segmentCoords = new Coordinate[]{roadCoords[i], roadCoords[i+1]}; LineString segment = geomFac.createLineString(segmentCoords); // Draw a small buffer around the line segment and look for the coordinate within the buffer Geometry buffer = segment.buffer(little_buffer_distance); if (!toJunction) { // If heading away from a junction, keep adding road coords until we find the destination routeCoords.add(roadCoords[i]); if (destinationPointGeom.within(buffer)) { routeCoords.add(destinationCoord); return routeCoords; } } else if (toJunction) { // If heading towards a junction: find the curent coord, add it to the route, then add all the remaining // coords which make up the road segment if (currentPointGeom.within(buffer)) { routeCoords.add(destinationCoord); for (int j=i+1; j<roadCoords.length; j++) { routeCoords.add(roadCoords[j]); } return routeCoords; } } if (destinationPointGeom.within(buffer) ) { routeCoords.add(destinationCoord); break; } } // for // If we get here then the route hasn't been created System.err.println("Route: getCoordsAlongRoad: couuld not find destination coordinates" + "along the road for this person. Heading "+(toJunction? "towards" : "away from")+" a junction." + "(Person: "+ this.person.getName()+")"); return null; } /** * Returns all the coordinates that describe how to get between two junctions. */ private ArrayList<Coordinate> getRouteBetweenJunctions (Junction currJunc, Junction destJunc) { // Get the edges that make up the shortest path List<RepastEdge<Junction>> shortestPath = new ShortestPath<Junction>(roadNetwork).getPath(currJunc, destJunc); // Find the roads which are associated with these edges ArrayList<Road> roadPath = new ArrayList<Road>(); for (RepastEdge<Junction> edge:shortestPath) { String roadID = cityContext.getIDFromEdge(edge); Road road = cityContext.findRoadWithID(roadID); roadPath.add(road); } // Go through each road and get the coordinates of it's line segments, adding them to an array. ArrayList<Coordinate> coordPath = new ArrayList<Coordinate>(); for (Road road:roadPath) { Coordinate[] coords = roadGeography.getGeometry(road).getCoordinates(); // Make sure the coordinates of the road are added in the correcct order: check that the new road starts from // the last point in our road array if (coordPath.size()>1 && !coords[0].equals(coordPath.get(coordPath.size()-1))) { ArrayUtils.reverse(coords); } for (Coordinate coord:coords) { coordPath.add(coord); } // for coord:coords } // for road:roadPath return coordPath; } /** * Find a random coordainte on a road. * @return any road coordinate */ public Coordinate getRandomRoadCoordinate() { // Get a random road and find a point on it RoadContext roadContext = ContextCreator.getRoadContext(); Road road = (Road) roadContext.getRandomObject(); Geometry roadGeom = ContextCreator.getRoadGeography().getGeometry(road); Coordinate[] coords = roadGeom.getCoordinates(); return coords[RandomHelper.nextIntFromTo(0,coords.length-1)]; } // /**// * Find a random coordinate in a house.// * @return any house coordinate// */// public Coordinate getRandomHouseCoordinate() {// // Get a random road and find a point on it// BuildingContext buildingContext = ContextCreator.getBuildingContext();// House house= (House) buildingContext.getRandomObjects(House.class, 1);// Geometry houseGeom = ContextCreator.getBuildingGeography().getGeometry(house);// Coordinate[] coords = houseGeom.getCoordinates();// return coords[RandomHelper.nextIntFromTo(0,coords.length-1)];// } // XXXX - only using this for testing public static Coordinate getRandomCoordinateStatic() { // Get a random road and find a point on it RoadContext roadContext = ContextCreator.getRoadContext(); Road road = (Road) roadContext.getRandomObject(); Geometry roadGeom = ContextCreator.getRoadGeography().getGeometry(road); Coordinate[] coords = roadGeom.getCoordinates(); return coords[RandomHelper.nextIntFromTo(0,coords.length-1)]; } /** * Determine whether or not the person associated with this Route is at their destiantion. * @return True if the person is at their destination * @throws ItemNotFoundException */ public boolean atDestination() { Geometry destGeom = geomFac.createPoint(this.destination); Geometry destBuffer = null;; // Will return true if the person is within 1m of their destination destBuffer = destGeom.buffer(little_buffer_distance); //destBuffer = destGeom.buffer(Route.convertFromMeters(1)); Geometry persGeom = personGeography.getGeometry(person); //Coordinate curr = offGeom.getCoordinate(); if (persGeom.within(destBuffer)) { // System.out.println("Offender "+person.getID()+person.getName()+" at destination"); return true; } else return false; } public Coordinate getDestination() { return this.destination; } /** * Test if a coordinate is part of a road segment. * @param coord The coordinate which we want to test * @return True if the coordinate is part of a road segment */ private boolean onRoad(Coordinate coord) { Point coordGeom = geomFac.createPoint(coord); // Iterate over all roads in the area, returning true if the coordinate is part of one of them for (Road road:roadGeography.getObjectsWithin(coordGeom.buffer(big_buffer_distance).getEnvelopeInternal())) { if (coordGeom.within(geomFac.createGeometry( roadGeography.getGeometry(road).buffer(little_buffer_distance)))) { return true; } } return false; } // /* Overloaded function, takes the persons current position as a coordinate (useful when travelling because// * the person isn't actually moved until the end of the iteration */// public boolean atDestination(Coordinate coord) {// Geometry destGeom = geomFac.createPoint(person.getDestination());// Geometry destBuffer = destGeom.buffer(0.00001); // Geometry currentPosition = geomFac.createPoint(coord);// //Coordinate curr = offGeom.getCoordinate();// if (currentPosition.within(destBuffer)) {// System.out.println("Offender "+person.getID()+person.getName()+" at destination");// return true;// }// else// return false;// } /** * Removes any duplicate coordinates from the route. If my route-generating algorithm was better this would't be * necessary. Code adapted from here: http://docs.google.com/View?docid=ah9xr5g2vzfz_32gvtwfw */ private void removeDuplicateCoords() { /*Use a LinkedHashSet as a mean to remove the duplicate entries. * The LinkedHashSet has two characteristics that fit for the job: * First, it retains the insertion order, which ensure the output's * order is the same as the input's. Secondly, by being a set, it * only accept each entries once; a LinkedHashSet ignores subsequent * insertion of the same entry.*/ LinkedHashSet<Coordinate> set = new LinkedHashSet<Coordinate>(); for (Coordinate coord:route) set.add(coord); this.route = new Vector<Coordinate>(); for (Coordinate coord:set) { this.route.add(coord); } } // /* Returns true if the two coordinates are almost identical. This is useful for comparing coordinates// * which are not *exactly* equal and so Coordinate.equals() cannot be used*/// private boolean almostEqualCoords(Coordinate c1, Coordinate c2) {// Parameters p = RunEnvironment.getInstance().getParameters();// Geometry buffer = geomFac.createPoint(c1).buffer(((Double) p.getValue("bufferDist"))/1000);// if (geomFac.createPoint(c2).within(buffer))// return true;// else// return false;// } // /* Displays all the coordinates which make up this route */// private void displayRoute() {// System.out.println("Displaying route for "+person.getName());// // Remove any nodes from the context// for (Person node:personContext.getObjects(DummyNode.class)){// personContext.remove(node);// }// for (Person node:personContext.getObjects(DummyDestination.class)){// personContext.remove(node);// }// DummyDestination dest = new DummyDestination(-1, person.getDestination());// personContext.add(dest);// try {// personGeography.move(dest, geomFac.createPoint(dest.getCoord()));// } catch (Exception e) {System.out.println("DEST EXCEPTION");}// int counter = 0;// for (Coordinate coord:route) {// DummyNode node = new DummyNode(counter++, coord);// personContext.add(node);// Point point = geomFac.createPoint(coord);// System.out.println(node.getRouteNumber()+"\t"+point.getCoordinate().toString());// try {// personGeography.move(node, point);// // } catch (Exception e) {// System.out.println("\t\tEXCEPTION");// }// } // } /** * Converts a distance (passed as lat/log decimal degrees) to meters * @param dist The distance in decimal degrees * @return the equivalent distance in meters */ public static double convertToMeters(double dist) { double distInMeters = NonSI.NAUTICAL_MILE.getConverterTo(SI.METER).convert(dist*60);// System.out.println("To meters: "+dist+" - "+distInMeters);// System.out.println(6378137.0*Math.PI*dist/180); return distInMeters; } /** * Converts a distance (passed as meters) to lat/log decimal degrees * @param dist The distance in decimal degrees * @return the equivalent distance in meters */ public static double convertFromMeters(double dist) { double distInDegrees = SI.METER.getConverterTo(NonSI.NAUTICAL_MILE).convert(dist)/(60.0);// System.out.println("From meters: "+dist+" - "+distInDegrees);// System.out.println((dist*180)/(6378137.0*Math.PI)); return distInDegrees; } /** * Returns the angle of the vector from p0 to p1. The angle will be between * -Pi and Pi. I got this directly from the JUMP program source. * @return the angle (in radians) that p0p1 makes with the positive x-axis. */ public static double angle(Coordinate p0, Coordinate p1) { double dx = p1.x - p0.x; double dy = p1.y - p0.y; return Math.atan2(dy, dx); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -