研究開発

取り込む駅データ(2)

第2章

このプラグインは「m_station.csv」駅のデータ、「station_join.csv」隣り合う駅データの2つのデータを読み込み、描画するものです。
大まかな流れは、

  • 駅データの選択、チェック。
  • 隣り合う駅データの選択、チェック。
  • 駅データの読み込み、解析、描画。
  • 隣り合う駅データの読み込み、解析、描画。

となっています。

メッセージダイアログにファイル名を表示し、ファイル選択ダイアログを出します。
選択したら、ファイルをオープンします。

	Message( '「m_station.csv」ファイルを選択してください。' );
	GetFile( nodefile );
	Open( nodefile );

VectorScriptのファイル入力はテキストベースです。
リードは1レコード(1行)ごとに処理しますが、TSV(Tab Separated Values)区切りのフォーマットであれば、文字データであっても、整数、実数として読み込むことができますが、CSV(Comma Separated Values)の場合、1バイトごとにカンマであるかどうかを解析し、情報を分ける必要があります。

駅データはこのようなデータで始まっています。

   
rr_cd,line_cd,station_cd,line_sort,station_sort,station_g_cd,r_type,rr_name, line_name,station_name,pref_cd,lon,lat,f_flag
11,11101,1110101,11101,1110101,1110101,1,JR,JR函館本線(函館~長万部),函館,1,140.726413,41.773709,1
11,11101,1110102,11101,1110102,1110102,1,JR,JR函館本線(函館~長万部),五稜郭,1,140.733539,41.803557,1
...
...

まず1レコード分dummy変数(STRING)に読み込みます。
次に、Pos関数で、最初のカンマの位置を探します。
Copy関数で、1文字目から filePoint-1 文字分、rr_cd(STRING)変数にコピーします。
ここでは、rr_cdの内容が、'rr_cd' であるかどうかを判定して、選択したファイルが、駅データであるかを判定しています。
あっていなければ、エラーダイアログを出し、ファイルを閉じて、終了。
あっていればファイルを閉じて次へ進みます。

	ReadLn( dummy );
	filePoint := Pos( ',', dummy );
	rr_cd := Copy ( dummy, 1, filePoint-1 );
	IF 	rr_cd <> 'rr_cd' THEN
	BEGIN
		AlrtDialog( '駅データ(マスターデータ)ではないようです。' ) ;
		Close( nodefile );
		GOTO 9999;
	END;
	Close( nodefile );

隣り合う駅データはこのようなデータで始まっています。

     11101,1110101,1110102,,
     11101,1110102,1110103,,
     11101,1110103,1110104,,
      ...
      ...

隣り合う駅データはオープンはせずにファイルパスだけとっておきます。
ファイル選択ダイアログでキャンセルを押された場合には終了です。

	Message( '「station_join.csv」ファイルを選択してください。' );
	GetFile( linkfile );
	IF DidCancel THEN
	BEGIN
		GOTO 9999;
	END;

各駅ごとの情報はレコードとして取っておくため、レコードの初期化をします。
駅情報レコードに鉄道会社コード、鉄道名、...、都道府県名とフィールド名を付けます。

	NewField( '駅情報', '鉄道会社コード', '', 4, 0 );
	NewField( '駅情報', '鉄道名', '', 4, 0 );
	NewField( '駅情報', '路線コード', '', 4, 0 );
	NewField( '駅情報', '路線名', '', 4, 0 );
	NewField( '駅情報', '駅コード', '', 4, 0 );
	NewField( '駅情報', '駅名', '', 4, 0 );
	NewField( '駅情報', '駅グループコード', '', 4, 0 );
	NewField( '駅情報', '駅タイプ', '', 4, 0 );
	NewField( '駅情報', '都道府県コード', '', 4, 0 );
	NewField( '駅情報', '都道府県名', '', 4, 0 );

改めて、駅データをオープンします。1レコード目はもはや不要なので読み飛ばします。
そしてファイルの終わりでない間繰り返します。

	Open( nodefile );
	ReadLn( dummy );

	WHILE NOT EOF( nodefile ) DO
	BEGIN
		ReadLn( dummy );

2行目以降はデータがはいっています。カンマを探して、rr_cd(鉄道概要コード)にコピーします。
次のカンマを探すために、カンマまでをDeleteで削除します。したものを改めてdummy変数にいれます。

		filePoint := Pos( ',', dummy );
		rr_cd := Copy ( dummy, 1, filePoint-1 );
		Delete ( dummy, 1, filePoint );

line_cd、station_cd1、station_g_cd、r_type、rr_name、line_name、station_name、pref_cd
文字データとして必要な情報を変数に溜め込みます。

		filePoint := Pos( ',', dummy );
		line_cd := Copy ( dummy, 1, filePoint-1 );
		Delete ( dummy, 1, filePoint );

		filePoint := Pos( ',', dummy );
		station_cd1 := Copy ( dummy, 1, filePoint-1 );
		Delete ( dummy, 1, filePoint );

		filePoint := Pos( ',', dummy );
		Delete ( dummy, 1, filePoint );

		filePoint := Pos( ',', dummy );
		Delete ( dummy, 1, filePoint );

		filePoint := Pos( ',', dummy );
		station_g_cd := Copy ( dummy, 1, filePoint-1 );
		Delete ( dummy, 1, filePoint );

		filePoint := Pos( ',', dummy );
		r_type := Copy ( dummy, 1, filePoint-1 );
		Delete ( dummy, 1, filePoint );

		filePoint := Pos( ',', dummy );
		rr_name := Copy ( dummy, 1, filePoint-1 );
		Delete ( dummy, 1, filePoint );

		filePoint := Pos( ',', dummy );
		line_name := Copy ( dummy, 1, filePoint-1 );
		Delete ( dummy, 1, filePoint );

		filePoint := Pos( ',', dummy );
		station_name := Copy ( dummy, 1, filePoint-1 );
		Delete ( dummy, 1, filePoint );

		filePoint := Pos( ',', dummy );
		pref_cd := Copy ( dummy, 1, filePoint-1 );
		Delete ( dummy, 1, filePoint );

この2つは緯度経度の情報なので、Str2Numを使って整数化します。

		filePoint := Pos( ',', dummy );
		p1X := Str2Num ( Copy ( dummy, 1, filePoint-1 ) );
		Delete ( dummy, 1, filePoint );

		filePoint := Pos( ',', dummy );
		p1Y := Str2Num ( Copy ( dummy, 1, filePoint-1 ) );
		Delete ( dummy, 1, filePoint );

rr_name(鉄道会社名)ごとにレイヤを分けるためLayerを実行します。
最初の一つだけ路線名を描画するため、路線コードの付いたオブジェクトがないかを探します。
rr_name(鉄道会社名)-line_name(路線名)ごとにクラスを設定するためNameClassを実行します。
路線名でテキストオブジェクトを描画。
テキストオブジェクトに路線コードを名前として付けます。

		Layer( rr_name );
		{		IF rr_cd = '28' THEN}
		BEGIN
			IF GetObject( Concat( 'NJAA_Station', line_cd ) ) = NIL THEN
			BEGIN
				NameClass( Concat( rr_name, '-', line_name ) );
				TextOrigin( p1X, p1Y );
				CreateText ( line_name );
				SetName( LNewObj, Concat( 'NJAA_Station', line_cd ) );
			END;

駅を2D基準点Locusで描画します。次に読み込む隣り合う駅データで検索できるように、station_cd(駅コード)を名前にします。
描画とは関係ありませんが、駅の情報をレコードとして保持します。

			NameClass( Concat( rr_name, '-', line_name ) );
			Locus ( p1X, p1Y );
			SetName( LNewObj, Concat( 'NJAA_Station', station_cd1 ) );
			Record( LNewObj, '駅情報' );
			Field( LNewObj, '駅情報', '鉄道会社コード', rr_cd );
			Field( LNewObj, '駅情報', '鉄道名', rr_name );
			Field( LNewObj, '駅情報', '路線コード', line_cd );
			Field( LNewObj, '駅情報', '路線名', line_name );
			Field( LNewObj, '駅情報', '駅コード', station_cd1 );
			Field( LNewObj, '駅情報', '駅名', station_name );
			Field( LNewObj, '駅情報', '駅グループコード', station_g_cd );
			Field( LNewObj, '駅情報', '駅タイプ', r_type );
			Field( LNewObj, '駅情報', '都道府県コード', pref_cd );

都道府県名はコードで入ってきますが、都道府県名に変換してレコードに保持します。

			IF pref_cd = '1' THEN Field( LNewObj, '駅情報', '都道府県名', '北海道' );
			IF pref_cd = '2' THEN Field( LNewObj, '駅情報', '都道府県名', '青森県' );
			IF pref_cd = '3' THEN Field( LNewObj, '駅情報', '都道府県名', '岩手県' );
			IF pref_cd = '4' THEN Field( LNewObj, '駅情報', '都道府県名', '宮城県' );
			IF pref_cd = '5' THEN Field( LNewObj, '駅情報', '都道府県名', '秋田県' );
			IF pref_cd = '6' THEN Field( LNewObj, '駅情報', '都道府県名', '山形県' );
			IF pref_cd = '7' THEN Field( LNewObj, '駅情報', '都道府県名', '福島県' );
			IF pref_cd = '8' THEN Field( LNewObj, '駅情報', '都道府県名', '茨城県' );
			IF pref_cd = '9' THEN Field( LNewObj, '駅情報', '都道府県名', '栃木県' );
			IF pref_cd = '10' THEN Field( LNewObj, '駅情報', '都道府県名', '群馬県' );
			IF pref_cd = '11' THEN Field( LNewObj, '駅情報', '都道府県名', '埼玉県' );
			IF pref_cd = '12' THEN Field( LNewObj, '駅情報', '都道府県名', '千葉県' );
			IF pref_cd = '13' THEN Field( LNewObj, '駅情報', '都道府県名', '東京都' );
			IF pref_cd = '14' THEN Field( LNewObj, '駅情報', '都道府県名', '神奈川県' );
			IF pref_cd = '15' THEN Field( LNewObj, '駅情報', '都道府県名', '新潟県' );
			IF pref_cd = '16' THEN Field( LNewObj, '駅情報', '都道府県名', '富山県' );
			IF pref_cd = '17' THEN Field( LNewObj, '駅情報', '都道府県名', '石川県' );
			IF pref_cd = '18' THEN Field( LNewObj, '駅情報', '都道府県名', '福井県' );
			IF pref_cd = '19' THEN Field( LNewObj, '駅情報', '都道府県名', '山梨県' );
			IF pref_cd = '20' THEN Field( LNewObj, '駅情報', '都道府県名', '長野県' );
			IF pref_cd = '21' THEN Field( LNewObj, '駅情報', '都道府県名', '岐阜県' );
			IF pref_cd = '22' THEN Field( LNewObj, '駅情報', '都道府県名', '静岡県' );
			IF pref_cd = '23' THEN Field( LNewObj, '駅情報', '都道府県名', '愛知県' );
			IF pref_cd = '24' THEN Field( LNewObj, '駅情報', '都道府県名', '三重県' );
			IF pref_cd = '25' THEN Field( LNewObj, '駅情報', '都道府県名', '滋賀県' );
			IF pref_cd = '26' THEN Field( LNewObj, '駅情報', '都道府県名', '京都府' );
			IF pref_cd = '27' THEN Field( LNewObj, '駅情報', '都道府県名', '大阪府' );
			IF pref_cd = '28' THEN Field( LNewObj, '駅情報', '都道府県名', '兵庫県' );
			IF pref_cd = '29' THEN Field( LNewObj, '駅情報', '都道府県名', '奈良県' );
			IF pref_cd = '30' THEN Field( LNewObj, '駅情報', '都道府県名', '和歌山県' );
			IF pref_cd = '31' THEN Field( LNewObj, '駅情報', '都道府県名', '鳥取県' );
			IF pref_cd = '32' THEN Field( LNewObj, '駅情報', '都道府県名', '島根県' );
			IF pref_cd = '33' THEN Field( LNewObj, '駅情報', '都道府県名', '岡山県' );
			IF pref_cd = '34' THEN Field( LNewObj, '駅情報', '都道府県名', '広島県' );
			IF pref_cd = '35' THEN Field( LNewObj, '駅情報', '都道府県名', '山口県' );
			IF pref_cd = '36' THEN Field( LNewObj, '駅情報', '都道府県名', '徳島県' );
			IF pref_cd = '37' THEN Field( LNewObj, '駅情報', '都道府県名', '香川県' );
			IF pref_cd = '38' THEN Field( LNewObj, '駅情報', '都道府県名', '愛媛県' );
			IF pref_cd = '39' THEN Field( LNewObj, '駅情報', '都道府県名', '高知県' );
			IF pref_cd = '40' THEN Field( LNewObj, '駅情報', '都道府県名', '福岡県' );
			IF pref_cd = '41' THEN Field( LNewObj, '駅情報', '都道府県名', '佐賀県' );
			IF pref_cd = '42' THEN Field( LNewObj, '駅情報', '都道府県名', '長崎県' );
			IF pref_cd = '43' THEN Field( LNewObj, '駅情報', '都道府県名', '熊本県' );
			IF pref_cd = '44' THEN Field( LNewObj, '駅情報', '都道府県名', '大分県' );
			IF pref_cd = '45' THEN Field( LNewObj, '駅情報', '都道府県名', '宮崎県' );
			IF pref_cd = '46' THEN Field( LNewObj, '駅情報', '都道府県名', '鹿児島県' );
			IF pref_cd = '47' THEN Field( LNewObj, '駅情報', '都道府県名', '沖縄県' );
			IF pref_cd = '99' THEN Field( LNewObj, '駅情報', '都道府県名', 'その他' );

1レコードにつき1駅描画してレコードがなくなったら、終了。駅データファイルを閉じます。

Close( nodefile );

続いて、隣り合う駅データファイルをオープンします。
各隣り合う駅データはレコードとして取っておくため、レコードの初期化をします。
隣り合う駅情報レコードに路線コード、路線名、...、駅名2とフィールド名を付けます。

	Open( linkfile );

	NewField( '隣り合う駅情報', '路線コード', '', 4, 0 );
	NewField( '隣り合う駅情報', '路線名', '', 4, 0 );
	NewField( '隣り合う駅情報', '駅コード1', '', 4, 0 );
	NewField( '隣り合う駅情報', '駅名1', '', 4, 0 );
	NewField( '隣り合う駅情報', '駅コード2', '', 4, 0 );
	NewField( '隣り合う駅情報', '駅名2', '', 4, 0 );

ファイルが終わりでない間繰り返します。
カンマを探して、line_cd(路線コード)にコピーします。
次のカンマを探すために、カンマまでをDeleteで削除します。したものを改めてdummy変数にいれます。
続けてカンマを探して、station_cd1(駅コード1)にコピーします。
続けてカンマを探して、station_cd2(駅コード2)にコピーします。
駅コード1を元に1つ目の駅データのハンドルを探します。
駅コード2を元に2つ目の駅データのハンドルを探します。

	WHILE NOT EOF( linkfile ) DO
	BEGIN
		ReadLn( dummy );

		filePoint := Pos( ',', dummy );
		line_cd := Copy ( dummy, 1, filePoint-1 );
		Delete ( dummy, 1, filePoint );

		filePoint := Pos( ',', dummy );
		station_cd1 := Copy ( dummy, 1, filePoint-1 );
		Delete ( dummy, 1, filePoint );

		filePoint := Pos( ',', dummy );
		station_cd2 := Copy ( dummy, 1, filePoint-1 );
		Delete ( dummy, 1, filePoint );

		pt1H := GetObject( Concat( 'NJAA_Station', station_cd1 ) );
		pt2H := GetObject( Concat( 'NJAA_Station', station_cd2 ) );

1つ目の駅、2つ目の駅、両方がある場合に隣り合う駅(線)を描画します。
レイヤとクラスは駅データと同じものを使います。
ハンドルからそれぞれの2D基準点の座標を求めます。
1つ目から2つ目へと線を引きます。
隣り合う駅の情報をレコードとして保持します。

		IF ( pt1H <> NIL ) & ( pt2H <> NIL ) THEN
		BEGIN

			Layer( GetLName( GetLayer( pt1H ) ) );
			NameClass( GetClass( pt1H ) );

			GetLocPt( pt1H, p1X, p1Y );
			GetLocPt( pt2H, p2X, p2Y );

			MoveTo( p1X, p1Y );
			LineTo( p2X, p2Y );
			Record( LNewObj, '隣り合う駅' );
			Field( LNewObj, '隣り合う駅情報', '路線コード', line_cd );
			Field( LNewObj, '隣り合う駅情報', '路線名', GetRField( pt1H, '駅情報', '路線名' ) );
			Field( LNewObj, '隣り合う駅情報', '駅コード1', station_cd1 );
			Field( LNewObj, '隣り合う駅情報', '駅名1', GetRField( pt1H, '駅情報', '駅名' ) );
			Field( LNewObj, '隣り合う駅情報', '駅コード2', station_cd2 );
			Field( LNewObj, '隣り合う駅情報', '駅名2', GetRField( pt2H, '駅情報', '駅名' ) );

		END;

レコードがなくなるまで繰り返したら、ファイルをクローズします。
メッセージウインドウを消して終了です。

	END;

	Close ( linkfile );

9999:ClrMessage;
END;
Run( StationDB );