軌跡壓縮之Douglas-Peucker算法之C++實現
阿新 • • 發佈:2017-11-03
max delta lose i+1 atan 進行 input main ati
http://www.cnblogs.com/xdlwd086/p/5100425.html
這位學長編了java版本的,於是在借鑒學長的思路的基礎上,做出了C++的實現,以此分享。
#include <stdio.h> //定義輸入/輸出函數 #include <stdlib.h> //定義雜項函數及內存分配函數 #include <ctime> #include <cstdlib> #include <string> #include <sstream> #include <iostream> #include <fstream> #include <iomanip> #include <cmath> using namespace std; #define M_PI 3.14159265358979323846 #define DMax 30.0 long double gps[3150][2]; int gps_visit[3150] = {0}; /* The code of GeoDistance function: Input: Two coordination {Latitude1, Longitude1, Latitude2, Longitude2 } (type:double) Output: Distance(Unit: m) (type:double) */ long double Rad(long double d){ return d * M_PI / 180.0; } //經度 longitude 緯度latitude long double Geodist(long double lon1, long double lat1, long double lon2, long double lat2){ long double radLat1 = Rad(lat1); long double radLat2 = Rad(lat2); long double delta_lon = Rad(lon2 - lon1); long double top_1 = cos(radLat2) * sin(delta_lon); long double top_2 = cos(radLat1) * sin(radLat2) - sin(radLat1) * cos(radLat2) * cos(delta_lon); long double top = sqrt(top_1 * top_1 + top_2 * top_2); long double bottom = sin(radLat1) * sin(radLat2) +cos(radLat1) * cos(radLat2) * cos(delta_lon); long double delta_sigma = atan2(top, bottom); long double distance = delta_sigma * 6378137.0; return distance; } //將2007-10-14-GPS.log文件中的GPS數據提取出來,轉換之後另存起來 void init1(){ ifstream in1; ofstream out1; in1.open("F:\\研一上\\滴滴算法競賽\\城市計算\\Task\\Data\\task 1-compression\\2007-10-14-GPS.log"); out1.open("F:\\研一上\\滴滴算法競賽\\城市計算\\Task\\Data\\task 1-compression\\GPS.txt"); for(int i=0;i<3150;i++){ string temp; getline(in1, temp); string gps_E = temp.substr(20,10); string gps_N = temp.substr(33,9); out1<<gps_E<<" "<<gps_N<<endl; } out1.close(); in1.close(); } void init2(){ ifstream in2; ofstream out2; in2.open("F:\\研一上\\滴滴算法競賽\\城市計算\\Task\\Data\\task 1-compression\\GPS.txt"); out2.open("F:\\研一上\\滴滴算法競賽\\城市計算\\Task\\Data\\task 1-compression\\realGPS1.txt"); for(int i=0;i<3150;i++){ long double gps_E,gps_N; in2>>gps_E>>gps_N; gps_E = (gps_E - 11600.0)*1.0/60+116.0; gps_N = (gps_N - 3900)*1.0/60+39.0; out2 <<setiosflags(ios::fixed)<<setprecision(6)<<gps_E<<" "<<gps_N<<" "<<i+1<< endl; gps[i][0] = gps_E; gps[i][1] = gps_N; } out2.close(); in2.close(); } long double get_d(int point_A,int point_B,int point_C ){ long double a = abs( Geodist(gps[point_B][0],gps[point_B][1],gps[point_C][0],gps[point_C][1] ) ); long double b = abs( Geodist(gps[point_A][0],gps[point_A][1],gps[point_C][0],gps[point_C][1] ) ); long double c = abs( Geodist(gps[point_A][0],gps[point_A][1],gps[point_B][0],gps[point_B][1] ) ); long double p = (a+b+c)/2.0; long double s = sqrtl( abs( p*(p-a)*(p-b)*(p-c) ) ); long double d = s*2.0/c; return d; } void dp_gps(int point_start,int point_end){ if(point_start<point_end){ //遞歸進行條件 long double maxDist = 0; //最大距離 int mid = 0; //最大距離對應的下標 for(int i=point_start+1;i<point_end;i++){ long double temp = get_d(point_start,point_end,i); if(temp>maxDist){ maxDist = temp; mid = i; }//求出最大距離及最大距離對應點的下標 } if(maxDist>=DMax){ gps_visit[mid] = 1; //記錄當前點加入 //將原來的線段以當前點為中心拆成兩段,分別進行遞歸處理 dp_gps(point_start,mid); dp_gps(mid,point_end); } } } int main(){ int count = 0; //記錄輸出點的個數 long double Mean_distance_error; //平均距離誤差 long double Compression_rate; //壓縮率 init1(); init2(); gps_visit[0] = 1; gps_visit[3149] = 1; dp_gps(0,3149); ofstream out3; out3.open("F:\\研一上\\滴滴算法競賽\\城市計算\\Task\\Data\\task 1-compression\\pointID.txt"); for(int i=0;i<3150;i++ ){ if(gps_visit[i]==1){ out3<<i+1<<endl; count++; } } out3.close(); long double sum_notVisit_d = 0; int start = 0,end; for(int i=0;i<3150;){ if(start == 3149) break; //如果開始點是尾點,那就結束 for(int j=start+1;j<3150;j++){ //找出下一個壓縮節點 if(gps_visit[j]==1){ end = j; break; } } for(int k=start+1;k<end;k++ ){ if(gps_visit[k]==0){ sum_notVisit_d+= get_d( start,end,k ); } } start = end; } Mean_distance_error = sum_notVisit_d/3150.0; Compression_rate = count/3150.0; cout<<count<<endl; //輸出壓縮後點的個數 cout<<setiosflags(ios::fixed)<<setprecision(6)<<Mean_distance_error <<endl; cout<<setiosflags(ios::fixed)<<setprecision(4)<<Compression_rate*100<<"%"<<endl; system("pause"); return 0; }
軌跡壓縮之Douglas-Peucker算法之C++實現