ArcGis series-java publishes GP analysis results (with style)

1 Introduction

Following the previous ArcGis series-java calling GP analysis , the release, call, and polling of gp tools have been realized, and the vector data json, raster data tif files and style files required for publishing map services have been saved separately

To publish the results of gp analysis as a layer for front-end display, the basic python environment is still the same as publishing the space table , and
the implementation idea is basically the same. It is also to use the local empty project structure to add layers to build draft files to upload and publish

2, java code

If the execution of calling the published python is successful, first check the publishing address in the content of the ArcGIS Enterprise console, and
then splicing the correct publishing address in the getPublishLayerUrl method

/**
     * 调用python发布图层到arcgis
     * @param dir 图层及样式文件临时目录
     * @param host
     * @param name
     * @param password
     * @param serviceName 图层服务名称
     * @return
     * @throws Exception
     */
    public String publishLayerToArcgis(String dir, String host, String name, String password, String serviceName) throws Exception {
        //host = host.replace("https","http");
        dir = dir.replace("\\","/");
        List<Object> params = new ArrayList<>();
        params.add("cmd.exe");
        params.add("/c");
        params.add("python");
        //python全路径
        String pyScriptName = scriptLocation + File.separator + PY_PUBLISH_LAYER;
        params.add(pyScriptName);
        params.add(dir);
        params.add(host);
        params.add(name);
        params.add(password);
        params.add(serviceName);
        String[] arr = params.toArray(new String[params.size()]);
        log.info("发布gp结果参数:{}", Arrays.toString(arr));
        int i = execSync(pyScriptName, arr);
        if (i == 0) {
            return getPublishLayerUrl(host, serviceName);
        } else {
            throw new Exception("调用" + scriptLocation + PY_PUBLISH_LAYER + "python异常!");
        }
    }

private int execSync(String fileName, String params[]) throws IOException {
        log.info("同步读取python文件 init fileName={}", fileName);
        Process process;
        if (OS.startsWith("Windows")) {
            // windows执行脚本需要使用 cmd.exe /c 才能正确执行脚本
            process = new ProcessBuilder(params).
                    start();
        } else {
            // linux执行脚本一般是使用python3 + 文件所在路径
//            process = new ProcessBuilder("python3", LINUX_PATH + fileName, params).start();
            process = new ProcessBuilder(params).start();
        }

        taskPool.submit(() -> {
            log.info("读取python文件 开始 fileName={}", fileName);
            BufferedReader errorReader = null;
            // 脚本执行异常时的输出信息
            errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
            List<String> errorString = read(fileName, errorReader);
            log.info("读取python文件 fileName={}  errorString={}", fileName, errorString);
        });

        taskPool.submit(() -> {
            // 脚本执行正常时的输出信息
            BufferedReader inputReader = null;
            inputReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            List<String> returnString = read(fileName, inputReader);
            log.info("读取python文件 fileName={}  returnString={}", fileName, returnString);
        });

        try {
            boolean res = process.waitFor(1L, TimeUnit.DAYS);
            if (res) {
                int i = process.exitValue();
                log.info("执行python文件 fileName={} == 结束 == {}", fileName, i);
                return i;
            }
            return 1;
        } catch (InterruptedException e) {
            log.error("同步读取python文件 fileName=" + fileName + " 等待结果返回异常", e);
            return 1;
        }
    }

3. Python code

Traverse the json file and tif file in the project, add them all to the new project, and then create a draft;
because the gp analysis id is used as the serverName, the front end allows repeated analysis, so you must set coverage when publishing

# -*- coding: UTF-8 -*-
import arcpy
import os
import sys
import calendar
import time
import shutil

# 将标准输出和标准错误输出都重定向到同一个文件中
log_file = open("D:/ITS/pythonlog.txt", "w")
sys.stdout = log_file
sys.stderr = log_file
# 覆盖
arcpy.env.overwriteOutput = True

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


def publish_layers(temp_dir, host, name, password, service_name):
    arcpy.env.workspace = targetProjectPath
    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中的哪个地图下

    json_dir = os.path.join(temp_dir, "json")
    file_list = os.listdir(json_dir)
    for file in file_list:
        # 利用os.path.join()方法取得路径全名,并存入cur_path变量,否则每次只能遍历一层目录
        json_file_path = os.path.join(json_dir, file)
        feature_name = file.split(".")[0]
        arcpy.conversion.JSONToFeatures(json_file_path, os.path.join(gdbName, feature_name))
        aprx_map.addDataFromPath(os.path.join(targetProjectPath, gdbName, feature_name))

    #aprx_map.addDataFromPath("D:\\ITS\\map\\layerparam\\dem1.tif")
    json_dir = os.path.join(temp_dir, "tif")
    for subdir, dirs, files in os.walk(json_dir):
        for file in files:
            tifpath = os.path.abspath(os.path.join(subdir, file))
            if tifpath.endswith(".tif"):  # 如果文件后缀是tif
                aprx_map.addDataFromPath(tifpath)
            else:
                os.remove(tifpath)  # 删除该文件

    # 遍历图层添加样式
    layers = aprx_map.listLayers()
    for layer in layers:
        layer_name = arcpy.Describe(layer).file + ".lyrx"
        layer_name = layer_name.replace(".tif", "")
        print(layer_name)
        style_path = os.path.join(temp_dir, "style", layer_name)
        if os.path.exists(style_path):
            arcpy.ApplySymbologyFromLayer_management(layer, style_path)

    aprx.save()

    # 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
    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.overwriteExistingService=service_name
    sd_draft.portalFolder = "gptest"
    sd_draft.serverFolder = "gptest"
    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)
    arcpy.UploadServiceDefinition_server(sd_output_filename, sd_draft.federatedServerUrl, service_name, None, None, "gptest",None, True, None, True, None, None)

    print("Finish Publishing")


if __name__ == '__main__':
    a = []
    for i in range(1, len(sys.argv)):
        print("arg:" + sys.argv[i])
        a.append(sys.argv[i])
    publish_layers(a[0], a[1], a[2], a[3], a[4])
    #publish_layers("D:/ITS/map/layerparam/44bgexhvc10000", "https://aaa.bbbb.com/arcgis", "name", "password","44bgexhvc10000")

    # shutil.rmtree(a[0])

4, problems that may be encountered

If the version of arcgis pro is not compatible with the service version of arcgis, the python under pro will also report some strange errors. I use 3.0.1 pro and 10.6 arcgis; if you execute the python script package url problem, you can switch between https
and Try http, it is related to the version of arcgis;
when debugging, you can view the execution log in the manage of arcgis https://aaa.myarcgis.com:6443/arcgis/manager
insert image description here

Guess you like

Origin blog.csdn.net/u012796085/article/details/130952553