前言
此文档主要是记录一下 最近的一次机遇 arcpy 来发布 地图文件到 arcgis服务器 上面
arcpy 主要是来自于 ArcGIS_Desktop_105_154030.zip 安装之后会在 python 的安装目录 安装另外的一份带 arcgis 的 python 环境, 然后 本文相关类库 也是基于 这个
arcpy 的 python 环境
然后执行 "import arcpy" 测试 arcpy 的使用, 如下 没有任何 报错, 表示可以正常使用
arcgis 服务器的信息
基于 docker 直接搭建, 然后 不要挂载 任何信息, 相关的问题 会少一些
root@ubuntu:~/docker/arcgis# cat docker-compose.yml
version: '3'
services:
arcgisserver:
image: huas/arcgisserver:10.3.1
container_name: arcgisserver
# volumes:
# - ./gisdata:/arcgis
ports:
- 6080:6080
测试的 mk.mxd 的文件
看一下 我们这里的 mxd 文件, 在 arcmap 中打开效果如下
PublishService.py
然后我们这里发布的代码 也是直接来源于网络
Github 上面 suwenjiang 的 TinyTools 下面的 Publishservice.py
项目链接如下 TinyTools
核心业务 没有任何修改, 仅仅是 调整了一下 注释, 因为原文 注释似乎是乱了
发布代码如下
import sys
import time
import arcpy
__author__ = 'jiangmb'
from arcpy import mapping
import xml.dom.minidom as DOM
import os
import tempfile
# create connection to arcgis server
class CreateContectionFile(object):
def __init__(self):
self.__filePath = None
self.__loginDict = None
def CreateContectionFile(self):
try:
server_url = "http://{}:{}/arcgis/admin".format(self.__loginDict['server'], self.__loginDict['port'])
connection_file_path = str(self.__filePath) #
use_arcgis_desktop_staging_folder = False
if os.path.exists(connection_file_path):
os.remove(connection_file_path)
out_name = os.path.basename(connection_file_path)
path = os.path.split(self.filePath)[0]
print ("++++++++ INFO: before connect to arcgis server succeed ++++++++")
result = mapping.CreateGISServerConnectionFile("ADMINISTER_GIS_SERVICES", path, out_name, server_url, "ARCGIS_SERVER", use_arcgis_desktop_staging_folder, path,
self.__loginDict['userName'], self.__loginDict['passWord'], "SAVE_USERNAME")
print ("++++++++ INFO: connect to arcgis server succeed ++++++++")
return connection_file_path
except Exception as msg:
print (msg)
@property
def filePath(self):
return self.__filePath
@filePath.setter
def filePath(self, value):
self.__filePath = value
@property
def loginInfo(self):
return self.__loginDict
@loginInfo.setter
def loginInfo(self, value):
self.__loginDict = value
# create service definition draft
class CreateSddraft:
def CreateSddraft(self, mapDocPath, con, serviceName, copy_data_to_server=True, folder=None):
mapDoc = mapping.MapDocument(mapDocPath)
sddraft = mapDocPath.replace(".mxd", ".sddraft")
print ("++++++++ INFO: before " + serviceName + " create draft file ++++++++")
result = mapping.CreateMapSDDraft(mapDoc, sddraft, serviceName, 'ARCGIS_SERVER', con, copy_data_to_server, folder)
print ("++++++++ INFO: after " + serviceName + " create draft file ++++++++")
return sddraft
def setTheClusterName(self, xml, clusterName):
doc = DOM.parse(xml)
doc.getElementsByTagName('Cluster')[0].childNodes[0].nodeValue = clusterName
outXml = xml
f = open(outXml, 'w')
doc.writexml(f)
f.close()
return outXml
# publish arcgis service
class PublishServices:
def checkfileValidation(self, mxdLists):
print ("++++++++ INFO: before before check mxd file list ++++++++")
file_to_be_published = []
for file in mxdLists:
mxd = mapping.MapDocument(file)
brknlist = mapping.ListBrokenDataSources(mxd)
if not len(brknlist) == 0:
print ("++++++++ ERROR: process mxd file " + os.path.split(file)[1] + " ++++++++")
else:
file_to_be_published.append(file)
print ("++++++++ INFO: after before check mxd file list ++++++")
return file_to_be_published
def publishServices(self, mxdLists, con, clusterName='default', copy_data_to_server=True, folder=None):
for file in self.checkfileValidation(mxdLists):
serviceName = os.path.splitext(os.path.split(file)[1])[0]
clsCreateSddraft = CreateSddraft()
sddraft = clsCreateSddraft.CreateSddraft(file, con, serviceName, copy_data_to_server, folder)
analysis = arcpy.mapping.AnalyzeForSD(sddraft)
dirName = os.path.split(file)[0]
if analysis['errors'] == {}:
print ("++++++++ WARNING: there are warning as follow +++++++")
print (analysis['warnings'])
sd = dirName + "\\" + serviceName + ".sd"
if (os.path.exists(sd)):
print ("++++++++ INFO: remove old service definition :" + serviceName + " +++++++")
os.remove(sd)
try:
print ("++++++++ INFO: before generate service definition from service definition draft : " + serviceName + " +++++++")
arcpy.StageService_server(sddraft, sd)
print ("++++++++ INFO: after generate service definition from service definition draft : " + serviceName + " +++++++")
print ("++++++++ INFO: before upload service definition to arcgis server : " + str(serviceName) + " ++++++")
arcpy.UploadServiceDefinition_server(sd, con, in_cluster=clusterName)
print ("++++++++ INFO: after upload service definition to arcgis server : " + str(serviceName) + " ++++++")
except Exception as msg:
print (msg)
else:
print ('++++++++ ERROR: process error:' + analysis['errors'] + '++++++++')
time.sleep(5)
sys.exit(1)
def checkWarnings(self, warnings):
for warning in warnings:
if warning[1] == 24011:
print ("++++++++ check warning, received error code 24011 +++++++")
return True
return False
def GetMxFileList(self, filePath):
if not os.path.exists(filePath):
print ("++++++++ ERROR: target mxd folder does not exists +++++++")
sys.exit(1)
list = []
for root, dirname, files in os.walk(filePath):
for file in files:
if os.path.splitext(file)[1] == '.mxd':
mxdfile = os.path.join(root, file)
list.append(mxdfile)
if list == []:
print ("++++++++ INFO: collected empty mxd file list ++++++++")
time.sleep(5)
sys.exit(1)
return list
def publishMxdFolder():
server = "192.168.220.133"
userName = "admin"
passWord = "admin@2021"
port = "6080"
mxdDir = "D:\\Jobs\\99_arcgis\\mxd\\test01Mk"
servic_dir = "jerry_20230620"
clusterName = "default"
logDict = {
'server': server,
'userName': userName,
'passWord': passWord,
'port': port
}
contionfile = os.path.join(tempfile.mkdtemp(), 'server.ags')
instace = CreateContectionFile()
instace.filePath = contionfile
instace.loginInfo = logDict
instace.CreateContectionFile()
if (os.path.isfile(contionfile) == False):
print ("++++++++ ERROR: connect to arcgis server failed ++++++++")
time.sleep(5)
sys.exit(1)
clsPublishservice = PublishServices()
fileList = clsPublishservice.GetMxFileList(mxdDir)
if len(servic_dir) == 0:
servic_dir == None
if len(clusterName) == 0:
clusterName = 'default'
clsPublishservice = PublishServices()
clsPublishservice.publishServices(fileList, contionfile, clusterName, copy_data_to_server=False, folder=servic_dir)
if __name__ == '__main__':
publishMxdFolder()
然后执行给定的脚本, 日志信息如下
++++++++ INFO: before connect to arcgis server succeed ++++++++
++++++++ INFO: connect to arcgis server succeed ++++++++
++++++++ INFO: before before check mxd file list ++++++++
++++++++ INFO: after before check mxd file list ++++++
++++++++ INFO: before mk create draft file ++++++++
++++++++ INFO: after mk create draft file ++++++++
++++++++WARNING: there are warning as follow +++++++
{(u'Map is being published with data copied to the server using data frame full extent', 10045): [], (u"Layer's data source is not registered with the server and data will be copied to the server", 24011): [<map layer u'mk'>, <map layer u'lyjq'>], (u'Missing Tags in Item Description', 24059): [], (u"Layer's data source doesn't have a spatial index", 10002): [<map layer u'mk'>], (u'Missing Summary in Item Description', 24058): []}
++++++++ INFO: remove old service definition :mk +++++++
++++++++ INFO: before generate service definition from service definition draft : mk +++++++
++++++++ INFO: after generate service definition from service definition draft : mk +++++++
++++++++ INFO: before upload service definition to arcgis server : mk ++++++
++++++++ INFO: after upload service definition to arcgis server : mk ++++++
然后 刷新 arcgis服务器 上面的服务信息, 就可以看到对应的服务信息
mk 服务的 rest url 信息如下
客户端的使用
然后前端这边 使用给定的图层服务信息, 这里使用的是 ol 包
let tileSources = new TileArcGISRest({
url:'http://192.168.220.133:6080/arcgis/rest/services/jerry_20230620/mk/MapServer'
});
let tileLayers = new Tile({
className:'testLayer',
source: tileSources,
zIndex: 1,
});
this.map.addLayer(tileLayers);
页面上查看效果, 和 arcmap 中看到的效果 一致
完