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

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

2018/07/07

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

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

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

2018-07-07_131932.png

また、このスクリプトでは、面積値をいったん一時的なレイヤに書き込んで、後から元のレイヤ(面積値を記入した図形があるレイヤ)に移動しています。これは一種の保険としてやっているだけで、「選択図形に面積値を書き込む動き」として見れば不要です。

*

以下がスクリプトです(私は VectorScript の専門家ではなく、「必要な結果が得られれば十分」というポリシーです)。行頭をインデントしていないので、多少読みづらいですがご容赦ください。実行に際してはコメント行は不要なので削除しても大丈夫です。またレイヤ名、クラス名、作業レイヤの削除の有無などは、必要に応じてアレンジしてください。それから変数名をreiyaのように頭が悪そうな名前にしていますが、本物の英語である組み込みコマンドと見間違えないようにするためです。動作確認は、Windows版 Vectorworks 2017/2018 で行いました。(某掲示板で、Mac版2018で動いたという報告を頂戴しました。)

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

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

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

*

VectorScriptユーザは分かると思いますが、{}内は注記なので実際の動作には必要ありません。

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の前の数値で設定。また平方ミリを1000^2=1000000で割って平方メートルに換算している。}
CreateText(Num2Str(2,HArea(h)/1000000));
{単位を付ける場合は、上の1行を下記のように変更すればOK。
CreateText(Concat(Num2Str(2,HArea(h)/1000000),’㎡’));
CreateText(Concat(Num2Str(2,HArea(h)/1000000*0.3025),’坪’));
㎡、坪を併記する場合は、Concatで繋げるか、㎡を書かせた後、MoveToで位置をずらしてt坪を書かせるような手順にすればよい。}

{レイヤを元に戻す}
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で自動処理することにしたのでした。

【2018年10月追記】この報告書、インターネットで公開されていました。
http://www.city.fukuyama.hiroshima.jp/soshiki/bunka/129485.html

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

 

<補足>

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

2018-07-07_103941.png

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

この後、あらたな必要でデータをGISに落とし込んだりしましたが、それもあまり手間がかからずに可能でした。この手の要求を容易にかなえてくれる点がVectorworksの強みだと思います。Vectorworksの宣伝や紹介において3Dやレンダリングの能力が強調される場合が多いですが、他のBIMにおいても似たり寄ったりです。Vectorworksのこういう部分こそが強みであると私は思うし、私はこんな使い方をするのが好きです。

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