ArcGis系列-java发布空间表为地图服务(map)

1,实现思路

  1. 使用java调用cmd命令执行python脚本
  2. python环境使用arcgis pro安装目录下的 \ArcGIS\Pro\bin\Python\envs\arcgispro-py3
  3. 作为地图服务应该可以支持添加样式文件
  4. 发布表需要用到sde文件,使用java创建sde的代码可以看这里
  5. 发布表时,先在本地的空项目模板中添加数据库表作为图层,然后上传发布这个项目

2,java实现

execSync异步调用参考上一篇文章

     /**
     * 调用python发布sqlserver数据库表到arcgis
     *
     * @param sde       sde文件路径 D:\\ITS\\itsPython\\192.168.10.153.sde
     * @param host      arcgis地址 https://aaa.myarcgis.com/arcgis
     * @param name      arcgis用户名 username
     * @param password  arcgis密码 xxxx
     * @param table     表名 STB
     * @param stylePath 样式文件路径 D:/ITS/temp/dbid/xxx.lyrx
     * @return
     * @throws Exception
     */
    public String publishTableToArcgisV2(String sde, String host, String name, String password, String table, String stylePath) throws Exception {
        host = host.replace(":6443", "");
        sde = sde.replace("\\", "/");
        List<Object> params = new ArrayList<>();
        params.add("cmd.exe");
        params.add("/c");
        params.add("python");
        String pyScriptName = scriptLocation + File.separator + PY_CREATE_TABLE2;
        params.add(pyScriptName);
        params.add(sde);
        params.add(host);
        params.add(name);
        params.add(password);
        params.add(table);
        params.add(stylePath);
        String[] arr = params.toArray(new String[params.size()]);
        log.info("发布空间表及样式参数:{}", Arrays.toString(arr));
        //publish_single_table("D:\\ITS\\itsPython\\192.168.10.153.sde", "https://aaa.myarcgis.com/arcgis", "lzwpro", "lzwpro123", "SD","D:/ITS/temp/dbid/xxx.lyrx")
        int i = execSync(pyScriptName, arr);
        if (i == 0) {
            //https://lzw.gis107.com/server/rest/services/SD/MapServer
            return getPublishTableMapUrl(host, table);
        } else {
            throw new Exception("执行python异常");
        }
    }

3,python脚本

  • 发布表是在本地一个空的项目作为模板(D:\ITS\map\MyProject2),添加数据库表,生成草稿文件来发布;
  • 空项目文件可以使用arcgis pro创建项目删除所有地图得到;
  • 添加表图层时要根据空间表实际类型来,区分矢量表和栅格表;
  • 指定发布目录是要确保目录在arcgis已创建,发布图层这里设置的覆盖且直接公开;
  • 某些空间表的坐标系可能有些差异,为了统一需要指定项目的坐标系为前端渲染需要的坐标系;
# -*- coding: UTF-8 -*-
import arcpy
import os
import calendar
import time
import shutil

# 覆盖
arcpy.env.overwriteOutput = True
log_file = open("D:/ITS/pythonlog.txt", "w")
sys.stdout = log_file
sys.stderr = log_file

projectDir = r"D:\ITS\map"
templateProject = "MyProject2"
targetProject = "project_" + str(calendar.timegm(time.gmtime()))
targetProjectPath = os.path.join(projectDir, targetProject)
aprxName = "MyProject2.aprx"


def publish_single_table(sde, host, name, password, table, sstylefile):
    arcpy.env.workspace = sde
    service_name = "map_" + table.split(".")[-1]
    shutil.copytree(os.path.join(projectDir, templateProject), targetProjectPath)
    mpmath = os.path.join(targetProjectPath, aprxName)
    aprx = arcpy.mp.ArcGISProject(mpmath)  # aprx存储路径
    aprx_map = aprx.listMaps("*")[0]  # 要将数据添加到aprx中的哪个地图下
    sde_list = arcpy.ListFeatureClasses()
    # 遍历矢量图层
    print("add layer")
    for item in sde_list:
        if item.split(".")[-1] == table:
            aprx_map.addDataFromPath(sde + "\\" + item)
            break
    else:
        print('ListFeatureClasses is null')
        # 如果矢量图层未找到目标则遍历栅格图层
        sde_list=arcpy.ListRasters()
        for item in sde_list:
            if item.split(".")[-1] == table:
                aprx_map.addDataFromPath(sde + "\\" + item)
                break
        else:
            print('ListRasters is null')
            raise Exception(table + "  table is not find")
    print("add style")
    listLayers = aprx_map.listLayers()
    arcpy.ApplySymbologyFromLayer_management(listLayers[0], sstylefile)
    # 指定项目坐标系为2000
    out_coordinate_system = arcpy.SpatialReference(4490)
    aprx_map.spatialReference = out_coordinate_system
    aprx.save()

    # Sign in to portal
    print("Sign in to portal")
    arcpy.SignInToPortal(host, name, password)

    # Set output file names
    out_dir = os.path.join(targetProjectPath, "out")
    os.makedirs(out_dir)
    sd_draft_filename = service_name + ".sddraft"
    sd_draft_output_filename = os.path.join(out_dir, sd_draft_filename)
    sd_filename = service_name + ".sd"
    sd_output_filename = os.path.join(out_dir, sd_filename)

    # Reference map to publish
    # aprx = arcpy.mp.ArcGISProject("D:\\ITS\\map\\MyProjectMyProject.aprx")
    m = aprx.listMaps()[0]

    # Create FeatureSharingDraft and set metadata, portal folder, and export data properties
    print("Create FeatureSharingDraft")
    server_type = "FEDERATED_SERVER"
    sd_draft = m.getWebLayerSharingDraft(server_type, "MAP_IMAGE", service_name)
    hosts = host.split("/")
    b = hosts[len(hosts) - 1]
    print(b)
    sd_draft.federatedServerUrl = host.replace(b, "server")
    sd_draft.credits = "These are credits"
    sd_draft.description = "This is description"
    sd_draft.summary = "This is summary"
    sd_draft.tags = "tag1, tag2"
    sd_draft.useLimitations = "These are use limitations"
    sd_draft.portalFolder = "tablemap"
    sd_draft.serverFolder = "tablemap"
    sd_draft.allowExporting = True
    sd_draft.overwriteExistingService = True

    # Create Service Definition Draft file
    sd_draft.exportToSDDraft(sd_draft_output_filename)

    # Stage Service
    print("Start Staging")
    arcpy.StageService_server(sd_draft_output_filename, sd_output_filename)

    # Share to portal
    print("Start Uploading")
    arcpy.UploadServiceDefinition_server(sd_output_filename, sd_draft.federatedServerUrl, service_name, None, None, "tablemap",None, True, None, True, None, None)

    print("Finish Publishing")
    # https://aaa.myarcgis.com/server/rest/services/ROAD/MapServer

if __name__ == '__main__':
    a = []
    for i in range(1, len(sys.argv)):
        print("arg:" + sys.argv[i])
        a.append(sys.argv[i])

    publish_single_table(a[0], a[1], a[2], a[3], a[4], a[5])
    #publish_single_table("D:\\ITS\\map\\sde\\64142f6fed18f3049248ae24.sde", "https://aaa.myarcgis.com/arcgis", "lzwpro", "lzwpro123", "STBHHX1", "D:/ITS/temp/646ad60076c43d31a8fe1f9f/dbo.STBHHX.lyrx")

3,可能会遇到的问题

如果arcgis pro的版本与arcgis的服务版本不兼容,pro下的python也会报一些奇怪的错,我使用的3.0.1的pro和10.6的arcgis;
如果执行python脚本包url问题,可以切换https与http试下,与arcgis的版本有关;
调试时在arcgis的manage可以查看执行日志 https://aaa.myarcgis.com:6443/arcgis/manager
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

占星安啦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值