ArcGIS の Python でのマルチプロセス処理 - 実装例

1020
0
10-24-2019 10:33 PM
Labels (1)

ArcGIS の Python でのマルチプロセス処理 - 実装例

はじめに

前回の ArcGIS の Python でのマルチプロセス処理 の記事で、ArcGIS プラットフォームの拡張手段として定着している ArcPy と Python でのマルチプロセス処理をとりあげ、ベスト プラクティスや、コーディング パターンをサンプルを交えながら紹介させて頂きました。
詳細な解説は、前回の記事をご参照いただきたいですが、コーティング パターンのポイントとしてあげたのは以下の3つです。
  1) ワーカー関数:batch_convert
  2) ワーカー関数のラッパー:multi_run_batch_convert
  3) マルチプロセスの処理:exec_batch_convert
今回の記事では農林水産省が公開している「農地の区画情報(筆ポリゴン)」を例に、前回の記事で取り上げたコーディング パターンに従って、処理を書いてみたコードを公開します

サンプルコード

今回のサンプルは、筆ポリゴンのZIP 解凍後の1つの「都道府県フォルダ」の筆ポリゴンを処理するものです。
1つの「都道府県フォルダ」の下に「各市区町村フォルダ」があり、その下に1つの「シェープファイル」が入っています。
それを「都道府県_filegdbフォルダ」の下に「各市区町村ファイル ジオデータベース」を作成後、「シェープファイル」から「フィーチャクラス」への変換と「市区町村コードと市区町村名を属性に格納する処理」をマルチプロセスで実行します。
また、最終的に各市区町村に分かれている「フィーチャクラス」のマージをシングルプロセスで実行するコードや、マージ後に不要となった「各市区町村ファイル ジオデータベース」の削除も書いています。
#coding:utf-8
#---------------------------------------------------------------------
# Name: Multiprocess_Forge_ShapefileToFeatureClass_uft8.py
# Purpose: 農地の筆界をマルチプロセスでフィーチャクラスに変換
# 自治体コードや自治体名をフィールドに入れる
# フォルダ内のフィーチャクラスをマージしたフィーチャクラスを作成
# Author: Kataya @ ESRI Japan
# Created: xx/10/2019
# Copyright: (c) ESRI Japan Corporation
# ArcGIS Version: 10.x
# Python Version: 2.7
#---------------------------------------------------------------------
import arcpy,os
import sys
import multiprocessing
import datetime
import traceback

reload(sys)
sys.setdefaultencoding('cp932')

def split_citycode_cityname(wsname):
'''
農地筆の自治体コードと自治体名からそれぞれ抽出して返す
フォルダ名の例) 02201青森市2019
    02202弘前市2019
'''

l = len(wsname)
citycode = "'{0}'".format(wsname[:5]) #自治体コードだけを抽出
cityname = '"' + "{0}".format(wsname[5:l-4]) + '"' #自治体名だけを抽出
return citycode, cityname

def multi_run_batch_convert(args):
'''
batch_convertのwrapper:
複数の引数を実行処理に渡すために必要なラッパー
'''

return batch_convert(*args)

def batch_convert(inws, outws):
'''
1プロセスで実行する処理:
1) FGDBへの書込みは仕様で複数プロセスで書込みできないため
1市区町村フォルダ下のシェープファイルを
1市区町村のFGDB下のフィーチャクラスに変換
2) すべてのフィーチャクラスを統合したとき識別しやすいように
フォルダ名から市区町村コードと、自治体名を作成しフィールドに値を格納
'''

print(u"Convert: {0} ⇒ {1}\n".format(inws,outws))
if not arcpy.Exists(outws):
outfolder = u"{0}".format(os.path.dirname(outws))
foldername= u"{0}".format(os.path.basename(outws))
arcpy.CreateFileGDB_management(outfolder, foldername, "CURRENT")
arcpy.env.workspace = inws
fieldname1 = "CITYCODE"
fieldname2 = "CITYNAME"
fcs = arcpy.ListFeatureClasses()
for fc in fcs:
infc=os.path.splitext(fc)[0]
newfc = u"c_{0}".format(infc) #シェープファイル名が数値ではじまり、FGDBへそのまま変換できないので接頭にc_を入れる
wsname = os.path.basename(inws)
citycode, cityname = split_citycode_cityname(wsname) #フォルダ名から自治体コードと自治体名を抽出
## 座標系はそのまま変換
if arcpy.Exists(os.path.join(outws,newfc)):
outfc=os.path.join(outws,newfc)
arcpy.Append_management(fc,outfc)
else:
arcpy.FeatureClassToFeatureClass_conversion(fc,outws,newfc)
outfc=os.path.join(outws,newfc)
arcpy.AddField_management(outfc,fieldname1,"TEXT",field_length=5)
arcpy.AddField_management(outfc,fieldname2,"TEXT",field_length=30)
# citycode, cityname をフィールド値にいれる
calfc = os.path.join(outws,newfc)
arcpy.CalculateField_management(calfc, fieldname1, citycode, "PYTHON_9.3", "#")
arcpy.CalculateField_management(calfc, fieldname2, cityname, "PYTHON_9.3", "#")

del fcs
return u" 変換済:{0}".format(outws)

def exec_batch_convert(infolder,outfolder):
'''
マルチプロセスでの処理:
'''

try:
start=datetime.datetime.now()
print(u"-- Strat: Multiprocess_Forge_ShapefileToFeatureClass --:{0}".format(start))
cpu_cnt=multiprocessing.cpu_count()
arcpy.env.workspace = infolder
inwss = arcpy.ListWorkspaces("*","Folder")
# 各プロセスに渡すパラメータをリスト化
params=[]
for inws in inwss:
param1=inws # 市区町村フォルダ(シェープファイルが入っている)
gdbname=u"{0}.gdb".format(os.path.basename(inws))
param2=os.path.join(outfolder,gdbname) # 市区町村ファイルジオデータベース
params.append((param1,param2))
if len(inwss) < cpu_cnt: # 処理フォルダ数CPUコアより少ない場合無駄なプロセスを起動不要
cpu_cnt=len(inwss)
pool = multiprocessing.Pool(cpu_cnt) # cpu数分プロセス作成
results=pool.map(multi_run_batch_convert,params) # 割り当てプロセスで順次実行される
pool.close()
pool.join()
# 各プロセスでの処理結果を出力
for r in results:
print(u"{0}".format(r))

# 各プロセスからのマージ版を作成
arcpy.env.workspace = outfolder
outwss = arcpy.ListWorkspaces("*","FileGDB")
foldername="{0}.gdb".format(os.path.basename(outfolder))
forgefc = "forge"
print(u" Mearge to FeatureClass:{1} in FGDB:{0} ".format(foldername, forgefc))
arcpy.CreateFileGDB_management(outfolder,foldername,"CURRENT")
forgews = os.path.join(outfolder, foldername)
for outws in outwss:
arcpy.env.workspace = outws
fc = arcpy.ListFeatureClasses()[0] #農地筆は1ファイルしかないので固定
print(u" merge: {0} ⇒ {1}".format(fc,forgefc))
if arcpy.Exists(os.path.join(forgews, forgefc)):
outfc=os.path.join(forgews,forgefc)
arcpy.Append_management(fc,outfc)
else:
arcpy.FeatureClassToFeatureClass_conversion(fc,forgews,forgefc)

# マージが終わったので後片付け 各市区町村のFGDBを削除 - 必要に応じてコメントアウトを外す
#for outws in outwss:
# arcpy.Delete_management(outws)

fin=datetime.datetime.now()
print(u"-- Finish: Multiprocess_Forge_ShapefileToFeatureClass --:{0}".format(fin))
print(u" Elapsed time:{0}".format(fin-start))

except:
print(u"Exception:{0}".format(sys.exc_info()[2]))

def setup_batch_convert():
'''
コマンドプロンプトからの実行パラメータを設定の場合:
市区町村別のシェープファイルが入った都道府県フォルダ :infolder
例)
|-02青森県2019
  |-02201青森市2019
  | 02201青森市2019_5.shp
  |-02202弘前市2019
  | 02202弘前市2019_5.shp
  |-02203八戸市2019
  |-02204黒石市2019
・・・・・
市区町村別のファイル ジオデータベースの作成先フォルダ :outfolder
)
|-02青森県2019_filegdb
  |-02201青森市2019.gdb
  | c_02201青森市2019_5
  |-02202弘前市2019.gdb
  | c_02202弘前市2019_5
  |-02203八戸市2019
  |-02204黒石市2019
・・・・・
  |-02青森県2019_filegdb.gdb # 市区町村別のフィーチャクラスをマージしたフィーチャクラスを格納するファイル ジオデータベース
  | forge
'''
infolder=ur"F:\Temp\農地の筆ポリゴン\02青森県2019" #市区町村別のシェープファイルが入った都道府県フォルダ(平面直角座標系ごと)
outfolder=ur"F:\Temp\農地の筆ポリゴン\02青森県2019_filegdb" #市区町村別のファイル ジオデータベースの作成先フォルダ
exec_batch_convert(infolder,outfolder)


if __name__ == '__main__':
setup_batch_convert()
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

64-bit 環境でのPython スクリプトの実行例

前回の記事と同様、Pythonスクリプトの実行例としてArcGIS Desktop、ArcGIS Proでの例を載せておきます。

実行例)ArcGIS Desktop 10.7.1

>C:\Python27\ArcGISx6410.7\python.exe Multiprocess_Forge_ShapefileToFeatureClass_utf8.py

実行例)ArcGIS Pro 2.4

>"c:\Program Files\ArcGIS\Pro\bin\Python\scripts\propy.bat" Multiprocess_Forge_ShapefileToFeatureClass_utf8.py

参考

Labels (1)
Tags (1)
Version history
Revision #:
1 of 1
Last update:
‎10-24-2019 10:33 PM
Updated by:
 
Contributors