/** * @return The distance between the origin and the snapped {@link Location} */ public Distance getDistance() { return this.origin.distanceTo(this); }
@Override public Distance length() { return this.start().distanceTo(this.end()); }
/** * @param atlas * The {@link Atlas} on which the router works * @param threshold * The threshold to look for edges in case of routing between locations * @return A Dijkstra router (the heuristic looks at the distance from the start only) */ public static AStarRouter dijkstra(final Atlas atlas, final Distance threshold) { return new AStarRouter(atlas, threshold, (start, candidate, end) -> start.getLocation() .distanceTo(candidate.getLocation()).asMeters()); }
/** * @param atlas * The {@link Atlas} on which the router works * @param threshold * The threshold to look for edges in case of routing between locations * @return A balanced A* Router, which gives 75% cost to the distance from the end and 25% cost * to the distance from the start. */ public static AStarRouter balanced(final Atlas atlas, final Distance threshold) { final double distanceFromStartCostRatio = 0.25; return new AStarRouter(atlas, threshold, (start, candidate, end) -> distanceFromStartCostRatio * start.getLocation().distanceTo(candidate.getLocation()).asMeters() + (1 - distanceFromStartCostRatio) * candidate.getLocation().distanceTo(end.getLocation()).asMeters()); }
/** * @param atlas * The {@link Atlas} on which the router works * @param threshold * The threshold to look for edges in case of routing between locations * @return A fast A* Router, which gives all cost to the distance from the end. The route will * be found faster, but the result will be non-optimal */ public static AStarRouter fastComputationAndSubOptimalRoute(final Atlas atlas, final Distance threshold) { return new AStarRouter(atlas, threshold, (start, candidate, end) -> candidate.getLocation() .distanceTo(end.getLocation()).asMeters()); }
final SortedSet<Node> nodes = new TreeSet<>((node1, node2) -> final Distance distance1 = location.distanceTo(node1.getLocation()); final Distance distance2 = location.distanceTo(node2.getLocation()); final double difference = distance2.asMillimeters() - distance1.asMillimeters(); if (difference > 0.0) for (final Node candidate : nodes) final Distance distance = location.distanceTo(candidate.getLocation()); if (distance.isLessThanOrEqualTo(toleranceDistance))
@Test public void testCrossingAntimeridian() { final Location one = new Location(Latitude.degrees(37), Longitude.degrees(179.998)); final Location two = new Location(Latitude.degrees(37), Longitude.degrees(179.999)); // This one is actually -180.0 final Location thr = new Location(Latitude.degrees(37), Longitude.degrees(180.0)); final Location fur = new Location(Latitude.degrees(37), Longitude.degrees(-179.999)); logger.info("one equirectangular two: {}", one.equirectangularDistanceTo(two)); logger.info("two equirectangular thr: {}", two.equirectangularDistanceTo(thr)); logger.info("thr equirectangular fur: {}", thr.equirectangularDistanceTo(fur)); logger.info("one haversine two: {}", one.haversineDistanceTo(two)); logger.info("two haversine thr: {}", two.haversineDistanceTo(thr)); logger.info("thr haversine fur: {}", thr.haversineDistanceTo(fur)); logger.info("one mixed two: {}", one.distanceTo(two)); logger.info("two mixed thr: {}", two.distanceTo(thr)); logger.info("thr mixed fur: {}", thr.distanceTo(fur)); logger.info("one heading two: {}", one.headingTo(two)); logger.info("two heading thr: {}", two.headingTo(thr)); logger.info("thr heading fur: {}", thr.headingTo(fur)); Assert.assertEquals(one.distanceTo(two).asMeters(), two.distanceTo(thr).asMeters(), 3); Assert.assertEquals(two.distanceTo(thr).asMeters(), thr.distanceTo(fur).asMeters(), 3); Assert.assertEquals(one.headingTo(two).asDegrees(), two.headingTo(thr).asDegrees(), 3); Assert.assertEquals(two.headingTo(thr).asDegrees(), thr.headingTo(fur).asDegrees(), 3); }
/** * Get the offset from the start of the node's location * * @param node * The location to test * @param occurrenceIndex * In case of a self intersecting polyline (one or more locations appear more than * once), indicate the index at which this method should return the location. 0 would * be first occurrence, 1 second, etc. * @return The offset ratio from the start of the {@link PolyLine} */ public Ratio offsetFromStart(final Location node, final int occurrenceIndex) { final Distance max = this.length(); Distance candidate = Distance.ZERO; Location previous = this.first(); int index = 0; for (final Location location : this) { candidate = candidate.add(previous.distanceTo(location)); if (location.equals(node) && occurrenceIndex == index++) { return Ratio.ratio(candidate.asMeters() / max.asMeters()); } previous = location; } throw new CoreException("The location {} is not a node of the PolyLine", node); }
@Test public void testDistanceCost() { final PolyLine source = new PolyLine(Location.CROSSING_85_280, Location.TEST_2, Location.TEST_1); final PolyLine destination = new PolyLine(Location.CROSSING_85_280, Location.TEST_6, Location.TEST_1); final Distance distanceToOneWay = source.averageOneWayDistanceTo(destination); final Distance distanceFromOneWay = destination.averageOneWayDistanceTo(source); final Distance distanceTo = source.averageDistanceTo(destination); final Distance distanceFrom = destination.averageDistanceTo(source); logger.info("distanceToOneWay: {}", distanceToOneWay); logger.info("distanceFromOneWay: {}", distanceFromOneWay); logger.info("distanceTo: {}", distanceTo); logger.info("distanceFrom: {}", distanceFrom); Assert.assertEquals(distanceTo, distanceFrom); Assert.assertTrue( Location.TEST_2.distanceTo(Location.TEST_6).asMeters() / 3 > distanceTo.asMeters()); }
@Test public void testMidPointAccuracyAndSpeed() { final Location location1 = new Location(Latitude.degrees(51.127), Longitude.degrees(1.338)); final Location location2 = new Location(Latitude.degrees(50.964), Longitude.degrees(1.853)); final Time beginning = Time.now(); final Location derivedMidPoint = location1.shiftAlongGreatCircle( location1.headingTo(location2), location1.distanceTo(location2).scaleBy(Ratio.HALF)); System.out.println("Derived Duration: " + beginning.elapsedSince()); System.out.println(derivedMidPoint.toString() + "\n"); final Time beginning2 = Time.now(); final Location calculatedMidPoint = location1.midPoint(location2); System.out.println("Calculated Duration: " + beginning2.elapsedSince()); System.out.println(calculatedMidPoint.toString() + "\n"); final Time beginning3 = Time.now(); final Location calculatedLoxodromicMidPoint = location1.loxodromicMidPoint(location2); System.out.println("Calculated Loxodromic Duration: " + beginning3.elapsedSince()); System.out.println(calculatedLoxodromicMidPoint.toString() + "\n"); }
.distanceTo(this.rectangle1.upperRight()); final Rectangle collapsedRectangle1 = this.rectangle1.contract(rectangle1CornerToCorner); Assert.assertEquals(collapsedRectangle1.center().bounds(), collapsedRectangle1); .distanceTo(this.rectangle1.upperRight()).scaleBy(.51); final Rectangle collapsedHorizontally = this.rectangle1 .contract(contractRectangle1Distance); Math.round(new Location(this.rectangle1.lowerLeft().getLatitude(), collapsedHorizontally.middle().getLongitude()) .distanceTo(collapsedHorizontally.lowerLeft()).asMeters())); .distanceTo(this.rectangle2.lowerLeft()).scaleBy(.51); final Rectangle collapsedVertically = this.rectangle2.contract(contractRectangle2Distance); Assert.assertEquals(Surface.forDm7Squared(0), collapsedVertically.surface()); Math.round(new Location(collapsedVertically.middle().getLatitude(), this.rectangle2.lowerLeft().getLongitude()) .distanceTo(collapsedVertically.lowerLeft()).asMeters()));