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 中看到的效果 一致

相关推荐
北京耐用通信2 小时前
自动化通信谜团:耐达讯自动化Modbus RTU如何变身 Profibus连接触摸屏
人工智能·网络协议·自动化·信息与通信
忆~遂愿3 小时前
谷歌云+Apache Airflow,数据处理自动化的强力武器
人工智能·python·深度学习·opencv·自动化·apache
角砾岩队长6 小时前
基于ArcGIS实现Shapefile转KML并保留标注
arcgis
细节控菜鸡6 小时前
【2025最新】ArcGIS for JS二维底图与三维地图的切换
javascript·arcgis
zenithdev113 小时前
开源库入门教程 Cesium:3D地球和地图库
其他·3d·arcgis
守城小轩17 小时前
基于Chrome140的FB账号自动化——需求分析&环境搭建(一)
自动化·facebook·浏览器自动化·指纹浏览器·浏览器开发·超级浏览器·浏览器rpa
zzywxc7872 天前
AI行业应用:金融、医疗、教育、制造业的落地实践与技术创新
人工智能·机器学习·金融·自动化·prompt·ai编程·xcode
葵花日记2 天前
Linux——自动化建构make/makefile
linux·运维·自动化
施努卡机器视觉2 天前
SNK施努卡汽车一体式天幕生产线
运维·机器人·自动化
Lin_Aries_04212 天前
基于 CI/CD(Jenkins)将 Spring Boot 应用自动部署到 Kubernetes 集群
spring boot·ci/cd·docker·容器·自动化·jenkins