Compare commits

...

8 Commits

Author SHA1 Message Date
Patrick Niklaus
edafb0a83c
[skip ci] Add breaking notice to changelog 2016-06-21 19:49:13 +02:00
Patrick Niklaus
f7cc89400a
Update the v5.2.4 changelog 2016-06-21 19:47:39 +02:00
Lauren Budorick
473e4e129c
Update tests to catch 0-subtraction error 2016-06-21 19:41:01 +02:00
Patrick Niklaus
2ac497c6b8
Fix fromTop and fromLeft calculation 2016-06-21 19:40:50 +02:00
Michael Krasnyk
defdc8cc4b
Fix omitting the last point's coordinates in the geometry field 2016-06-21 18:23:29 +02:00
Moritz Kobitzsch
4c5314676a
fix issues with roundabouts and intersections and sliproads 2016-06-21 18:23:06 +02:00
Moritz Kobitzsch
1da044f3e3 fix roundabout-handling when name changes 2016-06-17 11:19:27 -07:00
Patrick Niklaus
45516ef534 Enable travis builds for 5.2 branch 2016-06-14 14:36:41 +02:00
14 changed files with 237 additions and 82 deletions

View File

@ -13,6 +13,7 @@ notifications:
branches:
only:
- master
- "5.2"
cache:
ccache: true

View File

@ -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:

View File

@ -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 |

View File

@ -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&center=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 |

View File

@ -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;
}

View File

@ -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 |

View File

@ -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

View File

@ -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"

View File

@ -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);
}

View File

@ -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 &current_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());

View File

@ -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;

View File

@ -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 =

View File

@ -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;

View File

@ -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);
}