概要
現在表示されているマップの範囲と完全に含まれるフィーチャ、重なるフィーチャ、または表示範囲から指定した距離に含まれるフィーチャを選択するサンプル ツールをご紹介します。
今回はサンプル ツールのため、フィーチャを選択するだけですが、コードの一部を変更することで表示範囲に完全に含まれるフィーチャを一度にクリップ(抽出する)といったことも可能になります。
入力パラメータ
- [選択レイヤ] : 現在アクティブなデータ フレームに追加されているフィーチャ レイヤ
- [選択方法] : フィーチャを選択する方法(完全に含まれる、重なる、指定した距離内にある)
- [距離] : [選択方法] から [表示範囲から指定した距離内にある] を選らんだ場合のみ入力する距離、単位
内容
[選択レイヤ] のドロップ ダウン リストには 現在アクティブなデータ フレームに追加されている レイヤのリストが表示されます。もし、リストから何も選ばずに実行した場合はアクティブなデータ フレームに追加されているすべてのフィーチャ レイヤに対して、ツールが実行されます。
[選択方法] にはデフォルトとして、[表示範囲に完全に含まれる] が設定されていますが、ドロップ ダウン リストから [表示範囲に含まれる]、または [表示範囲から指定した距離内にある] に変更が可能です。また、[表示範囲から指定した距離内にある] を選択した場合は、[距離] パラメータに 距離と単位の設定が可能となります。
使用手順
- zip ファイルをダウンロードし、任意のフォルダに解凍します。
- ArcMap を起動し、データを追加します。
- [カタログ] ウィンドウで解凍により作成されたフォルダを展開します。
- フォルダ内の「SelectExtentTool」ツールボックスを展開し、[表示範囲でフィーチャを選択] ツールをダブルクリックします。
- パラメータを入力し、ツールを実行します。
制限事項
- ArcMap 上で実行した場合のみ有効なツールです。
- データ フレームに座標系が定義されていない場合は、エラーとなります。
- データ フレームの座標系が地理座標系である場合は、フィーチャの選択に失敗します。
ダウンロード
※ ans4465.zip という名前の zip ファイルがダウンロードされます。
Python ソース コード
# coding:cp932
# Purpose : 現在表示されているマップの範囲を使用してフィーチャを選択します。
#
# Author : ESRIジャパン
# ArcPyサイト パッケージ、osモジュールのインポート
import arcpy,os
arcpy.env.overwriteOutput = 1
# mxd,データ フレームを設定します。
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd,mxd.activeView)[0]
if df.spatialReference.name == "":
arcpy.AddError(u"データ フレームに座標系が定義されていないため、ツールを終了します。")
else:
lyrs = arcpy.mapping.ListLayers(mxd,"",df)
for lyr in lyrs:
desc_layer = arcpy.Describe(lyr)
if desc_layer.datatype == u"FeatureLayer":
count = arcpy.GetCount_management(lyr.dataSource)
desc = arcpy.Describe(lyr.dataSource)
OIDField = desc.OIDFieldName
exp = '"' + OIDField + '" =' + str(int(count.getOutput(0)) + 1)
arcpy.SelectLayerByAttribute_management(lyr,"NEW_SELECTION",exp)
else :
lyrs.remove(lyr)
if len(lyrs) == 0:
arcpy.AddError("フィーチャレイヤが存在しません。")
else:
# ツールのパラメータを設定します。
list = arcpy.GetParameterAsText(0)
selectionType = arcpy.GetParameterAsText(1)
distance = arcpy.GetParameterAsText(2)
i = 0
if len(list) == 0:
new_list = lyrs
else:
new_list = list.split(";")
for relist in new_list:
new_list[i] = arcpy.mapping.Layer(relist)
i +=1
arcpy.AddMessage("n")
# 現在のデータ フレームのエクステントを取得
extent = df.extent
# Xmax:右、Ymax:上、Xmin:左、Ymin:下
Xmax = extent.XMax
Ymax = extent.YMax
Xmin = extent.XMin
Ymin = extent.YMin
# 取得した座標値を使用して、四隅に仮想的な
# ポイント オブジェクトを作成します。
point1 = arcpy.Point(Xmax,Ymax)
point2 = arcpy.Point(Xmax,Ymin)
point3 = arcpy.Point(Xmin,Ymin)
point4 = arcpy.Point(Xmin,Ymax)
# 空のArrayオブジェクトを作成し、先ほど作成した
# ポイント オブジェクトからポリゴン オブジェクトを作成します。
array = arcpy.Array()
array.add(point1)
array.add(point2)
array.add(point3)
array.add(point4)
array.add(point1)
polygon = arcpy.Polygon(array)
# 仮想的に作成したポリゴン オブジェクトをツールで使用するために
# [フィーチャのコピー]ツールでフィーチャクラスとして出力します。
# 出力先 in_memory キーワードを指定すると、作業場所として
# 一時的に作成される仮想フォルダを指定できます。
in_memory = "in_memory"
outfc = in_memory + os.sep + r"temp_po"
arcpy.CopyFeatures_management(polygon,outfc)
temp_polygon = arcpy.DefineProjection_management(outfc,df.spatialReference)
# ※os.sep はディレクトの区切り記号を表します。
# ダイアログで設定したレイヤに対して、任意の選択方法を選択し
# 現在の表示範囲を利用してフィーチャの選択を行います。
for lyr in new_list:
# [空間検索]ツールで、レイヤと現在の表示範囲から作成した
# 仮想ポリゴンを使用し、条件分岐によりフィーチャを選択します。
if selectionType == u"表示範囲と重なる":
arcpy.SelectLayerByLocation_management(lyr,"INTERSECT",temp_polygon,"","ADD_TO_SELECTION")
elif selectionType == u"表示範囲内に完全に含まれる":
arcpy.SelectLayerByLocation_management(lyr,"WITHIN",temp_polygon,"","ADD_TO_SELECTION")
elif selectionType == u"表示範囲から指定した距離内にある":
arcpy.SelectLayerByLocation_management(lyr,"WITHIN_A_DISTANCE",temp_polygon,distance,"ADD_TO_SELECTION")
count = arcpy.GetCount_management(lyr)
arcpy.AddMessage(lyr.name + u" レイヤ内の " + str(count.getOutput(0)) + u" フィーチャが選択されました")
# 仮想フォルダを削除します。
arcpy.Delete_management("in_memory")
# マップを再描画を行い、選択状態を表示させます。
arcpy.RefreshActiveView()
arcpy.AddMessage("n")
# mxdへの参照を削除し、解放します。
del mxd
こちらのサンプルはあくまでもコーディングの見本であり、ツール実行時に発生したエラーの対処方法につきましては、サポート対象外とさせていただきます。また、操作方法やソースコードに関するご質問は別途有償の開発者サポート契約にてご対応させていただきます。新規バージョンに対応したツールを継続的に提供することを保証するものでもないことも予めご承知おきください。なお、ツールを利用して生じたいかなる損害についても弊社では責任を負いかねます。
このナレッジはお役に立ちましたか?
フィードバックをいただきありがとうございます!