言っていた通り、前回のままではGooglemapに送信したときにエラー(フリーズ)
することが判明したので修正版をあげておきます。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
FILE *fr,*fw;
void KMLlayout(void);
void KMLlayout2(void);
int main (void){
errno_t error;
if((error = fopen_s(&fr,"gpsdata.txt","r")) != 0){
printf("gpsdata File Open Error!");
getchar();
return -1;
}
if((error = fopen_s(&fw,"mapdata.kml","w")) != 0){
printf("mapdata File Open Error!");
return -1;
}
KMLlayout();
int count;
double latitude,longitude;
char c[100];
char endflag[10] ="";
char *token,*nexttoken;
while(1){
count =0;
fscanf_s(fr,"%s",c,100);//fscanfのセキュリティ版
token = strtok_s(c,",",&nexttoken);//文字列を指定した文字で区切る(string.h)
/*終了フラグ*/
if(strcmp(token,endflag) == 0){
break;//2回連続で同じ行を読み込んだら終了する
/*最後の行までいくと最後の行を連続で読み続ける*/
}
strcpy_s(endflag,10,token);
/*変換*/
if(strcmp(token,"$GPGGA") == 0){
while(token != NULL){
if (count == 2){//NMEAとgoogleの経度緯度の順が逆なので分ける
latitude = atof(token);//文字列をdoubleに(stdlib.h)
latitude = latitude/100;//googleの位置フォーマットに合わせる
}
else if(count == 4){//別々の変数に入れる
longitude = atof(token);
longitude = longitude/100;
}
token = strtok_s(NULL,",",&nexttoken);//2度目以降はNULL文字
count++;
}
fprintf(fw,"%f,%f,0.000000 ",longitude,latitude);
}
}
KMLlayout2();
fclose(fr);
fclose(fw);
}
void KMLlayout(void){
fprintf(fw,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://earth.google.com/kml/2.2\">"
"<Document>"
" <name>無題</name>"
" <description><![CDATA[test]]></description>"
" <Style id=\"style1\">"
" <LineStyle>"
" <color>73FF0000</color>"
" <width>5</width>"
" </LineStyle>"
" </Style>"
" <Placemark>"
" <name>line</name>"
" <Snippet></Snippet>"
" <description><![CDATA[]]></description>"
" <styleUrl>#style1</styleUrl>"
" <ExtendedData>"
" <Data name=\"_SnapToRoads\">"
" <value>true</value>"
" </Data>"
" </ExtendedData>"
" <LineString>"
" <tessellate>1</tessellate>"
" <coordinates>");
}
void KMLlayout2(void){
fprintf(fw,"</coordinates>"
" </LineString>"
" </Placemark>"
"</Document>"
"</kml>");
}
#include <string.h>
#include <stdlib.h>
FILE *fr,*fw;
void KMLlayout(void);
void KMLlayout2(void);
int main (void){
errno_t error;
if((error = fopen_s(&fr,"gpsdata.txt","r")) != 0){
printf("gpsdata File Open Error!");
getchar();
return -1;
}
if((error = fopen_s(&fw,"mapdata.kml","w")) != 0){
printf("mapdata File Open Error!");
return -1;
}
KMLlayout();
int count;
double latitude,longitude;
char c[100];
char endflag[10] ="";
char *token,*nexttoken;
while(1){
count =0;
fscanf_s(fr,"%s",c,100);//fscanfのセキュリティ版
token = strtok_s(c,",",&nexttoken);//文字列を指定した文字で区切る(string.h)
/*終了フラグ*/
if(strcmp(token,endflag) == 0){
break;//2回連続で同じ行を読み込んだら終了する
/*最後の行までいくと最後の行を連続で読み続ける*/
}
strcpy_s(endflag,10,token);
/*変換*/
if(strcmp(token,"$GPGGA") == 0){
while(token != NULL){
if (count == 2){//NMEAとgoogleの経度緯度の順が逆なので分ける
latitude = atof(token);//文字列をdoubleに(stdlib.h)
latitude = latitude/100;//googleの位置フォーマットに合わせる
}
else if(count == 4){//別々の変数に入れる
longitude = atof(token);
longitude = longitude/100;
}
token = strtok_s(NULL,",",&nexttoken);//2度目以降はNULL文字
count++;
}
fprintf(fw,"%f,%f,0.000000 ",longitude,latitude);
}
}
KMLlayout2();
fclose(fr);
fclose(fw);
}
void KMLlayout(void){
fprintf(fw,"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<kml xmlns=\"http://earth.google.com/kml/2.2\">"
"<Document>"
" <name>無題</name>"
" <description><![CDATA[test]]></description>"
" <Style id=\"style1\">"
" <LineStyle>"
" <color>73FF0000</color>"
" <width>5</width>"
" </LineStyle>"
" </Style>"
" <Placemark>"
" <name>line</name>"
" <Snippet></Snippet>"
" <description><![CDATA[]]></description>"
" <styleUrl>#style1</styleUrl>"
" <ExtendedData>"
" <Data name=\"_SnapToRoads\">"
" <value>true</value>"
" </Data>"
" </ExtendedData>"
" <LineString>"
" <tessellate>1</tessellate>"
" <coordinates>");
}
void KMLlayout2(void){
fprintf(fw,"</coordinates>"
" </LineString>"
" </Placemark>"
"</Document>"
"</kml>");
}
これはもう完成版で、前回ミスしていたところの修正とkmlへの対応版となっています。
まだkmlのフォーマットについて理解していない部分があるので現在は直線でしか表示できません。
(「ルートに沿う」が出来ない。これはmapの方で指定できます。)
修正の内容について。
まず、前回は$GPGGAの行の2要素(緯度)と4要素目(経度)になればファイルに書き出す、という
流れに任せたプログラムでしたがkmlでは緯度経度が逆の順に並んでいるので、kmlに書き出すと
「北緯135度,東経45度」というあり得ない数値になっていたのが原因のようです。
そこで修正版では一度緯度データをdoubleに保存しておき(この時点ではatof関数によってcharからdoubleに変換されている)、経度も同じように保存してまとめて表示するという文になりました。
経度は特にdoubleに入れる必要はありませんが、どうせなら表示は1か所の方が見やすいので、
緯度経度ともに変数に格納しました。
下の二つのKMLlayoutは、単にプログラム内にkmlのベース文を表示させるだけのプログラムです。
これとの兼ね合いで最初のFILE宣言がグローバルになっています。
あと、ファイルオープンで自動でダイアログが消えないようにgetcharを仕込みました。
まああってもなくてもいいんですけど、ないと成功したのか失敗したのかわかんないので^^;
出力部分を抜けばかなり短い文になった感じですね。
Excelでオセロ作った時は知識もないしすごい長かった記憶が…(笑
たしか1500行くらい使ったような。
こんな感じでたぶんGPSデータをgooglekmlに変換することができたんじゃないかな?
それにしても標準の関数だけでここまで出来るんだなぁー。なんて。
文字比較と文字→数値、文字分割あたりはすごく便利に感じました。
文字系統が全然理解できていないので簡単に使えるといいですよね。
あとはハード的な解決とマイコンの方のプログラムかなー。
0 件のコメント:
コメントを投稿