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

相关推荐
英英_几秒前
python 自动化教程
开发语言·python·自动化
weixin-WNXZ02181 小时前
闲上淘 自动上货工具运行原理解析
爬虫·python·自动化·软件工程·软件需求
水银嘻嘻14 小时前
12 web 自动化之基于关键字+数据驱动-反射自动化框架搭建
运维·前端·自动化
da-peng-song16 小时前
ArcGIS Desktop使用入门(二)常用工具条——数据框工具(旋转视图)
开发语言·javascript·arcgis
厦门辰迈智慧科技有限公司1 天前
城市综合管廊监测与维护一体化解决方案
物联网·自动化·监测
sy_cora1 天前
IEEE 列表会议第五届机器人、自动化与智能控制国际会议
运维·人工智能·机器人·自动化
云手机管家1 天前
CDN加速对云手机延迟的影响
运维·服务器·网络·容器·智能手机·矩阵·自动化
云手机管家1 天前
账号风控突破:云手机设备指纹篡改检测与反制技术解析
android·运维·网络协议·网络安全·智能手机·矩阵·自动化
玩大数据的龙威1 天前
【ArcGIS技巧】根据地块、界址点图层生成界址线
arcgis
你是一个铁憨憨2 天前
使用深度学习预训练模型检测物体
人工智能·深度学习·arcgis·影像