112 arcpy 发布 mxd地图文件 到 arcgis服务器 为 地图服务

前言

此文档主要是记录一下 最近的一次机遇 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 中看到的效果 一致

相关推荐
云飞云共享云桌面1 小时前
非标自动化研发成本高?云飞云共享云桌面:1台主机=10台工作站,年省数十万。
大数据·运维·服务器·人工智能·自动化·云计算·电脑
紧固视界1 小时前
3C电子自动化装配加速,微型紧固件需求持续增长_2026上海紧固件展 华网上海展
人工智能·自动化·紧固件·上海紧固件展·紧固件展
智航GIS2 小时前
ArcGIS大师之路500技---074ArcGIS数据压缩:解决大文件卡顿的实用技巧
arcgis
北京耐用通信4 小时前
工业通信优选:耐达讯自动化实现CC-Link IE转Modbus RTU稳定传输
人工智能·物联网·网络协议·自动化·信息与通信
新钛云服6 小时前
如何构建一套自动化的阿里云费用报告系统
运维·阿里云·自动化·云计算
不一样的故事1268 小时前
核心预测未来 10 年
运维·安全·自动化
不良人天码星9 小时前
GUI自动化基础(一)
python·ui·自动化
袖手蹲11 小时前
Arduino UNO Q 板载 Nanobot 自动化编程指南之五
运维·自动化
东方不败之鸭梨的测试笔记12 小时前
UI自动化执行时,元素不在视野内,需要拖动滑动条才能找到,这种元素怎么处理?
运维·ui·自动化
新新学长搞科研12 小时前
【高届数人工智能会议】第七届人工智能、网络与信息技术国际学术会议(AINIT 2026)
运维·网络·人工智能·计算机网络·自动化·信号处理·可信计算技术