Changes Single Coordinate Geoms from Point to LineString, closes #3425.

This commit is contained in:
Daniel J. Hofmann 2016-12-08 13:20:23 +01:00
parent 2288704bb5
commit cbfb055f81
5 changed files with 86 additions and 11 deletions

View File

@ -29,6 +29,7 @@
- fixed a bug that could result in crashes when leaving a ferry directly onto a motorway ramp - fixed a bug that could result in crashes when leaving a ferry directly onto a motorway ramp
- fixed a bug in the tile plugin that resulted in discovering invalid edges for connections - fixed a bug in the tile plugin that resulted in discovering invalid edges for connections
- improved error messages when missing files during traffic updates (#3114) - improved error messages when missing files during traffic updates (#3114)
- For single coordinate geometries the GeoJSON `Point` encoding was broken. We now always emit `LineString`s even in the one-coordinate-case (backwards compatible) (#3425)
- Debug Tiles - Debug Tiles
- Added support for turn penalties - Added support for turn penalties
- Internals - Internals

View File

@ -519,7 +519,7 @@ step.
|------------|--------------------------------------------------------------------| |------------|--------------------------------------------------------------------|
| polyline | [polyline](https://www.npmjs.com/package/polyline) with precision 5 in [latitude,longitude] encoding | | polyline | [polyline](https://www.npmjs.com/package/polyline) with precision 5 in [latitude,longitude] encoding |
| polyline6 | [polyline](https://www.npmjs.com/package/polyline) with precision 6 in [latitude,longitude] encoding | | polyline6 | [polyline](https://www.npmjs.com/package/polyline) with precision 6 in [latitude,longitude] encoding |
| geojson | [GeoJSON `LineString`](http://geojson.org/geojson-spec.html#linestring) or [GeoJSON `Point`](http://geojson.org/geojson-spec.html#point) if it is only one coordinate (not wrapped by a GeoJSON feature)| | geojson | [GeoJSON `LineString`](http://geojson.org/geojson-spec.html#linestring) |
- `name`: The name of the way along which travel proceeds. - `name`: The name of the way along which travel proceeds.
- `ref`: A reference number or code for the way. Optionally included, if ref data is available for the given way. - `ref`: A reference number or code for the way. Optionally included, if ref data is available for the given way.

View File

@ -54,22 +54,25 @@ util::json::Object makeGeoJSONGeometry(ForwardIter begin, ForwardIter end)
auto num_coordinates = std::distance(begin, end); auto num_coordinates = std::distance(begin, end);
BOOST_ASSERT(num_coordinates != 0); BOOST_ASSERT(num_coordinates != 0);
util::json::Object geojson; util::json::Object geojson;
if (num_coordinates > 1)
{
geojson.values["type"] = "LineString"; geojson.values["type"] = "LineString";
util::json::Array coordinates; util::json::Array coordinates;
if (num_coordinates > 1)
{
coordinates.values.reserve(num_coordinates); coordinates.values.reserve(num_coordinates);
std::transform( auto into = std::back_inserter(coordinates.values);
begin, end, std::back_inserter(coordinates.values), &detail::coordinateToLonLat); std::transform(begin, end, into, &detail::coordinateToLonLat);
geojson.values["coordinates"] = std::move(coordinates);
} }
else if (num_coordinates > 0) else if (num_coordinates > 0)
{ {
geojson.values["type"] = "Point"; // For a single location we create a [location, location] LineString
util::json::Array coordinates; // instead of a single Point making the GeoJSON output consistent.
coordinates.values.push_back(detail::coordinateToLonLat(*begin)); coordinates.values.reserve(2);
geojson.values["coordinates"] = std::move(coordinates); auto location = detail::coordinateToLonLat(*begin);
coordinates.values.push_back(location);
coordinates.values.push_back(location);
} }
geojson.values["coordinates"] = std::move(coordinates);
return geojson; return geojson;
} }

View File

@ -57,7 +57,7 @@ target_include_directories(util-tests PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(engine-tests ${ENGINE_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) target_link_libraries(engine-tests ${ENGINE_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
target_link_libraries(extractor-tests ${EXTRACTOR_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) target_link_libraries(extractor-tests ${EXTRACTOR_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
target_link_libraries(library-tests osrm ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) target_link_libraries(library-tests osrm ${ENGINE_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
target_link_libraries(server-tests osrm ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) target_link_libraries(server-tests osrm ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
target_link_libraries(util-tests ${UTIL_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) target_link_libraries(util-tests ${UTIL_LIBRARIES} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})

View File

@ -0,0 +1,71 @@
#include <boost/test/test_case_template.hpp>
#include <boost/test/unit_test.hpp>
#include "coordinates.hpp"
#include "equal_json.hpp"
#include "engine/api/json_factory.hpp"
#include "osrm/coordinate.hpp"
#include <iterator>
#include <vector>
using namespace osrm;
BOOST_AUTO_TEST_SUITE(json)
BOOST_AUTO_TEST_CASE(test_json_linestring)
{
const std::vector<util::Coordinate> locations{get_dummy_location(), //
get_dummy_location(), //
get_dummy_location()}; //
auto geom = engine::api::json::makeGeoJSONGeometry(begin(locations), end(locations));
const auto type = geom.values["type"].get<util::json::String>().value;
BOOST_CHECK_EQUAL(type, "LineString");
const auto coords = geom.values["coordinates"].get<util::json::Array>().values;
BOOST_CHECK_EQUAL(coords.size(), 3); // array of three location arrays
for (const auto each : coords)
{
const auto loc = each.get<util::json::Array>().values;
BOOST_CHECK_EQUAL(loc.size(), 2);
const auto lon = loc[0].get<util::json::Number>().value;
const auto lat = loc[1].get<util::json::Number>().value;
(void)lon;
(void)lat;
// cast fails if type do not match
}
}
BOOST_AUTO_TEST_CASE(test_json_single_point)
{
const std::vector<util::Coordinate> locations{get_dummy_location()};
auto geom = engine::api::json::makeGeoJSONGeometry(begin(locations), end(locations));
const auto type = geom.values["type"].get<util::json::String>().value;
BOOST_CHECK_EQUAL(type, "LineString");
const auto coords = geom.values["coordinates"].get<util::json::Array>().values;
BOOST_CHECK_EQUAL(coords.size(), 2); // array of two location arrays
for (const auto each : coords)
{
const auto loc = each.get<util::json::Array>().values;
BOOST_CHECK_EQUAL(loc.size(), 2);
const auto lon = loc[0].get<util::json::Number>().value;
const auto lat = loc[1].get<util::json::Number>().value;
(void)lon;
(void)lat;
// cast fails if type do not match
}
}
BOOST_AUTO_TEST_SUITE_END()