基于Boost库C++文件夹级别数据批处理
2015-10-31 19:32
465 查看
最近,帮助一个师妹实现了地理坐标的欧式距离计算,其数据存储在文本文件中,然后很多类似的文本文件组成一个文件夹路径,本程序源码主要实现了C++文件便利,存储,以及计算相关功能的实现。下边的贴图是数据的基本格式:文件的前六行是数据说明文件,在处理的时候需要略过,正文数据意义为:纬度,经度,无意义,高程,离1899年的天数,日期和时间。需要做的操作如下:
1. 从文件中读出数据到一个类中,定义为User,
2. 给定文件夹路径,遍历所有文件
3. 文件的命名是日期,需要按照日期排序
4. 相邻的两个文件求得欧式距离,取得最大值
5. 获取所有相邻文件的最大值
假设文件有1,2,3,4.则12之间相应求解欧式距离,取得所有欧式距离的最大值,与此类似,取得34最大值,最后取得1234最大值。
关于boost库的安装参照本人前边的博客。
Geolife trajectory
WGS 84
Altitude is in Feet
Reserved 3
0,2,255,My Track,0,0,2,8421376
0
39.984702,116.318417,0,492,39744.1201851852,2008-10-23,02:53:04
39.984683,116.31845,0,492,39744.1202546296,2008-10-23,02:53:10
39.984686,116.318417,0,492,39744.1203125,2008-10-23,02:53:15
39.984688,116.318385,0,492,39744.1203703704,2008-10-23,02:53:20
39.984655,116.318263,0,492,39744.1204282407,2008-10-23,02:53:25
39.984611,116.318026,0,493,39744.1204861111,2008-10-23,02:53:30
39.984608,116.317761,0,493,39744.1205439815,2008-10-23,02:53:35
39.984563,116.317517,0,496,39744.1206018519,2008-10-23,02:53:40
39.984539,116.317294,0,500,39744.1206597222,2008-10-23,02:53:45
39.984606,116.317065,0,505,39744.1207175926,2008-10-23,02:53:50
39.984568,116.316911,0,510,39744.120775463,2008-10-23,02:53:55
User.hpp:实现了操作符重载,
//
// User.hpp
// Test
//
// Created by 秦传庆 on 15/10/23.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#ifndef User_hpp
#define User_hpp
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <sstream>
namespace gregorianDate = boost::gregorian;
using namespace boost::posix_time;
using namespace std;
/*
39.984702,116.318417,0,492,39744.1201851852,2008-10-23,02:53:04
39.984683,116.31845,0,492,39744.1202546296,2008-10-23,02:53:10
39.984686,116.318417,0,492,39744.1203125,2008-10-23,02:53:15
39.984688,116.318385,0,492,39744.1203703704,2008-10-23,02:53:20
39.984655,116.318263,0,492,39744.1204282407,2008-10-23,02:53:25
39.984611,116.318026,0,493,39744.1204861111,2008-10-23,02:53:30
39.984608,116.317761,0,493,39744.1205439815,2008-10-23,02:53:35
*/
class User {
private:
double latitude;
double longitude;
int nonsense;
int altitude;
double daysince18991230;
gregorianDate::date date;
time_duration time;
//ptime date;
public:
friend ostream &operator<<(ostream &os, const User &c);
friend istream &operator>>(istream &is, User &c);
/*Java, setter and geter*/
void setLatitude(double latitude);
double getLatitude();
void setLongitude(double longitude);
double getLongitude();
void setNonsense(int nonsense);
int getNonsense();
void setAltitude(int altitude);
int getAltitude();
void setDaysince18991230(double daysince18991230);
double getDaysince18991230();
void setDate(string date);
void setDate(gregorianDate::date date);
gregorianDate::date getDate();
void setTime(string time);
void setTime(time_duration time);
time_duration getTime();
};
template<class out, class in>
out ConvertDataType(const in& a);
#endif /* User_hpp */
User.cpp
FileIter.hpp: 实现基于boost库的文件遍历
FileIter.cpp
//
// FileIter.cpp
// Test
//
// Created by 秦传庆 on 15/10/23.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#include "FileIter.hpp"
FileIter::FileIter(string path) {
this->path = path;
}
void FileIter::walk() {
walk(path);
}
void FileIter::walk(string path) {
auto p = boost::filesystem::path(path);
walk(p);
sort(data.begin(), data.end(), compare);
//PrintVector(data);
}
void FileIter::walk(boost::filesystem::path p) {
try {
if (exists(p)) {
if (is_regular_file(p) && !boost::filesystem::is_empty(p)) {
//cout << p << " size is " << file_size(p) << '\n';
data.push_back(p.string());
}else if (is_directory(p)) {
//cout << p << " is a directory containing:\n";
for (directory_entry& x : directory_iterator(p)) {
walk(x.path());
}
}else {
cout << p << " exists, but is not a regular file or directory\n";
}
}else {
cout << p << " does not exist\n";
}
}catch (const filesystem_error& ex) {
cout << ex.what() << '\n';
}
}
vector<string> FileIter::getVector() {
return data;
}
bool compare(string file1, string file2){
file1 = file1.substr(file1.find_last_of("/") + 1, 14);
file2 = file2.substr(file2.find_last_of("/") + 1, 14);
//cout << file1 << "," << file2 << endl;
return file1 < file2;
}
Utils.hpp : 实现了一些功能调试函数,文件是否打开成功,打印容器内容,易于查看。
//
// Utils.hpp
// Test
//
// Created by 秦传庆 on 15/10/25.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#ifndef Utils_hpp
#define Utils_hpp
#define BOOST_LOG_DYN_LINK
#include <fstream>
#include <vector>
#include <iostream>
#include <sstream>
#include <boost/lexical_cast.hpp>
using namespace boost;
using namespace std;
bool FileExist(const fstream& in);
template<class out, class in>
out ConvertDataType(const in& a)
{
/*
std::stringstream temp;
temp<<a;
out b;
temp>>b;
return b;
*/
return lexical_cast<out>(a);
}
template<typename T>
void PrintVector(const vector<T>& data);
template<typename T>
string VectorToString(const vector<T>& data){
string content;
for (auto& temp : data){
content.append(ConvertDataType<std::string>(temp));
}
return content;
}
#include "TestUnit.cpp"
#endif /* Utils_hpp */
Utils.cpp
TestUnit.cpp : 模版方法打印容器内容
SpaceDistance.hpp : 实现欧式距离计算
//
// SpaceDistance.hpp
// Test
//
// Created by 秦传庆 on 15/10/25.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#ifndef SpaceDistance_hpp
#define SpaceDistance_hpp
#include "User.hpp"
#include "Utils.hpp"
#include "FileIter.hpp"
#include "Logger.hpp"
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <boost/timer.hpp>
using namespace std;
class SpaceDistance{
private:
boost::timer time;
FileIter folder;
vector<string> file_names;
fstream file_stream;
vector<User> data_original;
vector<User> data_compare;
//vector<vector<User>> data;
istream_iterator<User> eof;
vector<string>::size_type file_number;
public:
SpaceDistance(string path);
double calculateDistance();
private:
bool checkFileNumber(){
return true;
}
vector<User> getDataFromFile(string file_name);
double calculateDistanceOfTwo();
void validateFiles();
};
#endif /* SpaceDistance_hpp */
SpaceDistance.cpp
//
// SpaceDistance.cpp
// Test
//
// Created by 秦传庆 on 15/10/25.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#include "SpaceDistance.hpp"
using namespace std;
SpaceDistance::SpaceDistance(string path):folder(path){
folder.walk();
file_names = folder.getVector();
//PrintVector(file_names);
validateFiles();
file_number = file_names.size();
}
double SpaceDistance::calculateDistance(){
double distanceOfTwo;
double maxDistance;
string msg;
if (!checkFileNumber()){
return 0.0;
}
vector<double> distance;
/*
for (auto fileName:file_names){
data.push_back(getDataFromFile(fileName));
}
*/
for (auto i = 0; i < file_number - 1; i++) {
time.restart();
data_original = getDataFromFile(file_names[i]);
//data_original = data[i];
for (auto j = i + 1; j < file_number; j++){
data_compare = getDataFromFile(file_names[j]);
//data_compare = data[j];
distanceOfTwo = calculateDistanceOfTwo();
distance.push_back(distanceOfTwo);
//info_log(file_names[i]);
msg.clear();
msg.append(file_names[i]);
msg.append(",");
msg.append(file_names[j]);
msg.append(":");
msg.append(ConvertDataType<std::string>(distanceOfTwo));
BOOST_LOG_FUNCTION();
info_log(msg);
}
msg.clear();
msg.append("Time elapesd: ");
msg.append(ConvertDataType<std::string>(time.elapsed()));
BOOST_LOG_FUNCTION();
info_log(msg);
}
//PrintVector(distance);
//BOOST_LOG_FUNCTION();
maxDistance = *max_element(distance.begin(), distance.end());
//info_log(maxDistance);
return maxDistance;
}
vector<User> SpaceDistance::getDataFromFile(string file_name){
file_stream.open(file_name.c_str(), fstream::in);
if (!FileExist(file_stream)) {
return vector<User>();
}
string temp;
/*
* below for cycle will go over 6 lines in each file.
*/
for(int i = 0; i < 6; i++){
getline(file_stream, temp);
}
istream_iterator<User> item_iter(file_stream);
vector<User> data(item_iter, eof);
file_stream.close();
file_stream.clear();
return data;
}
double SpaceDistance::calculateDistanceOfTwo(){
/*
* here do math of the gero.
*/
vector<double> data;
vector<double> temp;
//auto length = data_original.size() > data_compare.size()? data_compare.size():data_original.size();
double x_original;
double y_original;
double x_compare;
double y_compare;
auto original_length = data_original.size();
auto compare_length = data_compare.size();
for (auto i = 0; i < original_length; i++){
x_original = data_original[i].getLongitude();
y_original = data_original[i].getLatitude();
temp.clear();
for (auto j = 0; j < compare_length; j++){
x_compare = data_compare[j].getLongitude();
y_compare = data_compare[j].getLatitude();
temp.push_back(sqrt(pow((x_original - x_compare), 2) + pow((y_original - y_compare), 2)));
}
//PrintVector(temp);
data.push_back(*max_element(temp.begin(), temp.end()));
}
//PrintVector(data);
//BOOST_LOG_FUNCTION();
//info_log(VectorToString(data));
return *max_element(data.begin(), data.end());
}
void SpaceDistance::validateFiles(){
string extension_string = ".plt";
for (auto iter = file_names.begin(); iter != file_names.end();){
if (extension_string != (*iter).substr((*iter).size() - extension_string.size(), extension_string.size())){
file_names.erase(iter);
} else {
iter++;
}
}
}Logger.hpp 日志记录系统
//
// Logger.hpp
// Test
//
// Created by 秦传庆 on 15/11/2.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#ifndef Logger_hpp
#define Logger_hpp
#define BOOST_LOG_DYN_LINK
#include <iostream>
#include <fstream>
#include <boost/log/expressions.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/core/null_deleter.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/attributes/named_scope.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/detail/format.hpp>
#include <boost/log/detail/thread_id.hpp>
namespace logging = boost::log;
namespace sinks = boost::log::sinks;
namespace src = boost::log::sources;
namespace expr = boost::log::expressions;
namespace attrs = boost::log::attributes;
namespace keywords = boost::log::keywords;
using namespace logging::trivial;
using namespace std;
class Logger {
public:
static void init();
};
template<class T>
void trace_log(const T& content) {
src::severity_logger<severity_level> lg;
BOOST_LOG_SEV(lg, logging::trivial::trace) << content;
}
template<class T>
void debug_log(const T& content) {
src::severity_logger<severity_level> lg;
BOOST_LOG_SEV(lg, logging::trivial::debug) << content;
}
template<class T>
void info_log(const T& content) {
src::severity_logger<severity_level> lg;
BOOST_LOG_SEV(lg, logging::trivial::info) << content;
}
template<class T>
void warning_log(const T& content) {
src::severity_logger<severity_level> lg;
BOOST_LOG_SEV(lg, logging::trivial::warning) << content;
}
template<class T>
void error_log(const T& content) {
src::severity_logger<severity_level> lg;
BOOST_LOG_SEV(lg, logging::trivial::error) << content;
}
template<class T>
void fatal_log(const T& content) {
src::severity_logger<severity_level> lg;
BOOST_LOG_SEV(lg, logging::trivial::fatal) << content;
}
#endif /* Logger_hpp */
Logger.cpp
//
// Logger.cpp
// Test
//
// Created by 秦传庆 on 15/11/2.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#include "Logger.hpp"
void Logger::init() {
typedef sinks::synchronous_sink<sinks::text_ostream_backend> text_sink;
boost::shared_ptr<text_sink> sink = boost::make_shared< text_sink >();
boost::shared_ptr<std::ostream> stream(&std::clog, boost::null_deleter());
sink->locked_backend()->add_stream(stream);
auto pSink = logging::add_file_log
(
keywords::file_name = "/Users/qinchuanqing/Downloads/000/sample_%N.log",
keywords::rotation_size = 10 * 1024 * 1024,
keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),
//keywords::format = "[%LineID%][%TimeStamp%]: %Message%"
keywords::format =
(
expr::stream
<< "[" << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S.%f")
<< " " << expr::format_named_scope("Scope", keywords::format = "%f:%l]")
<< "<" << logging::trivial::severity
<< "> " << expr::smessage
)
);
logging::core::get()->set_filter
(
logging::trivial::severity >= logging::trivial::trace
);
logging::core::get()->add_sink(sink);
pSink->locked_backend()->auto_flush(true);//使日志实时更新
logging::core::get()->add_global_attribute("Scope", attrs::named_scope());
logging::add_common_attributes();
}
main.cpp : 主测试函数:
//
// main.cpp
// Test
//
// Created by 秦传庆 on 15/10/23.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#include "SpaceDistance.hpp"
#include <time.h>
using namespace std;
int main() {
Logger::init();
time_t t_start, t_end;
t_start = time(NULL);
SpaceDistance distance("/Users/qinchuanqing/Downloads/000/Trajectory");
double max_distance = distance.calculateDistance();
BOOST_LOG_FUNCTION();
string msg = "Max number is: ";
msg.append(ConvertDataType<string>(max_distance));
info_log(msg);
msg = "Total time is: ";
t_end = time(NULL);
msg.append(ConvertDataType<string>(difftime(t_end,t_start)));
msg.append(" seconds");
BOOST_LOG_FUNCTION();
trace_log(msg);
return 0;
}
1. 从文件中读出数据到一个类中,定义为User,
2. 给定文件夹路径,遍历所有文件
3. 文件的命名是日期,需要按照日期排序
4. 相邻的两个文件求得欧式距离,取得最大值
5. 获取所有相邻文件的最大值
假设文件有1,2,3,4.则12之间相应求解欧式距离,取得所有欧式距离的最大值,与此类似,取得34最大值,最后取得1234最大值。
关于boost库的安装参照本人前边的博客。
Geolife trajectory
WGS 84
Altitude is in Feet
Reserved 3
0,2,255,My Track,0,0,2,8421376
0
39.984702,116.318417,0,492,39744.1201851852,2008-10-23,02:53:04
39.984683,116.31845,0,492,39744.1202546296,2008-10-23,02:53:10
39.984686,116.318417,0,492,39744.1203125,2008-10-23,02:53:15
39.984688,116.318385,0,492,39744.1203703704,2008-10-23,02:53:20
39.984655,116.318263,0,492,39744.1204282407,2008-10-23,02:53:25
39.984611,116.318026,0,493,39744.1204861111,2008-10-23,02:53:30
39.984608,116.317761,0,493,39744.1205439815,2008-10-23,02:53:35
39.984563,116.317517,0,496,39744.1206018519,2008-10-23,02:53:40
39.984539,116.317294,0,500,39744.1206597222,2008-10-23,02:53:45
39.984606,116.317065,0,505,39744.1207175926,2008-10-23,02:53:50
39.984568,116.316911,0,510,39744.120775463,2008-10-23,02:53:55
User.hpp:实现了操作符重载,
//
// User.hpp
// Test
//
// Created by 秦传庆 on 15/10/23.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#ifndef User_hpp
#define User_hpp
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <sstream>
namespace gregorianDate = boost::gregorian;
using namespace boost::posix_time;
using namespace std;
/*
39.984702,116.318417,0,492,39744.1201851852,2008-10-23,02:53:04
39.984683,116.31845,0,492,39744.1202546296,2008-10-23,02:53:10
39.984686,116.318417,0,492,39744.1203125,2008-10-23,02:53:15
39.984688,116.318385,0,492,39744.1203703704,2008-10-23,02:53:20
39.984655,116.318263,0,492,39744.1204282407,2008-10-23,02:53:25
39.984611,116.318026,0,493,39744.1204861111,2008-10-23,02:53:30
39.984608,116.317761,0,493,39744.1205439815,2008-10-23,02:53:35
*/
class User {
private:
double latitude;
double longitude;
int nonsense;
int altitude;
double daysince18991230;
gregorianDate::date date;
time_duration time;
//ptime date;
public:
friend ostream &operator<<(ostream &os, const User &c);
friend istream &operator>>(istream &is, User &c);
/*Java, setter and geter*/
void setLatitude(double latitude);
double getLatitude();
void setLongitude(double longitude);
double getLongitude();
void setNonsense(int nonsense);
int getNonsense();
void setAltitude(int altitude);
int getAltitude();
void setDaysince18991230(double daysince18991230);
double getDaysince18991230();
void setDate(string date);
void setDate(gregorianDate::date date);
gregorianDate::date getDate();
void setTime(string time);
void setTime(time_duration time);
time_duration getTime();
};
template<class out, class in>
out ConvertDataType(const in& a);
#endif /* User_hpp */
User.cpp
<pre name="code" class="cpp">// // User.cpp // Test // // Created by 秦传庆 on 15/10/23. // Copyright © 2015年 秦传庆. All rights reserved. // #include "User.hpp" void User::setLatitude(double latitude) { this->latitude = latitude; } double User::getLatitude() { return latitude; } void User::setLongitude(double longitude) { this->longitude = longitude; } double User::getLongitude() { return longitude; } void User::setNonsense(int nonsense) { this->nonsense = nonsense; } int User::getNonsense() { return nonsense; } void User::setAltitude(int altitude) { this->altitude = altitude; } int User::getAltitude() { return altitude; } void User::setDaysince18991230(double daysince18991230) { this->daysince18991230 = daysince18991230; } double User::getDaysince18991230() { return daysince18991230; } void User::setDate(string date) { this->setDate(gregorianDate::from_string(date)); } void User::setDate(gregorianDate::date date){ this->date = date; } gregorianDate::date User::getDate() { return date; } void User::setTime(string time) { this->setTime(duration_from_string(time)); } void User::setTime(time_duration time){ this->time = time; } time_duration User::getTime() { return time; } ostream &operator<<(ostream &out, const User &user) { ostream::fmtflags curr_fmt = out.flags(); out.precision(10); out << user.latitude << ","; out << user.longitude << ","; out << user.nonsense << ","; out << user.altitude << ","; out << user.daysince18991230 << ","; out << gregorianDate::to_simple_string(user.date) << ","; out << to_simple_string(user.time) << endl; out.flags(curr_fmt); return out; } /*char temp used to go over the ","*/ istream &operator>>(istream &in, User &user) { char temp; string temp_string; istream::fmtflags curr_fmt = in.flags(); in >> user.latitude; in >> temp; in >> user.longitude; in >> temp; in >> user.nonsense; in >> temp; in >> user.altitude; in >> temp; in >> user.daysince18991230; in >> temp; in >> temp_string; if ("" == temp_string){ return in; } size_t pos = temp_string.find_first_of(","); user.date = gregorianDate::from_string(temp_string.substr(0, pos)); user.time = duration_from_string(temp_string.substr(pos + 1, temp_string.size())); in.flags(curr_fmt); return in; }
FileIter.hpp: 实现基于boost库的文件遍历
// // FileIter.hpp // Test // // Created by 秦传庆 on 15/10/23. // Copyright © 2015年 秦传庆. All rights reserved. // #ifndef FileIter_hpp #define FileIter_hpp #include <iostream> #include <boost/filesystem.hpp> #include <algorithm> #include "Utils.hpp" using namespace std; using namespace boost::filesystem; class FileIter { private: string path; vector<string> data; public: FileIter(string path); void walk(); void walk(string path); vector<string> getVector(); friend bool compare(string file1, string file2); private: void walk(boost::filesystem::path p); }; bool compare(string file1, string file2); #endif /* FileIter_hpp */
FileIter.cpp
//
// FileIter.cpp
// Test
//
// Created by 秦传庆 on 15/10/23.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#include "FileIter.hpp"
FileIter::FileIter(string path) {
this->path = path;
}
void FileIter::walk() {
walk(path);
}
void FileIter::walk(string path) {
auto p = boost::filesystem::path(path);
walk(p);
sort(data.begin(), data.end(), compare);
//PrintVector(data);
}
void FileIter::walk(boost::filesystem::path p) {
try {
if (exists(p)) {
if (is_regular_file(p) && !boost::filesystem::is_empty(p)) {
//cout << p << " size is " << file_size(p) << '\n';
data.push_back(p.string());
}else if (is_directory(p)) {
//cout << p << " is a directory containing:\n";
for (directory_entry& x : directory_iterator(p)) {
walk(x.path());
}
}else {
cout << p << " exists, but is not a regular file or directory\n";
}
}else {
cout << p << " does not exist\n";
}
}catch (const filesystem_error& ex) {
cout << ex.what() << '\n';
}
}
vector<string> FileIter::getVector() {
return data;
}
bool compare(string file1, string file2){
file1 = file1.substr(file1.find_last_of("/") + 1, 14);
file2 = file2.substr(file2.find_last_of("/") + 1, 14);
//cout << file1 << "," << file2 << endl;
return file1 < file2;
}
Utils.hpp : 实现了一些功能调试函数,文件是否打开成功,打印容器内容,易于查看。
//
// Utils.hpp
// Test
//
// Created by 秦传庆 on 15/10/25.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#ifndef Utils_hpp
#define Utils_hpp
#define BOOST_LOG_DYN_LINK
#include <fstream>
#include <vector>
#include <iostream>
#include <sstream>
#include <boost/lexical_cast.hpp>
using namespace boost;
using namespace std;
bool FileExist(const fstream& in);
template<class out, class in>
out ConvertDataType(const in& a)
{
/*
std::stringstream temp;
temp<<a;
out b;
temp>>b;
return b;
*/
return lexical_cast<out>(a);
}
template<typename T>
void PrintVector(const vector<T>& data);
template<typename T>
string VectorToString(const vector<T>& data){
string content;
for (auto& temp : data){
content.append(ConvertDataType<std::string>(temp));
}
return content;
}
#include "TestUnit.cpp"
#endif /* Utils_hpp */
Utils.cpp
// // Utils.cpp // Test // // Created by 秦传庆 on 15/10/25. // Copyright © 2015年 秦传庆. All rights reserved. // #include "Utils.hpp" bool FileExist(fstream& in){ if (!in){ std::cerr << "unable open the file, please check it." << std::endl; return false; } return true; }
TestUnit.cpp : 模版方法打印容器内容
// // TestUnit.cpp // Test // // Created by 秦传庆 on 15/10/23. // Copyright © 2015年 秦传庆. All rights reserved. // #include <iostream> #include <vector> #include<fstream> using namespace std; template<typename T> void PrintVector(vector<T> data) { cout << "{" ; for (auto item : data) { cout << item << ","; } cout << "}" ; cout << endl; }
SpaceDistance.hpp : 实现欧式距离计算
//
// SpaceDistance.hpp
// Test
//
// Created by 秦传庆 on 15/10/25.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#ifndef SpaceDistance_hpp
#define SpaceDistance_hpp
#include "User.hpp"
#include "Utils.hpp"
#include "FileIter.hpp"
#include "Logger.hpp"
#include <iostream>
#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <boost/timer.hpp>
using namespace std;
class SpaceDistance{
private:
boost::timer time;
FileIter folder;
vector<string> file_names;
fstream file_stream;
vector<User> data_original;
vector<User> data_compare;
//vector<vector<User>> data;
istream_iterator<User> eof;
vector<string>::size_type file_number;
public:
SpaceDistance(string path);
double calculateDistance();
private:
bool checkFileNumber(){
return true;
}
vector<User> getDataFromFile(string file_name);
double calculateDistanceOfTwo();
void validateFiles();
};
#endif /* SpaceDistance_hpp */
SpaceDistance.cpp
//
// SpaceDistance.cpp
// Test
//
// Created by 秦传庆 on 15/10/25.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#include "SpaceDistance.hpp"
using namespace std;
SpaceDistance::SpaceDistance(string path):folder(path){
folder.walk();
file_names = folder.getVector();
//PrintVector(file_names);
validateFiles();
file_number = file_names.size();
}
double SpaceDistance::calculateDistance(){
double distanceOfTwo;
double maxDistance;
string msg;
if (!checkFileNumber()){
return 0.0;
}
vector<double> distance;
/*
for (auto fileName:file_names){
data.push_back(getDataFromFile(fileName));
}
*/
for (auto i = 0; i < file_number - 1; i++) {
time.restart();
data_original = getDataFromFile(file_names[i]);
//data_original = data[i];
for (auto j = i + 1; j < file_number; j++){
data_compare = getDataFromFile(file_names[j]);
//data_compare = data[j];
distanceOfTwo = calculateDistanceOfTwo();
distance.push_back(distanceOfTwo);
//info_log(file_names[i]);
msg.clear();
msg.append(file_names[i]);
msg.append(",");
msg.append(file_names[j]);
msg.append(":");
msg.append(ConvertDataType<std::string>(distanceOfTwo));
BOOST_LOG_FUNCTION();
info_log(msg);
}
msg.clear();
msg.append("Time elapesd: ");
msg.append(ConvertDataType<std::string>(time.elapsed()));
BOOST_LOG_FUNCTION();
info_log(msg);
}
//PrintVector(distance);
//BOOST_LOG_FUNCTION();
maxDistance = *max_element(distance.begin(), distance.end());
//info_log(maxDistance);
return maxDistance;
}
vector<User> SpaceDistance::getDataFromFile(string file_name){
file_stream.open(file_name.c_str(), fstream::in);
if (!FileExist(file_stream)) {
return vector<User>();
}
string temp;
/*
* below for cycle will go over 6 lines in each file.
*/
for(int i = 0; i < 6; i++){
getline(file_stream, temp);
}
istream_iterator<User> item_iter(file_stream);
vector<User> data(item_iter, eof);
file_stream.close();
file_stream.clear();
return data;
}
double SpaceDistance::calculateDistanceOfTwo(){
/*
* here do math of the gero.
*/
vector<double> data;
vector<double> temp;
//auto length = data_original.size() > data_compare.size()? data_compare.size():data_original.size();
double x_original;
double y_original;
double x_compare;
double y_compare;
auto original_length = data_original.size();
auto compare_length = data_compare.size();
for (auto i = 0; i < original_length; i++){
x_original = data_original[i].getLongitude();
y_original = data_original[i].getLatitude();
temp.clear();
for (auto j = 0; j < compare_length; j++){
x_compare = data_compare[j].getLongitude();
y_compare = data_compare[j].getLatitude();
temp.push_back(sqrt(pow((x_original - x_compare), 2) + pow((y_original - y_compare), 2)));
}
//PrintVector(temp);
data.push_back(*max_element(temp.begin(), temp.end()));
}
//PrintVector(data);
//BOOST_LOG_FUNCTION();
//info_log(VectorToString(data));
return *max_element(data.begin(), data.end());
}
void SpaceDistance::validateFiles(){
string extension_string = ".plt";
for (auto iter = file_names.begin(); iter != file_names.end();){
if (extension_string != (*iter).substr((*iter).size() - extension_string.size(), extension_string.size())){
file_names.erase(iter);
} else {
iter++;
}
}
}Logger.hpp 日志记录系统
//
// Logger.hpp
// Test
//
// Created by 秦传庆 on 15/11/2.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#ifndef Logger_hpp
#define Logger_hpp
#define BOOST_LOG_DYN_LINK
#include <iostream>
#include <fstream>
#include <boost/log/expressions.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/core/null_deleter.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/attributes/named_scope.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/detail/format.hpp>
#include <boost/log/detail/thread_id.hpp>
namespace logging = boost::log;
namespace sinks = boost::log::sinks;
namespace src = boost::log::sources;
namespace expr = boost::log::expressions;
namespace attrs = boost::log::attributes;
namespace keywords = boost::log::keywords;
using namespace logging::trivial;
using namespace std;
class Logger {
public:
static void init();
};
template<class T>
void trace_log(const T& content) {
src::severity_logger<severity_level> lg;
BOOST_LOG_SEV(lg, logging::trivial::trace) << content;
}
template<class T>
void debug_log(const T& content) {
src::severity_logger<severity_level> lg;
BOOST_LOG_SEV(lg, logging::trivial::debug) << content;
}
template<class T>
void info_log(const T& content) {
src::severity_logger<severity_level> lg;
BOOST_LOG_SEV(lg, logging::trivial::info) << content;
}
template<class T>
void warning_log(const T& content) {
src::severity_logger<severity_level> lg;
BOOST_LOG_SEV(lg, logging::trivial::warning) << content;
}
template<class T>
void error_log(const T& content) {
src::severity_logger<severity_level> lg;
BOOST_LOG_SEV(lg, logging::trivial::error) << content;
}
template<class T>
void fatal_log(const T& content) {
src::severity_logger<severity_level> lg;
BOOST_LOG_SEV(lg, logging::trivial::fatal) << content;
}
#endif /* Logger_hpp */
Logger.cpp
//
// Logger.cpp
// Test
//
// Created by 秦传庆 on 15/11/2.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#include "Logger.hpp"
void Logger::init() {
typedef sinks::synchronous_sink<sinks::text_ostream_backend> text_sink;
boost::shared_ptr<text_sink> sink = boost::make_shared< text_sink >();
boost::shared_ptr<std::ostream> stream(&std::clog, boost::null_deleter());
sink->locked_backend()->add_stream(stream);
auto pSink = logging::add_file_log
(
keywords::file_name = "/Users/qinchuanqing/Downloads/000/sample_%N.log",
keywords::rotation_size = 10 * 1024 * 1024,
keywords::time_based_rotation = sinks::file::rotation_at_time_point(0, 0, 0),
//keywords::format = "[%LineID%][%TimeStamp%]: %Message%"
keywords::format =
(
expr::stream
<< "[" << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d %H:%M:%S.%f")
<< " " << expr::format_named_scope("Scope", keywords::format = "%f:%l]")
<< "<" << logging::trivial::severity
<< "> " << expr::smessage
)
);
logging::core::get()->set_filter
(
logging::trivial::severity >= logging::trivial::trace
);
logging::core::get()->add_sink(sink);
pSink->locked_backend()->auto_flush(true);//使日志实时更新
logging::core::get()->add_global_attribute("Scope", attrs::named_scope());
logging::add_common_attributes();
}
main.cpp : 主测试函数:
//
// main.cpp
// Test
//
// Created by 秦传庆 on 15/10/23.
// Copyright © 2015年 秦传庆. All rights reserved.
//
#include "SpaceDistance.hpp"
#include <time.h>
using namespace std;
int main() {
Logger::init();
time_t t_start, t_end;
t_start = time(NULL);
SpaceDistance distance("/Users/qinchuanqing/Downloads/000/Trajectory");
double max_distance = distance.calculateDistance();
BOOST_LOG_FUNCTION();
string msg = "Max number is: ";
msg.append(ConvertDataType<string>(max_distance));
info_log(msg);
msg = "Total time is: ";
t_end = time(NULL);
msg.append(ConvertDataType<string>(difftime(t_end,t_start)));
msg.append(" seconds");
BOOST_LOG_FUNCTION();
trace_log(msg);
return 0;
}
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- boost相关小知识(长期顶置更新)
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- 解析C++中派生的概念以及派生类成员的访问属性