Skip to content

Commit

Permalink
🐛 Fix a bug caused by CRLF line ending
Browse files Browse the repository at this point in the history
  • Loading branch information
cyang-kth committed Aug 10, 2020
1 parent 6d6fa9c commit e325196
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 37 deletions.
32 changes: 18 additions & 14 deletions src/io/gps_reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
*/
#include "io/gps_reader.hpp"
#include "util/debug.hpp"
#include "util/util.hpp"
#include "config/gps_config.hpp"
#include <iostream>
#include <string>

using namespace FMM;
using namespace FMM::CORE;
using namespace FMM::IO;
using namespace FMM::UTIL;

std::vector<Trajectory> ITrajectoryReader::read_next_N_trajectories(int N) {
std::vector<Trajectory> trajectories;
Expand Down Expand Up @@ -68,7 +70,7 @@ GDALTrajectoryReader::GDALTrajectoryReader(const std::string &filename,
std::exit(EXIT_FAILURE);
} else {
SPDLOG_DEBUG("Geometry type is {}",
OGRGeometryTypeToName(ogrFDefn->GetGeomType()));
OGRGeometryTypeToName(ogrFDefn->GetGeomType()));
}
SPDLOG_INFO("Total number of trajectories {}", NUM_FEATURES);
SPDLOG_INFO("Finish reading meta data");
Expand All @@ -87,7 +89,7 @@ Trajectory GDALTrajectoryReader::read_next_trajectory() {
int trid = ogrFeature->GetFieldAsInteger(id_idx);
OGRGeometry *rawgeometry = ogrFeature->GetGeometryRef();
FMM::CORE::LineString linestring =
FMM::CORE::ogr2linestring((OGRLineString *) rawgeometry);
FMM::CORE::ogr2linestring((OGRLineString *) rawgeometry);
OGRFeature::DestroyFeature(ogrFeature);
++_cursor;
return Trajectory{trid, linestring};
Expand All @@ -105,14 +107,14 @@ CSVTrajectoryReader::CSVTrajectoryReader(const std::string &e_filename,
const std::string &id_name,
const std::string &geom_name,
const std::string &timestamp_name) :
ifs(e_filename) {
ifs(e_filename) {
std::string line;
std::getline(ifs, line);
std::stringstream check1(line);
std::string intermediate;
// Tokenizing w.r.t. space ' '
int i = 0;
while (getline(check1, intermediate, delim)) {
while (safe_get_line(check1, intermediate, delim)) {
if (intermediate == id_name) {
id_idx = i;
}
Expand All @@ -137,7 +139,7 @@ CSVTrajectoryReader::CSVTrajectoryReader(const std::string &e_filename,
}

std::vector<double> CSVTrajectoryReader::string2time(
const std::string &str) {
const std::string &str) {
std::vector<double> values;
std::stringstream ss(str);
double v;
Expand Down Expand Up @@ -199,14 +201,14 @@ CSVPointReader::CSVPointReader(const std::string &e_filename,
const std::string &x_name,
const std::string &y_name,
const std::string &time_name) :
ifs(e_filename) {
ifs(e_filename) {
std::string line;
std::getline(ifs, line);
std::stringstream check1(line);
std::string intermediate;
// Tokenizing w.r.t. space ' '
int i = 0;
while (getline(check1, intermediate, delim)) {
while (safe_get_line(check1, intermediate, delim)) {
if (intermediate == id_name) {
id_idx = i;
}
Expand All @@ -226,10 +228,10 @@ CSVPointReader::CSVPointReader(const std::string &e_filename,
SPDLOG_CRITICAL("Id column {} not found", id_name);
}
if (x_idx < 0) {
SPDLOG_CRITICAL("Geom column {} not found", x_name);
SPDLOG_CRITICAL("X column name {} not found", x_name);
}
if (y_idx < 0) {
SPDLOG_CRITICAL("Geom column {} not found", y_name);
SPDLOG_CRITICAL("Y column name {} not found", y_name);
}
std::exit(EXIT_FAILURE);
}
Expand Down Expand Up @@ -293,7 +295,7 @@ Trajectory CSVPointReader::read_next_trajectory() {
prev_line = line;
}
}
if (!has_next_trajectory()){
if (!has_next_trajectory()) {
trid = prev_id;
}
return Trajectory{trid, geom, timestamps};
Expand Down Expand Up @@ -321,17 +323,19 @@ bool CSVPointReader::has_timestamp() {
GPSReader::GPSReader(const FMM::CONFIG::GPSConfig &config) {
mode = config.get_gps_format();
if (mode == 0) {
SPDLOG_INFO("GPS data in trajectory shapefile format");
reader = std::make_shared<GDALTrajectoryReader>
(config.file, config.id,config.timestamp);
(config.file, config.id,config.timestamp);
} else if (mode == 1) {
SPDLOG_INFO("GPS data in trajectory CSV format");
reader = std::make_shared<CSVTrajectoryReader>
(config.file, config.id, config.geom, config.timestamp);
(config.file, config.id, config.geom, config.timestamp);
} else if (mode == 2) {
SPDLOG_INFO("GPS data in point CSV format");
reader = std::make_shared<CSVPointReader>
(config.file, config.id, config.x, config.y, config.timestamp);
(config.file, config.id, config.x, config.y, config.timestamp);
} else {
SPDLOG_CRITICAL("Unrecognized GPS format");
std::exit(EXIT_FAILURE);
}
};

30 changes: 15 additions & 15 deletions src/io/gps_reader.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* Fast map matching.
*
* Definition of GPS reader classes
* Definition of GPS reader classes
*
* @author: Can Yang
* @version: 2017.11.11
Expand All @@ -27,7 +27,7 @@ namespace IO {
* Trajectory Reader Interface.
*/
class ITrajectoryReader {
public:
public:
/**
* Read the next trajectory in the class
* @return a trajectory
Expand Down Expand Up @@ -69,7 +69,7 @@ class ITrajectoryReader {
* a trajectory.
*/
class GDALTrajectoryReader : public ITrajectoryReader {
public:
public:
/**
* Constructor of GDALTrajectoryReader
* @param filename a GPS ESRI shapefile path
Expand All @@ -87,7 +87,7 @@ class GDALTrajectoryReader : public ITrajectoryReader {
* Get the number of trajectories in the file
*/
int get_num_trajectories();
private:
private:
int NUM_FEATURES = 0;
int id_idx = -1; // Index of the id column in shapefile
int timestamp_idx = -1; // Index of the id column in shapefile
Expand All @@ -113,7 +113,7 @@ class GDALTrajectoryReader : public ITrajectoryReader {
* 1;LineString(1 0,1 1);1,1
*/
class CSVTrajectoryReader : public ITrajectoryReader {
public:
public:
/**
* Constructor of CSVTrajectoryReader
* @param e_filename input file name.
Expand Down Expand Up @@ -156,7 +156,7 @@ class CSVTrajectoryReader : public ITrajectoryReader {
* @return a vector of timestamps
*/
static std::vector<double> string2time(const std::string &str);
private:
private:
std::fstream ifs;
int id_idx = -1;
int geom_idx = -1;
Expand All @@ -179,7 +179,7 @@ class CSVTrajectoryReader : public ITrajectoryReader {
* 1;1;2;2
*/
class CSVPointReader : public ITrajectoryReader {
public:
public:
/**
* Reader class for CSV point data.
* @param e_filename file name
Expand All @@ -190,11 +190,11 @@ class CSVPointReader : public ITrajectoryReader {
* an empty timestamp vector will be returned for every trajectory.
*/
CSVPointReader(
const std::string &e_filename,
const std::string &id_name,
const std::string &x_name,
const std::string &y_name,
const std::string &time_name);
const std::string &e_filename,
const std::string &id_name,
const std::string &x_name,
const std::string &y_name,
const std::string &time_name);
/**
* Read the next trajectory in the file.
* @return A trajectory object
Expand All @@ -218,7 +218,7 @@ class CSVPointReader : public ITrajectoryReader {
* Close the reader object
*/
void close() override;
private:
private:
std::string prev_line = "";
std::fstream ifs;
int id_idx = -1;
Expand All @@ -233,7 +233,7 @@ class CSVPointReader : public ITrajectoryReader {
* a file by specifying GPSConfig as input.
*/
class GPSReader {
public:
public:
/**
* Constructor
* @param config configuration of GPS data, the file format will be
Expand Down Expand Up @@ -271,7 +271,7 @@ class GPSReader {
inline std::vector<FMM::CORE::Trajectory> read_all_trajectories() {
return reader->read_all_trajectories();
};
private:
private:
std::shared_ptr<ITrajectoryReader> reader;
int mode; /**< Mode marking the type of GPS data stored in the file */
};
Expand Down
28 changes: 28 additions & 0 deletions src/util/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,33 @@ std::string get_file_directory(const std::string &fn) {
return {};
};

std::istream& safe_get_line(std::istream& is, std::string& t, char delim)
{
t.clear();
std::istream::sentry se(is, true);
std::streambuf* sb = is.rdbuf();
for(;;) {
int c = sb->sbumpc();
switch (c) {
case '\n':
return is;
case '\r':
if(sb->sgetc() == '\n')
sb->sbumpc();
return is;
case std::streambuf::traits_type::eof():
// Also handle the case when the last line has no line ending
if(t.empty())
is.setstate(std::ios::eofbit);
return is;
default:
if (c==delim){
return is;
}
t += (char)c;
}
}
}

} // Util
} // FMM
21 changes: 13 additions & 8 deletions src/util/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ std::ostream &operator<<(std::ostream &os,
* @return the stream with trajectory candidate information written
*/
std::ostream &operator<<(std::ostream &os,
const FMM::MM::Traj_Candidates &tr_cs);
const FMM::MM::Traj_Candidates &tr_cs);

/**
* Write optimal candidate path into a stream
Expand All @@ -62,7 +62,7 @@ std::ostream &operator<<(std::ostream &os,
* @return the stream with candidate path information written
*/
std::ostream &operator<<(std::ostream &os,
const FMM::MM::OptCandidatePath &opath);
const FMM::MM::OptCandidatePath &opath);

/**
* Write a point into a stream
Expand All @@ -71,7 +71,7 @@ std::ostream &operator<<(std::ostream &os,
* @return the stream with wkt point written.
*/
std::ostream &operator<<(std::ostream &os,
const FMM::CORE::Point &geom);
const FMM::CORE::Point &geom);

} // namespace std

Expand Down Expand Up @@ -144,7 +144,7 @@ bool check_file_extension(const std::string &filename,
*/
template<typename T>
std::string vec2string(
const std::vector<T> &vec) {
const std::vector<T> &vec) {
std::ostringstream vts;
if (!vec.empty()) {
std::copy(vec.begin(), vec.end() - 1,
Expand All @@ -161,7 +161,7 @@ std::string vec2string(
*/
template<typename T>
std::vector<T> string2vec(
const std::string &str) {
const std::string &str) {
std::vector<T> vec;
std::stringstream ss(str);
T i;
Expand Down Expand Up @@ -191,7 +191,7 @@ std::chrono::time_point<std::chrono::system_clock> get_current_time();
* @param start_time timestamp point
*/
void print_time(
const std::chrono::time_point<std::chrono::system_clock> &start_time);
const std::chrono::time_point<std::chrono::system_clock> &start_time);

/**
* Calculate the duration between two time points
Expand All @@ -200,8 +200,13 @@ void print_time(
* @return the duration between two time points
*/
double get_duration(
const std::chrono::time_point<std::chrono::system_clock> &start_time,
const std::chrono::time_point<std::chrono::system_clock> &end_time);
const std::chrono::time_point<std::chrono::system_clock> &start_time,
const std::chrono::time_point<std::chrono::system_clock> &end_time);

/**
* Get line correctly by handling `\r\n` line endings
*/
std::istream& safe_get_line(std::istream& is, std::string& t, char delim);

} // Util
} // FMM
Expand Down

0 comments on commit e325196

Please sign in to comment.