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 小时前
自动化脚本开发最佳实践
运维·自动化
m0_525724723 小时前
Jenkins共享库目录规范解析
自动化
llgdwuhan5 小时前
CPO 架构革新撕开设备缺口:测试 + 耦合双赛道,国产迎来黄金窗口期
自动化·光模块·耦合测试设备·光模块耦合设备·芯片测试设备
测试_AI_一辰8 小时前
AI Agent 评测最隐蔽的坑-记忆
人工智能·算法·ai·自动化·ai编程
学习和思考9 小时前
非自动化专业如何自学PLC?我的6个月学习路线图
笔记·学习·自动化·学习方法
微硬创新10 小时前
如何让4-20mA信号跑上PROFINET高速路?耐达讯自动化NY-PN-A160C给出答案
人工智能·物联网·网络协议·自动化·信息与通信
m0_5257247210 小时前
Jenkins共享库实现流水线复用
自动化·k8s·devops
Black蜡笔小新11 小时前
从智慧社区到雪亮工程:国标GB28181公网平台EasyCVR如何构建视频“一张网”?
人工智能·自动化·easycvr
梦想的旅途212 小时前
企业微信自动化实战:客户资料自动修改与备注同步
运维·自动化·企业微信
梦想的旅途212 小时前
企业微信自动化实战:客户通讯录备份与关系自动迁移
运维·自动化·企业微信