Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //土質のみの情報を点群の色調で可視化するプログラム
- //点群の密度は一定
- //"ren69-2.csv"には柱状図1本分の土質のデータがある。
- //このプログラムでは"ren69-2.csv"を読み込み、土質のみの可視化をする実行文を作る。
- //実行文は"test69-2.sh"というShellScriptに出力する。
- //地層を表す土質コードからRGBを指定する。
- //リナックスでShellScriptを走らせると、それによりxyzrgbの情報が"newfile.xyz"1つにまとめられる。
- //参考ネット:C++メモ STLをできるだけ使ってCSVを読み込んでみる
- //参考URL:http://www.tetsuyanbo.net/tetsuyanblog/23821
- #include <iostream>
- #include <string>
- #include <vector>
- #include <fstream>
- #include <sstream> // ※istringstreamを使うために必要
- // 名前空間
- using namespace std;
- //
- // CSVを取得する
- // filename 読み込むファイル名
- // table 読み込んだCSVの内容
- // delimiter 区切り文字(今回はデフォルトでカンマ)
- //
- bool GetContents(const string &filename, vector<vector<string> >& table, const char delimiter = ',')
- {
- // ファイルを開く
- fstream filestream("ren69-2.csv");
- if (!filestream.is_open())
- {
- // ファイルが開けなかった場合は終了する
- return false;
- }
- // ファイルを読み込む
- while (!filestream.eof())
- {
- // 1行読み込む
- string buffer;
- filestream >> buffer;
- // ファイルから読み込んだ1行の文字列を区切り文字で分けてリストに追加する
- vector<string> record; // 1行分の文字列のリスト
- istringstream streambuffer(buffer); // 文字列ストリーム
- string token; // 1セル分の文字列
- while (getline(streambuffer, token, delimiter))
- {
- // 1セル分の文字列をリストに追加する
- record.push_back(token);
- }
- // 1行分の文字列を出力引数のリストに追加する
- table.push_back(record);
- }
- return true;
- }
- //
- // メインメソッド
- //
- int main(int argc, const char * argv[])
- {
- // 変数を定義する
- bool status = false; // メソッドのステータス
- string filename = "ren69-2.csv"; // ファイル名
- vector<vector<string> > table; // 読み込んだCSVファイルの内容
- ofstream fout("test69-2.sh");
- if(!fout)
- {
- cout <<"ファイルをオープンできませんでした。"<<endl;
- return 1;
- }
- else
- {
- cout << "ファイルを作成しました。"<<endl;
- }
- // CSVファイルの内容を取得する
- status = GetContents(filename, table);
- if (!status)
- {
- // 取得に失敗した場合はエラー終了する
- return -1;
- }
- // int m=0;
- // 確認のためにコンソールに内容を出力する
- for (int row = 0; row < table.size(); row++)
- {
- int m=0;
- vector<string> record; // 1行分の内容
- record = table[row]; // 1行分読み込む
- // 1セルずつ読み込んでコンソールに出力する
- for (int column = 0; column < record.size(); column++)
- {
- // fout << record[column]; //エクセルの中身を表示する
- // cout << record[column];
- // // 末尾の列でない場合はカンマを出力する
- // if (column < record.size() - 1)
- // {
- // fout << ",";
- // cout << ",";
- // }
- }
- // fout<<endl;
- // fout <<" 4番目は "<< record[4]<<endl;
- // cout <<" 4番目は "<< record[4]<<endl;
- //s0〜s4は座標や地層の数標高のデータ、ss1〜ss3は一層ごとのデータ
- int s0,s1,s2,s3,s4,ss1,ss2,ss3;
- float ymin,xmin,ymax,xmax;
- float ymin2,xmin2,ymax2,xmax2;
- istringstream(record[0])>>s0;
- istringstream(record[1])>>s1;
- istringstream(record[2])>>s2;
- istringstream(record[3])>>s3;
- istringstream(record[4])>>s4;
- ymin=s0*280-37878.1660;
- xmin=-(s1+1)*230-73881.5077;
- ymax=(s0+1)*280-37878.1660;
- xmax=-(s1)*230-73881.5077;
- //ここでは1マスを4分割した時の細かい座標の補正をする
- if(s2==1){ymin2=ymin,xmin2=xmin,ymax2=ymax-140,xmax2=xmax-115;}
- else if(s2==2){ymin2=ymin+140,xmin2=xmin,ymax2=ymax,xmax2=xmax-115;}
- else if(s2==3){ymin2=ymin,xmin2=xmin+115,ymax2=ymax-140,xmax2=xmax;}
- else if(s2==4){ymin2=ymin+140,xmin2=xmin+115,ymax2=ymax,xmax2=xmax;}
- // cout<<"s0="<<s0<<" , "<<s1<<" , "<<s2<<" , "<<s3<<" , "<<s4<<endl;
- // cout<<"ymin="<<ymin<<endl;
- //このfor文では1層ごとのデータからz座標を求める
- int e=0;
- for(int i=0; i<s3; i++)
- {
- e=3*i+5;
- istringstream(record[e])>>ss1; //record[x]の中身を数値として認識させる
- istringstream(record[e+1])>>ss2;
- istringstream(record[e+2])>>ss3;
- double o1,o2,zmin,zmax; //少数の計算が1発で走らないのでo1,o2を使用した
- o1=(s4-ss1);
- zmax=o1/100;
- o2=(s4-ss2);
- zmin=o2/100;
- unsigned long int pointsize;
- pointsize=(ss2-ss1)*23*28;
- //pointsizeの計算がうまく走らないので高さの/100と1平方メートルの点群量を導く*1は省略
- //(この時、1メッシュ面積の230*280の280を28にする事で対応)
- //本当の計算式はpointsize=(ss2-ss1)/100*230*280*1である。
- //意味は「1平方メートルあたり1個の点群を高さ分つくる」である。
- //このif文では土質コードをRGBに変換している。
- int w,x,y,z,r,g,b;
- w=ss3;
- x= w/100;
- y= (w/10)%10;
- z= w%10;
- if(x== 0){r= 0;}
- else if(x== 1){r= 25;}
- else if(x== 2){r= 50;}
- else if(x== 3){r= 75;}
- else if(x== 4){r= 100;}
- else if(x== 5){r= 125;}
- else if(x== 6){r= 150;}
- else if(x== 7){r= 175;}
- else if(x== 8){r= 200;}
- else if(x== 9){r= 225;}
- if(y== 0){g= 0;}
- else if(y== 1){g= 25;}
- else if(y== 2){g= 50;}
- else if(y== 3){g= 75;}
- else if(y== 4){g= 100;}
- else if(y== 5){g= 125;}
- else if(y== 6){g= 150;}
- else if(y== 7){g= 175;}
- else if(y== 8){g= 200;}
- else if(y== 9){g= 225;}
- if(z== 0){b= 0;}
- else if(z== 1){b= 25;}
- else if(z== 2){b= 50;}
- else if(z== 3){b= 75;}
- else if(z== 4){b= 100;}
- else if(z== 5){b= 125;}
- else if(z== 6){b= 150;}
- else if(z== 7){b= 175;}
- else if(z== 8){b= 200;}
- else if(z== 9){b= 225;}
- m=m+1; //ボーリングの層を数えるための変数
- cout.precision(4);
- fout << "pcl_generate" <<" "<<s0<<"-"<<s1<<"-"<<m<<".pcd "<<"-size "<<pointsize<<fixed<<" -xmin "<<ymin2<<" -ymin "<<xmin2<<" -zmin "<<zmin<<" -xmax "<<ymax2<<" -ymax "<<xmax2<<" -zmax "<<zmax<<endl;
- //今回の研究では平面直角座標のx,y座標の変換が手間であるため、この段階で無理矢理変えておく。
- //以下で『" -xmin "<<ymin2』などとなっているのは、そのためである。
- // fout << "pcl_generate" <<" "<<s0<<"-"<<s1<<"-"<<m<<".pcd "<<"-size "<<pointsize<<" -xmin "<<ymin2<<" -ymin "<<xmin2<<" -zmin "<<zmin<<" -xmax "<<ymax2<<" -ymax "<<xmax2<<" -zmax "<<zmax<<endl;
- // fout<<r<<" "<<g<<" "<<b<<endl;
- // count=count+1;
- // if(count==1)
- // {
- // fout<<"cmake ."<<endl;
- // fout<<"make"<<endl;
- // }
- //xyzの冒頭の説明文を排除して純粋なxyzの数列にする。
- fout<<"./xyzpcd2xyz"<<" "<<s0<<"-"<<s1<<"-"<<m<<".pcd "<<s0<<"-"<<s1<<"-"<<m<<".xyz"<<endl;
- //上で作ったxyzの数列にRGBの情報を追加する。
- fout<<"./xyz2xyzrgb "<<s0<<"-"<<s1<<"-"<<m<<".xyz "<<s0<<"-"<<s1<<"-"<<m<<"tengunxyzrgb.xyz "<<r<<" "<<g<<" "<<b<<endl;
- //今まで作った点群の情報を『newfile.xyz』の1つのファイルにまとめる。
- fout<<"cat "<<s0<<"-"<<s1<<"-"<<m<<"tengunxyzrgb.xyz >> newfile.xyz"<<endl;
- }
- }
- cout<<endl;
- cout << "ファイルに書き込みました。" <<endl;
- cout<<endl;
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement