MANDARA – オブジェクトの種類と作成

オブジェクトの種類

形状の種類

点オブジェクト
図形としては位置情報だけを持つ。場所や建物などに使う。
線オブジェクト
端点と任意個数の通過点を持つ折れ線。道路や鉄道などに使う。
面オブジェクト
複数のラインで囲まれた閉じた面。自治体区域などのエリアに使う。

包含関係の種類

通常オブジェクト
それ自身が点/線/面の形状で規定される。集成オブジェクトの構成要素となりうる。
集成オブジェクト
通常オブジェクトや集成オブジェクトの集合体としてのオブジェクト。集成オブジェクトの構成要素となりうる。たとえば最小単位としての市区町村を通常オブジェクトとして、複数の市区町村オブジェクトからなる集成オブジェクトとしての都道府県オブジェクトを構成するなど。

通常オブジェクトの作成

通常オブジェクトを作成・格納するのは地図データファイル(MPF)で、マップエディタ上で複数種類のオブジェクトを作成していく。

点オブジェクトの作成

  1. マップエディタで「オブジェクト編集」を選択
  2. 「新規オブジェクト」ボタンを押すと、画面中央に新たな点オブジェクトが表示される
  3. 点の位置はマウスカーソルを矢印の状態にしてドラッグ
    • 左上に座標または経緯度が表示される。
  4. オブジェクトの名前とオブジェクトグループを入力・選択して「登録」ボタンを押す

線オブジェクトの作成

まず必要に応じて、新たな線種とオブジェクトグループを登録する。

線種の新規登録

  1. 「設定」→「線種設定」→「線種設定」でダイアログ表示
  2. 「線種追加」ボタンを押すと、新規の線種が追加される
    • 線種の名称(ex. 道路)とタイプ(通常オブジェクト/オブジェクトグループ連動)を選択
    • 「パターン」をクリックして線の色とタイプを選択
  3. 「OK」ボタンを押して線種を登録

オブジェクトグループの新規登録

  1. 「設定」→「オブジェクトグループ設定」→「オブジェクトグループ設定」でダイアログ表示
  2. 「グループ追加」ボタンで新規グループが追加される
    • 名称を入力
    • タイプと形状を選択
    • 使用する線種を選択
  3. 「OK」ボタンを押してオブジェクトグループを登録

作成の第1ステップは、オブジェクトの実体としての線を描く。

  1. マップエディタで「ライン編集」を選択
  2. 「新規ライン」ボタンを押すと、画面中央に両端点と中点を持ったラインが表示される
  3. ラインの各点を必要な位置に移動
  4. 通過点の追加削除
    • リンク部分をクリックして新しい通過点を追加
    • 既存の通過点を右クリックして削除
  5. 「登録」ボタンを押してラインを登録

第2ステップは、オブジェクトの作成とラインの関係づけ

  1. 「オブジェクト編集」を選択
  2. 「新規オブジェクト」ボタンを押すと、画面中央に新たな点オブジェクトが表示される
  3. オブジェクトの名称を入力
  4. 目的のオブジェクトグループを選択
    • このとき線形状のオブジェクトグループを選択すると「オブジェクトグループの形状が異なります。」と表示されるが、かまわず「はい」を押す
  5. 目的のラインをクリックするとラインが赤色に変わり、形状が点から線に変わる
  6. オブジェクト代表点をラインの上などに移動して位置決め
  7. 「登録」ボタンを押してオブジェクトを登録

面オブジェクトの作成

  1. まず、必要に応じて線種とオブジェクトを新規登録(線オブジェクトの作成を参照)。
  2. 第1ステップの面の描画は線オブジェクトと同じ手順だが、最後にループとすること。
  3. 第2ステップのオブジェクトの登録は線オブジェクトと同じ。

集成オブジェクトの作成

 

Path2D

概要

Path2DはJavaScriptによるWeb APIの一つで、一連のサブパスを保持する。Path2Dの内容は後に一度に描画される。

コンストラクタ

Path2Dのコンストラクタは3種類。

Path2D()
空のPath2Dオブジェクトをつくる。
Path2D(path)
既存のPath2Dオブジェクトを複製する。
Path2D(d)
SVGパスの文字列を与えてオブジェクトをつくる。

パスの追加

addPath(path)
現在のパスにpathを追加する。

パスの操作

moveTo(x, y)
(x, y)の点に移動する。
lineTo(x, y)
現在の点から(x, y)の点まで直線を引く。
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
現在の点から(x, y)の点までベジエ曲線を描く。
quadraticCurveTo(cpx, cpy, x, y)
現在の点から(x, y)の点まで二次ベジエ曲線を描く。
arcTo(x1, y1, x2, y2, radius)
現在の点から、指定した制御点と半径で円弧を描く。
arc(x, y, radius, startAngle, endAngle, anticlockwise)
(x, y)を中心とした半径radiusの円弧を描く。startAndleが開始角、endAngleが終了角で、デフォルトは時計回りだがanticlockwiseをtrueにすると反時計回りに描く。
ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise)
(x, y)を中心とし、xyの2方向の半径を指定して楕円(弧)を描く。rotationは楕円全体の傾き。その他はarc()と同じ意味。
rect(x, y, width, height)
(x, y)から幅width、高さheightの長方形を描く。

 

BrythonでPath2Dオブジェクトを使う

Brythonでcanvasに描画をする場合、取得したcontextに直接描いていくほかに、Path2Dオブジェクトにサブパスを追加していってから最後に描くという方法がある(HTML5のcanvasを参照)。

BrythonにはPath2Dオブジェクトは実装されていないが、JavaScriptの組み込みクラスを扱う方法によって、Path2Dオブジェクトを使えるようになる。

 

 

BrythonでJavaScriptの組み込みクラスを使う

次の手順でBrythonからJavaScriptのクラスを直接使うことができる。JavaScript側の自作クラスをPythonで使う例はいくつか見かけたが、組込関数はどうかと思って試してみた。

  • browserモジュールからwindowオブジェクトをインポートする
  • JSConstructor()関数の引数にJavaScriptの組み込みクラスのコンストラクタを与えてPythonとしてのコンストラクタを得る
    • ()や引数はつけない
    • 引数に与えるJavaScriptのコンストラクタはwindowオブジェクトに属している
  • 上のコンストラクタを使ってインスタンスを生成

たとえばJavaScriptの組込クラスArrayを使ってみる。

Arrayオブジェクトをつくると、Pythonのリストとして生成されているらしい。メソッドも使えそう。

ところがtoString()メソッドを使おうとするとエラーに。

これを見ると、JavaScriptのコンストラクタを使っているが、Pythonではリストとして解釈されるので、メソッドが存在しない、とエラーになる。上のreverse()sort()は、JavaScriptのArrayクラスのメソッドではなく、Pythonのリストオブジェクトのメソッドとして解釈・実行されたということになる。

Pythonのクラスに定義されていないプロパティにアクセスした場合もエラーになる。

もともとBrythonに該当するものがないJavaScriptのクラスの場合。たとえばPath2Dをつくってみると、JSObjectでラップされたオブジェクトになっているらしい。

このPath2DオブジェクトのmoveTo()lineTo()といったメソッドは問題なく機能して、canvasに描画することができる。

 

Python3 – 関数の引数は値渡しか

参照渡しだが値は保護

以下のコードを実行すると、関数実行の前後で引数に渡した変数の値が影響を受けていない。挙動だけ見ると値渡し(call by value)だが、Pythonの関数引数は参照渡し(call by reference)だという。

実際には、引数を受け取った段階では、元の引数オブジェクトへの参照が渡されているが、その内容が変更されたときに新しいオブジェクトが生成され、元の変数の内容は保たれるらしい。

だが、時には関数に渡した引数の内容を、関数で変更したいような時がある(たとえばシステムの状態に関するフラグの変更など)。そのような変数をglobal定義してもよいが、やはり全体系への汚染のことを考えると気持ちはよくない。

リストを使った場合

以下の例では、要素を1つ持つリストをつくり、そのリストを関数に渡して、関数内でリストの要素の値を変更している。

リストなどのミュータブルなオブジェクトの場合、その内容が関数内での変更の影響を受けている。

クラスを使った場合

以下の例では、カウンタをプロパティに持つクラスをつくり、そのインスタンスを関数に渡して、関数内でインスタンスのカウンタの値を変更している。

変数の内容を特定の関数で変更させたい場合、リストよりもクラスを使った方が意味づけができてよいのではないか。

 

Brython – 日時とタイマ

このページでは、Brythonの外部スクリプトファイルを読み込んで実行している。ページのロード後にその時の日時が表示され、下のボタンを押すたびに現在時刻が1秒間隔で表示され、またそれが停止する。

このページのHTML部分は以下の通りで、ボタンと表示部、スクリプト読み込みが主要部分。

外部スクリプトの内容は以下の通り。global変数は使わず、timerを保持・表示するクラスを関数の引数に渡している。

また、timer.set_interval()の引数に関数を渡す際、インスタンスメソッドを渡すこともできる。

Brythonでのタイマの使い方についてはこちらを参照。

Brythonの開発環境

概要

Brythonの開発環境については、Brython Documentationの”Development Environment“で説明されている。

開発環境のダウンロードと解凍

まず、開発環境のzipファイルをダウンロードする。ファイルは”BrythonX.Y.Z_site_mirror”で、X.Y.Zはバージョン番号。

ダウンロードしたファイルをディレクトリ下に解凍する。以下、このディレクトリを”brython_directory”とする。

サーバの起動・終了

Brythonをローカル環境で開発するため、ローカルサーバを起動する。サーバはPythonでつくられていて、その場所はbrython_directory直下、ファイル名はserver.py。

brython_directoryで、コンソールからpython server.pyと打つとポート8000でローカルサーバが動き出す。

起動時の--portオプション指定で8000以外のポートを割り当てることも可能。

サーバの終了は、サーバが稼働中のコンソールで[CTRL-C]

ファイルの配置と呼び出し

開発するBrythonを呼び出すHTMLファイルを置く場所は、brython_directory/wwwの下に任意のディレクトリを作成して配置。

たとえばbrython_directory/www/brython_test/index.htmlなど。

ブラウザからこのファイルを読みに行く場合は”http://localhost:8000/brython_test/index.html”とする。

 

WordPressでのBrythonの扱い方

注意点

WordPressでBrythonを使うとき、以下の点に気を付けなければならない。

  1. brython.jsを読み込むのはheadセクションだが、カスタムセクションにこれを書くなど、WordPressとしての扱いが必要
  2. onload時にbrython()を実行させる処理が必要
  3. スクリプトをHTML内に直接書くときに、WordPressのエディタの仕様が問題になる(勝手に<p>タグがつけられる)。

Brythonの読み込み

通常はHTMLドキュメントのheadセクションでbrython.jsを読み込むが、WordPressの場合は別途処理しなければならない。

このページでは、Custom CSS and JavaScriptでターゲットを指定している。

onload時の処理

<body>タグがPHPに含まれているので触り難いが、以下のようなjavascriptファイルをheadセクションで読み込んでおけば、onload時に関数が呼ばれてbrython()が実行される(WordPressでのonload処理を参照)。

このページでは、上記ファイルをonload_brython.jsとしてサーバ上に置き、先のBrythonの読み込みの後に、Custom CSS and JavaScriptで読み込んでいる。

スクリプトを直接書く時の注意

Brythonを展開するのに、直接HTMLファイルにスクリプトを書く方法と、外部スクリプトファイルに分ける方法の2つがあるのは他のスクリプトと同じ。

ただしWordPressのエディタのテキストモードでスクリプトをHTML内に直接書く場合、スクリプト中に空行があると勝手に<p>タグが挿入されるので、実行時にエラーとなる。<p>タグを付加するのを抑制するか、あるいは空行なしで書けば正常に実行される。

以下の例は、このページ中に直接Brythonのスクリプトを書いたもの。

あるいは下の例のように、スクリプトを外部ファイルにすれば、問題なく実行される。

 

WordPressで<body onload=…>を使う

WordPressでは<body>タグはphpのコードに書かれているが、それとは別にonload時の実行を、以下のようなjavascriptコードで実現できる。

まず以下のようなjsファイルをアップロードしておく。

custom_jsなどを利用して、headセクションでこのファイルを読み込む。

このページのonload時に、上のファイルが実行されてダイアログが表示されたはず。

 

Python3 – 正規表現 – シンタックス

文字にマッチするもの

一覧

文字 それぞれの文字にマッチする。Python3ではUnicode文字も対象。
. '\n'以外の任意の一文字にマッチする。re.S/re.DOTALLフラグが設定されると’\n’にもマッチする。
[...] 文字クラス。[]内に含まれる文字のいずれか一文字マッチする。'-'で範囲指定も可能。たとえば[abc]abcにマッチ。[a-z]は全ての小文字のアルファベット文字にマッチ。[abcx-z]abcxyzにマッチ。Unicode文字にも対応していて[0-9]は全角の数字にマッチ。先頭に'^'記号があると、その文字クラス以外の文字列がマッチする。たとえば[^abc]abc以外にマッチする。
\d 数字[0-9]にマッチ。Unicode文字の数字も対象となり、全角の数字[0-9]なども対象となる。re.A/re.ASCIIフラグが設定されると[0-9]にのみマッチする。バイト列に対しては[0-9]と等価。
\D 数字以外の文字にマッチ。Unicode文字の数字も除外対象となる。
\w 任意のUnicode単語文字にマッチ。あらゆる単語の一部になりうる文字で、文字・数字・アンダースコアが含まれる。re.ASCIIフラグが設定された場合[a-zA-Z0-9_]にマッチ。バイト列に対しては[a-zA-Z0-9_]と等価。
\W Unicode単語文字以外の文字にマッチ。
\s 任意の空白文字とマッチ。[ \t\n\r\f\v]など。
\S 空白以外の文字にマッチ。

Pythonの標準エスケープも正規表現で認識される。

\a\b\f\n\r\t\u\U\v、\x\\

ただし\bは単語境界を表し、文字クラス内でのみバックスペース文字を表す。

文字クラス

文字クラスはUnicode文字にも対応。

文字クラス内では特殊文字は意味を失い、1つの文字として扱われる。たとえば[(*+)]'(''*''+'')'のいずれかとマッチする。

'^'と、']'は例外で、'^'は先頭の場合のみ否定の意味でそれ以外の位置では文字'^'を表し、']'は末尾では無視されそれ以外の位置では文字']'を表す。

位置にマッチするもの

一覧

^ 文字列の先頭にマッチする。たとえば'^A'は先頭の文字が'A'であることを示す。デフォルトでは文字列全体の先頭だけにマッチするが、re.MULTILINEが指定されていれば、各改行の前にもマッチする。
$ 文字列の末尾にマッチする。たとえば’Z$'は末尾の文字が'Z'であることを示す。デフォルトでは文字列全体の末尾だけにマッチするが、re.MULTILINEが指定されていれば、各改行の後にもマッチする。
\b 単語境界にマッチする。単語境界は[^a-zA-Z0-9]

MULTILINE

re.MULTILINEフラグ指定の有無による動作の違いを確認する。

\b – 文字列境界

文字列境界が[^a-zA-Z0-9]であることが、以下の例で分かる。

繰り返し

 *  直前の文字の0回以上でできるだけ多くの繰り返し。'ab*'abbcに対してaabではなくabbとしてマッチする。
 +  直前の文字の1回以上でできるだけ多くの繰り返し。'ab+'abbbcに対してababbではなくabbbとしてマッチする。'ab?'abb...に対してabとしてマッチする。
 ?  直前の文字が0個か1個でできるだけ多くの場合にマッチ。
{m} 直前の文字のm回の繰り返し。
{m,n} 直前の文字のm回以上n回以下でできるだけ多くの繰り返し。
 {m,}  直前の文字のm回以上でできるだけ多くの繰り返し。
 {,n}  直前の文字のn回以下でできるだけ多くの繰り返し。

実行例

'a*'は長さ0の文字列にもマッチする。マッチした文字列の直後の空文字列にマッチすることが、以下の例でもわかる。

'aa?'aaaにマッチするが、最後のaaaに対しては、先頭のaaにマッチした後、残ったaにマッチしている。

'a{2}'は先頭からaaにマッチしていき、最後のaaaaには2回マッチしている。

'a{,3}'は各マッチの後の長さ0の文字列にもマッチしていて、最後のaaaaに対しては先頭のaaaにマッチした後、残ったaにマッチしている。

選択演算子(|)

'|'で区切られた要素のどれかとマッチすればよいことを表す。

注意点としては、'|'で区切られた要素の左から右へマッチング評価され、ある要素がマッチしたと評価されると、その部分列に対してそれ以降の要素の評価は行われない。

グループ(…)

()で囲んだ要素はグループ化されて、1つの文字と同じ様に扱われる。たとえば次の例では、'Aa'というパターンを1つのグループとして、それが繰り返される回数でマッチングさせている。

後方参照

()囲った部分には、先頭から順番に番号nがふられて、そのあとで'\n'のようにマッチした内容を再利用できる。