対象読者 ArcGIS Pro 利用者
実行環境 Windows10, ArcGIS Pro 2.8.2 (python 3.7.10, arcpy 2.8)
はじめに
紛らわしいので、まず最初にお伝えします。
ここで取り上げる CIM は Construction Information Modeling ではありません。
これから説明する CIM は Esri Cartographic Information Model になります。
国交省の BIM/CIM とは別物です。
この後者の CIM を最近知ったのですが、「使える」と思ったのでご紹介します。
CIM を使ったオブジェクト操作
先述の通り CIM は Esri Cartographic Information Model の略で、直訳すると「Esri地図製作情報モデル」でしょうか。
ArcGIS 関連ソフトで採用されているオブジェクトモデルになります。
Arcpy には Mapping というモジュール (Arcpy.mp モジュール) があって、マップに関するオブジェクトにアクセスできるようになっていますが、CIM を使うと arcpy.mp モジュールよりも詳細な設定が可能になります。
マップ、レイアウト、レイヤは、それぞれ .mapx .pagx .lyrx という拡張子のファイルとしてエクスポートできますが、これらが CIM に準拠しています。
これらのファイルはテキストエディタで読むことができて、中身はJSON形式で書かれています。
(拡張子を .json に変えて、対応エディタで開くと読みやすくなります。)
ということで、この中身をエディタで直接書き換えてインポートするという使い方ができるのですが、残念ながらこの方法は非推奨、というか禁止とされています。
理由は、エディタで編集すると、通常ではありえない設定をしてしまう恐れがあるためで、それをしてしまうと、アプリケーションやプロジェクトファイルに悪影響を与えることになります。
では、どうするのかというと CIM 用の API を通じてオブジェクトにアクセスするようにします。
流れとしてはこんな感じです。
1. オブジェクトの取得
2. getDefinition() メソッドでオブジェクト定義の読込
3. オブジェクト定義を API で変更
4. setDefinition() メソッドでオブジェクトにプッシュ
難点は、どこをどう変えればいいのかはちょっとググるくらいでは分からないところです。
GitHub リポジトリにリファレンスもありますが、項目が多すぎて逆に分かりにくいです。
変更項目を特定する正攻法としては、公式ページでおすすめしている通り、変更前後のJSONファイルを比較する方法になります。
あとは、提供されているサンプルスクリプトを参考にするのも良いと思います。
CIM を使ったレイヤのソースの変更
レイヤ操作の簡単な具体例です。
東京都の行政区域ポリゴンを、神奈川県の行政区域ポリゴンに置き換えます。
データは国土数値情報の行政区域ポリゴンを使っています。
設定項目の変更は指定の文字列で置換する方法をとっています。
なお、本コードはフィーチャレイヤを想定したもので、ラスタ等のレイヤについてはエラーが出ます。
ファイルの階層
C:\data
├─N03-20210101_13_GML
│ N03-21_13_210101.shp < 東京都の行政区域ポリゴン
└─N03-20210101_14_GML
N03-21_14_210101.shp < 神奈川県の行政区域ポリゴン
import arcpy
# マップ名
map_name = 'マップ'
# 置換用文字列 レイヤ名とファイル名に使用
name_old = 'N03-21_13_210101'
name_new = 'N03-21_14_210101'
# 置換用文字列 ソースパスに使用
path_old = 'N03-20210101_13_GML'
path_new = 'N03-20210101_14_GML'
# ArcGIS Pro で現在開いているプロジェクトを取得
aprx = arcpy.mp.ArcGISProject("CURRENT")
# マップを取得
m = aprx.listMaps(map_name)[0]
# レイヤリストを取得
lyrs = m.listLayers()
for lyr in lyrs:
# CIM定義を取得
lyrCIM = lyr.getDefinition('V2')
# CIM定義からdataConectionを取得
dc = lyrCIM.featureTable.dataConnection
# レイヤ名を置換
lyrCIM.name = lyrCIM.name.replace(name_old, name_new)
# ファイル名を置換
dc.dataset = dc.dataset.replace(name_old, name_new)
# ソースパスを置換
dc.workspaceConnectionString = dc.workspaceConnectionString.replace(path_old, path_new)
# CIM定義の変更を適用
lyr.setDefinition(lyrCIM)
シンボル表示はそのままで、ファイルソースとレイヤ名が変更されました。
ソースのフォルダパスやレイヤ名を変更することは arcpy.ma モジュールだけでもできるのですが、参照ファイル名の変更は CIM で初めて実現できました。
最後に
CIM の紹介をしました。
複数のレイヤのシンボル情報や結合しているテーブルの情報のようなディープな階層の設定も CIM を使えば実現できると思うので、arcpy.ma モジュールと使い分けながらCIM を使っていきたいと思います。
Python CIM access (Esri 公式ページ)
https://pro.arcgis.com/ja/pro-app/latest/arcpy/mapping/python-cim-access.htm
GitHub リポジトリ
https://github.com/esri/cim-spec
サンプルスクリプト
https://www.arcgis.com/home/item.html?id=8772f61319584882bb697ba003030636