Ejemplo n.º 1
0
 def dist_traveled(self, stop, old_dist_traveled):
     if old_dist_traveled and self._xdist:
         # Case 1: we have in the original data shape_dist_traveled
         # We need to remap from the old scale to the new meter scale
         return self._xdist.interpolate(old_dist_traveled)
     else:
         # Case 2: we do not have original shape_dist_traveled
         # We need to determine ourselves where in the shape we lie
         # TODO Implement a cache, this can be slow for lots of trips
         # and the result is the same for the same pattern
         # Check the cache first
         cache_entry = self._cache_cursor.next_entry(stop)
         if cache_entry is not None:
             self._cache_cursor = cache_entry
             self._cache_hit += 1
             return cache_entry.distance()
         min_dist = 1e20
         best_i = self._istart
         best_dist = 0
         for i in range(self._istart, len(self._shape.points) - 1):
             a = self._shape.points[i]
             b = self._shape.points[i + 1]
             dist, pdist = orthodromic_seg_distance(stop, a, b)
             newdist = a.shape_dist_traveled + pdist
             howfar = newdist - self._distance
             # Add a slight "cone" offset. There are pathological
             # cases with backtracking shapes where the best distance
             # is slightly better way further (for eg 0.01m) than at
             # the starting point (for eg 0.02m). In that case we should
             # obviously keep the first point instead of moving too fast
             # to the shape end. That offset should help for some cases.
             dist += howfar * self.K
             if dist < min_dist:
                 min_dist = dist
                 best_i = i
                 best_dist = newdist
         if best_dist > self._distance:
             self._distance = best_dist
         else:
             delta = self._distance - best_dist
             if delta > 10:
                 # This is harmless if the backtracking distance is small.
                 # We have lots of false positive (<<1m) due to rounding errors.
                 logger.warn(
                     "Backtracking of %f m detected in shape %s for stop %s (%s) (%f,%f) at distance %f < %f m on segment #[%d-%d]"
                     % (delta, self._shape.shape_id, stop.stop_id,
                        stop.stop_name, stop.stop_lat, stop.stop_lon,
                        best_dist, self._distance, best_i, best_i + 1))
         self._istart = best_i
         self._cache_miss += 1
         self._cache_cursor = self._cache_cursor.insert(
             stop, self._distance)
         return self._distance
Ejemplo n.º 2
0
 def test_seg_distance(self):
     a = SimplePoint(0, 0)
     daaa, daaa2 = orthodromic_seg_distance(a, a, a)
     self.assertAlmostEqual(daaa, 0.0, 3)
     self.assertAlmostEqual(daaa2, 0.0, 3)
     b = SimplePoint(1, 0)
     daab, daab2 = orthodromic_seg_distance(a, a, b)
     self.assertAlmostEqual(daab, 0.0, 3)
     self.assertAlmostEqual(daab2, 0.0, 3)
     dbab, dbab2 = orthodromic_seg_distance(b, a, b)
     self.assertAlmostEqual(dbab, 0.0, 3)
     self.assertAlmostEqual(dbab2 / 60, self._NAUTICAL_MILE, 2)
     c = SimplePoint(0.5, 0)
     dcab, dcab2 = orthodromic_seg_distance(c, a, b)
     self.assertAlmostEqual(dcab, 0.0, 3)
     self.assertAlmostEqual(dcab2 / 60, self._NAUTICAL_MILE / 2.0, 3)
     d = SimplePoint(-1, 0)
     ddab, ddab2 = orthodromic_seg_distance(d, a, b)
     self.assertAlmostEqual(ddab / 60, self._NAUTICAL_MILE, 2)
     print(ddab2)
     self.assertAlmostEqual(ddab2, 0, 2)
     e = SimplePoint(2, 0)
     deab, deab2 = orthodromic_seg_distance(e, a, b)
     self.assertAlmostEqual(deab / 60, self._NAUTICAL_MILE, 2)
     self.assertAlmostEqual(deab2 / 60, self._NAUTICAL_MILE, 2)
     f = SimplePoint(0.01, 1)
     dfab, dfab2 = orthodromic_seg_distance(f, a, b)
     self.assertAlmostEqual(dfab / 60, self._NAUTICAL_MILE, 2)
     self.assertAlmostEqual(dfab2 / 60, self._NAUTICAL_MILE * 0.01, 2)
     g = SimplePoint(1, 1)
     h = SimplePoint(0.5, 0.5)
     dhag, dhag2 = orthodromic_seg_distance(h, a, g)
     self.assertAlmostEqual(dhag, 0, 3)
     self.assertAlmostEqual(dhag2 / 60,
                            self._NAUTICAL_MILE / 2 * math.sqrt(2), 0)
     # Please note that the following is true only because
     # the distance is an approximation on the equirectangular projection.
     dbag, dbag2 = orthodromic_seg_distance(b, a, g)
     self.assertAlmostEqual(dbag / 60 * math.sqrt(2), self._NAUTICAL_MILE,
                            0)
     self.assertAlmostEqual(dbag2 / 60,
                            self._NAUTICAL_MILE / 2 * math.sqrt(2), 0)
Ejemplo n.º 3
0
 def dist_traveled(self, stop, old_dist_traveled):
     if old_dist_traveled and self._xdist:
         # Case 1: we have in the original data shape_dist_traveled
         # We need to remap from the old scale to the new meter scale
         return self._xdist.interpolate(old_dist_traveled)
     else:
         # Case 2: we do not have original shape_dist_traveled
         # We need to determine ourselves where in the shape we lie
         # TODO Implement a cache, this can be slow for lots of trips
         # and the result is the same for the same pattern
         # Check the cache first
         cache_entry = self._cache_cursor.next_entry(stop)
         if cache_entry is not None:
             self._cache_cursor = cache_entry
             self._cache_hit += 1
             return cache_entry.distance()
         min_dist = 1e20
         best_i = self._istart
         best_dist = 0
         for i in range(self._istart, len(self._shape.points) - 1):
             a = self._shape.points[i]
             b = self._shape.points[i+1]
             dist, pdist = orthodromic_seg_distance(stop, a, b)
             newdist = a.shape_dist_traveled + pdist
             howfar = newdist - self._distance
             # Add a slight "cone" offset. There are pathological
             # cases with backtracking shapes where the best distance
             # is slightly better way further (for eg 0.01m) than at
             # the starting point (for eg 0.02m). In that case we should
             # obviously keep the first point instead of moving too fast
             # to the shape end. That offset should help for some cases.
             dist += howfar * self.K
             if dist < min_dist:
                 min_dist = dist
                 best_i = i
                 best_dist = newdist
         if best_dist > self._distance:
             self._distance = best_dist
         else:
             delta = self._distance - best_dist
             if delta > 10:
                 # This is harmless if the backtracking distance is small.
                 # We have lots of false positive (<<1m) due to rounding errors.
                 logger.warn("Backtracking of %f m detected in shape %s for stop %s (%s) (%f,%f) at distance %f < %f m on segment #[%d-%d]" % (
                             delta, self._shape.shape_id, stop.stop_id, stop.stop_name, stop.stop_lat, stop.stop_lon, best_dist, self._distance, best_i, best_i+1))
         self._istart = best_i
         self._cache_miss += 1
         self._cache_cursor = self._cache_cursor.insert(stop, self._distance)
         return self._distance
Ejemplo n.º 4
0
 def test_seg_distance(self):
     a = SimplePoint(0, 0)
     daaa, daaa2 = orthodromic_seg_distance(a, a, a)
     self.assertAlmostEqual(daaa, 0.0, 3)
     self.assertAlmostEqual(daaa2, 0.0, 3)
     b = SimplePoint(1, 0)
     daab, daab2 = orthodromic_seg_distance(a, a, b)
     self.assertAlmostEqual(daab, 0.0, 3)
     self.assertAlmostEqual(daab2, 0.0, 3)
     dbab, dbab2 = orthodromic_seg_distance(b, a, b)
     self.assertAlmostEqual(dbab, 0.0, 3)
     self.assertAlmostEqual(dbab2 / 60, self._NAUTICAL_MILE, 2)
     c = SimplePoint(0.5, 0)
     dcab, dcab2 = orthodromic_seg_distance(c, a, b)
     self.assertAlmostEqual(dcab, 0.0, 3)
     self.assertAlmostEqual(dcab2 / 60, self._NAUTICAL_MILE / 2.0, 3)
     d = SimplePoint(-1, 0)
     ddab, ddab2 = orthodromic_seg_distance(d, a, b)
     self.assertAlmostEqual(ddab / 60, self._NAUTICAL_MILE, 2)
     print(ddab2)
     self.assertAlmostEqual(ddab2, 0, 2)
     e = SimplePoint(2, 0)
     deab, deab2 = orthodromic_seg_distance(e, a, b)
     self.assertAlmostEqual(deab / 60, self._NAUTICAL_MILE, 2)
     self.assertAlmostEqual(deab2 / 60, self._NAUTICAL_MILE, 2)
     f = SimplePoint(0.01, 1)
     dfab, dfab2 = orthodromic_seg_distance(f, a, b)
     self.assertAlmostEqual(dfab / 60, self._NAUTICAL_MILE, 2)
     self.assertAlmostEqual(dfab2 / 60, self._NAUTICAL_MILE * 0.01, 2)
     g = SimplePoint(1, 1)
     h = SimplePoint(0.5, 0.5)
     dhag, dhag2 = orthodromic_seg_distance(h, a, g)
     self.assertAlmostEqual(dhag, 0, 3)
     self.assertAlmostEqual(dhag2 / 60, self._NAUTICAL_MILE / 2 * math.sqrt(2), 0)
     # Please note that the following is true only because
     # the distance is an approximation on the equirectangular projection.
     dbag, dbag2 = orthodromic_seg_distance(b, a, g)
     self.assertAlmostEqual(dbag / 60 * math.sqrt(2), self._NAUTICAL_MILE, 0)
     self.assertAlmostEqual(dbag2 / 60, self._NAUTICAL_MILE / 2 * math.sqrt(2), 0)