Ejemplo n.º 1
0
void write_point(const SearchPoint& sp, const FlatGeoPoint& p, const char* name)
{
  printf("%g %g %d %d # %s\n",
         (double)sp.get_location().longitude.Degrees(),
         (double)sp.get_location().latitude.Degrees(),
         p.Longitude,
         p.Latitude,
         name);
  fflush(stdout);
}
Ejemplo n.º 2
0
gcc_pure
static bool
IsInRange(const SearchPoint &a, const SearchPoint &b,
          unsigned half_max_range_sq, double max_distance)
{
  /* optimisation: if the flat distance is much smaller than the
     maximum range, we don't need to call the method
     GeoPoint::Distance() which is very expensive */
  return a.GetFlatLocation().DistanceSquared(b.GetFlatLocation()) <= half_max_range_sq ||
    a.GetLocation().DistanceS(b.GetLocation()) <= max_distance;
}
Ejemplo n.º 3
0
/**
 * Test whether two points (as previous search locations) are significantly
 * different to warrant a new search
 *
 * @param a1 First point to compare
 * @param a2 Second point to compare
 * @param dist_threshold Threshold distance for significance
 *
 * @return True if distance is significant
 */
gcc_pure
static bool
DistanceIsSignificant(const SearchPoint &a1, const SearchPoint &a2,
                      const unsigned dist_threshold = 1)
{
  return a1.FlatSquareDistance(a2) > (dist_threshold * dist_threshold);
}
Ejemplo n.º 4
0
  /** 
   * Distance function for free point
   * 
   * @param curNode Destination node
   * @param currentLocation Origin location
   * 
   * @return Distance (flat) from origin to destination
   */
  gcc_pure
  unsigned CalcDistance(const ScanTaskPoint curNode,
                        const SearchPoint &currentLocation) const {
    /* using expensive floating point formulas here to avoid integer
       rounding errors */

    const GeoPoint &a = GetPoint(curNode).GetLocation();
    const GeoPoint &b = currentLocation.GetLocation();

    return (unsigned)a.Distance(b);
  }
Ejemplo n.º 5
0
bool
TaskDijkstraMin::DistanceMin(const SearchPoint &currentLocation)
{
  dijkstra.Clear();
  dijkstra.Reserve(256);

  if (currentLocation.IsValid()) {
    AddStartEdges(0, currentLocation);
  } else {
    AddZeroStartEdges();
  }

  return Run();
}
Ejemplo n.º 6
0
static bool
sortleft (const SearchPoint& sp1, const SearchPoint& sp2)
{ 
  return sp1.sort(sp2);
}
Ejemplo n.º 7
0
bool
OLCTriangle::FindClosingPairs(unsigned old_size)
{
  if (predict) {
    return closing_pairs.Insert(ClosingPair(0, n_points-1));
  }

  struct TracePointNode {
    const TracePoint *point;
    unsigned index;
  };

  struct TracePointNodeAccessor {
    gcc_pure
    int GetX(const TracePointNode &node) const {
      return node.point->GetFlatLocation().x;
    }

    gcc_pure
    int GetY(const TracePointNode &node) const {
      return node.point->GetFlatLocation().y;
    }
  };

  QuadTree<TracePointNode, TracePointNodeAccessor> search_point_tree;

  for (unsigned i = old_size; i < n_points; ++i) {
    TracePointNode node;
    node.point = &GetPoint(i);
    node.index = i;

    search_point_tree.insert(node);
  }

  search_point_tree.Optimise();

  bool new_pair = false;

  for (unsigned i = old_size; i < n_points; ++i) {
    TracePointNode point;
    point.point = &GetPoint(i);
    point.index = i;

    const SearchPoint start = *point.point;
    const unsigned max_range = trace_master.ProjectRange(start.GetLocation(), max_distance);
    const unsigned half_max_range_sq = max_range * max_range / 2;

    const int min_altitude = GetMinimumFinishAltitude(*point.point);
    const int max_altitude = GetMaximumStartAltitude(*point.point);

    unsigned last = 0, first = i;

    const auto visitor = [this, i, start,
                          half_max_range_sq,
                          min_altitude, max_altitude,
                          &first, &last]
      (const TracePointNode &node) {
      const auto &dest = *node.point;

      if (node.index + 2 < i &&
          dest.GetIntegerAltitude() <= max_altitude &&
          IsInRange(start, dest, half_max_range_sq, max_distance)) {
        // point i is last point
        first = std::min(node.index, first);
        last = i;
      } else if (node.index > i + 2 &&
                 dest.GetIntegerAltitude() >= min_altitude &&
                 IsInRange(start, dest, half_max_range_sq, max_distance)) {
        // point i is first point
        first = i;
        last = std::max(node.index, last);
      }
    };

    search_point_tree.VisitWithinRange(point, max_range, visitor);

    if (last != 0 && closing_pairs.Insert(ClosingPair(first, last)))
      new_pair = true;
  }

  return new_pair;
}
Ejemplo n.º 8
0
 /**
  * Accessor to retrieve location of the sample/boundary polygon
  * node that produces the minimum task distance.
  *
  * @return Location of minimum distance node
  */
 const GeoPoint &GetLocationMin() const {
     return search_min.GetLocation();
 };
Ejemplo n.º 9
0
 /**
  * Accessor to retrieve location of the sample/boundary polygon
  * node that produces the maximum task distance.
  *
  * @return Location of max distance node
  */
 gcc_pure
 const GeoPoint &GetLocationMax() const {
     return search_max.GetLocation();
 };
Ejemplo n.º 10
0
TriangleSecondLeg::Result
TriangleSecondLeg::Calculate(const SearchPoint &c, unsigned best) const
{
  // this is a heuristic to remove invalid triangles
  // we do as much of this in flat projection for speed

  const unsigned df_2 = b.FlatDistanceTo(c);
  const unsigned df_3 = c.FlatDistanceTo(a);
  const unsigned df_total = df_1+df_2+df_3;

  // require some distance!
  if (df_total<20) {
    return Result(0, 0);
  }

  // no point scanning if worst than best
  if (df_total<= best) {
    return Result(0, 0);
  }

  const unsigned shortest = std::min({df_1, df_2, df_3});

  // require all legs to have distance
  if (!shortest)
    return Result(0, 0);

  if (is_fai && (shortest*4<df_total))
    // fails min < 25% worst-case rule!
    return Result(0, 0);

  const unsigned d = df_3 + df_2;

  // without FAI rules, allow any triangle
  if (!is_fai)
    return Result(d, df_total);

  if (shortest * 25 >= df_total * 7)
    // passes min > 28% rule,
    // this automatically means we pass max > 45% worst-case
    return Result(d, df_total);

  const unsigned longest = std::max({df_1, df_2, df_3});
  if (longest * 20 > df_total * 9) // fails max > 45% worst-case rule!
    return Result(0, 0);

  // passed basic tests, now detailed ones

  // find accurate min leg distance
  fixed leg(0);
  if (df_1 == shortest)
    leg = a.GetLocation().Distance(b.GetLocation());
  else if (df_2 == shortest)
    leg = b.GetLocation().Distance(c.GetLocation());
  else if (df_3 == shortest)
    leg = c.GetLocation().Distance(a.GetLocation());

  // estimate total distance by scaling.
  // this is a slight approximation, but saves having to do
  // three accurate distance calculations.

  const fixed d_total(df_total* leg / shortest);
  if (d_total >= fixed(500000)) {
    // long distance, ok that it failed 28% rule
    return Result(d, df_total);
  }

  return Result(0, 0);
}
Ejemplo n.º 11
0
 TriangleSecondLeg(bool _fai, const SearchPoint &_a, const SearchPoint &_b)
   :is_fai(_fai), a(_a), b(_b), df_1(a.FlatDistanceTo(b)) {}
Ejemplo n.º 12
0
  /**
   * Set the location of the sample/boundary polygon node
   * that produces the minimum task distance.
   *
   * @param locmin Location of min distance node
   */
  void SetSearchMin(const SearchPoint &locmin) {
    assert(locmin.IsValid());

    search_min = locmin;
  }
Ejemplo n.º 13
0
  /**
   * Set the location of the sample/boundary polygon node
   * that produces the maximum task distance.
   *
   * @param locmax Location of max distance node
   */
  void SetSearchMax(const SearchPoint &locmax) {
    assert(locmax.IsValid());

    search_max = locmax;
  }