mirror of https://github.com/CGAL/cgal
fix WKT I/O error handling
This commit is contained in:
parent
050677f002
commit
765744e8b2
|
|
@ -44,18 +44,42 @@ namespace internal {
|
||||||
template <typename K>
|
template <typename K>
|
||||||
void pop_back_if_equal_to_front(CGAL::Polygon_2<K>& poly)
|
void pop_back_if_equal_to_front(CGAL::Polygon_2<K>& poly)
|
||||||
{
|
{
|
||||||
typename CGAL::Polygon_2<K>::iterator it = poly.end();
|
auto last_it = std::prev(poly.end());
|
||||||
--it;
|
if((*poly.begin()) == *last_it)
|
||||||
if((*poly.begin()) == *it)
|
poly.erase(last_it);
|
||||||
poly.erase(it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename K>
|
template <typename K>
|
||||||
void pop_back_if_equal_to_front(CGAL::Polygon_with_holes_2<K>& pwh)
|
void pop_back_if_equal_to_front(CGAL::Polygon_with_holes_2<K>& pwh)
|
||||||
{
|
{
|
||||||
pop_back_if_equal_to_front(pwh.outer_boundary());
|
pop_back_if_equal_to_front(pwh.outer_boundary());
|
||||||
for(auto i = pwh.holes_begin(); i!= pwh.holes_end(); ++i)
|
for(auto& hole : pwh.holes())
|
||||||
pop_back_if_equal_to_front(*i);
|
pop_back_if_equal_to_front(hole);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Geometry>
|
||||||
|
bool read_wkt_or_fail_stream(std::istream& in,
|
||||||
|
const std::string& line,
|
||||||
|
Geometry& geometry)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
boost::geometry::read_wkt(line, geometry);
|
||||||
|
} catch(std::exception& e) {
|
||||||
|
std::cerr << "error: " << e.what() << std::endl;
|
||||||
|
in.clear(in.rdstate() | std::ios::failbit);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool get_a_new_line(std::istream& in, std::string& line)
|
||||||
|
{
|
||||||
|
in >> std::ws; // skip whitespaces
|
||||||
|
if(in.good()) {
|
||||||
|
return !std::getline(in, line).fail();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
@ -76,28 +100,12 @@ template<typename Point>
|
||||||
bool read_point_WKT(std::istream& in,
|
bool read_point_WKT(std::istream& in,
|
||||||
Point& point)
|
Point& point)
|
||||||
{
|
{
|
||||||
if(!in.good())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
while(std::getline(in, line))
|
while(internal::get_a_new_line(in, line))
|
||||||
{
|
{
|
||||||
std::istringstream iss(line);
|
if(line.substr(0, 5).compare("POINT") == 0)
|
||||||
std::string type;
|
|
||||||
iss >> type;
|
|
||||||
|
|
||||||
if(type.substr(0, 5).compare("POINT") == 0)
|
|
||||||
{
|
{
|
||||||
try
|
internal::read_wkt_or_fail_stream(in, line, point);
|
||||||
{
|
|
||||||
boost::geometry::read_wkt(line, point);
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
std::cerr << "error." << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -124,25 +132,13 @@ template<typename MultiPoint>
|
||||||
bool read_multi_point_WKT(std::istream& in,
|
bool read_multi_point_WKT(std::istream& in,
|
||||||
MultiPoint& mp)
|
MultiPoint& mp)
|
||||||
{
|
{
|
||||||
if(!in.good())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CGAL::internal::Geometry_container<MultiPoint, boost::geometry::multi_point_tag> gc(mp);
|
|
||||||
std::string line;
|
std::string line;
|
||||||
while(std::getline(in, line))
|
while(internal::get_a_new_line(in, line))
|
||||||
{
|
{
|
||||||
std::istringstream iss(line);
|
if(line.substr(0, 10).compare("MULTIPOINT") == 0)
|
||||||
std::string type;
|
|
||||||
iss >> type;
|
|
||||||
|
|
||||||
if(type.substr(0, 10).compare("MULTIPOINT") == 0)
|
|
||||||
{
|
{
|
||||||
try{
|
CGAL::internal::Geometry_container<MultiPoint, boost::geometry::multi_point_tag> gc(mp);
|
||||||
boost::geometry::read_wkt(line, gc);
|
internal::read_wkt_or_fail_stream(in, line, gc);
|
||||||
} catch(...){
|
|
||||||
std::cerr << "error." << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -170,25 +166,13 @@ template<typename LineString>
|
||||||
bool read_linestring_WKT(std::istream& in,
|
bool read_linestring_WKT(std::istream& in,
|
||||||
LineString& polyline)
|
LineString& polyline)
|
||||||
{
|
{
|
||||||
if(!in.good())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CGAL::internal::Geometry_container<LineString, boost::geometry::linestring_tag> gc(polyline);
|
|
||||||
std::string line;
|
std::string line;
|
||||||
while(std::getline(in, line))
|
while(internal::get_a_new_line(in, line))
|
||||||
{
|
{
|
||||||
std::istringstream iss(line);
|
if(line.substr(0, 10).compare("LINESTRING") == 0)
|
||||||
std::string type;
|
|
||||||
iss >> type;
|
|
||||||
|
|
||||||
if(type.substr(0, 10).compare("LINESTRING") == 0)
|
|
||||||
{
|
{
|
||||||
try{
|
CGAL::internal::Geometry_container<LineString, boost::geometry::linestring_tag> gc(polyline);
|
||||||
boost::geometry::read_wkt(line, gc);
|
internal::read_wkt_or_fail_stream(in, line, gc);
|
||||||
} catch(...){
|
|
||||||
std::cerr << "error." << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -214,40 +198,26 @@ template<typename MultiLineString>
|
||||||
bool read_multi_linestring_WKT(std::istream& in,
|
bool read_multi_linestring_WKT(std::istream& in,
|
||||||
MultiLineString& mls)
|
MultiLineString& mls)
|
||||||
{
|
{
|
||||||
if(!in.good())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
typedef typename MultiLineString::value_type PointRange;
|
|
||||||
typedef CGAL::internal::Geometry_container<PointRange, boost::geometry::linestring_tag> LineString;
|
|
||||||
|
|
||||||
std::vector<LineString> pr_range;
|
|
||||||
CGAL::internal::Geometry_container<std::vector<LineString>, boost::geometry::multi_linestring_tag> gc(pr_range);
|
|
||||||
std::string line;
|
std::string line;
|
||||||
while(std::getline(in, line))
|
while(internal::get_a_new_line(in, line))
|
||||||
{
|
{
|
||||||
std::istringstream iss(line);
|
if(line.substr(0, 15).compare("MULTILINESTRING") == 0)
|
||||||
std::string type;
|
|
||||||
iss >> type;
|
|
||||||
|
|
||||||
if(type.substr(0, 15).compare("MULTILINESTRING") == 0)
|
|
||||||
{
|
{
|
||||||
try
|
using PointRange = typename MultiLineString::value_type;
|
||||||
{
|
using LineString = CGAL::internal::Geometry_container<PointRange, boost::geometry::linestring_tag>;
|
||||||
boost::geometry::read_wkt(line, gc);
|
|
||||||
}
|
std::vector<LineString> pr_range;
|
||||||
catch(...)
|
CGAL::internal::Geometry_container<std::vector<LineString>, boost::geometry::multi_linestring_tag> gc(pr_range);
|
||||||
{
|
|
||||||
std::cerr << "error." << std::endl;
|
internal::read_wkt_or_fail_stream(in, line, gc);
|
||||||
return false;
|
for(LineString& ls : gc) {
|
||||||
|
mls.push_back(*ls.range);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(LineString& ls : gc)
|
|
||||||
mls.push_back(*ls.range);
|
|
||||||
|
|
||||||
return !in.fail();
|
return !in.fail();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,28 +236,12 @@ template<typename Polygon>
|
||||||
bool read_polygon_WKT(std::istream& in,
|
bool read_polygon_WKT(std::istream& in,
|
||||||
Polygon& polygon)
|
Polygon& polygon)
|
||||||
{
|
{
|
||||||
if(!in.good())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::string line;
|
std::string line;
|
||||||
while(std::getline(in, line))
|
while(internal::get_a_new_line(in, line))
|
||||||
{
|
{
|
||||||
std::istringstream iss(line);
|
if(line.substr(0, 7).compare("POLYGON") == 0)
|
||||||
std::string type;
|
|
||||||
iss >> type;
|
|
||||||
|
|
||||||
if(type.substr(0, 7).compare("POLYGON") == 0)
|
|
||||||
{
|
{
|
||||||
try
|
internal::read_wkt_or_fail_stream(in, line, polygon);
|
||||||
{
|
|
||||||
boost::geometry::read_wkt(line, polygon);
|
|
||||||
}
|
|
||||||
catch( ...)
|
|
||||||
{
|
|
||||||
in.setstate(std::ios::failbit);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
internal::pop_back_if_equal_to_front(polygon);
|
internal::pop_back_if_equal_to_front(polygon);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -313,31 +267,16 @@ template<typename MultiPolygon>
|
||||||
bool read_multi_polygon_WKT(std::istream& in,
|
bool read_multi_polygon_WKT(std::istream& in,
|
||||||
MultiPolygon& polygons)
|
MultiPolygon& polygons)
|
||||||
{
|
{
|
||||||
if(!in.good())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CGAL::internal::Geometry_container<MultiPolygon, boost::geometry::multi_polygon_tag> gc(polygons);
|
|
||||||
std::string line;
|
std::string line;
|
||||||
while(std::getline(in, line))
|
while(internal::get_a_new_line(in, line))
|
||||||
{
|
{
|
||||||
std::istringstream iss(line);
|
if(line.substr(0, 12).compare("MULTIPOLYGON") == 0)
|
||||||
std::string type;
|
|
||||||
iss >> type;
|
|
||||||
|
|
||||||
if(type.substr(0, 12).compare("MULTIPOLYGON") == 0)
|
|
||||||
{
|
{
|
||||||
try
|
CGAL::internal::Geometry_container<MultiPolygon, boost::geometry::multi_polygon_tag> gc(polygons);
|
||||||
{
|
internal::read_wkt_or_fail_stream(in, line, gc);
|
||||||
boost::geometry::read_wkt(line, gc);
|
|
||||||
}
|
|
||||||
catch( ...)
|
|
||||||
{
|
|
||||||
in.setstate(std::ios::failbit);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
for(typename CGAL::internal::Geometry_container<MultiPolygon, boost::geometry::multi_polygon_tag>::iterator it = gc.begin(); it != gc.end(); ++it)
|
for(auto& p : gc)
|
||||||
internal::pop_back_if_equal_to_front(*it);
|
internal::pop_back_if_equal_to_front(p);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -517,17 +456,15 @@ bool read_WKT(std::istream& is,
|
||||||
MultiLineString& polylines,
|
MultiLineString& polylines,
|
||||||
MultiPolygon& polygons)
|
MultiPolygon& polygons)
|
||||||
{
|
{
|
||||||
if(!is.good())
|
auto fail = [&is]() { is.clear(is.rdstate() | std::ios::failbit); return false; };
|
||||||
return false;
|
|
||||||
|
|
||||||
while(is.good() && !is.eof())
|
std::string line;
|
||||||
|
while(is >> std::ws && is.good() && std::getline(is, line))
|
||||||
{
|
{
|
||||||
typedef typename MultiPoint::value_type Point;
|
typedef typename MultiPoint::value_type Point;
|
||||||
typedef typename MultiLineString::value_type LineString;
|
typedef typename MultiLineString::value_type LineString;
|
||||||
typedef typename MultiPolygon::value_type Polygon;
|
typedef typename MultiPolygon::value_type Polygon;
|
||||||
|
|
||||||
std::string line;
|
|
||||||
std::getline(is, line);
|
|
||||||
std::string::size_type header_end = line.find("("); // }
|
std::string::size_type header_end = line.find("("); // }
|
||||||
if(header_end == std::string::npos){
|
if(header_end == std::string::npos){
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -549,42 +486,42 @@ bool read_WKT(std::istream& is,
|
||||||
if(type == "POINT")
|
if(type == "POINT")
|
||||||
{
|
{
|
||||||
Point p;
|
Point p;
|
||||||
CGAL::IO::read_point_WKT(iss, p);
|
if(!IO::read_point_WKT(iss, p) ) return fail();
|
||||||
points.push_back(p);
|
points.push_back(p);
|
||||||
}
|
}
|
||||||
else if(type == "LINESTRING")
|
else if(type == "LINESTRING")
|
||||||
{
|
{
|
||||||
LineString l;
|
LineString l;
|
||||||
CGAL::IO::read_linestring_WKT(iss, l);
|
if(!IO::read_linestring_WKT(iss, l)) return fail();
|
||||||
polylines.push_back(l);
|
polylines.push_back(std::move(l));
|
||||||
}
|
}
|
||||||
else if(type == "POLYGON")
|
else if(type == "POLYGON")
|
||||||
{
|
{
|
||||||
Polygon p;
|
Polygon p;
|
||||||
CGAL::IO::read_polygon_WKT(iss, p);
|
if(!IO::read_polygon_WKT(iss, p)) return fail();
|
||||||
if(!p.outer_boundary().is_empty())
|
if(!p.outer_boundary().is_empty())
|
||||||
polygons.push_back(p);
|
polygons.push_back(std::move(p));
|
||||||
}
|
}
|
||||||
else if(type == "MULTIPOINT")
|
else if(type == "MULTIPOINT")
|
||||||
{
|
{
|
||||||
MultiPoint mp;
|
MultiPoint mp;
|
||||||
CGAL::IO::read_multi_point_WKT(iss, mp);
|
if(!IO::read_multi_point_WKT(iss, mp)) return fail();
|
||||||
for(const Point& point : mp)
|
for(const Point& point : mp)
|
||||||
points.push_back(point);
|
points.push_back(point);
|
||||||
}
|
}
|
||||||
else if(type == "MULTILINESTRING")
|
else if(type == "MULTILINESTRING")
|
||||||
{
|
{
|
||||||
MultiLineString mls;
|
MultiLineString mls;
|
||||||
CGAL::IO::read_multi_linestring_WKT(iss, mls);
|
if(!IO::read_multi_linestring_WKT(iss, mls)) return fail();
|
||||||
for(const LineString& ls : mls)
|
for(LineString& ls : mls)
|
||||||
polylines.push_back(ls);
|
polylines.push_back(std::move(ls));
|
||||||
}
|
}
|
||||||
else if(type == "MULTIPOLYGON")
|
else if(type == "MULTIPOLYGON")
|
||||||
{
|
{
|
||||||
MultiPolygon mp;
|
MultiPolygon mp;
|
||||||
CGAL::IO::read_multi_polygon_WKT(iss, mp);
|
if(!IO::read_multi_polygon_WKT(iss, mp)) return fail();
|
||||||
for(const Polygon& poly : mp)
|
for(Polygon& poly : mp)
|
||||||
polygons.push_back(poly);
|
polygons.push_back(std::move(poly));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,20 +46,16 @@ struct Geometry_container{
|
||||||
typedef typename Range::size_type size_type;
|
typedef typename Range::size_type size_type;
|
||||||
typedef typename Range::value_type value_type;
|
typedef typename Range::value_type value_type;
|
||||||
std::shared_ptr<Range> range;
|
std::shared_ptr<Range> range;
|
||||||
bool must_delete;
|
|
||||||
//
|
//
|
||||||
// Default constructor.
|
// Default constructor.
|
||||||
// Creates a new internal Range.
|
// Creates a new internal Range.
|
||||||
// De-allocate memory after usage.
|
// De-allocate memory after usage.
|
||||||
Geometry_container():range(new Range()), must_delete(true)
|
Geometry_container() : range(std::make_shared<Range>()) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
Copy constructor.
|
Store a pointer to the given range.
|
||||||
Memory NOT de-allocated after usage.
|
Memory NOT de-allocated after usage.
|
||||||
*/
|
*/
|
||||||
Geometry_container(Range& range)
|
Geometry_container(Range& range) : range(&range, Dummy_deleter()) {}
|
||||||
:range(&range, Dummy_deleter()), must_delete(false){}
|
|
||||||
|
|
||||||
iterator begin()
|
iterator begin()
|
||||||
{ return range->begin(); }
|
{ return range->begin(); }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue