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 小时前
Ubuntu 系统 NVIDIA 显卡驱动自动化安装全流程
linux·ubuntu·自动化
先生沉默先5 小时前
Nginx 反向代理学习:单端口统一访问多服务
学习·nginx·arcgis
施努卡机器视觉20 小时前
SNK施努卡车门自动化安装
运维·自动化
2401_77CN20 小时前
汇川Easy系列PLC封装一阶低通滤波器FC【双线性变换】(定时中断应用,固定步长求解)
笔记·自动化
一晌小贪欢1 天前
【Python办公】用 Selenium 自动化网页批量录入
开发语言·python·selenium·自动化·python3·python学习·网页自动化
垂金烟柳1 天前
MongoDB GridFS 历史数据自动化清理实践
数据库·mongodb·自动化
感谢地心引力1 天前
【ArcGIS Pro】克隆 arcpy 环境(ArcGIS Pro 3.54)
python·arcgis·arcpy·地理处理
奔跑吧邓邓子1 天前
Jenkins自动化持续集成:从入门到实战
ci/cd·自动化·实战·jenkins·自动化持续集成
ALex_zry2 天前
MySQL运维管理技术手册:从监控到自动化实战
运维·mysql·自动化
守城小轩2 天前
基于Chrome140的X账号自动化(关键词浏览)——脚本撰写(二)
自动化·chrome devtools·rpa·浏览器自动化