ホーム > VectorScript > 【VectorScript】 図形の面積値をスクリプトで記入する

【VectorScript】 図形の面積値をスクリプトで記入する

2018/07/07

このスクリプトは、アクティブレイヤの全図形(※1)ひとつひとつのほぼ中心(※2)に面積値(単位は㎡、小数点以下第2位まで)を書き込むためのスクリプトです。(2018/07/09 YouTubeで動作を示した動画を公開)

(※1)スクリプトは全図形を対象としていますが、スクリプト中にコメントした2行を削除すれば、予め手作業で選択した図形を対象にできます。

(※2)面積値を記入する座標としては、図形の境界ボックスの中心(下図)を拾っているので、L形など入り隅があるような図形では面積値が図形の外にこぼれます。その場合は、必要に応じて手動で修正することになります。

2018-07-07_131932.png

*

以下がスクリプトです。行頭をインデントしていないので、多少読みづらいですがご容赦ください。実行に際してはコメント行は不要なので削除しても大丈夫です。またレイヤ名、クラス名、作業レイヤの削除の有無などは、必要に応じてアレンジしてください。動作確認は、Windows版 Vectorworks 2017 で行いました。

なお、VectorScriptの基本的な作り方や実行方法は下記をご覧ください。

Vectorworksベストテクニック100表紙『VECTORWORKS ベストテクニック 100』

今までのVECTORWORKS解説書にはなかった、より便利に速く図面を描くためのVectorworksの使い方を100コ紹介しています。

*

Procedure WriteArea;
VAR
reiya:STRING;

{以下が面積値を記入するためのサブルーチン}
FUNCTION DoIt(h :HANDLE) :BOOLEAN;
VAR
x1,x2,y1,y2:REAL;
BEGIN
{面積記入用の一時的レイヤの設定}
Layer(‘面積記入用一時’);
{面積値を書き込む位置(座標)の設定}
GetBBox(h, x1,y1,x2, y2);
MoveTo( (x1+x2)/2, (y1+y2)/2 );
{面積値書き込み。小数点以下の桁数はHAreaの前の数値で設定。また平方ミリを1000000で割って平方メートルに換算している。}
CreateText(Num2Str(2,HArea(h)/1000000));
{レイヤを元に戻す}
Layer(reiya);
END;
{サブルーチンはここまで}

BEGIN
{作業状況の待避}
PushAttrs;

{アクティブレイヤの名称を取得}
reiya:=GetLName(ActLayer);

{記入用テキストの設定。設定はご随意に。}
TextSize(72);
TextJust(2);
TextVerticalAlign(1);

{作業用にクラス、レイヤの設定}
SetClassOptions(5);
SetLayerOptions(4);

{念のため、あらためてアクティブレイヤを作業用に設定する}
Layer(reiya);

{面積を記入するためのクラスを設定する(存在しない場合は自動追加)}
NameClass(‘面積値(㎡)’);

{選択図形のみに適用する場合は下の2行を削除}
DSelectAll;
SelectAll;

{面積記入用サブルーチンに飛ばす}
ForEachObjectInLayer(DoIt, 2, 0, 0);

{記入した面積値が選択状態になっているので、解除する}
DSelectAll;

{面積値を一時的レイヤから元のアクティブレイヤに移動する(必須ではない)}
Layer(‘面積記入用一時’);
DSelectAll;
SelectAll;
DoMenuTextByName(‘Cut’,0);

Layer(reiya);
DSelectAll;
DoMenuTextByName(‘Paste In Place’,0);
DSelectAll;
{一時的レイヤを削除しない場合は下の行を削除}
DelObject(GetLayerByName(‘面積記入用一時’));

{ここまでが面積値移動のためのスクリプト}

{作業状況の復帰}
PopAttrs;

END;
Run(WriteArea);

*

おまけ

上の動画中にある「削除」や「選択」はいずれも一行スクリプトなので、使う場合は改行を入れずに入力してください。

  • 選択
    DSelectAll; SelectObj((INSYMBOL & INVIEWPORT & (T=TEXT) & (C=’面積値(㎡)’)));
  • 削除(選択するスクリプトの最後に、「 DeleteObjs; 」を付けただけ)
    DSelectAll; SelectObj((INSYMBOL & INVIEWPORT & (T=TEXT) & (C=’面積値(㎡)’)));
    DeleteObjs;

*

<経緯>

ある掲示板に面白そうなネタがありました。以前作ったスクリプト(※)と同じ処理で可能な部分があったので掲示板にちょっとした書き込みをしましたが、せっかくなので自分なりに完成させてみました。

(※)数年前、ある伝統的建造物群保存地区の報告書のために地図を作成しました。この地図は3つの時代の地籍の変化を比較するためのもので、昔の歪んだ地図を現況の地図に合致させながらリライトし、さらに地籍ひとつひとつに地番を書き込む作業が必要でした。数千を超える地積ひとつひとつに手作業で地番を打つとヒューマンエラーが発生しやすいのでVectorScriptで自動処理することにしたのでした。

なお、元のスクリプトでは、ForEachObjectInLayer の部分にForEachObjectInListを使っていましたが、件の談話室でForEachObjectInLayer を使うと良いという指摘があったので、下記ではForEachObjectInLayer を使ってみています。ForEachObjectInListでも同じ結果を得られますが、変数が1つ増えます。

 

<補足>

上に記した報告書用の地籍図データは、下図のような感じです。これは明治初期の状態。元の手書き地図は歪みが甚だしかったので(「歪み」というほど生やさしいものではなかったので)、現状と突き合わせた作図は骨が折れました。今後、機会があればそんなことも含めて記事にしたいと思います。(報告書には地図作成における諸問題についてすでに記されていますが、もうちょっとスキル面からの記事を書いてみようかな、ということ。)

2018-07-07_103941.png

地番等は、Vectorworksのデータベース機能を利用し、Vectorworksの多角形で表現した地籍ひとつひとつにいくつかのフィールドを割り当てています。スクリプトは、それらの項目から地番フィールドを読み出して図形中央に打つためのものでした。不整形な地籍の場合は、文字がこぼれるので、ひとつひとつ手作業で位置を移動しました。大変ではあったけれど、社会的に大きな問題となっていた地域だったので、結果としては有意義な仕事でした。

この後、あらたな必要でデータをGISに落とし込んだりしましたが、それもあまり手間がかからずに可能でした。この手の要求を容易にかなえてくれる点がVectorworksの強みだと思います。私は3Dやレンダリングではなく、Vectorworksのこういう部分が好きです。

広告
カテゴリー:VectorScript
%d人のブロガーが「いいね」をつけました。