├── README.md ├── batch ├── DP │ ├── 20081023025304-0.csv │ ├── 20081023025304-0.plt │ ├── DP │ ├── DP.cpp │ └── DP.sh ├── DPTS │ ├── 20090330005208.plt │ ├── Makefile │ ├── ReadMe.txt │ ├── config.txt │ └── src │ │ ├── RN_appro.cpp │ │ ├── RN_appro.h │ │ ├── b_heap.cpp │ │ ├── b_heap.h │ │ ├── bst.cpp │ │ ├── bst.h │ │ ├── cact.cpp │ │ ├── cact.h │ │ ├── data_struct.h │ │ ├── data_utility.cpp │ │ ├── data_utility.h │ │ ├── main.cpp │ │ ├── min_error.cpp │ │ └── min_error.h ├── DPhull │ ├── .gps_reader.py.swp │ ├── 20081023025304-0.csv │ ├── 20081023025304-0.plt │ ├── DP.c │ ├── DP.h │ ├── DP.o │ ├── DPhull.c │ ├── DPhull.o │ ├── DPhull.py │ ├── DPhull.sh │ ├── DPhullfast.c │ ├── Makefile │ ├── PH.c │ ├── PH.h │ ├── PH.o │ ├── animate.c │ ├── animate.h │ ├── animate.o │ ├── core.txt │ ├── hull │ ├── nonrec │ ├── nonrec.c │ └── nonrec.o ├── MRPA │ ├── GPStraj_TS.m │ ├── PA_minMSED_tree.m │ ├── PA_minNSED_init.m │ ├── PA_mineSED_CRSDP.m │ ├── PreProc_genDataset.m │ ├── TDMRPA_SED.m │ ├── build_heap.m │ ├── calc_ISSED_pathpt.m │ ├── calc_LISE_SED.m │ ├── calc_TSperf_time.m │ ├── demo1.m │ ├── eval_mopsi_walknowalk.m │ ├── get_cumsumval_SED.m │ ├── heap_elementadd.m │ ├── heap_elementdel.m │ ├── heap_elementreplace.m │ ├── hp_elementadd.m │ ├── hp_elementdel.m │ ├── hp_elementreplace.m │ ├── intro.txt │ ├── measure_sed2.m │ ├── mercator_proj.m │ ├── r6.txt │ ├── readdata.m │ └── unixtime.m ├── MinError │ ├── DPTS │ ├── Makefile │ ├── ReadMe.txt │ ├── config.txt │ ├── data │ │ ├── 20090330005208.plt │ │ └── 2237.txt │ ├── src │ │ ├── RN_appro.cpp │ │ ├── RN_appro.h │ │ ├── b_heap.cpp │ │ ├── b_heap.h │ │ ├── bst.cpp │ │ ├── bst.h │ │ ├── data_struct.h │ │ ├── data_utility.cpp │ │ ├── data_utility.h │ │ ├── main.cpp │ │ ├── min_error.cpp │ │ ├── min_error.h │ │ ├── wavelet.cpp │ │ └── wavelet.h │ └── stat.txt └── TD-TR │ ├── 20081023025304-0.csv │ ├── 20081023025304-0.plt │ ├── TD-TR │ ├── TD-TR.cpp │ └── TD-TR.sh ├── lossless └── trajic │ ├── .gitignore │ ├── .travis.yml │ ├── COPYING │ ├── Doxyfile │ ├── Makefile │ ├── README.md │ ├── clustering │ ├── README.md │ └── trajstoreClustering.scala │ ├── experiments │ ├── common.rb │ ├── process_clusters.rb │ ├── run_error_vs_ratio.rb │ ├── run_full.rb │ ├── run_predictors.rb │ ├── run_size_vs_time.rb │ └── run_time_vs_ratio.rb │ ├── src │ ├── compressor.h │ ├── constant_predictor.cpp │ ├── constant_predictor.h │ ├── csv_reader.cpp │ ├── csv_reader.h │ ├── delta_compressor.cpp │ ├── delta_compressor.h │ ├── dp_compressor.cpp │ ├── dp_compressor.h │ ├── dummy_compressor.cpp │ ├── dummy_compressor.h │ ├── dynamic_encoder.cpp │ ├── dynamic_encoder.h │ ├── encoder.h │ ├── gps_point.cpp │ ├── gps_point.h │ ├── gps_reader.h │ ├── huffman.cpp │ ├── huffman.h │ ├── ibstream.cpp │ ├── ibstream.h │ ├── illinois_reader.cpp │ ├── illinois_reader.h │ ├── len_freq_div.cpp │ ├── len_freq_div.h │ ├── linear_predictor.cpp │ ├── linear_predictor.h │ ├── main.cpp │ ├── naive_linear_predictor.cpp │ ├── naive_linear_predictor.h │ ├── obstream.cpp │ ├── obstream.h │ ├── plt_reader.cpp │ ├── plt_reader.h │ ├── predictive_compressor.cpp │ ├── predictive_compressor.h │ ├── predictor.h │ ├── read_points.h │ ├── run_predictors.cpp │ ├── squish_compressor.cpp │ ├── squish_compressor.h │ ├── stats.cpp │ ├── util.cpp │ └── util.h │ └── test │ ├── test.cpp │ └── test.h └── online ├── .DS_Store ├── Angular ├── 20081023025304-0.plt ├── Angular$Point.class ├── Angular.class ├── Angular.java └── run.sh ├── BQS ├── 20081023025304-0.plt ├── BQS.sh ├── amnesic_bubbling.py ├── csvfile_read.py ├── csvfile_read.pyc ├── curve_approximation.py ├── curve_approximation.pyc ├── curve_test.py ├── curve_test.pyc ├── qs_p_to_seg.py ├── qs_p_to_seg.pyc ├── utils.py └── utils.pyc ├── CDR ├── 1.txt ├── 20090422023859-0.plt ├── CDR.cpp ├── CDR.sh └── CDR_my ├── DOTS ├── AlgorithmComparison.cpp ├── AlgorithmComparison.h ├── DotsException.cpp ├── DotsException.h ├── DotsSimplifier.cpp ├── DotsSimplifier.h ├── DouglasPeuckerBatchSimplifier.cpp ├── DouglasPeuckerBatchSimplifier.h ├── Helper.cpp ├── Helper.h ├── PersistenceBatchSimplifier.cpp ├── PersistenceBatchSimplifier.h ├── SquishBatchSimplifier.cpp ├── SquishBatchSimplifier.h ├── dots.pro ├── main.cpp ├── mainwindow.cpp ├── mainwindow.h ├── mainwindow.ui ├── psimpl │ └── psimpl.h ├── qcustomplot │ ├── qcustomplot.cpp │ └── qcustomplot.h └── r6.txt ├── Dead_Reckoning ├── 20081023025304-0.csv ├── 20081023025304-0.plt ├── Dead_Reckoning ├── Dead_Reckoning.cpp └── Dead_Reckoning.sh ├── FBQS ├── 20081023025304-0.plt ├── FBQS.sh ├── amnesic_bubbling.py ├── csvfile_read.py ├── csvfile_read.pyc ├── curve_approximation.py ├── curve_approximation.pyc ├── curve_test.py ├── curve_test.pyc ├── qs_p_to_seg.py ├── qs_p_to_seg.pyc ├── utils.py └── utils.pyc ├── Interval ├── 20081023025304-0.plt ├── Interval$Point.class ├── Interval$Range.class ├── Interval.class ├── Interval.java └── run.sh ├── OPERB ├── .classpath ├── .project ├── .settings │ ├── org.eclipse.core.resources.prefs │ ├── org.eclipse.core.runtime.prefs │ └── org.eclipse.jdt.core.prefs ├── 20081023025304-0.plt ├── BasicOPERP.class ├── BasicOPERP.java ├── GPSCompLine.class ├── GPSCompLine.java ├── GPSLine.class ├── GPSLine.java ├── GPSPoint.class ├── GPSPoint.java ├── OPERB.class ├── OPERB.java ├── OPERB.sh ├── SectorBound.java ├── TestOPERB.java ├── TrajectoryCompressor.class └── TrajectoryCompressor.java ├── OPW-TR ├── .OPW-TR.py.swp ├── .temp.sh.swp ├── 20081023025304-0.csv ├── 20081023025304-0.plt ├── OPW-TR ├── OPW-TR.sh └── OPW_TR.cpp ├── OPW ├── .normal_ow.py.swp ├── .normal_ow_all.sh.swp ├── 20081023025304-0.csv ├── 20081023025304-0.plt ├── OPW ├── OPW.cpp └── OPW.sh ├── SQUISH-E ├── 20081023025304-0.csv ├── 20081023025304-0.plt ├── 20081023025304-0.txt ├── SQUISH-E.sh ├── SQUISH_E └── SQUISH_E.cpp ├── SQUISH ├── .SQUISH.py.swp ├── 20081023025304-0.csv ├── 20081023025304-0.plt ├── SQUISH ├── SQUISH.cpp └── SQUISH.sh ├── STTrace ├── 20081023025304-0.csv ├── 20081023025304-0.plt ├── STTrace ├── STTrace.cpp └── STTrace.sh ├── Threshold ├── 20081023025304-0.csv ├── 20081023025304-0.plt ├── Threshold ├── Threshold.cpp └── Threshold.sh └── Uniform ├── 20081023025304-0.csv ├── 20081023025304-0.plt ├── Uniform ├── Uniform.cpp └── Uniform.sh /README.md: -------------------------------------------------------------------------------- 1 | # traj-compression 2 | The source code was use for the empirical study of trajectory compression ,"Trajectory Simplification: An Experimental Study andQuality Analysis" 3 | # lossless algorithms 4 | 1. TrajStore algorithm 5 | 2. Trajic algorithm 6 | # Trajectory Simplification in Batch Mode 7 | 1. DP algorithm 8 | 2. DPhull algorithm 9 | 3. TD-TR algorithm 10 | 4. MRPA algorithm 11 | 5. SP algorithm 12 | 6. Intersect algorithm 13 | 7. Error-Search algorithm 14 | 8. Span-Search algorithm 15 | # Trajectory Simplification in Online Mode 16 | 1. Unifrom algorithm 17 | 2. OPW algorithm 18 | 3. OPW-TR algorithm 19 | 4. Dead Reckoning algorithm 20 | 5. Threshold algorithm 21 | 6. STTrace algorithm 22 | 7. SQUISH algorithm 23 | 8. CDR algorithm 24 | 9. SQUISH-E(λ) algorithm 25 | 10. SQUISH-E(μ) algorithm 26 | 11. Persistene algorithm 27 | 12. BQS algorithm 28 | 13. FBQS algorithm 29 | 14. Angular algorithm 30 | 15. Interval algorithm 31 | 16. DOTS algorithm 32 | 17. OPERB algorithm 33 | # Usage: 34 | # 1. lossless alorithms 35 | a. cd lossless/trajic 36 | b. make all,run the test and produces both the trajic and stats binaries (the latter of which is used for running experiments). 37 | c. chmod +x Trajic.sh/TrajStore.sh 38 | d. ./Trajic.sh or TrajStore.sh 39 | 40 | # 2. Trajectory Simplification in Batch Mode 41 | a. SP,Intersect in batch/DPTS,make,./DPTS 42 | b. Error-Search,Span-Search in batch/MinError,make,./DPTS 43 | c. DP,DPhull,TD-TR,just chmod +x algorithm.sh,./algorithm.sh 44 | d. MRPA,matlab,demo1 45 | 46 | # 3. Trajectory Simplification in Online Mode 47 | a. Uniform,OPW,OPW-TR,Dead Reckoning,Threshold,STTrace,SQUISH,BQS,FBQS,Angular,Interval,OPERB,just chmod algorithm.sh,then ./algorithm 48 | b. DOTS and Persistene,you need run them in QT IDE. 49 | c. CDR,make,and chmod +x CDR.sh,finally ./CDR.sh. 50 | d. The source code of SQUISH-E(λ),SQUISH-E(μ) are in SQUISH-E dirname,when the parameter ratio = 1,the compression result of SQUISH-E(μ);when the parameter sed = 0,the result is SQUISH-E(λ) algorithm. 51 | 52 | -------------------------------------------------------------------------------- /batch/DP/DP: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uestc-db/traj-compression/784f098180c39152609331b5f1ee4dae373b60a1/batch/DP/DP -------------------------------------------------------------------------------- /batch/DP/DP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "sys/time.h" 8 | #include 9 | using namespace std; 10 | typedef struct Point{ 11 | double lat; 12 | double lon; 13 | double time; 14 | }Point; 15 | vector points; 16 | void gpsreader(string filename){ 17 | ifstream fin(filename.c_str()); 18 | if (!fin){ 19 | cout << "open file error !" << endl; 20 | exit(0); 21 | } 22 | while (fin){ 23 | string line; 24 | getline(fin, line); 25 | stringstream sin(line); 26 | double lat, lon, time; 27 | struct Point point; 28 | sin >> point.lat; 29 | sin >> point.lon; 30 | sin >> point.time; 31 | points.push_back(point); 32 | 33 | } 34 | points.pop_back(); 35 | return; 36 | } 37 | double cacl_PED(Point s, Point m, Point e){ 38 | 39 | 40 | double A = e.lon - s.lon; 41 | double B = s.lat - e.lat; 42 | double C = e.lat * s.lon - s.lat * e.lon; 43 | if (A == 0 && B == 0) 44 | return 0; 45 | double shortDist = fabs((A * m.lat + B * m.lon + C) / sqrt(A * A + B * B)); 46 | return shortDist; 47 | } 48 | vector DouglasPeucker(int start, int last, double epsilon){ 49 | 50 | double dmax = 0; 51 | int index = start; 52 | vector recResults; 53 | for (int i = start + 1; i < last; i++){ 54 | double d = cacl_PED(points[start], points[i], points[last]); 55 | if (d > dmax){ 56 | index = i; 57 | dmax = d; 58 | } 59 | } 60 | if (dmax > epsilon){ 61 | vector recResults1 = DouglasPeucker(start, index, epsilon); 62 | vector recResults2 = DouglasPeucker(index, last, epsilon); 63 | recResults.insert(recResults.end(), recResults1.begin(), recResults1.end()); 64 | recResults.insert(recResults.end(), recResults2.begin(), recResults2.end()); 65 | } 66 | else{ 67 | recResults.push_back(start); 68 | recResults.push_back(last); 69 | } 70 | 71 | 72 | return recResults; 73 | 74 | } 75 | 76 | int main(int argc, char** args){ 77 | string filename = args[1]; 78 | double epsilon = atof(args[2]); 79 | char* save_filename = args[3]; 80 | gpsreader(filename); 81 | struct timeval start,end; 82 | /* 83 | for (int i = 0; i < points.size(); i++) 84 | printf("%lf %lf %lf\n",points[i].lat,points[i].lon,points[i].time); 85 | */ 86 | gettimeofday(&start, NULL ); 87 | vector cmp_index = DouglasPeucker(0, points.size() - 1, epsilon); 88 | gettimeofday(&end, NULL ); 89 | long timeuse =1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec; 90 | sort(cmp_index.begin(), cmp_index.end()); 91 | cmp_index.erase(unique(cmp_index.begin(), cmp_index.end()), cmp_index.end()); 92 | // save to file 93 | FILE* s_fp= fopen(save_filename,"w+"); 94 | for (int i = 0; i < cmp_index.size(); i++) 95 | fprintf(s_fp,"%lf %lf %lf\n",points[cmp_index[i]].lat,points[cmp_index[i]].lon,points[cmp_index[i]].time); 96 | fprintf(s_fp,"%lf\n",timeuse /1000000.0); 97 | fclose(s_fp); 98 | } 99 | -------------------------------------------------------------------------------- /batch/DP/DP.sh: -------------------------------------------------------------------------------- 1 | g++ DP.cpp -o DP 2 | ./DP 20081023025304-0.plt 0.0001 20081023025304-0.csv 3 | -------------------------------------------------------------------------------- /batch/DPTS/Makefile: -------------------------------------------------------------------------------- 1 | 2 | DPTS: ./src/*.h ./src/*.cpp 3 | g++ -g ./src/*.h ./src/*.cpp -o DPTS 4 | -------------------------------------------------------------------------------- /batch/DPTS/ReadMe.txt: -------------------------------------------------------------------------------- 1 | 2 | Before you use this code, you should know 3 | ======================= 4 | 1. This code was used for the empirical study of the VLDB'2013 paper 5 | "Direction-Preserving Trajectory Simplification". 6 | 1. This code is developed by Cheng Long (clong@cse.ust.hk). 7 | 2. This code is written in C/C++. 8 | 3. This code runs under Unix/Linux. 9 | 4. In case that you encounter any problems when using this code, 10 | please figure out the problem by yourself 11 | (The code in fact is easy to read and you can modify it for your own purpose). 12 | 13 | Usage 14 | ======================= 15 | 16 | Step 1: specify the data input information. 17 | 19 | 20 | Step 2: compile the source code 21 | make 22 | 23 | Step 3: Run the code 24 | ./DPTS 25 | 26 | Step 4: Collect running statistics 27 | [you can ignore this step if you don't want to collect this information] 28 | 29 | The running statistics are stored in "stat.txt" 30 | which format is explained in Appendix II. 31 | 32 | 33 | 34 | 35 | Appendix 36 | 37 | I. The format of Config.txt 38 | ======================= 39 | 40 | 41 | <# of the positions in the trajectory> 42 | 43 | 44 | 45 | 46 | Explanation of the content in config.txt 47 | ----------------------- 48 | 49 | : 50 | The file that contains the trajectory. 51 | (the supported formats are those of Geolife and T-Drive, 52 | and to support your own data format, you should modify the "data reading" part of function DPTS by yourself) 53 | 54 | <#positions>: 55 | The number of positions in the trajectory. 56 | 57 | : 58 | The error tolerance of the DPTS problem. 59 | 60 | 61 | = 0: the basic DP 62 | = 1: the enhanced DP 63 | = 2: the basic SP 64 | = 3: the SP with the theoretical enhancement only 65 | = 4: the SP with the practical enhancement only 66 | = 5: the SP with the both enhancements 67 | = 6: the Intersect algorithm 68 | = 7: the Split algorithm 69 | = 8: the Merge algorithm 70 | = 9: the Greedy algorithm 71 | 72 | 73 | = 1: the dataset is the Geolife dataset; 74 | = 2: the dataset is the T-Drive dataset. 75 | 76 | (See file config.txt in the folder for example) 77 | 78 | 79 | II. The format of 80 | ============================= 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /batch/DPTS/config.txt: -------------------------------------------------------------------------------- 1 | 20090330005208.plt 100 1 6 1 -------------------------------------------------------------------------------- /batch/DPTS/src/b_heap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Cheng Long 3 | * Email: clong@cse.ust.hk 4 | */ 5 | 6 | 7 | 8 | /* 9 | * 1. The mechanism of "cmp" function and the "void*" type involved there. 10 | * 2. The choice min-heap or max-heap can be determined by changing the function of "cmp". 11 | * 3. The heap array's subscript starts from zero. 12 | * 4. The concept of "heap array" and "object array", which work collaborarily. 13 | * 14 | * 5. [Updated on 17 Feb. 2012] 15 | * (a). Variable MIN_HEAP_OPT is variable for specifying min-heap or max-heap. 16 | * (b). Object type should maintain an element 'key' for the heap structure. 17 | */ 18 | 19 | 20 | #ifndef B_HEAP_H 21 | #define B_HEAP_H 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "data_struct.h" 28 | #include "data_utility.h" 29 | 30 | 31 | #define B_CONFIG_FILE "b_config.txt" 32 | #define MAX_FILENAME_LENG 256 33 | #define FLOAT float 34 | 35 | //#define MIN_HEAP_OPT 0 36 | 37 | extern int MIN_HEAP_OPT; 38 | 39 | /* 40 | #define B_INPUT_FILE "b_input.txt" 41 | #define B_OUTPUT_FILE "b_output.txt" 42 | */ 43 | 44 | extern emp_stat_t emp_stat_v; 45 | 46 | //The structure of the object that indexed by the binary heap. 47 | typedef struct h_obj 48 | { 49 | int id; 50 | int loc; 51 | 52 | //object-specific variables. 53 | float key; //The key of the heap. 54 | 55 | //For the Merge algorithm. 56 | group_node_t* group_node_v; 57 | 58 | //For the Dogoulas-Peucker algorithm. 59 | part_node_t* part_node_v; 60 | 61 | int pre; 62 | int next; 63 | 64 | //For Merge-Error. 65 | R_node_t* R_node_v_sta; 66 | R_node_t* R_node_v_end; 67 | // R_node_t* R_node_v_sta2; 68 | // R_node_t* R_node_v_end2; 69 | 70 | //For Merge-Span. 71 | span_m_t span_m_v; 72 | 73 | //For Merge-Span2 (only) 74 | R_node_t* R_node_v_sta1; 75 | R_node_t* R_node_v_end1; 76 | 77 | //For Span-Search. 78 | 79 | 80 | } h_obj_t; 81 | 82 | 83 | //The structure of the node of a heap. 84 | typedef struct b_heap 85 | { 86 | int size; //the heap's size. 87 | int rear; //the heap's rear tag. 88 | h_obj_t* obj_arr; //the object array. 89 | int* h_arr; //the heap array. 90 | 91 | //For empirical study. 92 | float m_size; 93 | 94 | } b_heap_t; 95 | 96 | 97 | 98 | //------------------------------------- 99 | 100 | //int cmp( const void* obj_v, int fir, int sec); 101 | 102 | int cmp_min( int* array, int n1, int n2, h_obj_t* obj_v); 103 | 104 | int cmp_max( int* array, int n1, int n2, h_obj_t* obj_v); 105 | 106 | //------------------------------------- 107 | 108 | b_heap_t* alloc_b_heap( int size); 109 | 110 | void release_b_heap( b_heap_t* b_h); 111 | 112 | void b_t_heapify( int* array, int cur, h_obj_t* obj_v); 113 | 114 | void t_b_heapify( int* array, int cur, int rear, h_obj_t* obj_v); 115 | 116 | int insert_b_heap( b_heap_t* b_h, int n); 117 | 118 | int get_top( b_heap_t* b_h); 119 | 120 | void update_key( b_heap_t* b_h, int k); 121 | 122 | //------------------------------------- 123 | 124 | 125 | void print_b_heap( FILE* o_fp, b_heap_t* b_h); 126 | 127 | void test_b_heap( ); 128 | 129 | 130 | #endif -------------------------------------------------------------------------------- /batch/DPTS/src/bst.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Cheng Long 3 | * Email: clong@cse.ust.hk 4 | */ 5 | 6 | 7 | /* 8 | * 1. The implementation of the binary search tree follows pseudo-code in the textbook "Introduction to Algorithms". 9 | */ 10 | 11 | #ifndef BST_H 12 | #define BST_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "data_utility.h" 21 | 22 | #define KEY_TYPE float 23 | 24 | extern emp_stat_t emp_stat_v; 25 | 26 | /*The structure of the node in bst.*/ 27 | typedef struct bst_node 28 | { 29 | KEY_TYPE key; 30 | 31 | //For Span-Search 32 | int range_inx; 33 | 34 | struct bst_node* p; 35 | struct bst_node* left; 36 | struct bst_node* right; 37 | 38 | } bst_node_t; 39 | 40 | /*The structure of a bst.*/ 41 | typedef struct bst 42 | { 43 | bst_node_t* root; 44 | 45 | //Problem specific information. 46 | int node_n; 47 | 48 | KEY_TYPE min; 49 | KEY_TYPE max; 50 | 51 | //For empirical study. 52 | float m_size; 53 | 54 | //For span-search 55 | //bst_node_t* min_node; 56 | //bst_node_t* max_node; 57 | 58 | } bst_t; 59 | 60 | 61 | bst_t* bst_ini( ); 62 | 63 | void bst_release_sub( bst_node_t* x); 64 | 65 | void bst_release( bst_t* T); 66 | 67 | void bst_insert( bst_t* T, bst_node_t* z); 68 | 69 | bst_node_t* bst_insert_key( bst_t* bst_v, KEY_TYPE key); 70 | 71 | void bst_transplant( bst_t* T, bst_node_t* u, bst_node_t* v); 72 | 73 | bst_node_t* bst_min( bst_node_t* x); 74 | 75 | bst_node_t* bst_max( bst_node_t* x); 76 | 77 | void bst_delete( bst_t* T, bst_node_t* z); 78 | 79 | void in_order_walk( bst_node_t* x); 80 | 81 | bst_node_t* bst_successor( bst_node_t* x); 82 | 83 | bst_node_t* bst_predecessor( bst_node_t* x); 84 | 85 | void test_bst( ); 86 | 87 | 88 | #endif -------------------------------------------------------------------------------- /batch/DPTS/src/cact.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Cheng Long 3 | * Email: clong@cse.ust.hk 4 | */ 5 | 6 | 7 | 8 | /* 9 | * The implementation of the Clue-Aware Trajectory Clustering Algorithm (CATC) in 10 | * "Clustering and aggregating clues of trajectories for mining trajectory patterns and routes" by Chih-Chieh Hung et al. 11 | * 12 | * By Cheng Long, April 2013. 13 | * clong@cse.ust.hk. 14 | * 15 | */ 16 | 17 | 18 | #ifndef CACT_H 19 | #define CACT_H 20 | 21 | 22 | //#include "data_struct.h" 23 | #include "RN_appro.h" 24 | 25 | 26 | #define CATS_CONFIG "cats_config.txt" 27 | 28 | 29 | 30 | //The data structure for storing a set of trajectories. 31 | typedef struct tra_set 32 | { 33 | int tra_n; 34 | tra_list_t** tra_array; 35 | 36 | } tra_set_t; 37 | 38 | 39 | //The data structure for storing a clue_graph. 40 | typedef struct c_graph 41 | { 42 | int num; 43 | float** matrix; 44 | 45 | } c_graph_t; 46 | 47 | 48 | //The data structure for storing a stronly 49 | typedef struct sc_graph 50 | { 51 | int num; 52 | int** matrix; 53 | 54 | } sc_graph_t; 55 | 56 | 57 | //The data structure for storing a clique. 58 | typedef struct c_node 59 | { 60 | int id; 61 | struct c_node* next; 62 | 63 | } c_node_t; 64 | 65 | typedef struct c_list 66 | { 67 | int size; 68 | c_node_t* head; 69 | // c_node_t* rear; 70 | 71 | } c_list_t; 72 | 73 | 74 | //The data structure for storing a cluster candidate, which is a set of cliques. 75 | typedef struct clus_node 76 | { 77 | c_list_t* clique; 78 | struct clus_node* next; 79 | 80 | } clus_node_t; 81 | 82 | 83 | typedef struct clus_list 84 | { 85 | int size; 86 | clus_node_t* head; 87 | clus_node_t* rear; 88 | 89 | } clus_list_t; 90 | 91 | 92 | //The data structure for storing a set of clusters. 93 | typedef struct clus_set 94 | { 95 | int clus_n; 96 | int tra_n; 97 | clus_list_t** clus_array; 98 | 99 | } clus_set_t; 100 | 101 | tra_set_t* tra_set_alloc( int tra_n); 102 | 103 | void tra_set_release( tra_set_t* tra_set_v); 104 | 105 | float calc_f_eps( loc_t* loc_v1, loc_t* loc_v2, float eps); 106 | 107 | float calc_score_eps_tau( tra_node_t* tra_node_v, tra_list_t* tra_list_v, float eps, float tau); 108 | 109 | float calc_cats( tra_list_t* tra_list_v1, tra_list_t* tra_list_v2, float eps, float tau); 110 | 111 | c_graph_t* c_graph_alloc( int tra_n); 112 | 113 | void c_graph_release( c_graph_t* c_graph_v); 114 | 115 | c_graph_t* clue_graph_gen( tra_set_t* tra_set_v, float lambda, float eps, float tau); 116 | 117 | sc_graph_t* sc_graph_alloc( int tra_n); 118 | 119 | void sc_graph_release( sc_graph_t* sc_graph_v); 120 | 121 | void c_list_release( c_list_t* c_list_v); 122 | 123 | c_list_t* c_list_alloc( ); 124 | 125 | clus_list_t* clus_list_alloc( ); 126 | 127 | void clus_list_release( clus_list_t* clus_list_v); 128 | 129 | sc_graph_t* strong_clue_graph_gen( c_graph_t* c_graph_v); 130 | 131 | clus_list_t* comp_clique_cover( sc_graph_t* sc_graph_v); 132 | 133 | float comp_CCOH( clus_list_t* clus_list_v, c_graph_t* c_graph_v, float lambda); 134 | 135 | float comp_CSEP( clus_list_t* clus_list_v1, clus_list_t* clus_list_v2, c_graph_t* c_graph_v); 136 | 137 | float comp_benefit( clus_list_t* clus_list_v1, clus_list_t* clus_list_v2, c_graph_t* c_graph_v, float lambda); 138 | 139 | clus_set_t* clus_set_alloc( int clus_n); 140 | 141 | void clus_set_release( clus_set_t* clus_set_v); 142 | 143 | clus_set_t* cats( tra_set_t* tra_set_v, float eps, float tau, float lambda); 144 | 145 | void emp_cats( ); 146 | 147 | void collect_statistics_clustering_datasets( ); 148 | 149 | #endif 150 | -------------------------------------------------------------------------------- /batch/DPTS/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Cheng Long 3 | * Email: clong@cse.ust.hk 4 | */ 5 | 6 | 7 | 8 | 9 | #include "RN_appro.h" 10 | #include "cact.h" 11 | #include "min_error.h" 12 | 13 | stat_t stat_v; 14 | emp_stat_t emp_stat_v; 15 | 16 | int MIN_HEAP_OPT; 17 | 18 | int main( ) 19 | { 20 | 21 | //real_data_preprocess( ); 22 | 23 | //test2( ); 24 | 25 | //test_bst( ); 26 | 27 | //test_RN_simplify( ); 28 | 29 | //collect_non_passing_stat( ); 30 | 31 | #ifndef WIN32 32 | //combine_files( 2); 33 | 34 | //prepare_cluster_data_v1( ); 35 | 36 | //compress_data_set( ); 37 | 38 | //compress_data_set_v2( ); 39 | 40 | //collect_statistics( ); 41 | #endif 42 | 43 | //collect_statistics_clustering_datasets( ); 44 | 45 | //printf( "%lf\n", pow( 0, 2)); 46 | 47 | emp_DPTS( ); 48 | 49 | //emp_DPTS_v2( ); 50 | 51 | //emp_cats( ); 52 | 53 | //prepare_cluster_data_v2( ); 54 | 55 | //collect_clustering_measures( ); 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /batch/DPTS/src/min_error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Cheng Long 3 | * Email: clong@cse.ust.hk 4 | */ 5 | 6 | 7 | 8 | #ifndef MIN_ERROR_H 9 | #define MIN_ERROR_H 10 | 11 | 12 | #include "RN_appro.h" 13 | 14 | 15 | extern emp_stat_t emp_stat_v; 16 | 17 | //Starting from 17 July, 2013. 18 | //New APIs for the Min-Error problem. 19 | 20 | error_space_t* error_space_alloc( int pos_n); 21 | 22 | void error_space_release( error_space_t* error_space_v); 23 | 24 | //The DP algorithm. 25 | error_space_t* const_error_space_v1( R_list_t* R_list_v); 26 | 27 | float find_closest_slope( bst_t* bst_v, float slope_v); 28 | 29 | float calc_max_angular_diff( bst_t* bst_v, float slope_v); 30 | 31 | error_space_t* const_error_space_v2( R_list_t* R_list_v); 32 | 33 | float DP_Error( R_list_t* R_list_v, int W, int ver_opt); 34 | 35 | //The Error-Search algorithm. 36 | //int error_affordability_check( R_list_t* R_list_v, float eps); 37 | 38 | float* reform_error_space( error_space_t* error_space_v); 39 | 40 | id_list_t* Error_Search( R_list_t* R_list_v, int W); 41 | 42 | //The Span-Search algorithm. 43 | 44 | //span space maintenance. 45 | span_space_t* span_space_alloc( int pos_n); 46 | 47 | void span_space_release( span_space_t* span_space_v); 48 | 49 | void add_span_space_entry( span_space_t* span_space_v, int s, int e, int j); 50 | 51 | span_space_t* const_span_space( R_list_t* R_list_v); 52 | 53 | //pivot finding. 54 | float get_median( span_space_t* span_space_v, array_node_t* array_node_v); 55 | 56 | int is_a_pivot( span_space_t* span_space_v, float span_v); 57 | 58 | float find_pivot( span_space_t* span_space_v); 59 | 60 | //span affordability check. 61 | //angular_range_t* calc_mcar( bst_t* bst_v); 62 | 63 | //float calc_span_of_mcar( bst_t* bst_v); 64 | 65 | id_list_t* span_affordability_check( R_list_t* R_list_v, float span_v); 66 | 67 | float get_matrix_entry( span_space_t* span_space_v, int i, int j); 68 | 69 | void prune_span_space( span_space_t* span_space_v, float pivot, int tag); 70 | 71 | float comp_simp_error( R_list_t* R_list_v, id_list_t* id_list_v); 72 | 73 | id_list_t* Span_Search( R_list_t* R_list_v, int W); 74 | 75 | //Baselines of approximate algorithm. 76 | //Adapted from those baselines for the Min-Size problem. 77 | //int Split_sub( R_array_t* R_array_v, int seg_sta, int seg_end, int W); 78 | 79 | //int Split( R_list_t* R_list_v, int W); 80 | 81 | //id_list_t* Merge_sub( R_array_t* R_array_v, int W); 82 | 83 | id_list_t* Merge_sub2( R_array_t* R_array_v, int W); 84 | 85 | id_list_t* Merge( R_list_t* R_list_v, int W); 86 | 87 | //id_list_t* Greedy_v1( R_list_t* R_list_v, int W); 88 | 89 | //id_list_t* Greedy_v2( R_list_t* R_list_v, int W); 90 | 91 | void ini_part_node_dist( part_node_t* part_node_v); 92 | 93 | id_list_t* Dougolas_Peucker_adapt( R_list_t* R_list_v, int W); 94 | 95 | float DPTS_v2( tra_list_t* tra_list_v, int W, int alg_opt); 96 | 97 | void emp_DPTS_v2( ); 98 | 99 | 100 | //Testing. 101 | void print_error_space( error_space_t* error_space_v); 102 | 103 | void print_span_space( span_space_t* span_space_v); 104 | 105 | #ifndef WIN32 106 | void compress_data_set_v2( ); 107 | #endif 108 | 109 | #endif -------------------------------------------------------------------------------- /batch/DPhull/.gps_reader.py.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uestc-db/traj-compression/784f098180c39152609331b5f1ee4dae373b60a1/batch/DPhull/.gps_reader.py.swp -------------------------------------------------------------------------------- /batch/DPhull/DP.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uestc-db/traj-compression/784f098180c39152609331b5f1ee4dae373b60a1/batch/DPhull/DP.c -------------------------------------------------------------------------------- /batch/DPhull/DP.h: -------------------------------------------------------------------------------- 1 | /* 7-6-91 Jack Snoeyink 2 | Declarations for the Douglas Peucker line simplification algorithm. 3 | */ 4 | #pragma once 5 | 6 | #include 7 | #include 8 | 9 | #define FALSE 0 10 | #define TRUE 1 11 | 12 | #define MAX_POINTS 1001 13 | #define TWICE_MAX_POINTS 2002 14 | #define MAXPTS 500002 15 | 16 | typedef double POINT[3]; /* Most data is cartesian points */ 17 | typedef double HOMOG[3]; /* Some partial calculations are homogeneous */ 18 | 19 | int n_split; 20 | POINT *splits[MAXPTS]; 21 | 22 | #define XX 0 23 | #define YY 1 24 | #define WW 2 25 | #define TT 2 26 | 27 | #define CROSSPROD_2CCH(p, q, r) /* 2-d cartesian to homog cross product */\ 28 | (r)[WW] = (p)[XX] * (q)[YY] - (p)[YY] * (q)[XX];\ 29 | (r)[XX] = - (q)[YY] + (p)[YY];\ 30 | (r)[YY] = (q)[XX] - (p)[XX]; 31 | 32 | #define DOTPROD_2CH(p, q) /* 2-d cartesian to homog dot product */\ 33 | (q)[WW] + (p)[XX]*(q)[XX] + (p)[YY]*(q)[YY] 34 | 35 | 36 | #define DOTPROD_2C(p, q) /* 2-d cartesian dot product */\ 37 | (p)[XX]*(q)[XX] + (p)[YY]*(q)[YY] 38 | 39 | #define LINCOMB_2C(a, p, b, q, r) /* 2-d cartesian linear combination */\ 40 | (r)[XX] = (a) * (p)[XX] + (b) * (q)[XX];\ 41 | (r)[YY] = (a) * (p)[YY] + (b) * (q)[YY]; 42 | 43 | 44 | #define MIN(a,b) ( a < b ? a : b) 45 | #define MAX(a,b) ( a > b ? a : b) 46 | 47 | #define OutputVertex(v) R[num_result++] = v; 48 | 49 | extern POINT *V, /* V is the array of input points */ 50 | **R; /* R is the array of output pointers to V */ 51 | 52 | extern int n, /* number of elements in V */ 53 | num_result, /* number of elements in R */ 54 | outFlag, looping; 55 | 56 | extern double EPSILON, /* error tolerance */ 57 | EPSILON_SQ; /* error tolerance squared */ 58 | 59 | 60 | void Print_Points(); 61 | POINT *Alloc_Points(); /* alloc memory */ 62 | void Get_Points(char* filename); /* create test cases */ 63 | double Distance(); 64 | //void Init(), Output(), Print_Result(), Start_Timing(), End_Timing(); 65 | void Parse(int argc, char **argv); 66 | void swapV(int i, int j); 67 | int intersect(POINT a, POINT b, POINT c, POINT d); 68 | void fatalError(char *msg, char *var); 69 | void Print_Points(POINT **P, int n, int flag); 70 | POINT *Alloc_Points(int n); 71 | void Init(char *name); 72 | void Output(int i, int j); 73 | void AddSplit(POINT *split); 74 | void Print_Result(int flag); 75 | 76 | -------------------------------------------------------------------------------- /batch/DPhull/DP.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uestc-db/traj-compression/784f098180c39152609331b5f1ee4dae373b60a1/batch/DPhull/DP.o -------------------------------------------------------------------------------- /batch/DPhull/DPhull.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uestc-db/traj-compression/784f098180c39152609331b5f1ee4dae373b60a1/batch/DPhull/DPhull.o -------------------------------------------------------------------------------- /batch/DPhull/DPhull.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #coding:utf-8 3 | import sys 4 | import os 5 | def scan_files(directory,prefix=None,postfix=None): 6 | files_list=[] 7 | 8 | for root, sub_dirs, files in os.walk(directory): 9 | for special_file in files: 10 | if postfix: 11 | if special_file.endswith(postfix): 12 | files_list.append(os.path.join(root,special_file)) 13 | elif prefix: 14 | if special_file.startswith(prefix): 15 | files_list.append(os.path.join(root,special_file)) 16 | else: 17 | files_list.append(os.path.join(root,special_file)) 18 | 19 | return files_list 20 | 21 | if __name__ == '__main__': 22 | paras = sys.argv 23 | dirname = paras[1] 24 | spatial_erro = float(paras[2]) 25 | dataset = dirname.split('/')[-1] 26 | #files_list = scan_files(paras[1]) 27 | filenames = "/home/dingmengting/work/part/"+dataset+"_filelist.txt" 28 | f_filenames = open(filenames,'r') 29 | files_list = f_filenames.readlines() 30 | #files_list = scan_files(dir_names) 31 | for filename in files_list: 32 | filename = filename[:-1] 33 | print filename 34 | save_path = '/data4/dingmengting/time/DPhull' 35 | f = open(filename,"r") 36 | n = len(f.readlines()) 37 | if not os.path.exists(save_path): 38 | os.mkdir(save_path) 39 | if "Illinois" in filename: 40 | save_path = save_path +'/Illinois/' 41 | if "geolife" in filename: 42 | save_path = save_path + '/geolife/' 43 | if "indoor" in filename: 44 | save_path = save_path + '/indoor/' 45 | if "SingaporeTaxi" in filename: 46 | save_path = save_path + '/SingaporeTaxi/' 47 | if "truck" in filename: 48 | save_path = save_path +"/truck/" 49 | if "Phone" in filename: 50 | save_path = save_path +"/Phone/" 51 | if not os.path.exists(save_path): 52 | os.mkdir(save_path) 53 | save_path = save_path + str(spatial_erro)+'/' 54 | if not os.path.exists(save_path): 55 | os.mkdir(save_path) 56 | save_path = save_path + filename.split('/')[-3]+'/' 57 | if not os.path.exists(save_path): 58 | os.mkdir(save_path) 59 | save_path = save_path + filename.split('/')[-2]+'/' 60 | if not os.path.exists(save_path): 61 | os.mkdir(save_path) 62 | save_path = save_path + filename.split('/')[-1] 63 | commond = "/home/dingmengting/work/DPhull/hull" +" " + filename + " " + str(n) + " " + str(spatial_erro) + " " + save_path 64 | try: 65 | os.system(commond) 66 | except: 67 | continue 68 | -------------------------------------------------------------------------------- /batch/DPhull/DPhull.sh: -------------------------------------------------------------------------------- 1 | ./hull 20081023025304-0.plt 908 0.00005 20081023025304-0.csv 2 | -------------------------------------------------------------------------------- /batch/DPhull/Makefile: -------------------------------------------------------------------------------- 1 | #File Names 2 | #CFLAGS = -O -s 3 | CFLAGS = -g -DANIMATE 4 | LDFLAGS = -lm -lX11 5 | LINTFLAGS = -c 6 | LINTALLFLAGS = -lm -lgl 7 | HDRS = DP.h animate.h PH.h 8 | SRCS = DP.c DPhullfast.c PH.c DPhull.c animate.c nonrec.c 9 | H_OBJS = DP.o PH.o DPhull.o animate.o 10 | N_OBJS = DP.o nonrec.o animate.o 11 | OBJS = $(H_OBJS) $(N_OBJS) 12 | UBJS = DP.u DPhullfast.u nonrec.u 13 | LINTS = DP.ln animate.ln PH.ln DPhull.ln nonrec.ln 14 | EXECS = hull nonrec 15 | 16 | all: hull nonrec 17 | 18 | opt: $(SRCS) $(HDRS) 19 | cc -O4 -s DP.c DPhullfast.c -lm -o hull 20 | cc -O4 -s DP.c nonrec.c -lm -o nonrec 21 | 22 | hull: $(H_OBJS) 23 | cc $(CFLAGS) $(H_OBJS) $(LDFLAGS) -o hull 24 | 25 | nonrec: $(N_OBJS) 26 | cc $(CFLAGS) $(N_OBJS) $(LDFLAGS) -o nonrec 27 | 28 | $(OBJS): $(HDRS) 29 | 30 | lint: $(LINTS) 31 | 32 | lintall: $(LINTS) 33 | lint $(LINTALLFLAGS) $(LINTS) 34 | 35 | clean: 36 | rm $(OBJS) $(UBJS) 37 | 38 | nuke: 39 | rm $(LINTS) $(EXECS) $(OBJS) 40 | 41 | print: $(HDRS) $(SRCS) 42 | lwf -s7 -t4 -l -p-2 $? | lpr 43 | touch print 44 | 45 | .SUFFIXES: .c .o .ln .h .out .u 46 | 47 | .c.o: 48 | cc $(CFLAGS) -c $< 49 | 50 | .c.ln: 51 | lint $(LINTFLAGS) $(CFLAGS) $< 52 | -------------------------------------------------------------------------------- /batch/DPhull/PH.h: -------------------------------------------------------------------------------- 1 | /* 7-6-91 Jack Snoeyink 2 | Declarations for path hulls 3 | */ 4 | 5 | #pragma once 6 | 7 | #define HULL_MAX 10002 8 | #define TWICE_HULL_MAX 20002 9 | #define THRICE_HULL_MAX 30002 10 | 11 | #define PUSH_OP 0 /* Operation names saved in history stack */ 12 | #define TOP_OP 1 13 | #define BOT_OP 2 14 | 15 | typedef struct { /* Half of a Path Hull: \va{elt} is a double ended queue storing a convex hull, \va{top} and \va{bot} are the two ends. The history stack is \va{helt} for points and \va{op} for operations, \va{hp} is the stack pointer. */ 16 | int top, bot, 17 | hp, op[THRICE_HULL_MAX]; 18 | POINT *elt[TWICE_HULL_MAX], *helt[THRICE_HULL_MAX]; 19 | } PATH_HULL; 20 | 21 | 22 | extern PATH_HULL *left, *right; 23 | extern double top,bot; 24 | 25 | #define Hull_Push(h, e) /* Push element $e$ onto path hull $h$ */\ 26 | (h)->elt[++(h)->top] = (h)->elt[--(h)->bot] = (h)->helt[++(h)->hp] = e;\ 27 | (h)->op[(h)->hp] = PUSH_OP 28 | #define Hull_Pop_Top(h) /* Pop from top */\ 29 | (h)->helt[++(h)->hp] = (h)->elt[(h)->top--];\ 30 | (h)->op[(h)->hp] = TOP_OP 31 | #define Hull_Pop_Bot(h) /* Pop from bottom */\ 32 | (h)->helt[++(h)->hp] = (h)->elt[(h)->bot++];\ 33 | (h)->op[(h)->hp] = BOT_OP 34 | #define Hull_Init(h, e1, e2) /* Initialize path hull and history */\ 35 | (h)->elt[HULL_MAX] = e1;\ 36 | (h)->elt[(h)->top = HULL_MAX + 1] = \ 37 | (h)->elt[(h)->bot = HULL_MAX - 1] = \ 38 | (h)->helt[(h)->hp = 0] = e2;\ 39 | (h)->op[0] = PUSH_OP; 40 | 41 | #define LEFT_OF(a, b, c) /* Determine if point c is left of line a to b */\ 42 | (((*a)[XX] - (*c)[XX])*((*b)[YY] - (*c)[YY]) \ 43 | >= ((*b)[XX] - (*c)[XX])*((*a)[YY] - (*c)[YY])) 44 | 45 | #define SGN(a) (a >= 0) 46 | 47 | //void Hull_Add(), Split(), Hull_Print(), Find_Extreme(); 48 | void Split(register PATH_HULL *h, POINT *e); 49 | void Find_Extreme(register PATH_HULL *h, HOMOG line, POINT **e, register double *dist,POINT *i,POINT *j); 50 | void Hull_Add(register PATH_HULL *h, POINT *p); 51 | void Hull_Print(PATH_HULL *h); 52 | 53 | -------------------------------------------------------------------------------- /batch/DPhull/PH.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uestc-db/traj-compression/784f098180c39152609331b5f1ee4dae373b60a1/batch/DPhull/PH.o -------------------------------------------------------------------------------- /batch/DPhull/animate.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef ANIMATE 4 | //#include 5 | 6 | #define NAPTIME 15L /* 100ths of a second */ 7 | #define MAXPTS 500002 8 | 9 | #define SQRhf 0.70710678 10 | 11 | 12 | #define myBLACK 0x00000000L 13 | #define myRED 0x9f00009fL 14 | #define myGREEN 0x9f009f00L 15 | #define myYELLOW 0x9f009f9fL 16 | #define myBLUE 0x9f9f0000L 17 | #define myMAGENTA 0x9f9f009fL 18 | #define myCYAN 0x9f9f9f00L 19 | #define myWHITE 0x9f9f9f9fL 20 | #define myGREY 0x9f4f4f4fL 21 | #define myTRANSP1 0x80dfdfdf & myCYAN 22 | #define myTRANSP2 0x80dfdfdf & myGREEN 23 | #define mycolor(c) cpack(c) 24 | 25 | extern int A_delay, A_swapinterval, A_modeq, A_ack; 26 | extern char *A_modes[5]; 27 | 28 | extern double aspect; /* aspect ration x/y */ 29 | 30 | void A_Init(), A_Quit(), A_Setup(), 31 | A_Clear(), A_ClearBack(), A_SwapBuffers(), 32 | A_DrawLine(), A_DrawSeg(), A_DrawPLdist(), 33 | A_DrawChains(), A_DrawHull(), A_Update(), A_AddSplit(), 34 | A_UpdateH(); 35 | 36 | #endif /* ANIMATE */ 37 | 38 | -------------------------------------------------------------------------------- /batch/DPhull/animate.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uestc-db/traj-compression/784f098180c39152609331b5f1ee4dae373b60a1/batch/DPhull/animate.o -------------------------------------------------------------------------------- /batch/DPhull/hull: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uestc-db/traj-compression/784f098180c39152609331b5f1ee4dae373b60a1/batch/DPhull/hull -------------------------------------------------------------------------------- /batch/DPhull/nonrec: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uestc-db/traj-compression/784f098180c39152609331b5f1ee4dae373b60a1/batch/DPhull/nonrec -------------------------------------------------------------------------------- /batch/DPhull/nonrec.c: -------------------------------------------------------------------------------- 1 | /* 1-26-94 Jack Snoeyink 2 | Non-recursive implementation of the Douglas Peucker line simplification 3 | algorithm. 4 | */ 5 | #include "DP.h" 6 | #include "animate.h" 7 | 8 | /* Assumes that the polygonal line is in a global array V. 9 | * main() assumes also that a global variable n contains the number of 10 | * points in V. 11 | */ 12 | 13 | int stack[MAX_POINTS]; /* recursion stack */ 14 | int sp; /* recursion stack pointer */ 15 | 16 | #define Stack_Push(e) /* push element onto stack */\ 17 | stack[++sp] = e 18 | #define Stack_Pop() /* pop element from stack (zero if none) */\ 19 | stack[sp--] 20 | #define Stack_Top() /* top element on stack */\ 21 | stack[sp] 22 | #define Stack_EmptyQ() /* Is stack empty? */\ 23 | (sp < 0) 24 | #define Stack_Init() /* initialize stack */\ 25 | sp = -1 26 | 27 | 28 | void Find_Split(i, j, split, dist) /* linear search for farthest point */ 29 | int i, j, *split; /* from the segment Vi to Vj. returns */ 30 | double *dist; /* squared distance and a pointer */ 31 | { 32 | int k; 33 | HOMOG q; 34 | double tmp; 35 | 36 | #ifdef ANIMATE 37 | HOMOG l; 38 | 39 | CROSSPROD_2CCH(V[i], V[j], l); 40 | A_DrawLine(l); 41 | #endif 42 | *dist = -1; 43 | if (i + 1 < j) 44 | { 45 | CROSSPROD_2CCH(V[i], V[j], q); /* out of loop portion */ 46 | /* of distance computation */ 47 | for (k = i + 1; k < j; k++) 48 | { 49 | tmp = DOTPROD_2CH(V[k], q); /* distance computation */ 50 | if (tmp < 0) tmp = - tmp; /* calling fabs() slows us down */ 51 | #ifdef ANIMATE 52 | A_DrawPLdist(V[k], l); 53 | #endif 54 | if (tmp > *dist) 55 | { 56 | *dist = tmp; /* record the maximum */ 57 | *split = k; 58 | } 59 | } 60 | *dist *= *dist/(q[XX]*q[XX] + q[YY]*q[YY]); /* correction for segment */ 61 | } /* length---should be redone if can == 0 */ 62 | } 63 | 64 | 65 | 66 | void DPbasic(i,j) /* Basic DP line simplification */ 67 | int i, j; 68 | { 69 | int split; 70 | double dist_sq; 71 | 72 | #ifdef ANIMATE 73 | A_Mode(0); 74 | #endif 75 | Stack_Init(); 76 | Stack_Push(j); 77 | do 78 | { 79 | Find_Split(i, Stack_Top(), &split, &dist_sq); 80 | if (dist_sq > EPSILON_SQ) 81 | { 82 | #ifdef ANIMATE 83 | A_AddSplit(V+split); 84 | #endif 85 | Stack_Push(split); 86 | } 87 | else 88 | { 89 | Output(i, Stack_Top()); /* output segment Vi to Vtop */ 90 | i = Stack_Pop(); 91 | } 92 | #ifdef ANIMATE 93 | A_Update(); 94 | #endif 95 | } 96 | while (!Stack_EmptyQ()); 97 | } 98 | 99 | 100 | 101 | 102 | main(argc,argv) 103 | int argc; 104 | char **argv; 105 | { 106 | 107 | //#ifndef ANIMATE 108 | // register int i; 109 | //#endif /* not ANIMATE */ 110 | 111 | //Parse(argc, argv); 112 | //Init("DPfast"); 113 | 114 | //do 115 | // { 116 | //puts("111111111111111"); 117 | // Get_Points(); 118 | //#ifdef ANIMATE 119 | //A_modes[0] = "FindExtr."; 120 | // A_modes[1] = "Split"; 121 | // A_Setup(2); 122 | //#endif 123 | //double tstart, tend, tcost,ratio; 124 | //tstart=clock(); 125 | // Start_Timing(); 126 | 127 | //#ifndef ANIMATE 128 | //for (i=0; i < 100; i++) /* For timing purposes */ 129 | //#endif /* not ANIMATE */ 130 | //{ 131 | // outFlag = TRUE; 132 | //num_result = 0; 133 | // puts("before"); 134 | // DPbasic(0, n - 1); 135 | //} 136 | // puts("end"); 137 | //End_Timing(1); 138 | //tend=clock(); 139 | // tcost=(double)(tend-tstart)/100.0; 140 | //ratio=num_result*1.0/n; 141 | //printf("compression time =%lf s\n",tcost); 142 | //Print_Result(FALSE); 143 | //} 144 | //while (looping); 145 | //#ifdef ANIMATE 146 | //A_Quit(); 147 | //#endif 148 | 149 | } 150 | -------------------------------------------------------------------------------- /batch/DPhull/nonrec.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uestc-db/traj-compression/784f098180c39152609331b5f1ee4dae373b60a1/batch/DPhull/nonrec.o -------------------------------------------------------------------------------- /batch/MRPA/GPStraj_TS.m: -------------------------------------------------------------------------------- 1 | function [Xout,Yout,pathpt]= GPStraj_TS(ptx,pty,M) 2 | if M==2 3 | pathpt = [1 length(ptx)]; 4 | Xout = ptx(pathpt); 5 | Yout = pty(pathpt); 6 | return; 7 | end 8 | N = length(ptx); 9 | 10 | dx = diff(ptx); 11 | dy = diff(pty); 12 | dist0 = sqrt(dx.^2 +dy.^2); 13 | dist0 = dist0(1:end-1) + dist0(2:end); 14 | 15 | ang = atan2(dy,dx); 16 | dang = diff(ang); 17 | dang(dang>=pi) =dang(dang>=pi)-2*pi; 18 | 19 | dang(dang<=-pi) =dang(dang<=-pi)+2*pi; 20 | 21 | tu = 3; 22 | dangf = imfilter(dang,ones(1, 2*tu+1),'replicate'); 23 | dangabs = abs(dang); 24 | dangf = 180/pi*dangf; 25 | dangabs = 180/pi*dangf; 26 | wfinal = (abs(dangf)+dangabs).*dist0; 27 | [tmp,sq] = sort(wfinal,'descend'); 28 | if size(sq,1)==1 29 | sqall = [sq(1:M-2)+1 1 N]; 30 | else 31 | sqall = [sq(1:M-2)+1; 1; N]; 32 | end 33 | 34 | [sq,tmp]=sort(sqall); 35 | pathpt = sq; 36 | Xout = ptx(pathpt); 37 | Yout = pty(pathpt); -------------------------------------------------------------------------------- /batch/MRPA/PA_mineSED_CRSDP.m: -------------------------------------------------------------------------------- 1 | function [Xout,Yout, pathpt] = PA_mineSED_CRSDP(x0,y0,t0,linkcell,Xsum,Ysum,Tsum, X2sum,Y2sum,T2sum,XTsum,YTsum,thre,ptind) 2 | 3 | %testing for C-RSDP reduce e, using proirity queue structure 4 | 5 | ptnum = length(x0); 6 | if nargin<14 7 | ptind = 1:ptnum; 8 | end 9 | pathnum = length(linkcell)-1; 10 | E = inf*ones(1,ptnum); 11 | A = inf*ones(1,ptnum); 12 | E(1) = 0; 13 | A(1) = 0; 14 | linkcell{end} = ptnum; 15 | 16 | % treeinfo = cell2struct(treeinfo,'ch'); 17 | 18 | for m = 1:pathnum 19 | tarind = linkcell{m+1}; 20 | curind = linkcell{m}; 21 | 22 | for ind2 = 1:length(tarind) 23 | n = tarind(ind2); 24 | cmin = inf; 25 | 26 | xj = x0(n); 27 | yj = y0(n); 28 | tj = t0(n); 29 | 30 | for ind1 = 1:length(curind) 31 | j = curind(ind1); 32 | if j2 4 | b_inv = 1; 5 | else 6 | b_inv = 0; 7 | end 8 | 9 | l = length(x); 10 | 11 | heaps = x; 12 | heapind = 1:l; 13 | invind = 1:l; 14 | 15 | for i = 2:l 16 | curnode = i; 17 | while (curnode>1) 18 | parnode = fix(curnode/2); 19 | if heaps(parnode)>heaps(curnode)%FOR MIN-heaps 20 | %swap value 21 | tmp = heaps(parnode); 22 | heaps(parnode) = heaps(curnode); 23 | heaps(curnode) = tmp; 24 | %swap heapind 25 | tmp = heapind(parnode); 26 | heapind(parnode) = heapind(curnode); 27 | heapind(curnode) = tmp; 28 | if b_inv 29 | %update invind 30 | invind(heapind(parnode))= parnode; 31 | invind(heapind(curnode))= curnode; 32 | end 33 | curnode = parnode; 34 | else 35 | break; 36 | end 37 | end 38 | end 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /batch/MRPA/calc_ISSED_pathpt.m: -------------------------------------------------------------------------------- 1 | function distsISSED = calc_ISSED_pathpt(x0,y0,t0,pathpt,Xsum,Ysum,Tsum, X2sum,Y2sum,T2sum,XTsum, YTsum) 2 | % eml.inline('always') 3 | 4 | l = length(pathpt); 5 | distsISSED = 0; 6 | for i = 1:(l-1) 7 | fst = pathpt(i); 8 | lst = pathpt(i+1); 9 | if ( (fst +1) == lst) 10 | dists = 0; 11 | else 12 | 13 | xi = x0(fst); 14 | yi = y0(fst); 15 | ti = t0(fst); 16 | xj = x0(lst); 17 | yj = y0(lst); 18 | tj = t0(lst); 19 | 20 | 21 | c1x = xi*tj- xj*ti; 22 | c2x = c1x^2; 23 | c3x = (tj-ti); 24 | c4x = c3x^2; 25 | c5x = xj-xi; 26 | c6x = c5x^2; 27 | 28 | dists = (lst-fst-1)* c2x/ c4x + c6x/c4x * (T2sum(lst-1) - T2sum(fst)) ... 29 | + (X2sum(lst-1) - X2sum(fst))... 30 | + 2* c1x * c5x/c4x * (Tsum(lst-1) - Tsum(fst))... 31 | - 2* c1x/c3x *(Xsum(lst-1) - Xsum(fst))... 32 | - 2* c5x/c3x *(XTsum(lst-1) - XTsum(fst)); 33 | 34 | 35 | c1y = yi*tj- yj*ti; 36 | c2y = c1y^2; 37 | c3y = c3x; 38 | c4y = c3y^2; 39 | c5y = yj-yi; 40 | c6y = c5y^2; 41 | 42 | dists = dists + (lst-fst-1)* c2y/ c4y... 43 | + c6y/c4y * (T2sum(lst-1) - T2sum(fst))... 44 | + (Y2sum(lst-1) - Y2sum(fst))... 45 | + 2* c1y * c5y/c4y * (Tsum(lst-1) - Tsum(fst))... 46 | - 2* c1y/c3y *(Ysum(lst-1) - Ysum(fst))... 47 | - 2* c5y/c3y *(YTsum(lst-1) - YTsum(fst)); 48 | end 49 | 50 | distsISSED = distsISSED + dists; 51 | 52 | end -------------------------------------------------------------------------------- /batch/MRPA/calc_LISE_SED.m: -------------------------------------------------------------------------------- 1 | function dists = calc_LISE_SED(x0,y0,t0,fst,lst, Xsum,Ysum,Tsum, X2sum,Y2sum,T2sum,XTsum, YTsum) 2 | 3 | if ( (fst +1) == lst) 4 | dists = 0; 5 | return; 6 | end 7 | 8 | xi = x0(fst); 9 | yi = y0(fst); 10 | ti = t0(fst); 11 | 12 | xj = x0(lst); 13 | yj = y0(lst); 14 | tj = t0(lst); 15 | 16 | dists = 0; 17 | c1x = xi*tj- xj*ti; 18 | c2x = c1x^2; 19 | c3x = (tj-ti); 20 | c4x = c3x^2; 21 | c5x = xj-xi; 22 | c6x = c5x^2; 23 | 24 | dists = dists + (lst-fst-1)* c2x/ c4x; 25 | dists = dists + c6x/c4x * (T2sum(lst-1) - T2sum(fst)); 26 | dists = dists + (X2sum(lst-1) - X2sum(fst)); 27 | dists = dists + 2* c1x * c5x/c4x * (Tsum(lst-1) - Tsum(fst)); 28 | dists = dists - 2* c1x/c3x *(Xsum(lst-1) - Xsum(fst)); 29 | dists = dists - 2* c5x/c3x *(XTsum(lst-1) - XTsum(fst)); 30 | 31 | 32 | c1y = yi*tj- yj*ti; 33 | c2y = c1y^2; 34 | c3y = c3x; 35 | c4y = c3y^2; 36 | c5y = yj-yi; 37 | c6y = c5y^2; 38 | 39 | dists = dists + (lst-fst-1)* c2y/ c4y; 40 | dists = dists + c6y/c4y * (T2sum(lst-1) - T2sum(fst)); 41 | dists = dists + (Y2sum(lst-1) - Y2sum(fst)); 42 | dists = dists + 2* c1y * c5y/c4y * (Tsum(lst-1) - Tsum(fst)); 43 | dists = dists - 2* c1y/c3y *(Ysum(lst-1) - Ysum(fst)); 44 | dists = dists - 2* c5y/c3y *(YTsum(lst-1) - YTsum(fst)); 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /batch/MRPA/calc_TSperf_time.m: -------------------------------------------------------------------------------- 1 | function errall = calc_TSperf_time(ptx,pty,tpos,pathpt) 2 | %consider time 3 | % err = [rmse,mae,maxerr,rmse_SEC,mae_SEC, maxerr_SEC] 4 | dist_all = zeros(1,length(ptx)); 5 | for i = 1:(length(pathpt)-1) 6 | st = pathpt(i); 7 | ed = pathpt(i+1); 8 | dists = p2l_all(ptx,pty,st,ed); 9 | dist_all((st+1):(ed-1)) = dists; 10 | end 11 | rmse = sqrt(mean(dist_all.^2)); 12 | mae = mean(dist_all); 13 | merr = max(dist_all); 14 | 15 | mae_med = median(dist_all); 16 | 17 | appx_sec = ptx; 18 | appy_sec = pty; 19 | for i = 1:(length(pathpt)-1) 20 | st = pathpt(i); 21 | ed = pathpt(i+1); 22 | tst = tpos(st); 23 | ted = tpos(ed); 24 | dx = ptx(ed)-ptx(st); 25 | dy = pty(ed)-pty(st); 26 | xst = ptx(st); 27 | yst = pty(st); 28 | for pos = (st+1):(ed-1) 29 | rt = (tpos(pos)-tst)/(ted-tst); 30 | appx_sec(pos) = xst +dx*rt; 31 | appy_sec(pos) = yst +dy*rt; 32 | end 33 | end 34 | dist_sec = sqrt((ptx-appx_sec).^2 +(pty-appy_sec).^2); 35 | rmse_sec = sqrt(mean(dist_sec.^2)); 36 | mae_sec = mean(dist_sec); 37 | merr_sec = max(dist_sec); 38 | 39 | mae_sec_med = median(dist_sec); 40 | errall = [rmse mae mae_med merr rmse_sec mae_sec mae_sec_med merr_sec]; 41 | 42 | function distall = p2l_all(ptx,pty,st,ed) 43 | % sx, sy, ex, ey, px, py 44 | if st +1 ==ed 45 | distall = []; 46 | return; 47 | end 48 | distall = []; 49 | sx = ptx(st); 50 | sy = pty(st); 51 | ex = ptx(ed); 52 | ey = pty(ed); 53 | for pos = (st+1):(ed-1) 54 | px = ptx(pos); 55 | py = pty(pos); 56 | dA = px - sx; 57 | dB = py - sy; 58 | dC = ex - sx; 59 | dD = ey - sy; 60 | dot = dA * dC + dB * dD; 61 | len_sq = dC * dC + dD * dD; 62 | if len_sq==0 63 | dists = sqrt(dA*dA +dB*dB); 64 | else 65 | param = dot / len_sq; 66 | closest_X = sx + param * dC; 67 | closest_Y = sy + param * dD; 68 | dists = sqrt((px-closest_X)^2 + (py-closest_Y)^2); 69 | end 70 | distall = [distall dists]; 71 | 72 | end -------------------------------------------------------------------------------- /batch/MRPA/demo1.m: -------------------------------------------------------------------------------- 1 | clear all 2 | close all 3 | clc 4 | %Note that if only sptial info are considered, LISE and ISE can be used instead. 5 | 6 | %% load data 7 | %fin is the filename for simplification 8 | fin = 'r6.txt'; 9 | tic 10 | [lat, lon, tin] = readdata(fin); 11 | t= toc; 12 | disp(['time cost of read data and convert to unix time is ' num2str(t) 's']) 13 | 14 | %% mercator projection 15 | [xin,yin, scalefactor] = mercator_proj(lat,lon); 16 | 17 | 18 | %% simplification by given thre 19 | LSSDth = 10000; 20 | tic 21 | pathpt = TDMRPA_SED(xin,yin,tin, LSSDth,2,2); 22 | toc 23 | 24 | %% plot 25 | df = ['LSSD= ' num2str(LSSDth) ', N = ' num2str(length(lat)) ', M = ' num2str(length(pathpt))]; 26 | figure,plot(lon, lat,'b-',lon(pathpt),lat(pathpt), 'rx-'),title(df) 27 | 28 | -------------------------------------------------------------------------------- /batch/MRPA/eval_mopsi_walknowalk.m: -------------------------------------------------------------------------------- 1 | %out_mopsi, LSSD diff for walking and no-walking 2 | clear all 3 | close all 4 | clc 5 | % average N/M 6 | load mopsi_PA 7 | load perf_MRPASED_mopsi_PA 8 | Nall = zeros(length(xall),1); 9 | for i = 1:length(xall) 10 | Nall(i) = length(xall{i}); 11 | end 12 | NdM1 = mean(Nall'./m_MRPASED(1,:)); 13 | NdM2 = mean(Nall'./m_MRPASED(2,:)); 14 | NdM3 = mean(Nall'./m_MRPASED(3,:)); 15 | 16 | load geolife_PA 17 | load perf_MRPASED_geolife_PA 18 | Nall = zeros(length(xall),1); 19 | for i = 1:length(xall) 20 | Nall(i) = length(xall{i}); 21 | end 22 | NdM1a = mean(Nall'./m_MRPASED(1,:)); 23 | NdM2a = mean(Nall'./m_MRPASED(2,:)); 24 | NdM3a = mean(Nall'./m_MRPASED(3,:)); 25 | 26 | 27 | %% measure no-walking and walking reduction rate LSSD, 28 | %out_mopsi, LSSD diff for walking and no-walking 29 | clear all 30 | close all 31 | clc 32 | % average N/M 33 | load mopsi_PA 34 | load perf_MRPASED_mopsi_PA 35 | 36 | val_walk = zeros(16,1); 37 | val_nowalk = zeros(16,1); 38 | curr_w = 1; 39 | curr_nw = 1; 40 | 41 | for i = 1:length(xall) 42 | xtmp = xall{i}; 43 | ytmp = yall{i}; 44 | ttmp = tall{i}; 45 | spdtmp = sum(sqrt(diff(xtmp).^2 + diff(ytmp).^2))/(ttmp(end)- ttmp(1)); 46 | if spdtmp<1.8%walk 47 | val_walk(curr_w,1:4) = [length(xtmp) m_MRPASED(:,i)']; 48 | val_walk(curr_w,5:8) = [errall_MRPASED{1}(5:8,i)']; 49 | val_walk(curr_w,9:12) = [errall_MRPASED{2}(5:8,i)']; 50 | val_walk(curr_w,13:16) = [errall_MRPASED{3}(5:8,i)']; 51 | curr_w = curr_w +1; 52 | elseif spdtmp>15%car 53 | val_nowalk(curr_nw,1:4) = [length(xtmp) m_MRPASED(:,i)']; 54 | val_nowalk(curr_nw,5:8) = [errall_MRPASED{1}(5:8,i)']; 55 | val_nowalk(curr_nw,9:12) = [errall_MRPASED{2}(5:8,i)']; 56 | val_nowalk(curr_nw,13:16) = [errall_MRPASED{3}(5:8,i)']; 57 | curr_nw = curr_nw +1; 58 | end 59 | end 60 | 61 | m_walk = [mean(val_walk(:,1)./val_walk(:,2)) mean(val_walk(:,1)./val_walk(:,3)) mean(val_walk(:,1)./val_walk(:,4 )), ... 62 | mean(val_walk(:,5:end))]; 63 | 64 | m_nwalk = [mean(val_nowalk(:,1)./val_nowalk(:,2)) mean(val_nowalk(:,1)./val_nowalk(:,3)) mean(val_nowalk(:,1)./val_nowalk(:,4 )), ... 65 | mean(val_nowalk(:,5:end))]; 66 | 67 | 68 | -------------------------------------------------------------------------------- /batch/MRPA/get_cumsumval_SED.m: -------------------------------------------------------------------------------- 1 | function [Xsum,Ysum,Tsum, X2sum,Y2sum,T2sum,XTsum, YTsum]=get_cumsumval_SED(x0,y0,t0) 2 | %cumsum for LISE_SED caculation 3 | x2 = x0.*x0; 4 | y2 = y0.*y0; 5 | t2 = t0.*t0; 6 | xt = t0.*x0; 7 | yt = t0.*y0; 8 | 9 | Xsum = cumsum(x0); 10 | Ysum = cumsum(y0); 11 | Tsum = cumsum(t0); 12 | X2sum = cumsum(x2); 13 | Y2sum = cumsum(y2); 14 | T2sum = cumsum(t2); 15 | XTsum = cumsum(xt); 16 | YTsum = cumsum(yt); 17 | 18 | 19 | 20 | % ifint64 = 0; 21 | % if ifint64 22 | % ptx = int64(ptx); 23 | % pty = int64(pty); 24 | % X2 = ptx.*ptx; 25 | % XY = ptx.*pty; 26 | % Y2 = pty.*pty; 27 | % l = length(ptx); 28 | % Xsum = zeros(1,l,'int64'); 29 | % Ysum = zeros(1,l,'int64'); 30 | % X2sum = zeros(1,l,'int64'); 31 | % Y2sum = zeros(1,l,'int64'); 32 | % XYsum = zeros(1,l,'int64'); 33 | % 34 | % Xsum(1) = ptx(1); 35 | % Ysum(1) = pty(1); 36 | % XYsum(1) = XY(1); 37 | % X2sum(1) = X2(1); 38 | % Y2sum(1) = Y2(1); 39 | % for i = 2:l 40 | % i0 = i-1; 41 | % Xsum(i) = Xsum(i0) + ptx(i); 42 | % Ysum(i) = Ysum(i0) + pty(i); 43 | % XYsum(i) = XYsum(i0) + XY(i); 44 | % X2sum(i) = X2sum(i0)+X2(i); 45 | % Y2sum(i) = Y2sum(i0)+Y2(i); 46 | % end 47 | % else 48 | % X2 = ptx.*ptx; 49 | % XY = ptx.*pty; 50 | % Y2 = pty.*pty; 51 | % l = length(ptx); 52 | % Xsum = cumsum(ptx); 53 | % Ysum = cumsum(pty); 54 | % XYsum = cumsum(XY); 55 | % X2sum = cumsum(X2); 56 | % Y2sum = cumsum(Y2); 57 | 58 | 59 | % end 60 | -------------------------------------------------------------------------------- /batch/MRPA/heap_elementadd.m: -------------------------------------------------------------------------------- 1 | function [heaps,heapind,invind] = heap_elementadd(heaps,heapind,addval,addind,invind,heapsize) 2 | %invind is current pos of 1:l point in heaps 3 | if nargout>2 4 | b_inv = 1; 5 | else 6 | b_inv = 0; 7 | end 8 | if nargin<6 9 | heapsize = length(heaps); 10 | end 11 | 12 | 13 | l = heapsize + 1; 14 | heaps(l) = addval; 15 | heapind(l) = addind; 16 | 17 | if b_inv 18 | invind(addind)= l; 19 | end 20 | 21 | curnode = l; 22 | while (curnode>1) 23 | parnode = fix(curnode/2); 24 | if heaps(parnode)>heaps(curnode)%FOR MIN-heaps 25 | %swap value 26 | tmp = heaps(parnode); 27 | heaps(parnode) = heaps(curnode); 28 | heaps(curnode) = tmp; 29 | %swap heapind 30 | tmp = heapind(parnode); 31 | heapind(parnode) = heapind(curnode); 32 | heapind(curnode) = tmp; 33 | if b_inv 34 | %update invind 35 | invind(heapind(curnode))= curnode; 36 | invind(heapind(parnode))= parnode; 37 | end 38 | 39 | curnode = parnode; 40 | else 41 | break; 42 | end 43 | end -------------------------------------------------------------------------------- /batch/MRPA/heap_elementreplace.m: -------------------------------------------------------------------------------- 1 | function [hp,hpind,invind] = hp_elementreplace(hp,hpind,delsq,addval,addind,invind,hpsize) 2 | %% 3 | %merge one delete and one add together, delete position is replaced with 4 | %the new value, then heap updated 5 | %invind is current pos of 1:l point in heaps 6 | %% 7 | 8 | if nargin<7 9 | l = length(hp); 10 | else 11 | l = hpsize; 12 | end 13 | if nargout>2 14 | b_inv = 1; 15 | else 16 | b_inv = 0; 17 | end 18 | %% replace with new element in heap 19 | if b_inv 20 | %update invind 21 | tmp = hpind(delsq); 22 | invind(tmp)= 0; 23 | end 24 | hp(delsq) = addval; 25 | hpind(delsq) = addind; 26 | if b_inv 27 | %update invind 28 | invind(addind)= delsq; 29 | end 30 | %% update heap 31 | if (delsq==1) 32 | movetar = 1;%1 down 2up 33 | elseif(delsq>fix(l/2)) 34 | movetar = 2; 35 | else 36 | if hp(delsq)< hp(fix(delsq/2)) 37 | movetar = 2; 38 | else 39 | movetar = 1; 40 | end 41 | end 42 | if (movetar==1) %down 43 | curnode = delsq; 44 | halfl = fix(l/2); 45 | while (curnode<=halfl) 46 | sonnode1 = curnode*2; 47 | sonnode2 = sonnode1 +1; 48 | val1 = hp(curnode); 49 | val2 = hp(sonnode1); 50 | if l>=sonnode2 51 | val3 = hp(sonnode2); 52 | else 53 | val3 = inf; 54 | end 55 | if val1>val2 56 | if val2>val3 57 | %1>2>3,move3 58 | stat=3; 59 | else 60 | %1>2,3>2, move 2 61 | stat =2; 62 | end 63 | else 64 | if val1>val3 65 | %2>1>3 move 3 66 | stat = 3; 67 | else 68 | %2>1,3>1, stop 69 | stat = 0; 70 | end 71 | end 72 | if (stat==0) 73 | break; 74 | elseif (stat==3) 75 | %swap value,1<->3 76 | hp(sonnode2) = val1; 77 | hp(curnode) = val3; 78 | %swap heapind 79 | tmp = hpind(curnode); 80 | hpind(curnode) = hpind(sonnode2); 81 | hpind(sonnode2) = tmp; 82 | if b_inv 83 | %update invind 84 | invind(hpind(curnode))= curnode; 85 | invind(hpind(sonnode2))= sonnode2; 86 | end 87 | curnode = sonnode2; 88 | else % stat==2 89 | %swap value,1<->2 90 | hp(sonnode1) = val1; 91 | hp(curnode) = val2; 92 | %swap heapind 93 | tmp = hpind(curnode); 94 | hpind(curnode) = hpind(sonnode1); 95 | hpind(sonnode1) = tmp; 96 | if b_inv 97 | %update invind 98 | invind(hpind(curnode))= curnode; 99 | invind(hpind(sonnode1))= sonnode1; 100 | end 101 | curnode = sonnode1; 102 | end 103 | end 104 | else%movetar==2,up 105 | curnode = delsq; 106 | while (curnode>1) 107 | parnode = fix(curnode/2); 108 | if hp(parnode)>hp(curnode)%FOR MIN-heaps 109 | %swap value 110 | tmp = hp(parnode); 111 | hp(parnode) = hp(curnode); 112 | hp(curnode) = tmp; 113 | %swap heapind 114 | tmp = hpind(parnode); 115 | hpind(parnode) = hpind(curnode); 116 | hpind(curnode) = tmp; 117 | if b_inv 118 | %update invind 119 | invind(hpind(parnode))= parnode; 120 | invind(hpind(curnode))= curnode; 121 | end 122 | curnode = parnode; 123 | else 124 | break; 125 | end 126 | end 127 | end 128 | -------------------------------------------------------------------------------- /batch/MRPA/hp_elementadd.m: -------------------------------------------------------------------------------- 1 | function [hp,hpind,invind] = hp_elementadd(hp,hpind,addval,addind,invind,hpsize) 2 | %invind is current pos of 1:l point in hps 3 | if nargout>2 4 | b_inv = 1; 5 | else 6 | b_inv = 0; 7 | end 8 | if nargin<6 9 | hpsize = length(hp); 10 | end 11 | 12 | 13 | 14 | l = hpsize + 1; 15 | hp(l) = addval; 16 | hpind(l) = addind; 17 | 18 | if b_inv 19 | invind(addind)= l; 20 | end 21 | 22 | curnode = l; 23 | while (curnode>1) 24 | parnode = fix(curnode/2); 25 | if hp(parnode)>hp(curnode)%FOR MIN-heaps 26 | %swap value 27 | tmp = hp(parnode); 28 | hp(parnode) = hp(curnode); 29 | hp(curnode) = tmp; 30 | %swap heapind 31 | tmp = hpind(parnode); 32 | hpind(parnode) = hpind(curnode); 33 | hpind(curnode) = tmp; 34 | if b_inv 35 | %update invind 36 | invind(hpind(curnode))= curnode; 37 | invind(hpind(parnode))= parnode; 38 | end 39 | 40 | curnode = parnode; 41 | else 42 | break; 43 | end 44 | end -------------------------------------------------------------------------------- /batch/MRPA/hp_elementreplace.m: -------------------------------------------------------------------------------- 1 | function [hp,hpind,invind] = hp_elementreplace(hp,hpind,delsq,addval,addind,invind,hpsize) 2 | %% 3 | %merge one delete and one add together, delete position is replaced with 4 | %the new value, then heap updated 5 | %invind is current pos of 1:l point in heaps 6 | %% 7 | 8 | if nargin<7 9 | l = length(hp); 10 | else 11 | l = hpsize; 12 | end 13 | if nargout>2 14 | b_inv = 1; 15 | else 16 | b_inv = 0; 17 | end 18 | %% replace with new element in heap 19 | if b_inv 20 | %update invind 21 | tmp = hpind(delsq); 22 | invind(tmp)= 0; 23 | end 24 | hp(delsq) = addval; 25 | hpind(delsq) = addind; 26 | if b_inv 27 | %update invind 28 | invind(addind)= delsq; 29 | end 30 | %% update heap 31 | if (delsq==1) 32 | movetar = 1;%1 down 2up 33 | elseif(delsq>fix(l/2)) 34 | movetar = 2; 35 | else 36 | if hp(delsq)< hp(fix(delsq/2)) 37 | movetar = 2; 38 | else 39 | movetar = 1; 40 | end 41 | end 42 | if (movetar==1) %down 43 | curnode = delsq; 44 | halfl = fix(l/2); 45 | while (curnode<=halfl) 46 | sonnode1 = curnode*2; 47 | sonnode2 = sonnode1 +1; 48 | val1 = hp(curnode); 49 | val2 = hp(sonnode1); 50 | if l>=sonnode2 51 | val3 = hp(sonnode2); 52 | else 53 | val3 = inf; 54 | end 55 | if val1>val2 56 | if val2>val3 57 | %1>2>3,move3 58 | stat=3; 59 | else 60 | %1>2,3>2, move 2 61 | stat =2; 62 | end 63 | else 64 | if val1>val3 65 | %2>1>3 move 3 66 | stat = 3; 67 | else 68 | %2>1,3>1, stop 69 | stat = 0; 70 | end 71 | end 72 | if (stat==0) 73 | break; 74 | elseif (stat==3) 75 | %swap value,1<->3 76 | hp(sonnode2) = val1; 77 | hp(curnode) = val3; 78 | %swap heapind 79 | tmp = hpind(curnode); 80 | hpind(curnode) = hpind(sonnode2); 81 | hpind(sonnode2) = tmp; 82 | if b_inv 83 | %update invind 84 | invind(hpind(curnode))= curnode; 85 | invind(hpind(sonnode2))= sonnode2; 86 | end 87 | curnode = sonnode2; 88 | else % stat==2 89 | %swap value,1<->2 90 | hp(sonnode1) = val1; 91 | hp(curnode) = val2; 92 | %swap heapind 93 | tmp = hpind(curnode); 94 | hpind(curnode) = hpind(sonnode1); 95 | hpind(sonnode1) = tmp; 96 | if b_inv 97 | %update invind 98 | invind(hpind(curnode))= curnode; 99 | invind(hpind(sonnode1))= sonnode1; 100 | end 101 | curnode = sonnode1; 102 | end 103 | end 104 | else%movetar==2,up 105 | curnode = delsq; 106 | while (curnode>1) 107 | parnode = fix(curnode/2); 108 | if hp(parnode)>hp(curnode)%FOR MIN-heaps 109 | %swap value 110 | tmp = hp(parnode); 111 | hp(parnode) = hp(curnode); 112 | hp(curnode) = tmp; 113 | %swap heapind 114 | tmp = hpind(parnode); 115 | hpind(parnode) = hpind(curnode); 116 | hpind(curnode) = tmp; 117 | if b_inv 118 | %update invind 119 | invind(hpind(parnode))= parnode; 120 | invind(hpind(curnode))= curnode; 121 | end 122 | curnode = parnode; 123 | else 124 | break; 125 | end 126 | end 127 | end 128 | -------------------------------------------------------------------------------- /batch/MRPA/intro.txt: -------------------------------------------------------------------------------- 1 | run demo1 -------------------------------------------------------------------------------- /batch/MRPA/measure_sed2.m: -------------------------------------------------------------------------------- 1 | function sedist2 = measure_sed2(x0,y0,t0, i, j) 2 | %measure sum of sed2 dist of compressed curve 3 | %seddist = [maxsed, avesed, medsed. mssed] 4 | 5 | % t0 = t0-t0(1); 6 | % tc = tc-tc(1); 7 | 8 | sedist2 = 0; 9 | for k = i:j 10 | 11 | tp = (t0(k) - t0(i))/(t0(j) - t0(i)); 12 | 13 | 14 | xest = x0(i) + (x0(j)-x0(i))*tp; 15 | yest = y0(i) + (y0(j)-y0(i))*tp; 16 | 17 | sedist2 = sedist2+ (xest-x0(k))^2 + (yest-y0(k))^2; 18 | end 19 | 20 | 21 | -------------------------------------------------------------------------------- /batch/MRPA/mercator_proj.m: -------------------------------------------------------------------------------- 1 | function [xin,yin, scalefactor] = mercator_proj(lat,lon,param) 2 | %% mercator projection 3 | if ~exist('param') 4 | acc_scalefactor = 1e-4; 5 | acc_x = 0.1; 6 | acc_y = 0.1; 7 | else 8 | acc_scalefactor = param.acc_scalefactor; 9 | acc_x = param.acc_x; 10 | acc_y = param.acc_y; 11 | end 12 | 13 | xy_dist = 6378100; 14 | 15 | 16 | x = deg2rad(lon); 17 | y = deg2rad(lat); 18 | % Projection: 19 | y2 = log(abs(tan(y)+sec(y))); 20 | % y2 = log(tan(pi/4+y/2)); 21 | sf = sec(y); 22 | scalefactor = round(mean(sf)/acc_scalefactor)*acc_scalefactor; 23 | 24 | xin = x* xy_dist /scalefactor; 25 | yin = y2* xy_dist /scalefactor; 26 | 27 | xin = round(xin/acc_x)*acc_x; 28 | yin = round(yin/acc_y)*acc_y; 29 | 30 | 31 | 32 | 33 | 34 | 35 | function rad = deg2rad(deg) 36 | rad = deg*pi/180; 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /batch/MRPA/readdata.m: -------------------------------------------------------------------------------- 1 | function [lat, lon, tin] = readdata(fname) 2 | % read data lat/lon/time 3 | fid = fopen(fname); 4 | outtmp = textscan(fid, '%f %f %s %s'); 5 | fclose(fid); 6 | lat = outtmp{1,1}; 7 | lon = outtmp{1,2}; 8 | tin = zeros(size(lat)); 9 | for i = 1:length(tin) 10 | % tstr = [ outtmp{3}{i} ' ' outtmp{4}{i}]; 11 | % tin(i) = datenum(tstr); 12 | % datatime = datevec(tstr); 13 | datetmp = outtmp{3}{i}; 14 | timetmp = outtmp{4}{i}; 15 | sq1 = find(datetmp=='-'); 16 | sq2 = find(timetmp==':'); 17 | 18 | yy = str2double(datetmp(1:(sq1(1)-1))); 19 | mm = str2double(datetmp((sq1(1)+1):(sq1(2)-1))); 20 | dd = str2double(datetmp((sq1(2)+1):end)); 21 | 22 | hh = str2double(timetmp(1:(sq2(1)-1))); 23 | mi = str2double(timetmp((sq2(1)+1):(sq2(2)-1))); 24 | ss = str2double(timetmp((sq2(2)+1):end)); 25 | 26 | 27 | 28 | datatime = [yy mm dd hh mi ss]; 29 | 30 | 31 | tin(i) = unixtime(datatime); 32 | end 33 | 34 | 35 | %% MOPSI DATA has errors, remove points with same timestamp but different 36 | %% position 37 | difft = diff(tin); 38 | sq = find(difft==0); 39 | lat(sq) = []; 40 | lon(sq) = []; 41 | tin(sq) = []; 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /batch/MRPA/unixtime.m: -------------------------------------------------------------------------------- 1 | function [outputtime] = unixtime(inputtime) 2 | 3 | % this function either converts a matlab time vector (or a matrix containing time vectors) into unixtime 4 | % or unixtime into matlab time vector(s) 5 | % unixtime is seconds since 1.1.1970 6 | % matlabtime is days after 1.1.000 7 | 8 | if size(inputtime,1) == 0 9 | outputtime = []; 10 | else 11 | if size(inputtime,2) == 6 12 | unixstart = zeros(size(inputtime,1),6); 13 | for count = 1:size(inputtime,1) 14 | unixstart(count,:) = [1970,1,1,0,0,0]; 15 | end 16 | outputtime = etime(inputtime,unixstart); 17 | elseif size(inputtime,2) == 1 18 | secs = floor(inputtime); 19 | nanosecs = inputtime - secs; 20 | unixstart = [1970,1,1,0,0,0]; 21 | matlabtime = datenum(unixstart) + secs/86400; 22 | outputtime = datevec(matlabtime); 23 | outputtime(:,6) = outputtime(:,6) + nanosecs; 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /batch/MinError/DPTS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uestc-db/traj-compression/784f098180c39152609331b5f1ee4dae373b60a1/batch/MinError/DPTS -------------------------------------------------------------------------------- /batch/MinError/Makefile: -------------------------------------------------------------------------------- 1 | 2 | DPTS: ./src/*.h ./src/*.cpp 3 | g++ -g ./src/*.h ./src/*.cpp -o DPTS 4 | -------------------------------------------------------------------------------- /batch/MinError/ReadMe.txt: -------------------------------------------------------------------------------- 1 | 2 | Before you use this code, you should know 3 | ======================= 4 | 1. This code was used for the empirical study of the VLDB'2015 paper 5 | "Trajectory Simplification: On Minimizing the Direction-based Error". 6 | 1. This code is developed by Cheng Long (clong@cse.ust.hk). 7 | 2. This code is written in C/C++. 8 | 3. This code runs under Unix/Linux. 9 | 4. In case that you encounter any problems when using this code, 10 | please figure out the problem by yourself 11 | (The code in fact is easy to read and you can modify it for your own purpose). 12 | 13 | Usage 14 | ======================= 15 | 16 | Step 1: prepare the configuration file. 17 | 18 | 19 | Step 2: compile the source code 20 | make 21 | 22 | Step 3: Run the code 23 | ./DPTS 24 | 25 | Step 4: Collect running statistics 26 | 27 | The running statistics are stored in "stat.txt" which format is explained in Appendix II. 28 | 29 | 30 | Appendix 31 | 32 | I. The format of Config.txt 33 | ======================= 34 | 35 | 36 | <# of positions in the trajectory> 37 | 38 | 39 | 40 | 41 | Explanation of some parameters in config.txt 42 | ----------------------- 43 | 44 | : 45 | The file storing the raw trajectory data. 46 | (the supported formats are those of Geolife (an example is data/20090330005208.plt) and T-Drive (an example is data/2237.txt), and to support your own data format, you should modify the "data reading" part of function DPTS by yourself) 47 | 48 | 49 | = 0: the HWT method (Haar Wavelet Transformaiton) 50 | = 1: the basic DP algorithm 51 | = 2: an enhanced DP algorithm (by employing the O(n^2log n) method for computing the approximation errors of all possible segments) 52 | = 3: the Error-Search algorithm 53 | = 4: the Span-Search algorithm 54 | = 5: the Dougolas-Peucker algorithm 55 | = 6: the Error-Search algorithm with the Dougolas-Peucker algorithm adapted for the error feasibility check 56 | 57 | 58 | = 1: the dataset is in the format of the Geolife dataset; 59 | = 2: the dataset is in the format of the T-Drive dataset. 60 | 61 | (See file config.txt in the folder for example) 62 | 63 | 64 | II. The format of 65 | ============================= 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /batch/MinError/config.txt: -------------------------------------------------------------------------------- 1 | data/20090330005208.plt 100 0.7 3 1 2 | -------------------------------------------------------------------------------- /batch/MinError/src/b_heap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Cheng Long 3 | * Email: clong@cse.ust.hk 4 | */ 5 | 6 | 7 | 8 | /* 9 | * 1. The mechanism of "cmp" function and the "void*" type involved there. 10 | * 2. The choice min-heap or max-heap can be determined by changing the function of "cmp". 11 | * 3. The heap array's subscript starts from zero. 12 | * 4. The concept of "heap array" and "object array", which work collaborarily. 13 | * 14 | * 5. [Updated on 17 Feb. 2012] 15 | * (a). Variable MIN_HEAP_OPT is variable for specifying min-heap or max-heap. 16 | * (b). Object type should maintain an element 'key' for the heap structure. 17 | */ 18 | 19 | 20 | #ifndef B_HEAP_H 21 | #define B_HEAP_H 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "data_struct.h" 28 | #include "data_utility.h" 29 | 30 | 31 | #define B_CONFIG_FILE "b_config.txt" 32 | #define MAX_FILENAME_LENG 256 33 | #define FLOAT float 34 | 35 | //#define MIN_HEAP_OPT 0 36 | 37 | extern int MIN_HEAP_OPT; 38 | 39 | /* 40 | #define B_INPUT_FILE "b_input.txt" 41 | #define B_OUTPUT_FILE "b_output.txt" 42 | */ 43 | 44 | extern emp_stat_t emp_stat_v; 45 | 46 | //The structure of the object that indexed by the binary heap. 47 | typedef struct h_obj 48 | { 49 | int id; 50 | int loc; 51 | 52 | //object-specific variables. 53 | float key; //The key of the heap. 54 | 55 | //For the Merge algorithm. 56 | group_node_t* group_node_v; 57 | 58 | //For the Dogoulas-Peucker algorithm. 59 | part_node_t* part_node_v; 60 | 61 | int pre; 62 | int next; 63 | 64 | //For Merge-Error. 65 | R_node_t* R_node_v_sta; 66 | R_node_t* R_node_v_end; 67 | // R_node_t* R_node_v_sta2; 68 | // R_node_t* R_node_v_end2; 69 | 70 | //For Merge-Span. 71 | span_m_t span_m_v; 72 | 73 | //For Merge-Span2 (only) 74 | R_node_t* R_node_v_sta1; 75 | R_node_t* R_node_v_end1; 76 | 77 | //For Span-Search. 78 | 79 | 80 | } h_obj_t; 81 | 82 | 83 | //The structure of the node of a heap. 84 | typedef struct b_heap 85 | { 86 | int size; //the heap's size. 87 | int rear; //the heap's rear tag. 88 | h_obj_t* obj_arr; //the object array. 89 | int* h_arr; //the heap array. 90 | 91 | //For empirical study. 92 | float m_size; 93 | 94 | } b_heap_t; 95 | 96 | 97 | 98 | //------------------------------------- 99 | 100 | //int cmp( const void* obj_v, int fir, int sec); 101 | 102 | int cmp_min( int* array, int n1, int n2, h_obj_t* obj_v); 103 | 104 | int cmp_max( int* array, int n1, int n2, h_obj_t* obj_v); 105 | 106 | //------------------------------------- 107 | 108 | b_heap_t* alloc_b_heap( int size); 109 | 110 | void release_b_heap( b_heap_t* b_h); 111 | 112 | void b_t_heapify( int* array, int cur, h_obj_t* obj_v); 113 | 114 | void t_b_heapify( int* array, int cur, int rear, h_obj_t* obj_v); 115 | 116 | int insert_b_heap( b_heap_t* b_h, int n); 117 | 118 | int get_top( b_heap_t* b_h); 119 | 120 | void update_key( b_heap_t* b_h, int k); 121 | 122 | //------------------------------------- 123 | 124 | 125 | void print_b_heap( FILE* o_fp, b_heap_t* b_h); 126 | 127 | void test_b_heap( ); 128 | 129 | 130 | #endif -------------------------------------------------------------------------------- /batch/MinError/src/bst.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Cheng Long 3 | * Email: clong@cse.ust.hk 4 | */ 5 | 6 | 7 | /* 8 | * 1. The implementation of the binary search tree follows pseudo-code in the textbook "Introduction to Algorithms". 9 | */ 10 | 11 | #ifndef BST_H 12 | #define BST_H 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include "data_utility.h" 21 | 22 | #define KEY_TYPE float 23 | 24 | extern emp_stat_t emp_stat_v; 25 | 26 | /*The structure of the node in bst.*/ 27 | typedef struct bst_node 28 | { 29 | KEY_TYPE key; 30 | 31 | //For Span-Search 32 | int range_inx; 33 | 34 | struct bst_node* p; 35 | struct bst_node* left; 36 | struct bst_node* right; 37 | 38 | } bst_node_t; 39 | 40 | /*The structure of a bst.*/ 41 | typedef struct bst 42 | { 43 | bst_node_t* root; 44 | 45 | //Problem specific information. 46 | int node_n; 47 | 48 | KEY_TYPE min; 49 | KEY_TYPE max; 50 | 51 | //For empirical study. 52 | float m_size; 53 | 54 | //For span-search 55 | //bst_node_t* min_node; 56 | //bst_node_t* max_node; 57 | 58 | } bst_t; 59 | 60 | 61 | bst_t* bst_ini( ); 62 | 63 | void bst_release_sub( bst_node_t* x); 64 | 65 | void bst_release( bst_t* T); 66 | 67 | void bst_insert( bst_t* T, bst_node_t* z); 68 | 69 | bst_node_t* bst_insert_key( bst_t* bst_v, KEY_TYPE key); 70 | 71 | void bst_transplant( bst_t* T, bst_node_t* u, bst_node_t* v); 72 | 73 | bst_node_t* bst_min( bst_node_t* x); 74 | 75 | bst_node_t* bst_max( bst_node_t* x); 76 | 77 | void bst_delete( bst_t* T, bst_node_t* z); 78 | 79 | void in_order_walk( bst_node_t* x); 80 | 81 | bst_node_t* bst_successor( bst_node_t* x); 82 | 83 | bst_node_t* bst_predecessor( bst_node_t* x); 84 | 85 | void test_bst( ); 86 | 87 | 88 | #endif -------------------------------------------------------------------------------- /batch/MinError/src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Cheng Long 3 | * Email: clong@cse.ust.hk 4 | */ 5 | 6 | 7 | #include "RN_appro.h" 8 | #include "min_error.h" 9 | 10 | stat_t stat_v; 11 | emp_stat_t emp_stat_v; 12 | 13 | LOC_TYPE precision_thr_v2; 14 | 15 | int MIN_HEAP_OPT; 16 | 17 | int main( ) 18 | { 19 | 20 | //real_data_preprocess( ); 21 | 22 | //test2( ); 23 | 24 | //test_bst( ); 25 | 26 | //test_RN_simplify( ); 27 | 28 | //collect_non_passing_stat( ); 29 | 30 | #ifndef WIN32 31 | //combine_files( 2); 32 | 33 | //prepare_cluster_data_v1( ); 34 | 35 | //compress_data_set( ); 36 | 37 | //compress_data_set_v2( ); 38 | 39 | //collect_statistics( ); 40 | #endif 41 | 42 | //collect_statistics_clustering_datasets( ); 43 | 44 | //printf( "%lf\n", pow( 0, 2)); 45 | 46 | //emp_DPTS( ); 47 | 48 | emp_DPTS_v2( ); 49 | 50 | //test_HWT( ); 51 | 52 | //emp_cats( ); 53 | 54 | //prepare_cluster_data_v2( ); 55 | 56 | //collect_clustering_measures( ); 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /batch/MinError/src/min_error.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Author: Cheng Long 3 | * Email: clong@cse.ust.hk 4 | */ 5 | 6 | 7 | 8 | #ifndef MIN_ERROR_H 9 | #define MIN_ERROR_H 10 | 11 | 12 | #include "RN_appro.h" 13 | #include "wavelet.h" 14 | 15 | #define TRA_SIZE_TRUNCATION_OPT 1 16 | 17 | extern emp_stat_t emp_stat_v; 18 | extern LOC_TYPE precision_thr_v2; 19 | 20 | //Starting from 17 July, 2013. 21 | //New APIs for the Min-Error problem. 22 | 23 | error_space_t* error_space_alloc( int pos_n); 24 | 25 | void error_space_release( error_space_t* error_space_v); 26 | 27 | //The DP algorithm. 28 | error_space_t* const_error_space_v1( R_list_t* R_list_v); 29 | 30 | float find_closest_slope( bst_t* bst_v, float slope_v); 31 | 32 | float calc_max_angular_diff( bst_t* bst_v, float slope_v); 33 | 34 | error_space_t* const_error_space_v2( R_list_t* R_list_v); 35 | 36 | float DP_Error( R_list_t* R_list_v, int W, int ver_opt); 37 | 38 | //The Error-Search algorithm. 39 | //int error_affordability_check( R_list_t* R_list_v, float eps); 40 | 41 | float* reform_error_space( error_space_t* error_space_v); 42 | 43 | id_list_t* Error_Search( R_list_t* R_list_v, int W); 44 | 45 | //The Span-Search algorithm. 46 | 47 | //span space maintenance. 48 | span_space_t* span_space_alloc( int pos_n); 49 | 50 | void span_space_release( span_space_t* span_space_v); 51 | 52 | void add_span_space_entry( span_space_t* span_space_v, int s, int e, int j); 53 | 54 | span_space_t* const_span_space( R_list_t* R_list_v); 55 | 56 | //pivot finding. 57 | float get_median( span_space_t* span_space_v, array_node_t* array_node_v); 58 | 59 | int is_a_pivot( span_space_t* span_space_v, float span_v); 60 | 61 | float find_pivot( span_space_t* span_space_v); 62 | 63 | //span affordability check. 64 | //angular_range_t* calc_mcar( bst_t* bst_v); 65 | 66 | //float calc_span_of_mcar( bst_t* bst_v); 67 | 68 | id_list_t* span_affordability_check( R_list_t* R_list_v, float span_v); 69 | 70 | float get_matrix_entry( span_space_t* span_space_v, int i, int j); 71 | 72 | void prune_span_space( span_space_t* span_space_v, float pivot, int tag); 73 | 74 | float comp_simp_error( R_list_t* R_list_v, id_list_t* id_list_v); 75 | 76 | id_list_t* Span_Search( R_list_t* R_list_v, int W); 77 | 78 | //Baselines of approximate algorithm. 79 | //Adapted from those baselines for the Min-Size problem. 80 | //int Split_sub( R_array_t* R_array_v, int seg_sta, int seg_end, int W); 81 | 82 | //int Split( R_list_t* R_list_v, int W); 83 | 84 | //id_list_t* Merge_sub( R_array_t* R_array_v, int W); 85 | 86 | id_list_t* Merge_sub2( R_array_t* R_array_v, int W); 87 | 88 | id_list_t* Merge( R_list_t* R_list_v, int W); 89 | 90 | //id_list_t* Greedy_v1( R_list_t* R_list_v, int W); 91 | 92 | //id_list_t* Greedy_v2( R_list_t* R_list_v, int W); 93 | 94 | void ini_part_node_dist( part_node_t* part_node_v); 95 | 96 | id_list_t* Dougolas_Peucker_adapt( R_list_t* R_list_v, int W); 97 | 98 | float DPTS_v2( tra_list_t* tra_list_v, int W, int alg_opt); 99 | 100 | void emp_DPTS_v2( ); 101 | 102 | 103 | //Testing. 104 | void print_error_space( error_space_t* error_space_v); 105 | 106 | void print_span_space( span_space_t* span_space_v); 107 | 108 | #ifndef WIN32 109 | void compress_data_set_v2( ); 110 | #endif 111 | 112 | 113 | //Added on April 17, 2014. 114 | //Trajectory simplification interface based on HWT. 115 | float emp_TS_HWT( tra_list_t* tra_list_v, int W); 116 | 117 | float emp_TS_HWT_v2( tra_list_t* tra_list_v, int W); 118 | 119 | wavelet_data_t* TS_HWT( wavelet_data_t* wavelet_data_v, int k); 120 | 121 | float calc_error_tra( tra_list_t* tra_list_v1, tra_list_t* tra_list_v2); 122 | 123 | float calc_error_R( R_list_t* R_list_v1, R_list_t* R_list_v2); 124 | 125 | //Trajectory simplification interface with the feasibility check component done by the Douglas-Peucker algorithm. 126 | float Error_Search_DouglasPeucker( R_list_t* R_list_v, int W); 127 | 128 | #endif -------------------------------------------------------------------------------- /batch/MinError/src/wavelet.h: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * wavelet.h includes the APIs for Haar Wavelet Transformation. 4 | */ 5 | 6 | #ifndef WAVELET_H 7 | #define WAVELET_H 8 | 9 | #include "data_struct.h" 10 | #include "data_utility.h" 11 | #include "b_heap.h" 12 | 13 | 14 | wavelet_coeff_t* HWT( wavelet_data_t* wavelet_data_v, int k, int opt); 15 | 16 | wavelet_coeff_t* HWT_bottom_up( wavelet_data_t* wavelet_data_v, int k); 17 | 18 | wavelet_coeff_t* HWT_basis_vector( wavelet_data_t* wavelet_data_v, int k); 19 | 20 | wavelet_coeff_t* get_top_k( LOC_TYPE* values, int size, int k); 21 | 22 | wavelet_data_t* HWDT( wavelet_coeff_t* wavelet_coeff_v); 23 | 24 | //Testing APIs; 25 | void test_HWT( ); 26 | 27 | wavelet_config_t* read_wavelet_config( ); 28 | 29 | wavelet_data_t* read_wavelet_data( wavelet_config_t* config_v); 30 | 31 | void print_wavelet_data( wavelet_data_t* wavelet_data_v, char* f_name); 32 | 33 | void print_wavelet_coeff( wavelet_coeff_t* wavelet_coeff_v, char* f_name); 34 | 35 | #endif -------------------------------------------------------------------------------- /batch/MinError/stat.txt: -------------------------------------------------------------------------------- 1 | 0.086365 2 | 3 | 0.004000 4 | 0.044399 5 | 6 | -------------------------------------------------------------------------------- /batch/TD-TR/20081023025304-0.csv: -------------------------------------------------------------------------------- 1 | 39.984702 116.318417 1224701584.000000 2 | 39.983557 116.299235 1224702215.000000 3 | 39.996832 116.285446 1224706092.000000 4 | 39.984397 116.299292 1224706122.000000 5 | 39.991477 116.322668 1224707227.000000 6 | 39.999769 116.324886 1224707692.000000 7 | 40.009328 116.320887 1224731472.000000 8 | 0.000267 9 | -------------------------------------------------------------------------------- /batch/TD-TR/TD-TR: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/uestc-db/traj-compression/784f098180c39152609331b5f1ee4dae373b60a1/batch/TD-TR/TD-TR -------------------------------------------------------------------------------- /batch/TD-TR/TD-TR.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "sys/time.h" 8 | #include 9 | using namespace std; 10 | typedef struct Point{ 11 | double lat; 12 | double lon; 13 | double time; 14 | }Point; 15 | vector points; 16 | void gpsreader(string filename){ 17 | ifstream fin(filename.c_str()); 18 | if (!fin){ 19 | cout << "open file error !" << endl; 20 | exit(0); 21 | } 22 | while (fin){ 23 | string line; 24 | getline(fin, line); 25 | stringstream sin(line); 26 | double lat, lon, time; 27 | struct Point point; 28 | sin >> point.lat; 29 | sin >> point.lon; 30 | sin >> point.time; 31 | points.push_back(point); 32 | 33 | } 34 | points.pop_back(); 35 | return; 36 | } 37 | double cacl_SED(Point s, Point m, Point e){ 38 | double numerator = m.time - s.time; 39 | double denominator = e.time - s.time; 40 | double time_ratio = denominator == 0 ? 1 : numerator / denominator; 41 | double lat = s.lat + (e.lat - s.lat)*time_ratio; 42 | double lon = s.lon + (e.lon - s.lon)*time_ratio; 43 | double lat_diff = lat - m.lat; 44 | double lon_diff = lon - m.lon; 45 | return sqrt(lat_diff*lat_diff + lon_diff*lon_diff); 46 | } 47 | vector TD_TR(int start, int last, double epsilon){ 48 | 49 | double dmax = 0; 50 | int index = start; 51 | vector recResults; 52 | for (int i = start + 1; i < last; i++){ 53 | double d = cacl_SED(points[start], points[i], points[last]); 54 | if (d > dmax){ 55 | index = i; 56 | dmax = d; 57 | } 58 | } 59 | if (dmax > epsilon){ 60 | vector recResults1 = TD_TR(start, index, epsilon); 61 | vector recResults2 = TD_TR(index, last, epsilon); 62 | recResults.insert(recResults.end(), recResults1.begin(), recResults1.end()); 63 | recResults.insert(recResults.end(), recResults2.begin(), recResults2.end()); 64 | } 65 | else{ 66 | recResults.push_back(start); 67 | recResults.push_back(last); 68 | } 69 | 70 | 71 | return recResults; 72 | 73 | } 74 | 75 | int main(int argc, char** args){ 76 | string filename = args[1]; 77 | double epsilon = atof(args[2]); 78 | char* save_filename = args[3]; 79 | gpsreader(filename); 80 | struct timeval start,end; 81 | /* 82 | for (int i = 0; i < points.size(); i++) 83 | printf("%lf %lf %lf\n",points[i].lat,points[i].lon,points[i].time); 84 | */ 85 | gettimeofday(&start, NULL ); 86 | vector cmp_index = TD_TR(0, points.size() - 1, epsilon); 87 | gettimeofday(&end, NULL ); 88 | long timeuse =1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec; 89 | sort(cmp_index.begin(), cmp_index.end()); 90 | cmp_index.erase(unique(cmp_index.begin(), cmp_index.end()), cmp_index.end()); 91 | // save to file 92 | FILE* s_fp= fopen(save_filename,"w+"); 93 | for (int i = 0; i < cmp_index.size(); i++) 94 | fprintf(s_fp,"%lf %lf %lf\n",points[cmp_index[i]].lat,points[cmp_index[i]].lon,points[cmp_index[i]].time); 95 | fprintf(s_fp,"%lf\n",timeuse /1000000.0); 96 | fclose(s_fp); 97 | } 98 | -------------------------------------------------------------------------------- /batch/TD-TR/TD-TR.sh: -------------------------------------------------------------------------------- 1 | g++ TD-TR.cpp -o TD-TR 2 | ./TD-TR 20081023025304-0.plt 0.0065 20081023025304-0.csv 3 | -------------------------------------------------------------------------------- /lossless/trajic/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | obj/ 3 | doc/ 4 | bin/ 5 | test/test 6 | experiments/* 7 | 8 | !experiments/*.rb 9 | -------------------------------------------------------------------------------- /lossless/trajic/.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | compiler: 3 | - gcc 4 | before_install: 5 | - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y 6 | - sudo apt-get update -qq 7 | - if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.9; fi 8 | - if [ "$CXX" = "g++" ]; then export CXX="g++-4.9" CC="gcc-4.9"; fi 9 | - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 90 10 | install: 11 | - sudo apt-get install -qq libboost-test-dev libboost-iostreams-dev 12 | script: 13 | - make test 14 | -------------------------------------------------------------------------------- /lossless/trajic/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS = -std=c99 -O3 -Wall 2 | CXXFLAGS = -std=c++11 -O3 -Wall 3 | OBJDIR = obj 4 | SRCDIR = src 5 | INCLUDEDIR = src 6 | vpath %.c $(SRCDIR) 7 | vpath %.cpp $(SRCDIR) 8 | vpath %.h $(INCLUDEDIR) 9 | 10 | OBJS = $(addprefix $(OBJDIR)/, ibstream.o obstream.o gps_point.o huffman.o plt_reader.o \ 11 | len_freq_div.o linear_predictor.o predictive_compressor.o illinois_reader.o \ 12 | util.o csv_reader.o dynamic_encoder.o) 13 | 14 | STATS_OBJS = $(addprefix $(OBJDIR)/, delta_compressor.o dp_compressor.o dummy_compressor.o \ 15 | squish_compressor.o) 16 | 17 | PRED_OBJS = $(addprefix $(OBJDIR)/, constant_predictor.o naive_linear_predictor.o) 18 | 19 | default: trajic clean 20 | 21 | all: trajic test experiments clean 22 | 23 | test: $(OBJS) $(STATS_OBJS) 24 | $(CXX) $(CXXFLAGS) -I$(INCLUDEDIR) test/test.cpp -lboost_unit_test_framework $(OBJS) $(STATS_OBJS) -o test/test 25 | test/test 26 | 27 | $(OBJS): | $(OBJDIR) 28 | 29 | $(OBJDIR): 30 | @mkdir -p $@ 31 | 32 | trajic: $(OBJS) $(OBJDIR)/main.o 33 | $(CXX) $(OBJS) $(OBJDIR)/main.o -o bin/trajic 34 | 35 | $(OBJDIR)/%.o: %.cpp 36 | $(CXX) $(CXXFLAGS) -c -o $@ $< 37 | 38 | $(OBJDIR)/%.o: %.c 39 | $(CC) $(CFLAGS) -c -o $@ $< 40 | 41 | clean: 42 | -rm -rf $(OBJDIR) 43 | 44 | doc: 45 | doxygen 46 | 47 | experiments: $(OBJS) $(STATS_OBJS) $(PRED_OBJS) $(OBJDIR)/stats.o $(OBJDIR)/run_predictors.o .force 48 | $(CXX) $(OBJS) $(STATS_OBJS) $(OBJDIR)/stats.o -o experiments/stats 49 | $(CXX) $(OBJS) $(PRED_OBJS) $(OBJDIR)/run_predictors.o -ljansson -o experiments/run_predictors 50 | 51 | .force: 52 | -------------------------------------------------------------------------------- /lossless/trajic/README.md: -------------------------------------------------------------------------------- 1 | Trajic 2 | ====== 3 | 4 | [![Build Status](https://travis-ci.org/anibali/trajic.svg?branch=master)](https://travis-ci.org/anibali/trajic) 5 | 6 | Trajic is an algorithm for compressing GPS trajectory data. For a more in-depth 7 | academic explanation of how Trajic works, be sure to read the 8 | [research paper](https://raw.githubusercontent.com/anibali/trajic/gh-pages/trajic_paper.pdf) 9 | I wrote with [Dr Zhen He](http://homepage.cs.latrobe.edu.au/zhe/). 10 | 11 | This project contains a reference implementation of Trajic along with 12 | implementations of various other GPS trajectory compression schemes which were 13 | used for benchmarks and experiments. 14 | 15 | Development 16 | ----------- 17 | 18 | ### Compiling 19 | 20 | ```sh 21 | make 22 | ``` 23 | 24 | The default `make` task just builds the `trajic` binary. 25 | 26 | ```sh 27 | make all 28 | ``` 29 | 30 | The `all` task runs tests and produces both the `trajic` and `stats` binaries 31 | (the latter of which is used for running experiments). 32 | 33 | ### Dependencies 34 | 35 | * [libboost-test-dev](http://www.boost.org/doc/libs/1_54_0/libs/test/doc/html/index.html) 36 | * [libboost-iostreams-dev](http://www.boost.org/doc/libs/1_54_0/libs/iostreams/doc/index.html) 37 | 38 | Experiments also require 39 | 40 | * [Ruby](https://www.ruby-lang.org/) 41 | * [gnuplot](http://www.gnuplot.info/) 42 | * [libjansson-dev](http://www.digip.org/jansson/) 43 | 44 | Usage 45 | ----- 46 | 47 | Compress a trajectory losslessly: 48 | 49 | trajic c traj.plt 50 | 51 | Compress a trajectory with max errors of 0.1 s temporally and 0.001 degrees 52 | spatially: 53 | 54 | trajic c traj.plt 0.1 0.001 55 | 56 | Decompress a trajectory: 57 | 58 | trajic d traj.tjc 59 | 60 | Important classes 61 | ----------------- 62 | 63 | * @ref PredictiveCompressor 64 | * @ref ibstream 65 | * @ref obstream 66 | * @ref GPSPoint 67 | -------------------------------------------------------------------------------- /lossless/trajic/clustering/README.md: -------------------------------------------------------------------------------- 1 | This directory contains the code used to cluster the 2 | [Illinois trajectory data](https://www.cs.uic.edu/~boxu/mp2p/gps_data.html) 3 | for the experiments in our paper. It is intended to be run with 4 | [Apache Spark](https://spark.apache.org/). 5 | 6 | Please note that this code was not originally designed to be released, so 7 | it contains things like hard-coded file paths. We are making the code available 8 | in the hopes that it will have some use as a reference point. 9 | 10 | ## Credits 11 | 12 | `trajstoreClustering.scala` was written by Dr Zhen He. 13 | -------------------------------------------------------------------------------- /lossless/trajic/experiments/common.rb: -------------------------------------------------------------------------------- 1 | require 'mkmf' 2 | require 'find' 3 | require 'fileutils' 4 | include FileUtils 5 | 6 | # Disable mkmf log files 7 | module Logging 8 | @logfile = File::NULL 9 | end 10 | 11 | def check_for_executables! 12 | executables_missing = false 13 | 14 | %w[gnuplot].each do |executable| 15 | executables_missing ||= !find_executable(executable) 16 | end 17 | 18 | %w[stats run_predictors].each do |binary| 19 | print "checking for Trajic #{binary} binary..." 20 | binary_exists = File.exists?("./#{binary}") 21 | executables_missing ||= !binary_exists 22 | puts binary_exists ? " yes" : " no" 23 | end 24 | 25 | if executables_missing 26 | STDERR.puts "[ERROR] Executable(s) missing" 27 | exit 28 | end 29 | end 30 | 31 | DATA_BASE_PATH = "/home/aiden/Data/Trajectories/" 32 | 33 | def data_files path, extension, number=:all 34 | absolute_path = File.join(DATA_BASE_PATH, path) 35 | files = [] 36 | Find.find(absolute_path) do |path| 37 | if FileTest.file? path and path.end_with? ".#{extension}" 38 | files << path 39 | break if number.is_a? Fixnum and files.size >= number 40 | end 41 | end 42 | files 43 | end 44 | 45 | def median(array) 46 | sorted = array.sort 47 | len = sorted.length 48 | return (sorted[(len - 1) / 2] + sorted[len / 2]) / 2.0 49 | end 50 | -------------------------------------------------------------------------------- /lossless/trajic/experiments/process_clusters.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require './common' 4 | 5 | # In KMs 6 | max_errors = %w[0.001 0.005 0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1] 7 | 8 | base_path = File.join(DATA_BASE_PATH, "IllinoisClustered/Data") 9 | processed_base_path = File.join(DATA_BASE_PATH, "IllinoisClustered/Processed") 10 | 11 | if Dir.exists? processed_base_path 12 | rm_r processed_base_path 13 | end 14 | 15 | max_errors.each do |max_error| 16 | puts "Processing max_error=#{max_error}" 17 | member_list_path = File.join(base_path, "memberList-maxError-#{max_error}.txt") 18 | center_list_path = File.join(base_path, "centerList-maxError-#{max_error}.txt") 19 | 20 | centers_dir = File.join(processed_base_path, max_error, "centers") 21 | members_dir = File.join(processed_base_path, max_error, "members") 22 | 23 | mkdir_p centers_dir 24 | mkdir_p members_dir 25 | 26 | File.readlines(center_list_path).each do |line| 27 | next if line.empty? 28 | grid_id, traj_id, lat, lon, timestamp = *line.strip.split(",") 29 | File.open(File.join(centers_dir, [grid_id, traj_id].join("_") + ".csv"), "a") do |f| 30 | f.puts [timestamp, "%0.6f" % lat.to_f, "%0.6f" % -lon.to_f].join(", ") 31 | end 32 | end 33 | 34 | File.readlines(member_list_path).each do |line| 35 | next if line.empty? 36 | grid_id, center_traj_id, traj_id, timestamp = *line.strip.split(",") 37 | File.open(File.join(members_dir, [grid_id, center_traj_id, traj_id].join("_") + ".csv"), "a") do |f| 38 | f.puts timestamp 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lossless/trajic/experiments/run_error_vs_ratio.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require './common' 4 | 5 | check_for_executables! 6 | 7 | config = { 8 | data_path: "Geolife/Data", #"Illinois/person1", 9 | extension: "plt", 10 | n: 1000 11 | } 12 | 13 | files = data_files(config[:data_path], config[:extension], config[:n]) 14 | 15 | fout = open("results.dat", "w") 16 | 17 | error = 0.01 18 | 19 | squish_ratio = 0 20 | 21 | while error > 0.00000001 22 | squish_ratio += 0.05 23 | puts error 24 | ["trajic", "dpd", "dp", "squish"].each do |alg| 25 | checkpoint = 0.1 * files.length 26 | max_error_kms = -1 27 | usize = 0.0 28 | csize = 0.0 29 | n_trajs = 0 30 | compr_time = 0.0 31 | decompr_time = 0.0 32 | files.each_with_index do |path, i| 33 | if i >= checkpoint 34 | checkpoint += 0.1 * files.length 35 | print "." 36 | $stdout.flush 37 | end 38 | 39 | io = IO.popen("./stats #{alg} \"#{path}\" 0 #{alg == "squish" ? squish_ratio : error}") 40 | lines = io.readlines 41 | io.close 42 | 43 | unless lines.empty? 44 | results = {} 45 | lines.each do |line| 46 | key, val = *line.split("=") 47 | results[key] = val.strip 48 | end 49 | 50 | usize += results["raw_size"].to_i 51 | csize += results["compr_size"].to_i 52 | compr_time += results["compr_time"].to_i 53 | decompr_time += results["decompr_time"].to_i 54 | 55 | error_kms = results["max_error_kms"].to_f 56 | max_error_kms = error_kms if error_kms > max_error_kms 57 | 58 | n_trajs += 1 59 | end 60 | end 61 | puts "." 62 | puts "== #{alg} ==" 63 | puts "Max error: #{max_error_kms * 1000} m" 64 | puts "Compression ratio: #{csize / usize}" 65 | puts "Average compression time: #{compr_time / n_trajs / 1000} ms" 66 | puts "Average decompression time: #{decompr_time / n_trajs / 1000} ms" 67 | fout.print "#{max_error_kms * 1000} #{csize / usize} " 68 | end 69 | 70 | puts 71 | fout.puts 72 | error /= 2 73 | end 74 | 75 | fout.close 76 | 77 | gnuplot_instr = <<-END 78 | set autoscale 79 | set logscale x 80 | set xrange[0.001:100] 81 | set xtic auto 82 | set ytic auto 83 | set title "Max error vs compression ratio (#{config[:n]} trajectories)" 84 | set xlabel "Maximum error (m)" 85 | set ylabel "Compression ratio" 86 | set size 1.0, 0.6 87 | set terminal postscript portrait enhanced mono dashed dl 5 lw 1 "Helvetica" 14 88 | set output "error_vs_ratio-#{config[:n]}.ps" 89 | plot "results.dat" using 1:2 lt -1 title 'Trajic' with lines , \\ 90 | "results.dat" using 3:4 lt -1 pi -2 pt 2 title 'TD-SED + Delta' with linespoints , \\ 91 | "results.dat" using 5:6 lt -1 pi -2 pt 5 title 'TD-SED' with linespoints , \\ 92 | "results.dat" using 7:8 lt -1 pi -2 pt 6 title 'SQUISH' with linespoints 93 | END 94 | 95 | open("results.p", "w") do |f| 96 | f.puts gnuplot_instr 97 | end 98 | 99 | `gnuplot "results.p"` 100 | 101 | rm "results.dat" 102 | rm "results.p" 103 | 104 | -------------------------------------------------------------------------------- /lossless/trajic/experiments/run_full.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require './common' 4 | 5 | check_for_executables! 6 | 7 | config = { 8 | algorithm: "trajic", 9 | #data_path: "Illinois/person1", 10 | #extension: "txt" 11 | data_path: "IllinoisClustered/Processed/0.03/centers", 12 | extension: "csv" 13 | } 14 | 15 | files = data_files(config[:data_path], config[:extension], :all) 16 | 17 | checkpoint = 0.1 * files.length 18 | usize = 0.0 19 | csize = 0.0 20 | n_trajs = 0 21 | compr_time = 0.0 22 | decompr_time = 0.0 23 | max_error_kms = 0.0 24 | 25 | files.each_with_index do |path, i| 26 | if i >= checkpoint 27 | checkpoint += 0.1 * files.length 28 | print "." 29 | $stdout.flush 30 | end 31 | 32 | # # Lossless 33 | command = "./stats #{config[:algorithm]} '#{path}'" 34 | 35 | # # ~1m error 36 | # command= "./stats #{config[:algorithm]} '#{path}' 1 0.00001" 37 | 38 | # # ~30m error 39 | # if config[:algorithm] == "squish" 40 | # command = "./stats #{config[:algorithm]} '#{path}' 0 0.08" 41 | # else 42 | # command = "./stats #{config[:algorithm]} '#{path}' 0 0.00028" 43 | # end 44 | 45 | lines = IO.popen(command) do |io| 46 | io.readlines 47 | end 48 | 49 | unless $?.success? 50 | $stderr.puts "[FAIL] `#{command}`" 51 | next 52 | end 53 | 54 | unless lines.empty? 55 | results = {} 56 | lines.each do |line| 57 | key, val = *line.split("=") 58 | results[key] = val.strip 59 | end 60 | 61 | usize += results["raw_size"].to_i 62 | csize += results["compr_size"].to_i 63 | compr_time += results["compr_time"].to_i 64 | decompr_time += results["decompr_time"].to_i 65 | 66 | error_kms = results["max_error_kms"].to_f 67 | max_error_kms = error_kms if error_kms > max_error_kms 68 | 69 | n_trajs += 1 70 | end 71 | end 72 | 73 | puts "." 74 | puts "Algorithm: #{config[:algorithm]}" 75 | puts "Data path: #{config[:data_path]}" 76 | puts "Num trajectories: #{n_trajs}" 77 | puts "Max error: #{max_error_kms * 1000} m" 78 | puts "Compression ratio: #{csize / usize}" 79 | puts "Average compression time: #{compr_time / n_trajs / 1000} ms" 80 | puts "Average decompression time: #{decompr_time / n_trajs / 1000} ms" 81 | 82 | -------------------------------------------------------------------------------- /lossless/trajic/experiments/run_predictors.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require './common' 4 | 5 | require 'json' 6 | 7 | check_for_executables! 8 | 9 | config = { 10 | algorithm: "trajic", 11 | data_path: "Illinois/person1", 12 | extension: "txt" 13 | #data_path: "IllinoisClustered/Processed/0.03/centers", 14 | #extension: "csv" 15 | } 16 | 17 | files = data_files(config[:data_path], config[:extension], :all) 18 | 19 | checkpoint = 0.01 * files.length 20 | 21 | all_results = {} 22 | 23 | files.each_with_index do |path, i| 24 | if i >= checkpoint 25 | checkpoint += 0.01 * files.length 26 | print "." 27 | $stdout.flush 28 | end 29 | 30 | command = "./run_predictors '#{path}'" 31 | 32 | results = IO.popen(command) do |io| 33 | io.read 34 | end 35 | 36 | unless $?.success? 37 | $stderr.puts "[FAIL] `#{command}`" 38 | next 39 | end 40 | 41 | json = JSON.parse(results) 42 | json.fetch("predictors").each do |predictor| 43 | predictor_results = (all_results[predictor.fetch("name")] ||= {}) 44 | 45 | %w[time_us mean_residual_length mean_spatial_residual_length mean_temporal_residual_length].each do |metric_name| 46 | (predictor_results[metric_name] ||= []) << predictor.fetch(metric_name) 47 | end 48 | end 49 | end 50 | 51 | puts "." 52 | 53 | puts "Medians:" 54 | all_results.each do |predictor_name, metrics| 55 | puts "## #{predictor_name}" 56 | metrics.each do |metric_name, values| 57 | puts "#{metric_name}: #{median(values)}" 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /lossless/trajic/experiments/run_size_vs_time.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require './common' 4 | 5 | check_for_executables! 6 | 7 | DATA_ROOT = "/home/aiden/Data/Trajectories/Geolife/Data" 8 | 9 | config = { 10 | :n => 1000, 11 | :algorithm => "trajic", 12 | :time => "decompression" 13 | } 14 | 15 | files = [] 16 | Find.find(DATA_ROOT) do |path| 17 | if FileTest.file? path and path.end_with? ".plt" 18 | files << path 19 | end 20 | end 21 | 22 | unless config[:n].nil? or config[:n] == :all 23 | files = files[0...config[:n]] 24 | end 25 | 26 | fout = open("results.dat", "w") 27 | 28 | checkpoint = 0.1 * files.length 29 | files.each_with_index do |path, i| 30 | if i >= checkpoint 31 | checkpoint += 0.1 * files.length 32 | print "." 33 | $stdout.flush 34 | end 35 | 36 | # Error approx 1 s and 1 m 37 | io = IO.popen("./stats #{config[:algorithm]} \"#{path}\" 1 0.00001") 38 | lines = io.readlines 39 | io.close 40 | 41 | unless lines.empty? 42 | results = {} 43 | lines.each do |line| 44 | key, val = *line.split("=") 45 | results[key] = val.strip 46 | end 47 | 48 | points = results["raw_size"].to_i / 24 49 | time = 0 50 | if config[:time] == "compression" 51 | time = results["compr_time"].to_f / 1000 52 | elsif config[:time] == "decompression" 53 | time = results["decompr_time"].to_f / 1000 54 | end 55 | fout.puts "#{points} #{time}" 56 | end 57 | end 58 | puts "." 59 | 60 | fout.close 61 | 62 | gnuplot_instr = <<-END 63 | set autoscale 64 | set xtic auto 65 | set ytic auto 66 | set title "Trajectory size vs execution time (#{config[:n]} trajectories)" 67 | set xlabel "Number of points" 68 | set ylabel "#{config[:time].capitalize} time (ms)" 69 | set size 1.0, 0.6 70 | set terminal postscript portrait enhanced mono dashed lw 1 "Helvetica" 14 71 | set output "size_vs_#{config[:time][0..0]}time-#{config[:algorithm]}-#{config[:n]}.ps" 72 | plot "results.dat" using 1:2 title '#{config[:algorithm]}' with points 73 | END 74 | 75 | open("results.p", "w") do |f| 76 | f.puts gnuplot_instr 77 | end 78 | 79 | `gnuplot "results.p"` 80 | 81 | rm "results.dat" 82 | rm "results.p" 83 | -------------------------------------------------------------------------------- /lossless/trajic/experiments/run_time_vs_ratio.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require './common' 4 | 5 | check_for_executables! 6 | 7 | DATA_ROOT = "/home/aiden/Data/Trajectories/Geolife/Data" 8 | 9 | config = { 10 | :n => 100 11 | } 12 | 13 | files = [] 14 | Find.find(DATA_ROOT) do |path| 15 | if FileTest.file? path and path.end_with? ".plt" 16 | files << path 17 | end 18 | end 19 | 20 | unless config[:n].nil? or config[:n] == :all 21 | files = files[0...config[:n]] 22 | end 23 | 24 | fout = open("results.dat", "w") 25 | 26 | error = 0.1 27 | 28 | while error > 0.00000001 29 | puts error 30 | ["trajic", "dpd", "dp"].each do |alg| 31 | checkpoint = 0.1 * files.length 32 | max_error_kms = -1 33 | usize = 0.0 34 | csize = 0.0 35 | n_trajs = 0 36 | compr_time = 0.0 37 | decompr_time = 0.0 38 | files.each_with_index do |path, i| 39 | if i >= checkpoint 40 | checkpoint += 0.1 * files.length 41 | print "." 42 | $stdout.flush 43 | end 44 | 45 | io = IO.popen("./stats #{alg} \"#{path}\" 0 #{error}") 46 | lines = io.readlines 47 | io.close 48 | 49 | unless lines.empty? 50 | results = {} 51 | lines.each do |line| 52 | key, val = *line.split("=") 53 | results[key] = val.strip 54 | end 55 | 56 | usize += results["raw_size"].to_i 57 | csize += results["compr_size"].to_i 58 | compr_time += results["compr_time"].to_i 59 | decompr_time += results["decompr_time"].to_i 60 | 61 | error_kms = results["max_error_kms"].to_f 62 | max_error_kms = error_kms if error_kms > max_error_kms 63 | 64 | n_trajs += 1 65 | end 66 | end 67 | puts "." 68 | puts "Max error: #{max_error_kms * 1000} m" 69 | puts "Compression ratio: #{csize / usize}" 70 | puts "Average compression time: #{compr_time / n_trajs / 1000} ms" 71 | puts "Average decompression time: #{decompr_time / n_trajs / 1000} ms" 72 | if max_error_kms > 0.1 73 | fout.print "? ? " 74 | else 75 | fout.print "#{csize / usize} #{compr_time / n_trajs / 1000} " 76 | end 77 | end 78 | 79 | puts 80 | fout.puts 81 | error /= 2 82 | end 83 | 84 | fout.close 85 | 86 | gnuplot_instr = <<-END 87 | set autoscale 88 | set xrange[0:1] 89 | set yrange[0:6] 90 | set xtic auto 91 | set ytic auto 92 | set xlabel "Compression ratio" 93 | set ylabel "Compression time (ms)" 94 | set size 1.0, 0.6 95 | set terminal postscript portrait enhanced mono dashed dl 5 lw 1 "Helvetica" 14 96 | set output "time_vs_ratio-#{config[:n]}.ps" 97 | plot "results.dat" using 1:2 lt 1 title 'Trajic' with lines , \ 98 | "results.dat" using 3:4 lt 2 title 'TD-SED + Delta' with lines , \ 99 | "results.dat" using 5:6 lt 4 title 'TD-SED' with lines 100 | END 101 | 102 | open("results.p", "w") do |f| 103 | f.puts gnuplot_instr 104 | end 105 | 106 | `gnuplot "results.p"` 107 | 108 | rm "results.dat" 109 | rm "results.p" 110 | 111 | -------------------------------------------------------------------------------- /lossless/trajic/src/compressor.h: -------------------------------------------------------------------------------- 1 | #ifndef _COMPRESSOR_H_ 2 | #define _COMPRESSOR_H_ 3 | 4 | #include "gps_point.h" 5 | #include "obstream.h" 6 | #include "ibstream.h" 7 | 8 | #include 9 | using namespace std; 10 | 11 | /// An abstract base class for compressing GPS trajectories 12 | class Compressor 13 | { 14 | public: 15 | /// Compresses and writes out a trajectory 16 | virtual void compress(obstream& obs, vector points) = 0; 17 | /// Reads in and decompresses a trajectory 18 | virtual vector decompress(ibstream& ibs) = 0; 19 | }; 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /lossless/trajic/src/constant_predictor.cpp: -------------------------------------------------------------------------------- 1 | #include "constant_predictor.h" 2 | #include "gps_point.h" 3 | #include 4 | 5 | bits64 ConstantPredictor::predict_time(bits64 tuples[][3], int index) 6 | { 7 | double cur = tuples[index - 1][0].dbl; 8 | return bits64{.dbl = cur}; 9 | } 10 | 11 | void ConstantPredictor::predict_coords( 12 | bits64 tuples[][3], int index, bits64* result) 13 | { 14 | GPSPoint cur(tuples[index - 1]); 15 | 16 | double time = predict_time(tuples, index).dbl; 17 | double lat = cur.get_latitude(); 18 | double lon = cur.get_longitude(); 19 | 20 | result[0] = bits64{.dbl = time}; 21 | result[1] = bits64{.dbl = lat}; 22 | result[2] = bits64{.dbl = lon}; 23 | } 24 | -------------------------------------------------------------------------------- /lossless/trajic/src/constant_predictor.h: -------------------------------------------------------------------------------- 1 | #ifndef _CONSTANT_PREDICTOR_H_ 2 | #define _CONSTANT_PREDICTOR_H_ 3 | 4 | #include "predictor.h" 5 | 6 | class ConstantPredictor : public Predictor 7 | { 8 | public: 9 | virtual bits64 predict_time( 10 | bits64 tuples[][3], int index) override; 11 | virtual void predict_coords( 12 | bits64 tuples[][3], int index, bits64* result) override; 13 | }; 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /lossless/trajic/src/csv_reader.cpp: -------------------------------------------------------------------------------- 1 | #include "csv_reader.h" 2 | 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | GPSPoint CSVReader::read_point() 9 | { 10 | double time, lat, lon; 11 | *is >> lat; 12 | is->ignore(numeric_limits::max(), ' '); 13 | *is >> lon; 14 | is->ignore(numeric_limits::max(), ' '); 15 | *is >> time; 16 | is->ignore(numeric_limits::max(), '\n'); 17 | 18 | return GPSPoint(time, lat, lon); 19 | } 20 | 21 | 22 | -------------------------------------------------------------------------------- /lossless/trajic/src/csv_reader.h: -------------------------------------------------------------------------------- 1 | #ifndef _CSV_READER_H_ 2 | #define _CSV_READER_H_ 3 | 4 | #include "gps_reader.h" 5 | 6 | /// CSVReader reads GPS points from a CSV file with lines of the form 7 | /// "