Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix rsp last stop distance calc #436

Merged
merged 11 commits into from
Feb 23, 2016
10 changes: 7 additions & 3 deletions app/models/route_stop_pattern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ def calculate_distances
total_distance = 0.0
cartesian_factory = RGeo::Cartesian::Factory.new(srid: 4326)
cast_route = RGeo::Feature.cast(self[:geometry], cartesian_factory)
geometry_length = self[:geometry].length
self.stop_pattern.each_index do |i|
stop = Stop.find_by_onestop_id!(self.stop_pattern[i])
cast_stop = RGeo::Feature.cast(stop[:geometry], cartesian_factory)
Expand All @@ -126,13 +127,13 @@ def calculate_distances
# only the first and last stops are expected to have 1 split result instead of 2
# So this might be an outlier stop. Another possibility might be 2 consecutive stops
# having the same coordinates.
logger.info "stop #{stop.onestop_id} for route #{self.route.onestop_id} within route stop pattern #{self.onestop_id} may be an outlier or indicate invalid geometry"
logger.info "stop #{stop.onestop_id}, number #{i+1}, within route stop pattern #{self.onestop_id} may be an outlier or indicate invalid geometry"
# TODO add interpolated distance at halfway and split line there?
# if so, will need to take into account case of 2 consecutive stops having same location.
if (i == 0 && splits[1].nil?)
distances << 0.0
elsif (i == self.stop_pattern.size - 1 && splits[1].nil?)
distances << RGeo::Feature.cast(splits[1], RouteStopPattern::GEOFACTORY).length
elsif (i == self.stop_pattern.size - 1 && splits[0].nil?)
distances << geometry_length.round(DISTANCE_PRECISION)
else
distances << distances[i-1]
end
Expand All @@ -145,6 +146,9 @@ def calculate_distances
end
cast_route = splits[1]
end
if (distances[i] > geometry_length)
logger.info "stop #{stop.onestop_id}, number #{i+1}, of route stop pattern #{self.onestop_id} has a distance greater than the length of the geometry"
end
if (i != 0 && distances[i-1] > distances[i])
logger.info "stop #{self.stop_pattern[i]} occurs after stop #{self.stop_pattern[i-1]} but has a distance less than #{self.stop_pattern[i-1]}"
end
Expand Down
15 changes: 15 additions & 0 deletions spec/models/route_stop_pattern_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,21 @@
a_value_within(0.1).of(17001.5107)])
end

it 'assign a fallback distance value equal to the geometry length to the last stop if it is an outlier' do
# If the last stop is not found to be after the geometry and thus not added to the geometry, it can
# be an outlier if it is close enough to the geometry and before the penultimate stop, which would
# also be have to be an outlier itself (by having a nil result in its line split array).
last_stop_outlier = create(:stop,
onestop_id: "s-9q9hwtgq4s-last~outlier",
geometry: Stop::GEOFACTORY.point(-121.5, 37.3).to_s
)
@rsp.stop_pattern << last_stop_outlier.onestop_id
expect(@rsp.calculate_distances).to match_array([a_value_within(0.1).of(0.0),
a_value_within(0.1).of(12617.9271),
a_value_within(0.1).of(12617.9271),
a_value_within(0.1).of(17001.5107)])
end

it 'can calculate distances when two consecutive stop points are identical' do
identical = create(:stop,
onestop_id: "s-9q9hwtgq4s-sunnyvaleidentical",
Expand Down