土木測量プログラムの開発 (要素入力①)

2017/03/31


器械点登録(既知点)

いよいよ土木測量プログラムの本題に入ります。 まずは器械点データを登録するプログラムを作成します。

入力値はトータルステーションを設置した点の座標値と 0セットしたバックサイトの座標値を入力します。

プログラムが呼び出されるとメインメモリのファイルから、計算で使用される変数の値を呼び出します。

座標値の入力時に F6 キーを押すとメモ番号を聞いてくるので 1~100 の値でメモの座標値が代入されます。

器械点と後視点の座標値入力が終了したら、器械点の座標と後視点の方向角、点間距離が表示されます。

計算結果の表示後キー入力を待ち、表示終了後にメニューへと戻るのですが、 座標値が表示されている場合、F6 キーを押すことで座標メモに登録できるようにします。

最後に入力する器械高は、別に器械高のみを登録するメニューがあるので関数にする。

器械点登録(既知点)の計算

器械点座標(P0)の入力
後視点座標(BS)の入力

P0 と BS の点間距離を計算
P0 → BS の方向角を計算

器械高の入力

器械点座標(P0)の表示
点間距離・方向角の表示
//prog31.h

// 器械(既知点)登録 ********************
void prog31(void) {
int fileHandle, tmp;
    zahyo p0, bs;
    ladata ans;

// データ読み込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_ReadFile (fileHandle, &p0, sizeof(p0), ad_P31_P0);
    tmp = Bfile_ReadFile (fileHandle, &bs, sizeof(bs), ad_P31_BS);
    tmp = Bfile_CloseFile(fileHandle);

// 器械点座標入力
    Bdisp_AllClr_DDVRAM();
    CPrint(3, 1, (char*)"== キカイテン トウロク ==", 0, 0);
    BottomLine(1);
    CPrint(2, 3, (char*)"X P0 =", 0, 0);
    CPrint(2, 4, (char*)"Y P0 =", 0, 0);
    InputXYZ(3, &p0, 0);
    if (FuncKey == 1 || FuncKey == 2) return;

// データ書き込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_SeekFile(fileHandle, ad_P31_P0);
    tmp = Bfile_WriteFile(fileHandle, &p0, sizeof(p0));
    tmp = Bfile_CloseFile(fileHandle);

// 後視点座標入力
    Bdisp_AllClr_DDVRAM();
    CPrint(3, 1, (char*)"== コウシテンン トウロク ==", 0, 0);
    BottomLine(1);
    CPrint(2, 3, (char*)"X BS =", 0, 0);
    CPrint(2, 4, (char*)"Y BS =", 0, 0);
    InputXYZ(3, &bs, 0);
    if (FuncKey == 1 || FuncKey == 2) return;

// データ書き込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_SeekFile(fileHandle, ad_P31_BS);
    tmp = Bfile_WriteFile(fileHandle, &bs, sizeof(bs));
    tmp = Bfile_CloseFile(fileHandle);

// 器械高入力
    InputIH();
    if (FuncKey == 1 || FuncKey == 2) return;

// 計算
    pol (bs.x - p0.x, bs.y - p0.y, &ans);
    kikai.x = p0.x;
    kikai.y = p0.y;
    kikai_ha = ans.a;

// データ書き込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_SeekFile(fileHandle, ad_KIKAI);
    tmp = Bfile_WriteFile(fileHandle, &kikai, sizeof(kikai));
    tmp = Bfile_WriteFile(fileHandle, &kikai_ha, sizeof(kikai_ha));
    tmp = Bfile_CloseFile(fileHandle);

// 計算結果の表示
    Bdisp_AllClr_DDVRAM();
    CPrint(3, 1, (char*)"== キカイテン トウロク ==", 0, 0);
    RevLineC(0, 0, 0);
    BottomLine(1);
    CPrint(2, 2, (char*)"X P0 =", 0, 0);
    PrintNum(8, 2, kikai.x, 0);
    CPrint(2, 3, (char*)"Y P0 =", 0, 0);
    PrintNum(8, 3, kikai.y, 0);
    CPrint(4, 4, (char*)"IH =", 0, 0);
    PrintNum(8, 4, kikai.z, 0);
    CPrint(4, 5, (char*)"HA =", 0, 0);
    PirintDMS(9, 5, kikai_ha, 0);
    CPrint(4, 6, (char*)"HL =", 0, 0);
    PrintNum(8, 6, ans.l, 0);
    Wait();
    if (FuncKey == 1 || FuncKey == 2) return;
    memo = kikai;
    if (FuncKey == 6) SaveMemo();
}

器械点登録(任意点)

トータルステーションを適当な位置にセットし、座標値の確定している2点を測量することで器械点の座標値を得ることができます。

最近のトータルステーションには後方交会法で器械点の座標値を求めるプログラムが搭載されており、複数の既知点を測定することで精度を高めることができます。

ただ、本機に搭載する任意点での器械点登録プログラムは3辺の点間距離を用いて座標値を確定する方法を採用します。 つまり、精度が必要な測量に使用することはお勧めできないということを理解しておいてください。

計算結果の dl は観測データ(2辺と夾角)で得た既知点2点の点間距離と、座標値により得た点間距離の差です。 この差が大きいほど精度があやしいと言えます。

器械点登録(任意点 P0)の計算

後視点座標(P1)の入力(要 0-set)
既知点座標(P2)の入力
  P1 と P2 が同点の場合は入力エラーのため再入力する。
観測データの入力
  P1距離 L1
  P2距離 L2
  夾角   A(P1~P2)
    距離、角度で三角形が構成できない場合は入力エラーのため再入力する。

点間距離の計算( L3 )し誤差( dl )を求める
  座標値で求める ピタゴラスの定理
  観測値で求める 余弦定理

器械点の座標値を求める(余弦定理)
  角度 P1 ( pow(L3, 2) + pow(L1, 2) + pow(L2, 3) ) / ( 2 * L3 * L1 )
  方向角(P1→P2) atan2((p2.x - p1.x), (p2.y - p1.y))

  夾角 < 180 ならば 角度=方向角+夾角
  夾角 > 180 ならば 角度=方向角-夾角

上記の角度と L1 で座標値を計算し P1 の座標値を加えたのが器械点座標

  器械点座標と後視点(P1)で方向角を計算。

器械点座標(P0)の表示
点間距離・方向角の表示

//prog32.h

// 器械(任意点)登録 ********************
void prog32(void) {
    int fileHandle, tmp;
    zahyo p, p1, p2, p3;
    ladata la;
    double d, da, dl;

// データ読み込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_ReadFile (fileHandle, &p1, sizeof(p1), ad_P32_P1);
    tmp = Bfile_ReadFile (fileHandle, &p2, sizeof(p2), ad_P32_P2);
    tmp = Bfile_ReadFile (fileHandle, &p3, sizeof(p3), ad_P32_P3);
    tmp = Bfile_CloseFile(fileHandle);

// P1座標入力
    Bdisp_AllClr_DDVRAM();
    CPrint(1, 1, (char*)"== ニンイテン(P1) トウロク ==", 0, 0);
    BottomLine(1);
    CPrint(2, 3, (char*)"X P1 =", 0, 0);
    CPrint(2, 4, (char*)"Y P1 =", 0, 0);
    InputXYZ(3, &p1, 0);
    if (FuncKey == 1 || FuncKey == 2) return;

// データ書き込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_SeekFile(fileHandle, ad_P32_P1);
    tmp = Bfile_WriteFile(fileHandle, &p1, sizeof(p1));
    tmp = Bfile_CloseFile(fileHandle);

P32_START2:
// P2座標入力
    p = p2;
    Bdisp_AllClr_DDVRAM();
    CPrint(1, 1, (char*)"== ニンイテン(P2) トウロク ==", 0, 0);
    BottomLine(1);
    CPrint(2, 3, (char*)"X P2 =", 0, 0);
    CPrint(2, 4, (char*)"Y P2 =", 0, 0);
    InputXYZ(3, &p, 0);
    if (FuncKey == 1 || FuncKey == 2) return;

// 距離(P1-P2)を求める
    pol(p.x - p1.x, p.y - p1.y, &la);
    if (la.l == 0) goto P32_START2;

// データ書き込み
    p2 = p;
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_SeekFile(fileHandle, ad_P32_P2);
    tmp = Bfile_WriteFile(fileHandle, &p2, sizeof(p2));
    tmp = Bfile_CloseFile(fileHandle);

// 距離角度入力
    p = p3;
    Bdisp_AllClr_DDVRAM();
    CPrint(4, 1, (char*)"== カンソクデータ ==", 0, 0);
    BottomLine(2);
    CPrint(2, 3, (char*)"P1 L =", 0, 0);
    PrintNum(8, 3, p.x, 0);
    CPrint(2, 4, (char*)"P2 L =", 0, 0);
    PrintNum(8, 4, p.y, 0);
    CPrint(2, 5, (char*)"P2 A =", 0, 0);
    PirintDMS(9, 5, p.z, 1);

// L1
P32_START31:
    p.x = InputVal(3, p3.x, 0);
    if (FuncKey == 1 || FuncKey == 2) return;
    if(p.x <= 0) goto P32_START31;
// L2
P32_START32:
    p.y = InputVal(4, p3.y, 0);
    if (FuncKey == 1 || FuncKey == 2) return;
    if(p.y <= 0) goto P32_START32;
// A
P32_START33:
    p.z = InputVal(5, p3.z, 1);
    if (FuncKey == 1 || FuncKey == 2) return;
    if (p.z <= 0) goto P32_START33;
    da = Dms2Rad(p.z);

// 点間距離を計算
    d = sqrt(pow(p.x, 2) + pow(p.y, 2) - 2 * p.x * p.y * cos(da)); // 余弦定理
    dl = ans.l - d;

// 三角形の確認(ヘロン公式を応用)
    d = (p.x + p.y + ans.l) / 2;
    d = d * (d - p.x) * (d - p.y) * (d - ans.l);
    if (d < 0) {
        ErrorWindow(1, 3201);
        if (FuncKey == 1 || FuncKey == 2) return;
        goto P32_START31;
    }

// データ書き込み
    p3 = p;
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_SeekFile(fileHandle, ad_P32_P3);
    tmp = Bfile_WriteFile(fileHandle, &p3, sizeof(p3));
    tmp = Bfile_CloseFile(fileHandle);

// 器械高入力
    InputIH();
    if (FuncKey == 1 || FuncKey == 2) return;

// 計算
    d = (pow(la.l, 2)+pow(p3.x, 2)-pow(p3.y, 2)) / (2 * la.l * p3.x);
    da = acos(d);

    if (p3.z > 180) {
        la.a -= da;
    } else {
        la.a += da;
    }
    la.l = p3.x;

    rec(p3.x, la.a, &p);
    kikai.x = p.x + p1.x;
    kikai.y = p.y + p1.y;

    TS_pol(p1, &la);
    kikai_ha = la.a;

// データ書き込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_SeekFile(fileHandle, ad_KIKAI);
    tmp = Bfile_WriteFile(fileHandle, &kikai, sizeof(kikai));
    tmp = Bfile_WriteFile(fileHandle, &kikai_ha, sizeof(kikai_ha));
    tmp = Bfile_CloseFile(fileHandle);

// 計算結果の表示
    Bdisp_AllClr_DDVRAM();
    CPrint(3, 1, (char*)"== キカイテン トウロク ==", 0, 0);
    RevLineC(0, 0, 0);
    BottomLine(1);
    CPrint(2, 2, (char*)"X P0 =", 0, 0);
    PrintNum(8, 2, kikai.x, 0);
    CPrint(2, 3, (char*)"Y P0 =", 0, 0);
    PrintNum(8, 3, kikai.y, 0);
    CPrint(4, 4, (char*)"IH =", 0, 0);
    PrintNum(8, 4, kikai.z, 0);
    CPrint(4, 5, (char*)"HA =", 0, 0);
    PirintDMS(9, 5, kikai_ha, 0);
    CPrint(4, 6, (char*)"dl =", 0, 0);
    PrintNum(8, 6, dl, 0);
    memo = kikai;
    Wait();
    if (FuncKey == 1 || FuncKey == 2) return;
    if (FuncKey == 6) SaveMemo();
}

器械高登録

器械高の登録プログラムは、器械点登録プログラムを作成した段階で関数として作成しているので、メニューから関数を直接呼び出すだけです。

//prog00.h

// 器械高登録 ************************
void InputIH(void) {
    double z = kikai.z;
    int tmp, fileHandle;
    FuncKey = 0;

// 画面表示
    Bdisp_AllClr_DDVRAM();
    CPrint(3, 1, (char*)"== キカイダカ トウロク ==", 0, 0);
    BottomLine(1);
    CPrint(4, 3, (char*)"IH =", 0, 0);

IH_START:
    z = InputVal(3, z, 0);
    if (FuncKey == 1 || FuncKey == 2) return;
    if (FuncKey == 6) goto IH_MEMO;  // F6 で座標メモ呼び出し
    kikai.z = z;

// データ書き込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_SeekFile(fileHandle, ad_KIKAI + 16);  // 構造体のうち z のみ保存
    tmp = Bfile_WriteFile(fileHandle, &kikai.z, 8);
    tmp = Bfile_CloseFile(fileHandle);
    return;

// 座標メモ呼び出し
IH_MEMO:
    tmp = LoadMemo();
    if (FuncKey == 1 || FuncKey == 2) return;
    if (tmp != 0) z = memo.z;
    goto IH_START;
}

座標変換要素

座標変換要素は器械点(既知点)登録とほぼ同じプログラムになります。

座標変換要素の登録

原点座標の入力
方向座標の入力

方向角を求める

変換原点座標の表示
変換方向角の表示
//prog12.h

// 座標変換要素登録 **********************
void prog12(void) {
    int fileHandle, int tmp;
    zahyo p0, p1;
    ladata la;

// データ読み込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_ReadFile (fileHandle, &p0, sizeof(p0), ad_P12_P0);
    tmp = Bfile_ReadFile (fileHandle, &p1, sizeof(p1), ad_P12_P1);
    tmp = Bfile_CloseFile(fileHandle);

// P1座標入力
    Bdisp_AllClr_DDVRAM();
    CPrint(1, 1, (char*)"== ヘンカンゲンテン トウロク ==", 0, 0);
    BottomLine(1);
    CPrint(2, 3, (char*)"X P0 =", 0, 0);
    CPrint(2, 4, (char*)"Y P0 =", 0, 0);
    InputXYZ(3, &p0, 0);
    if (FuncKey == 1 || FuncKey == 2) return;

// データ書き込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_SeekFile(fileHandle, ad_P12_P0);
    tmp = Bfile_WriteFile(fileHandle, &p0, sizeof(p0));
    tmp = Bfile_CloseFile(fileHandle);

// P2座標入力
    Bdisp_AllClr_DDVRAM();
    CPrint(1, 1, (char*)"== ヘンカンホウコウ トウロク ==", 0, 0);
    BottomLine(1);
    CPrint(2, 3, (char*)"X P1 =", 0, 0);
    CPrint(2, 4, (char*)"Y P1 =", 0, 0);
    InputXYZ(3, &p1, 0);
    if (FuncKey == 1 || FuncKey == 2) return;

// データ書き込み
    fileHandle = Bfile_OpenMainMemory(datafile);
    tmp = Bfile_SeekFile(fileHandle, ad_P12_P1);
    tmp = Bfile_WriteFile(fileHandle, &p1, sizeof(p1));
    tmp = Bfile_CloseFile(fileHandle);

// 計算
    pol(p1.x - p0.x, p1.y - p0.y, &la);
    henkan.x = p0.x;
    henkan.y = p0.y;
    henkan_ha = la.a;

// 計算結果の表示
    Bdisp_AllClr_DDVRAM();
    CPrint(3, 1, (char*)"= ヘンカンヨウソ トウロク =", 0, 0);
    RevLineC(0, 0, 0);
    BottomLine(1);
    CPrint(2, 2, (char*)"X P0 =", 0, 0);
    PrintNum(8, 2, p0.x, 0);
    CPrint(2, 3, (char*)"Y P0 =", 0, 0);
    PrintNum(8, 3, p0.y, 0);
    CPrint(4, 4, (char*)"HA =", 0, 0);
    PirintDMS(9, 4, henkan_ha, 0);
    memo = henkan;
    Wait();
    if (FuncKey == 1 || FuncKey == 2) return;
    if (FuncKey == 6) SaveMemo();
}


今まで作成した関数の取りまとめ。

以前までのプログラムを見直してみると結構なバグが残ったままになっていました。 気が付いたら修正していきますが、関数も増え複雑になってきたので、 今まで作成した関数を取りまとめました。 本稿以降はこの取りまとめたプログラムを追加・修正し、て実務で使用できるプログラムにしてゆきます。 今後、各ページで追加、変更、修正したファイルを更新してゆきます。

初めに新しいプロジェクトを docal という名称で作成します。次のファイルをダウンロード、プロジェクトのフォルダに解凍します。

docal-001.zip