Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
edafb0a83c | ||
|
f7cc89400a | ||
|
473e4e129c | ||
|
2ac497c6b8 | ||
|
defdc8cc4b | ||
|
4c5314676a | ||
|
1da044f3e3 | ||
|
45516ef534 |
@ -13,6 +13,7 @@ notifications:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- "5.2"
|
||||
|
||||
cache:
|
||||
ccache: true
|
||||
|
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,3 +1,16 @@
|
||||
# 5.2.4
|
||||
Changes from 5.2.3:
|
||||
- Bugfixes:
|
||||
- Fixed a crash that arised on roundabouts in combination with intermediate intersections and sliproads
|
||||
- Fixed #2518: Invalid bilinear interpolation when using raster data
|
||||
- Fixed #2546: The geometry returned by the match service was missing the last coordinate.
|
||||
|
||||
BREAKING: The data format changed between 5.2.3 and 5.2.4, you need to reprocess.
|
||||
|
||||
# 5.2.3
|
||||
- Bugfixes:
|
||||
- Fixed an issue with name changes in roundabouts that could result in crashes
|
||||
|
||||
# 5.2.2
|
||||
Changes from 5.2.1
|
||||
- Bugfixes:
|
||||
|
@ -144,10 +144,10 @@ Feature: Intersections Data
|
||||
| hd | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns | intersections |
|
||||
| e,f | ea,fb,fb | depart,abcda-exit-1,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 |
|
||||
| e,g | ea,gc,gc | depart,abcda-exit-2,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0|
|
||||
| waypoints | route | turns | intersections |
|
||||
| e,f | ea,fb,fb | depart,abcda-exit-1,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 |
|
||||
| e,g | ea,gc,gc | depart,abcda-exit-2,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0 |
|
||||
| e,h | ea,hd,hd | depart,abcda-exit-3,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330,true:90 false:210 true:330;true:270 |
|
||||
| e,2 | ea,abcda,abcda | depart,abcda-exit-undefined,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1|
|
||||
| 1,g | abcda,gc,gc | depart,abcda-exit-2,arrive | true:214;true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:0|
|
||||
| 1,3 | abcda,abcda | depart,arrive | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214|
|
||||
| e,2 | ea,abcda,abcda | depart,abcda-exit-undefined,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1 |
|
||||
| 1,g | abcda,gc,gc | depart,abcda-exit-2,arrive | true:214;false:30 true:150 true:270,true:30 true:180 false:330;true:0 |
|
||||
| 1,3 | abcda,abcda | depart,arrive | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214 |
|
||||
|
@ -361,3 +361,79 @@ Feature: Basic Roundabout
|
||||
| a,f | ab,ef,ef | depart,roundabout-exit-2,arrive | 0->180,180->270,180->0 |
|
||||
| a,h | ab,gh,gh | depart,roundabout-exit-1,arrive | 0->180,180->270,270->0 |
|
||||
|
||||
Scenario: Motorway Roundabout
|
||||
#See 39.933742 -75.082345
|
||||
Given the node map
|
||||
| | | | | l | | | | a | | i |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | b | | | | |
|
||||
| | | | c | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | h | | |
|
||||
| n | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | d | | | | | | | | j |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | m | | | g | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | | | | | | | | | |
|
||||
| | | e | | f | | | | | | |
|
||||
|
||||
And the ways
|
||||
| nodes | junction | name | highway | oneway | ref |
|
||||
| ab | | crescent | trunk | yes | US 130 |
|
||||
| bcd | roundabout | crescent | trunk | yes | US 130 |
|
||||
| de | | crescent | trunk | yes | US 130 |
|
||||
| fg | | crescent | trunk | yes | US 130 |
|
||||
| gh | roundabout | crescent | trunk | yes | US 130 |
|
||||
| hi | | crescent | trunk | yes | US 130 |
|
||||
| jh | | | trunk_link | yes | NJ 38 |
|
||||
| hb | roundabout | | trunk_link | yes | NJ 38 |
|
||||
| bl | | | trunk_link | yes | NJ 38 |
|
||||
| cnd | | kaighns | trunk_link | yes | |
|
||||
| dmg | roundabout | | trunk_link | yes | |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,e | crescent (US 130),crescent (US 130),crescent (US 130) | depart,roundabout-exit-3,arrive |
|
||||
| j,l | NJ 38,NJ 38,NJ 38 | depart,roundabout-exit-2,arrive |
|
||||
|
||||
Scenario: Double Roundabout with through-lane
|
||||
#http://map.project-osrm.org/?z=18¢er=38.911752%2C-77.048667&loc=38.912003%2C-77.050831&loc=38.909277%2C-77.042516&hl=en&alt=0
|
||||
Given the node map
|
||||
| | | | | o | | | | | | | | | | | | n | | | | |
|
||||
| | | | | e | | | | | | | | | | | | j | | | | |
|
||||
| | | | | | | | | | | | | | | | | | | | | |
|
||||
| | | | | | | q | | | | | | | | | | | | | | |
|
||||
| a | | b | | | | | | s | | f | | | | g | | | | i | | k |
|
||||
| | | | | | | r | | | | | | | | | | | p | | | |
|
||||
| | | | | | | | | | | t | | | | | | | | | | |
|
||||
| | | | | c | | d | | | | | | | | | | h | | | | |
|
||||
| | | | | l | | | | | | | | | | | | m | | | | |
|
||||
|
||||
And the nodes
|
||||
| node | highway |
|
||||
| i | traffic_signals |
|
||||
|
||||
And the ways
|
||||
| nodes | junction | name | oneway |
|
||||
| bcdrqeb | roundabout | sheridan circle | yes |
|
||||
| ghi | roundabout | dupont circle | yes |
|
||||
| ijg | roundabout | dupont circle | yes |
|
||||
| ab | | massachusetts | no |
|
||||
| sfgpik | | massachusetts | no |
|
||||
| cl | | 23rd street | no |
|
||||
| oe | | r street | no |
|
||||
| jn | | new hampshire | no |
|
||||
| mh | | new hampshire | yes |
|
||||
| rsq | | massachusetts | yes |
|
||||
| ft | | suppressed | no |
|
||||
|
||||
And the relations
|
||||
| type | way:from | way:to | node:via | restriction |
|
||||
| restriction | sfgpik | ijg | i | no_left_turn |
|
||||
|
||||
When I route I should get
|
||||
| waypoints | route | turns |
|
||||
| a,k | massachusetts,massachusetts,massachusetts,massachusetts | depart,sheridan circle-exit-2,dupont circle-exit-1,arrive |
|
||||
|
@ -1,5 +1,6 @@
|
||||
var util = require('util');
|
||||
var d3 = require('d3-queue');
|
||||
var polyline = require('polyline');
|
||||
|
||||
module.exports = function () {
|
||||
this.When(/^I match I should get$/, (table, callback) => {
|
||||
@ -35,6 +36,7 @@ module.exports = function () {
|
||||
route = '',
|
||||
duration = '',
|
||||
annotation = '',
|
||||
geometry = '',
|
||||
OSMIDs = '';
|
||||
|
||||
|
||||
@ -63,6 +65,11 @@ module.exports = function () {
|
||||
annotation = this.annotationList(json.matchings[0]);
|
||||
}
|
||||
|
||||
if (headers.has('geometry')) {
|
||||
if (json.matchings.length != 1) throw new Error('*** Checking geometry only supported for matchings with one subtrace');
|
||||
geometry = json.matchings[0].geometry;
|
||||
}
|
||||
|
||||
if (headers.has('OSM IDs')) {
|
||||
if (json.matchings.length != 1) throw new Error('*** CHecking annotation only supported for matchings with one subtrace');
|
||||
OSMIDs = this.OSMIDList(json.matchings[0]);
|
||||
@ -85,6 +92,13 @@ module.exports = function () {
|
||||
got.annotation = annotation.toString();
|
||||
}
|
||||
|
||||
if (headers.has('geometry')) {
|
||||
if (this.queryParams['geometries'] === 'polyline')
|
||||
got.geometry = polyline.decode(geometry).toString();
|
||||
else
|
||||
got.geometry = geometry;
|
||||
}
|
||||
|
||||
if (headers.has('OSM IDs')) {
|
||||
got['OSM IDs'] = OSMIDs;
|
||||
}
|
||||
|
@ -128,3 +128,21 @@ Feature: Basic Map Matching
|
||||
| trace | matchings | OSM IDs |
|
||||
| abeh | abcedgh | 1,2,3,2,3,4,5,4,5,6,7 |
|
||||
| abci | abc,ci | 1,2,3,2,3,8,3,8 |
|
||||
|
||||
Scenario: Testbot - Geometry details
|
||||
Given the query options
|
||||
| overview | full |
|
||||
| geometries | polyline |
|
||||
|
||||
Given the node map
|
||||
| a | b | c |
|
||||
| | d | |
|
||||
|
||||
And the ways
|
||||
| nodes | oneway |
|
||||
| abc | no |
|
||||
| bd | no |
|
||||
|
||||
When I match I should get
|
||||
| trace | matchings | geometry |
|
||||
| abd | abd | 1,1,1,1.00009,1,1.00009,0.99991,1.00009 |
|
||||
|
@ -405,10 +405,10 @@ inline bool requiresNameAnnounced(const std::string &from,
|
||||
(from_ref.find(to_ref) != std::string::npos || to_ref.find(from_ref) != std::string::npos);
|
||||
const auto ref_is_removed = !from_ref.empty() && to_ref.empty();
|
||||
|
||||
const auto obvious_change = (names_are_empty && refs_are_empty) ||
|
||||
(names_are_equal && ref_is_contained) ||
|
||||
(names_are_equal && refs_are_empty) || name_is_removed ||
|
||||
ref_is_removed || is_suffix_change;
|
||||
const auto obvious_change =
|
||||
(names_are_empty && refs_are_empty) || (names_are_equal && ref_is_contained) ||
|
||||
(names_are_equal && refs_are_empty) || (ref_is_contained && name_is_removed) ||
|
||||
(names_are_equal && ref_is_removed) || is_suffix_change;
|
||||
|
||||
return !obvious_change;
|
||||
}
|
||||
@ -456,6 +456,26 @@ inline ConnectedRoad mirror(ConnectedRoad road)
|
||||
return road;
|
||||
}
|
||||
|
||||
inline bool hasRoundaboutType(const TurnInstruction instruction)
|
||||
{
|
||||
using namespace extractor::guidance::TurnType;
|
||||
const constexpr TurnType::Enum valid_types[] = {TurnType::EnterRoundabout,
|
||||
TurnType::EnterAndExitRoundabout,
|
||||
TurnType::EnterRotary,
|
||||
TurnType::EnterAndExitRotary,
|
||||
TurnType::EnterRoundaboutIntersection,
|
||||
TurnType::EnterAndExitRoundaboutIntersection,
|
||||
TurnType::EnterRoundaboutAtExit,
|
||||
TurnType::ExitRoundabout,
|
||||
TurnType::EnterRotaryAtExit,
|
||||
TurnType::ExitRotary,
|
||||
TurnType::EnterRoundaboutIntersectionAtExit,
|
||||
TurnType::ExitRoundaboutIntersection,
|
||||
TurnType::StayOnRoundabout};
|
||||
const auto valid_end = valid_types + 13;
|
||||
return std::find(valid_types, valid_end, instruction.type) != valid_end;
|
||||
};
|
||||
|
||||
} // namespace guidance
|
||||
} // namespace extractor
|
||||
} // namespace osrm
|
||||
|
@ -9,7 +9,8 @@
|
||||
"node-timeout": "0.0.4",
|
||||
"request": "^2.69.0",
|
||||
"xmlbuilder": "^4.2.1",
|
||||
"chalk": "^1.1.3"
|
||||
"chalk": "^1.1.3",
|
||||
"polyline": "^0.2.0"
|
||||
},
|
||||
"bin": {
|
||||
"cucumber": "./node_modules/cucumber/bin/cucumber.js"
|
||||
|
@ -85,12 +85,12 @@ std::vector<util::Coordinate> assembleOverview(const std::vector<LegGeometry> &l
|
||||
std::vector<util::Coordinate> overview_geometry;
|
||||
overview_geometry.reserve(overview_size);
|
||||
|
||||
auto leg_index = 0UL;
|
||||
auto leg_reverse_index = leg_geometries.size();
|
||||
for (const auto &geometry : leg_geometries)
|
||||
{
|
||||
auto begin = geometry.locations.begin();
|
||||
auto end = geometry.locations.end();
|
||||
if (leg_index < leg_geometries.size() - 1)
|
||||
if (--leg_reverse_index > 0)
|
||||
{
|
||||
end = std::prev(end);
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ RouteStep forwardInto(RouteStep destination, const RouteStep &source)
|
||||
// Overwrites turn instruction and increases exit NR
|
||||
destination.duration += source.duration;
|
||||
destination.distance += source.distance;
|
||||
|
||||
destination.maneuver.exit = source.maneuver.exit;
|
||||
if (destination.geometry_begin < source.geometry_begin)
|
||||
{
|
||||
destination.intersections.insert(destination.intersections.end(),
|
||||
@ -170,8 +170,6 @@ RouteStep forwardInto(RouteStep destination, const RouteStep &source)
|
||||
|
||||
destination.geometry_begin = std::min(destination.geometry_begin, source.geometry_begin);
|
||||
destination.geometry_end = std::max(destination.geometry_end, source.geometry_end);
|
||||
destination.maneuver.exit = destination.intersections.size() - 1;
|
||||
|
||||
return destination;
|
||||
}
|
||||
|
||||
@ -184,7 +182,6 @@ void fixFinalRoundabout(std::vector<RouteStep> &steps)
|
||||
if (entersRoundabout(propagation_step.maneuver.instruction))
|
||||
{
|
||||
propagation_step.maneuver.exit = 0;
|
||||
propagation_step.geometry_end = steps.back().geometry_begin;
|
||||
|
||||
// remember the current name as rotary name in tha case we end in a rotary
|
||||
if (propagation_step.maneuver.instruction.type == TurnType::EnterRotary ||
|
||||
@ -265,9 +262,16 @@ void closeOffRoundabout(const bool on_roundabout,
|
||||
// instruction and move it right to the beginning to make sure to immediately announce the
|
||||
// exit.
|
||||
BOOST_ASSERT(leavesRoundabout(steps[1].maneuver.instruction) ||
|
||||
steps[1].maneuver.instruction.type == TurnType::StayOnRoundabout);
|
||||
steps[1].maneuver.instruction.type == TurnType::StayOnRoundabout ||
|
||||
steps[1].maneuver.instruction.type == TurnType::Suppressed ||
|
||||
steps[1].maneuver.instruction.type == TurnType::NoTurn);
|
||||
steps[0].geometry_end = 1;
|
||||
steps[1].geometry_begin = 0;
|
||||
steps[1] = forwardInto(steps[1], steps[0]);
|
||||
steps[1].intersections.erase(steps[1].intersections.begin()); // otherwise we copy the
|
||||
// source
|
||||
if (leavesRoundabout(steps[1].maneuver.instruction))
|
||||
steps[1].maneuver.exit = 1;
|
||||
steps[0].duration = 0;
|
||||
steps[0].distance = 0;
|
||||
const auto exitToEnter = [](const TurnType::Enum type) {
|
||||
@ -305,7 +309,6 @@ void closeOffRoundabout(const bool on_roundabout,
|
||||
if (entersRoundabout(propagation_step.maneuver.instruction))
|
||||
{
|
||||
propagation_step.maneuver.exit = step.maneuver.exit;
|
||||
propagation_step.geometry_end = step.geometry_end;
|
||||
const auto entry_intersection = propagation_step.intersections.front();
|
||||
|
||||
// remember rotary name
|
||||
@ -335,8 +338,10 @@ void closeOffRoundabout(const bool on_roundabout,
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOST_ASSERT(propagation_step.maneuver.instruction.type =
|
||||
TurnType::StayOnRoundabout);
|
||||
BOOST_ASSERT(propagation_step.maneuver.instruction.type ==
|
||||
TurnType::StayOnRoundabout ||
|
||||
propagation_step.maneuver.instruction.type == TurnType::Suppressed ||
|
||||
propagation_step.maneuver.instruction.type == TurnType::NoTurn);
|
||||
propagation_step.maneuver.instruction =
|
||||
TurnInstruction::NO_TURN(); // mark intermediate instructions invalid
|
||||
}
|
||||
@ -473,7 +478,6 @@ void collapseTurnAt(std::vector<RouteStep> &steps,
|
||||
current_step.intersections.front()
|
||||
.bearings[current_step.intersections.front().out]) &&
|
||||
compatible(one_back_step, current_step))
|
||||
|
||||
{
|
||||
BOOST_ASSERT(two_back_index < steps.size());
|
||||
// the simple case is a u-turn that changes directly into the in-name again
|
||||
@ -584,12 +588,10 @@ std::vector<RouteStep> postProcess(std::vector<RouteStep> steps)
|
||||
}
|
||||
else if (leavesRoundabout(instruction))
|
||||
{
|
||||
if (!has_entered_roundabout)
|
||||
{
|
||||
// in case the we are not on a roundabout, the very first instruction
|
||||
// after the depart will be transformed into a roundabout and become
|
||||
// the first valid instruction
|
||||
}
|
||||
// if (!has_entered_roundabout)
|
||||
// in case the we are not on a roundabout, the very first instruction
|
||||
// after the depart will be transformed into a roundabout and become
|
||||
// the first valid instruction
|
||||
closeOffRoundabout(has_entered_roundabout, steps, step_index);
|
||||
has_entered_roundabout = false;
|
||||
on_roundabout = false;
|
||||
@ -661,7 +663,7 @@ std::vector<RouteStep> collapseTurns(std::vector<RouteStep> steps)
|
||||
for (std::size_t step_index = 1; step_index + 1 < steps.size(); ++step_index)
|
||||
{
|
||||
const auto ¤t_step = steps[step_index];
|
||||
if( current_step.maneuver.instruction.type == TurnType::NoTurn )
|
||||
if (current_step.maneuver.instruction.type == TurnType::NoTurn)
|
||||
continue;
|
||||
const auto one_back_index = getPreviousIndex(step_index);
|
||||
BOOST_ASSERT(one_back_index < steps.size());
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "extractor/guidance/roundabout_handler.hpp"
|
||||
#include "extractor/guidance/constants.hpp"
|
||||
#include "extractor/guidance/roundabout_handler.hpp"
|
||||
#include "extractor/guidance/toolkit.hpp"
|
||||
|
||||
#include "util/coordinate_calculation.hpp"
|
||||
@ -210,11 +210,11 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
||||
return util::Coordinate(node_info_list[node].lon, node_info_list[node].lat);
|
||||
};
|
||||
|
||||
unsigned roundabout_name_id = 0;
|
||||
std::unordered_set<unsigned> roundabout_name_ids;
|
||||
std::unordered_set<unsigned> connected_names;
|
||||
|
||||
const auto getNextOnRoundabout =
|
||||
[this, &roundabout_name_id, &connected_names](const NodeID node) {
|
||||
[this, &roundabout_name_ids, &connected_names](const NodeID node) {
|
||||
EdgeID continue_edge = SPECIAL_EDGEID;
|
||||
for (const auto edge : node_based_graph.GetAdjacentEdgeRange(node))
|
||||
{
|
||||
@ -226,16 +226,24 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
||||
// fork in roundabout
|
||||
return SPECIAL_EDGEID;
|
||||
}
|
||||
// roundabout does not keep its name
|
||||
if (roundabout_name_id != 0 && roundabout_name_id != edge_data.name_id &&
|
||||
requiresNameAnnounced(name_table.GetNameForID(roundabout_name_id),
|
||||
name_table.GetNameForID(edge_data.name_id),
|
||||
street_name_suffix_table))
|
||||
{
|
||||
return SPECIAL_EDGEID;
|
||||
}
|
||||
|
||||
roundabout_name_id = edge_data.name_id;
|
||||
if (EMPTY_NAMEID != edge_data.name_id)
|
||||
{
|
||||
bool add = true;
|
||||
for (auto name_id : roundabout_name_ids)
|
||||
{
|
||||
|
||||
if (!requiresNameAnnounced(name_table.GetNameForID(name_id),
|
||||
name_table.GetNameForID(edge_data.name_id),
|
||||
street_name_suffix_table))
|
||||
{
|
||||
add = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (add)
|
||||
roundabout_name_ids.insert(edge_data.name_id);
|
||||
}
|
||||
|
||||
continue_edge = edge;
|
||||
}
|
||||
@ -320,7 +328,8 @@ RoundaboutType RoundaboutHandler::getRoundaboutType(const NodeID nid) const
|
||||
// used with a reference and without. This will be fixed automatically
|
||||
// when we handle references separately or if the useage is more consistent
|
||||
|
||||
if (0 != roundabout_name_id && 0 == connected_names.count(roundabout_name_id))
|
||||
if (1 == roundabout_name_ids.size() &&
|
||||
0 == connected_names.count(*roundabout_name_ids.begin()))
|
||||
return RoundaboutType::Rotary;
|
||||
else
|
||||
return RoundaboutType::Roundabout;
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include "extractor/guidance/classification_data.hpp"
|
||||
#include "extractor/guidance/constants.hpp"
|
||||
#include "extractor/guidance/turn_analysis.hpp"
|
||||
|
||||
@ -123,14 +124,12 @@ TurnAnalysis::setTurnTypes(const NodeID from_nid, const EdgeID, Intersection int
|
||||
Intersection TurnAnalysis::handleSliproads(const EdgeID source_edge_id,
|
||||
Intersection intersection) const
|
||||
{
|
||||
|
||||
auto intersection_node_id = node_based_graph.GetTarget(source_edge_id);
|
||||
|
||||
const auto linkTest = [this](const ConnectedRoad &road) {
|
||||
return // isLinkClass(
|
||||
// node_based_graph.GetEdgeData(road.turn.eid).road_classification.road_class) &&
|
||||
!node_based_graph.GetEdgeData(road.turn.eid).roundabout && road.entry_allowed &&
|
||||
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) <= 2 * NARROW_TURN_ANGLE;
|
||||
return !node_based_graph.GetEdgeData(road.turn.eid).roundabout && road.entry_allowed &&
|
||||
angularDeviation(road.turn.angle, STRAIGHT_ANGLE) <= 2 * NARROW_TURN_ANGLE &&
|
||||
!hasRoundaboutType(road.turn.instruction);
|
||||
};
|
||||
|
||||
bool hasNarrow =
|
||||
|
@ -54,7 +54,9 @@ RasterDatum RasterSource::GetRasterInterpolate(const int lon, const int lat) con
|
||||
}
|
||||
|
||||
const auto xthP = (lon - xmin) / xstep;
|
||||
const auto ythP = (ymax - lat) / ystep;
|
||||
const auto ythP =
|
||||
(ymax - lat) /
|
||||
ystep; // the raster texture uses a different coordinate system with y pointing downwards
|
||||
|
||||
const std::size_t top = static_cast<std::size_t>(fmax(floor(ythP), 0));
|
||||
const std::size_t bottom = static_cast<std::size_t>(fmin(ceil(ythP), height - 1));
|
||||
@ -62,8 +64,8 @@ RasterDatum RasterSource::GetRasterInterpolate(const int lon, const int lat) con
|
||||
const std::size_t right = static_cast<std::size_t>(fmin(ceil(xthP), width - 1));
|
||||
|
||||
// Calculate distances from corners for bilinear interpolation
|
||||
const float fromLeft = (lon - left * xstep + xmin) / xstep;
|
||||
const float fromTop = (ymax - top * ystep - lat) / ystep;
|
||||
const float fromLeft = xthP - left; // this is the fraction part of xthP
|
||||
const float fromTop = ythP - top; // this is the fraction part of ythP
|
||||
const float fromRight = 1 - fromLeft;
|
||||
const float fromBottom = 1 - fromTop;
|
||||
|
||||
|
@ -24,58 +24,58 @@ BOOST_AUTO_TEST_CASE(raster_test)
|
||||
{
|
||||
SourceContainer sources;
|
||||
int source_id = sources.LoadRasterSource(
|
||||
"../unit_tests/fixtures/raster_data.asc", 0, 0.09, 0, 0.09, 10, 10);
|
||||
"../unit_tests/fixtures/raster_data.asc", 1, 1.09, 1, 1.09, 10, 10);
|
||||
BOOST_CHECK_EQUAL(source_id, 0);
|
||||
|
||||
// Expected nearest-neighbor queries
|
||||
// EDGES
|
||||
CHECK_QUERY(0, 0.00, 0.00, 10);
|
||||
CHECK_QUERY(0, 0.00, 0.09, 10);
|
||||
CHECK_QUERY(0, 0.09, 0.00, 40);
|
||||
CHECK_QUERY(0, 0.09, 0.09, 100);
|
||||
CHECK_QUERY(0, 0.09, 0.07, 140);
|
||||
CHECK_QUERY(0, 1.00, 1.00, 10);
|
||||
CHECK_QUERY(0, 1.00, 1.09, 10);
|
||||
CHECK_QUERY(0, 1.09, 1.00, 40);
|
||||
CHECK_QUERY(0, 1.09, 1.09, 100);
|
||||
CHECK_QUERY(0, 1.09, 1.07, 140);
|
||||
// OUT OF BOUNDS
|
||||
CHECK_QUERY(0, -0.1, 0.07, RasterDatum::get_invalid());
|
||||
CHECK_QUERY(0, -0.1, -3.0, RasterDatum::get_invalid());
|
||||
CHECK_QUERY(0, 0.3, 23.0, RasterDatum::get_invalid());
|
||||
CHECK_QUERY(0, -1.1, 1.07, RasterDatum::get_invalid());
|
||||
CHECK_QUERY(0, -1.1, -3.0, RasterDatum::get_invalid());
|
||||
CHECK_QUERY(0, 1.3, 23.0, RasterDatum::get_invalid());
|
||||
// ARBITRARY - AT DATA
|
||||
CHECK_QUERY(0, 0.06, 0.06, 100);
|
||||
CHECK_QUERY(0, 0.08, 0.05, 160);
|
||||
CHECK_QUERY(0, 0.01, 0.05, 20);
|
||||
CHECK_QUERY(0, 1.06, 1.06, 100);
|
||||
CHECK_QUERY(0, 1.08, 1.05, 160);
|
||||
CHECK_QUERY(0, 1.01, 1.05, 20);
|
||||
// ARBITRARY - BETWEEN DATA
|
||||
CHECK_QUERY(0, 0.054, 0.023, 40);
|
||||
CHECK_QUERY(0, 0.056, 0.028, 80);
|
||||
CHECK_QUERY(0, 0.05, 0.028, 60);
|
||||
CHECK_QUERY(0, 1.054, 1.023, 40);
|
||||
CHECK_QUERY(0, 1.056, 1.028, 80);
|
||||
CHECK_QUERY(0, 1.05, 1.028, 60);
|
||||
|
||||
// Expected bilinear interpolation queries
|
||||
// EDGES - same as above
|
||||
CHECK_INTERPOLATE(0, 0.00, 0.00, 10);
|
||||
CHECK_INTERPOLATE(0, 0.00, 0.09, 10);
|
||||
CHECK_INTERPOLATE(0, 0.09, 0.00, 40);
|
||||
CHECK_INTERPOLATE(0, 0.09, 0.09, 100);
|
||||
CHECK_INTERPOLATE(0, 0.09, 0.07, 140);
|
||||
CHECK_INTERPOLATE(0, 1.00, 1.00, 10);
|
||||
CHECK_INTERPOLATE(0, 1.00, 1.09, 10);
|
||||
CHECK_INTERPOLATE(0, 1.09, 1.00, 40);
|
||||
CHECK_INTERPOLATE(0, 1.09, 1.09, 100);
|
||||
CHECK_INTERPOLATE(0, 1.09, 1.07, 140);
|
||||
// OUT OF BOUNDS - same as above
|
||||
CHECK_INTERPOLATE(0, -0.1, 0.07, RasterDatum::get_invalid());
|
||||
CHECK_INTERPOLATE(0, -0.1, -3.0, RasterDatum::get_invalid());
|
||||
CHECK_INTERPOLATE(0, 0.3, 23.0, RasterDatum::get_invalid());
|
||||
CHECK_INTERPOLATE(0, -1.1, 1.07, RasterDatum::get_invalid());
|
||||
CHECK_INTERPOLATE(0, -1.1, -3.0, RasterDatum::get_invalid());
|
||||
CHECK_INTERPOLATE(0, 1.3, 23.0, RasterDatum::get_invalid());
|
||||
// ARBITRARY - AT DATA - same as above
|
||||
CHECK_INTERPOLATE(0, 0.06, 0.06, 100);
|
||||
CHECK_INTERPOLATE(0, 0.08, 0.05, 160);
|
||||
CHECK_INTERPOLATE(0, 0.01, 0.05, 20);
|
||||
CHECK_INTERPOLATE(0, 1.06, 1.06, 100);
|
||||
CHECK_INTERPOLATE(0, 1.08, 1.05, 160);
|
||||
CHECK_INTERPOLATE(0, 1.01, 1.05, 20);
|
||||
// ARBITRARY - BETWEEN DATA
|
||||
CHECK_INTERPOLATE(0, 0.054, 0.023, 54);
|
||||
CHECK_INTERPOLATE(0, 0.056, 0.028, 68);
|
||||
CHECK_INTERPOLATE(0, 0.05, 0.028, 56);
|
||||
CHECK_INTERPOLATE(0, 1.054, 1.023, 53);
|
||||
CHECK_INTERPOLATE(0, 1.056, 1.028, 68);
|
||||
CHECK_INTERPOLATE(0, 1.05, 1.028, 56);
|
||||
|
||||
int source_already_loaded_id = sources.LoadRasterSource(
|
||||
"../unit_tests/fixtures/raster_data.asc", 0, 0.09, 0, 0.09, 10, 10);
|
||||
"../unit_tests/fixtures/raster_data.asc", 1, 1.09, 1, 1.09, 10, 10);
|
||||
|
||||
BOOST_CHECK_EQUAL(source_already_loaded_id, 0);
|
||||
BOOST_CHECK_THROW(sources.GetRasterDataFromSource(1, normalize(0.02), normalize(0.02)),
|
||||
BOOST_CHECK_THROW(sources.GetRasterDataFromSource(1, normalize(1.02), normalize(1.02)),
|
||||
util::exception);
|
||||
|
||||
BOOST_CHECK_THROW(
|
||||
sources.LoadRasterSource("../unit_tests/fixtures/nonexistent.asc", 0, 0.1, 0, 0.1, 7, 7),
|
||||
sources.LoadRasterSource("../unit_tests/fixtures/nonexistent.asc", 0, 1.1, 0, 1.1, 7, 7),
|
||||
util::exception);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user