面倒なので ArcGIS Server のセットアップを ArcPy で自動化しました。
使える部品を紹介していきます。
ArcPyの環境構築
ArcGIS Desktopを入れます。
ArcPyの実行
例えば ArcGIS Desktop 10.5 をインストールし、Python をデフォルト設定でインストールした場合は以下のようになります。
C:\Python27\ArcGIS10.5\python.exe -B E:\Scripts\sample.py
-B で .cpy ファイルを作らないようにしています。
Arc Catalog にデータベース接続を追加する
- out_dir、file_name で接続ファイルのパスとファイル名を指定します。
- db_platform でデータベースの種類を指定します(SQLServer、Oracle、…)
- account_authentication で認証方式を指定します。
- DATABASE_AUTH: DB認証
- OPERATING_SYSTEM_AUTH: OS認証
- save_user_pass でユーザー名とパスワードを接続ファイルに保存するかどうかを指定します。
- SAVE_USERNAME: 保存する
- DO_NOT_SAVE_USERNAME: 保存しない
import arcpy
out_dir = r'C:\Users\someone\AppData\Roaming\ESRI\Desktop10.5\ArcCatalog'
file_name = 'db.sde'
db_platform = 'SQL_SERVER'
instance = 'SAMPLE'
account_authentication = 'DATABASE_AUTH'
user_name = 'user'
user_pass = 'pass'
save_user_pass = 'SAVE_USERNAME'
db_name = 'TEST_DB'
arcpy.CreateDatabaseConnection_management(out_dir,
file_name,
db_platform,
instance,
account_authentication,
user_name,
user_pass,
save_user_pass,
db_name)
参考
データベース接続の作成 (Create Database Connection)—ヘルプ | ArcGIS for Desktop
データベースまたは、エンタープライズ、ワークグループ、デスクトップ ジオデータベースへの接続ファイルを作成するための ArcGIS ジオプロセシング ツールです。
Arc Catalog に ArcGIS Server の接続を追加する
- gisserver_connection_type で接続の設定をします。
- USER_GIS_SERVICES: GISサービスを使用する
- PUBLISH_GIS_SERVICES: GISサービスを公開する
- ADMINISTER_GIS_SERVICES: GISサービスを管理する
- out_dir、file_name で接続ファイルのパスとファイル名を指定します。
- save_user_pass でユーザー名とパスワードを接続ファイルに保存するかどうかを指定します。
- SAVE_USERNAME: 保存する
- DO_NOT_SAVE_USERNAME: 保存しない
import arcpy
gisserver_connection_type = 'ADMINISTER_GIS_SERVICES'
out_dir = r'C:\Users\someone\AppData\Roaming\ESRI\Desktop10.5\ArcCatalog'
file_name = 'arcgisserverconn.ags'
arcgisserver_url = 'http://server:6080/arcgis/admin'
server_type = 'ARCGIS_SERVER'
use_arcgis_desktop_staging_folder = False
staging_folder_path = out_dir
user_name = 'user'
user_pass = 'pass'
save_user_pass = 'SAVE_USERNAME'
arcpy.mapping.CreateGISServerConnectionFile(gisserver_connection_type,
out_dir,
file_name,
arcgisserver_url,
server_type,
use_arcgis_desktop_staging_folder,
staging_folder_path,
user_name,
user_pass,
save_username_password)
参考
CreateGISServerConnectionFile—Help | ArcGIS for Desktop
ArcPy function to create a GIS Server Connection file.
ArcGIS Serverのデータストアにデータベースを追加する
- server_connection_file_full_pathでArcGIS Serverの接続ファイル(.ags)のフルパスを指定する.
- datastore_typeでデータストアの形式を指定する.
- DATABASE: データベース
- FOLDER: フォルダー
- connection_nameで接続に名前を付ける.
- db_connection_file_full_pathでデータベース接続ファイル(.sde)のフルパスを指定する.
import arcpy
server_connection_file_full_path = r'C:\Users\someone\AppData\Roaming\ESRI\Desktop10.5\ArcCatalog\arcgisserverconn.ags'
datastore_type = 'DATABASE'
connection_name = 'TEST_DB'
db_connection_file_full_path = r'C:\Users\someone\AppData\Roaming\ESRI\Desktop10.5\ArcCatalog\db.sde'
arcpy.AddDataStoreItem(server_connection_file_full_path,
datastore_type,
conn_name,
db_connection_file_full_path,
db_connection_file_full_path)
参考
AddDataStoreItem—ArcGIS Pro | ドキュメント
Registers a folder or database with an ArcGIS Server site.
mxd ファイルのデータソースを修正する
DBサーバーのリプレースに伴い、データソースを修正する必要がありました。GUIでやるのは超めんどくさいので ArcPy で自動化しました。
下のスクリプトでは念のため編集前の mxd のバックアップを取っています。
import arcpy
import os
base_dir = r'E:\MXD'
backup_dir = os.path.join(base_dir, 'backup')
modified_dir = os.path.join(base_dir, 'modified')
mxd_files = ['a.mxd', 'b.mxd', 'c.mxd', 'd.mxd', 'e.mxd']
old_sde = r'C:\Users\someone\AppData\Roaming\ESRI\Desktop10.1\ArcCatalog\old_db.sde'
new_sde = r'C:\Users\someone\AppData\Roaming\ESRI\Desktop10.5\ArcCatalog\db.sde'
for f in mxd_files:
file_full_path = os.path.join(c.base_dir, f)
# バックアップを取る
shutil.copy(file_full_path, backup_dir)
# mxdファイルを開いてデータソースを付け替える
mxd = arcpy.mapping.MapDocument(file_full_path)
mxd.findAndReplaceWorkspacePaths(old_sde, new_sde)
# mxdファイルを別ファイルとして保存する
modified_file_path = os.path.join(modified_dir, f)
mxd.saveACopy(modified_file_path)
del mxd
参考
Updating and fixing data sources with arcpy.mapping—Help | ArcGIS for Desktop
You can update and fix data sources with arcpy.mapping.
ArcGIS Serverのサービスを公開する
いちいち 1 個ずつ mxd ファイル開いてサービスを公開するのが辛いので ArcPy で自動化しました。
デフォルトで公開する
デフォルトの設定でサービスを公開する場合は以下になります。
流れは「分析してドラフトサービスを作成する→ドラフトサービスからサービス定義を作成する→サービス定義からサービスを公開する」です。
import arcpy
import os
mxd_dir = r'E:\MXD'
mxd_files = ['a.mxd', 'b.mxd', 'c.mxd', 'd.mxd', 'e.mxd']
sddraft_dir = r'E:\MXD\SDDRAFT'
sd_dir = r'E:\MXD\SD'
server_type = 'ARCGIS_SERVER'
server_connection_file_full_path = r'C:\Users\someone\AppData\Roaming\ESRI\Desktop10.5\ArcCatalog\arcgisserverconn.ags'
for mxd_file in mxd_files:
mapDoc = arcpy.mapping.MapDocument(os.path.join(c.mxd_dir, mxd_file))
service_name = mxd_file.split('.mxd')[0]
sddraft = os.path.join(sddraft_dir, '{0}.sddraft'.format(service_name))
sd = os.path.join(sd_dir, '{0}.sd'.format(service_name))
summary = ''
tags = ''
# 分析してドラフトサービスを作成する.
analysis = arcpy.mapping.CreateMapSDDraft(mapDoc,
sddraft,
service_name,
server_type,
server_connection_file_full_path,
True,
None,
summary,
tags)
# 分析結果にエラーが無ければサービスを公開する.
if analysis['errors'] == {}:
# ドラフトサービスからサービス定義を作成する.
arcpy.StageService_server(sddraft, sd)
# サービス定義からサービスを公開する.
arcpy.UploadServiceDefinition_server(sd, server_connection_file_full_path)
else:
# 分析結果にエラーがあったら表示する.
print(analysis['errors'])
ドラフトサービスを修正してサービスを公開する
例えば KML を無効にして Feature Access を有効にする場合は以下の通りです。
ドラフトサービスを頑張って編集します。
import arcpy
import os
import codecs
import xml.dom.minidom as DOM
mxd_dir = r'E:\MXD'
mxd_files = ['a.mxd', 'b.mxd', 'c.mxd', 'd.mxd', 'e.mxd']
sddraft_dir = r'E:\MXD\SDDRAFT'
sd_dir = r'E:\MXD\SD'
server_type = 'ARCGIS_SERVER'
server_connection_file_full_path = r'C:\Users\someone\AppData\Roaming\ESRI\Desktop10.5\ArcCatalog\arcgisserverconn.ags'
for mxd_file in mxd_files:
mapDoc = arcpy.mapping.MapDocument(os.path.join(c.mxd_dir, mxd_file))
service_name = mxd_file.split('.mxd')[0]
sddraft = os.path.join(sddraft_dir, '{0}.sddraft'.format(service_name))
sd = os.path.join(sd_dir, '{0}.sd'.format(service_name))
summary = ''
tags = ''
# 分析してドラフトサービスを作成する.
analysis = arcpy.mapping.CreateMapSDDraft(mapDoc,
sddraft,
service_name,
server_type,
server_connection_file_full_path,
True,
None,
summary,
tags)
# 分析結果にエラーが無ければサービスを公開する.
if analysis['errors'] == {}:
# sddraftを読み込む.
doc = DOM.parse(sddraft)
# kmlを無効にする.
services___ = doc.getElementsByTagName('TypeName')
for service__ in services___:
if service__.firstChild.data == 'KmlServer':
service__.parentNode.getElementsByTagName('Enabled')[0].firstChild.data = 'false'
# Feature Accessを有効にする.
for service__ in services___:
if service__.firstChild.data == 'FeatureServer':
service__.parentNode.getElementsByTagName('Enabled')[0].firstChild.data = 'true'
# 保存する.
if os.path.exists(sddraft):
os.remove(sddraft)
f = codecs.open(sddraft,"w",'utf-8')
doc.writexml(f, '', '\t','','utf-8')
f.close()
# ドラフトサービスからサービス定義を作成する.
arcpy.StageService_server(sddraft, sd)
# サービス定義からサービスを公開する.
arcpy.UploadServiceDefinition_server(sd, server_connection_file_full_path)
else:
# 分析結果にエラーがあったら表示する.
print(analysis['errors'])
参考
Specifying map service parameters when publishing with ArcPy?
I publish map services on a ArcGIS server using the typical arcpy script below. I need to better specify some service parameters. For example, the service shoul...