您现在的位置是:首页 >其他 >使用Supermap iobject python和Supermap iServer REST API发布地图服务,你能找到全国目前唯一iobjectpy用法,国产软件生态还是不好哇网站首页其他

使用Supermap iobject python和Supermap iServer REST API发布地图服务,你能找到全国目前唯一iobjectpy用法,国产软件生态还是不好哇

Anefuer_kpl 2024-08-23 12:01:02
简介使用Supermap iobject python和Supermap iServer REST API发布地图服务,你能找到全国目前唯一iobjectpy用法,国产软件生态还是不好哇

1.概要

这个是Windows的教程,Linux应该也大差不差
最近帮助老师干活,进行WebGis的开发,老师要求用国产软件SuperMap,从此开始了一段长达两周的踩坑。这可能是目前互联网上你能找到的唯一一篇专门使用iobjectpy开发的博客,别问我为什么不用java开发,问就是不会。

坑真的太多辣!鼠鼠要歇逼辣!

2.相关技术

  • Supermap iserver
  • Supermap iserver REST API
  • Supermap iObject Python (iobjectpy)
  • Python

3.我整理的相关资源

4.SuperMap iServer安装

可以参考这篇文章安装:Supermap iServer安装、发布地图服务、编写简单程序在浏览器显示地图
提醒:在该文章的 <配置许可>这一步中,你在<申请许可>之后,会下载一个类似于 KPLSCOMPUTER-20230526.licx 的文件,其中KPLSCOMPUTER表示我的计算机名,20230526为申请时间。请你自己类比。

必须要注意的是:iServer安装好,启动服务之后,其根目录是 iserver安装目录下的 webaps/iserver 目录,切记!切记!切记!

5.Supermap iObject Python (iobjectpy) 配置

跟着 iobjcetpy官方文档 安装即可
下面是我建议的安装方法:

1.无需下载 iobjectspy 产品包,通过 pip 进行在线安装:
python -m pip install iobjectspy

2.配置 SuperMap iObjects Java(iobjectpy其实调用的是java封装好的函数,因此这一步不能省)
Windows用户,可以通过以下方式配置 SuperMap iObjects Python 使用的 SuperMap iObjects Java 组件:
	(1)将 SuperMap iObjects Java 组件的 Bin 目录设置到 PATH 变量。
	(2)在安装完 SuperMap iObjects Python 后,
	   在 cmd 命令行中执行 "iobjectspy set-iobjects-java E:/SuperMap/iObjects/Bin_x64",
	   通过这种方式,必须确保 Python 的 Scripts 目录在 PATH 环境中,或者直接在 Scripts 目录下执行。
	(3)启动 python 窗口,执行以下代码(`你自己用创建好的python环境,创建一个python文件复制下面代码执行一下就好`):
		import iobjectspy
		iobjectspy.set_iobjects_java_path('E:/SuperMap/iObjects/Bin_x64')

提醒:

  1. E:/SuperMap/iObjects/Bin_x64 指的是你下载的SuperMap iObjects Java 组件的 Bin目录
  2. 下载SuperMap iObjects Java 组件的 Bin 目录,去这里 SuperMap官方资源下载中心 下载在这里插入图片描述
  3. 必须事先安装好java,才能执行iobjectpy代码。并且java版本不能太高,且必须为64位的java,否则服务与64位的uperMap iObjects Java 组件匹配,你可以抄我作业:java1.8 64位java1.8下载及安装方法
  4. 建议直接在 Python环境的 Scripts 目录下执行 cmd命令,这样比较省事,省得改环境,具体操作如下图(以我使用的Anaconda创建了一个运行环境webgis_sp为例):
    在这里插入图片描述
    进入创建的python环境目录下的 Scripts目录
    在这里插入图片描述
    在这里插入图片描述
    在地址栏中输入 cmd 打开终端,然后输入:iobjectspy set-iobjects-java E:/SuperMap/iObjects/Bin_x64切记把E:/SuperMap/iObjects/Bin_x64换成你自己下载的SuperMap iObjects Java 组件的 Bin目录,别傻乎乎的不改。最后回车执行。
    在这里插入图片描述

6.使用Supermap iServer REST API上传文件到iServer服务器

事先要启动iServer服务

(1) 申请临时token

import json
import requests

ownIp = "localhost"

def login():
    """申请临时token"""
    url = f'http://{ownIp}:8090/iserver/services/security/tokens.rjson'
    data = {
        "userName": "your_user_name",
        "password": "your_password",
        "clientType": "NONE",
        "expiration": 10
    }
    headers = {"Content-Type": "application/json"}

    response = requests.post(url, data=json.dumps(data), headers=headers)
    if response.status_code == 200:
        token = response.text
        print("Token successfully acquired.")
        return token
    else:
        print("Failed to acquire token.")

(2) 创建上传任务

这一步只是创建一个任务,目的是告诉服务器,我要上传一个数据,你做好准备接受

def getTask(token):
    """创建数据上传任务"""
    url = f'http://{ownIp}:8090/iserver/manager/filemanager/uploadtasks.json?token={token}'
    path = r"E:PycharmProjectWebGisworkspaceyy2022_shp.zip"    # 针对这个文件创建上传任务
    data = {"path": path}
    headers = {'Connection': 'Close', 'Accept': '*/*'}
    params = {'token': token}
    response = requests.post(url, data=json.dumps(data), headers=headers, params=params)
    taskID = response.json()["newResourceLocation"]	 # 此处的taskID其实是一个URL
    return taskID

(3)上传文件

执行getTask创建的任务,将文件上传至iServer服务器
topath: 表示将数据上传至iServer服务器上的哪个目录里。你可以创建一个临时目录用于存放上传的数据

def startUpFile(taskID, token):
    """执行上传任务,上传数据到iserver"""
    file_path = "E:PycharmProjectWebGisworkspaceyy2022_shp.zip"    # 与getTask要保持一致
    topath = 'E:\_DevelopToolSupermap_iServersupermap-iserver-11.0.1-windows-x64samplesdatayy2022_shp.zip'        
    with open(file_path, 'rb') as f:
        files = {'file': f}
        params = {'toFile': topath, 'overwrite': 'true', 'token': token}
        headers = {'Connection': 'Close', 'Accept': '*/*'}
        response = requests.post(taskID, files=files, data=params, headers=headers)
        result = response.content.decode('utf-8')
        print("上传状态码:", response.status_code)
    return result

输入输入示例

token = login()
taskID = getTask(token)
startUpFile(taskID, token)

7.使用iobjectpy将数据源保存为sxwu文件型工作空间

我以shp数据的转换为例,其他的数据转换请参考iobjectspy.conversion module 文档

(1) 将shp数据转换为udb数据源

import sys
import os
from iobjectspy.conversion import import_shape
from iobjectspy.data import Workspace, WorkspaceConnectionInfo, Datasource, DatasourceConnectionInfo
from iobjectspy.mapping import Map, LayerSettingVector


def shp_to_udb(input_shp, output_udb):
    """将shp数据转换为udb数据源
    :param input_shp: shp数据路径
    :param output_udb: 输出的udb数据路径
    """
    result = import_shape(input_shp, output_udb)
    if result is not None:
        for item in result:
            name = item
            if not isinstance(item, str):
                name = item.name
            sys.stdout.write('导入数据成功,导入到数据集 %s
' % name)

(2) 创建并保存sxwu文件型工作空间

def create_workspace(udb_path, save_workspace):
    """将udb数据源保存到 sxwu格式的文件型数据空间
    :param udb_path: udb数据源位置
    :param save_workspace: 将sxwu文件保存到哪个目录
    :return:
    """
    file_name, suffix = os.path.basename(udb_path).rsplit(".", 1)  # file_name用于设置图层名称
    save_name = f"{file_name}.sxwu"

    # WorkspaceConnectionInfo用于设置工作空间保存到哪个文件
    save_as = WorkspaceConnectionInfo(os.path.join(save_workspace, save_name))  # 路径符号必须用 /,而不能用 ,否则无法保存
    ws = Workspace()
    conn_info_dc = DatasourceConnectionInfo(udb_path)    # 连接数据源,会自动加载到工作空间
    ds = Datasource.open(conn_info_dc)

    map = Map()  # 创建地图
    # 地图设置
    map.set_name(file_name)

    # 图层样式设置
    vector_setting = LayerSettingVector()   # 创建图层样式设置类
    vector_style = vector_setting.get_style()   # 查看图层当前样式
    vector_style.set_fill_fore_color((255, 230, 153, 255))      # 设置填充颜色, 对应RGBA,A表示透明度
    vector_style.set_line_color((0, 0, 0))      # 设置线条颜色,对应RGB
    vector_style.set_line_width(0.1)            # 设置线条宽度

    layer = map.add_dataset(ds.datasets[0], layer_setting=vector_setting)  # 将指定数据源添加到Layer图层, layer_setting用于加载图层样式(样式可以提前修改)
    map_name = map.get_name()
    map_xml = map.to_xml()

    ws.add_map(map_name, map_xml)   # 制作好的地图,会因为显示比例太小,而无法直接看到,将图层放大即可看到,而不是地图制作失败导致的
    # Tips: 需要先将数据源添加到地图里,才能通过iserver添加地图服务
    ws.save_as(save_as)

    ws.close_all_datasources()  # 关闭所有数据源
    ws.close()  # 关闭工作空间

输入输出示例

shp_file = r'E:PycharmProjectWebGisworkspaceyy2022_shpyy2022.shp'
udb_file = r'E:\_DevelopToolSupermap_iServersupermap-iserver-11.0.1-windows-x64samplesdata	estyy2022_shp.UDB'
save_workspace = r"E:\_DevelopToolSupermap_iServersupermap-iserver-11.0.1-windows-x64samplesdata	est"

shp_to_udb(shp_file, udb_file)
create_workspace(udb_file, save_workspace)

8.将sxwu文件型工作空间发布为地图服务和数据服务

def upService(token):
    """Tips: 应该先将shp数据上传至服务器指定目录,然后在服务器上调用此函数发布地图服务"""
    url = "http://localhost:8090/iserver/manager/workspaces.rjson?returnContent=true&token="+token
    workspace = r"../../samples/data/test/yy2022_shp.sxwu"      # 在发布地图服务之前,工作空间必须确保已经上传至 iserver的目录列表 ../../samples/data 下, ../..是因为iserver的根目录为 webapps/iserver
    headers = {'Content-type': 'application/json', 'Accept': '*/*'}
    params = {'token': token}
    data = {
        'servicesTypes': ["RESTMAP", "RESTDATA"],  # 这里你可以修改要发布哪些服务类型
        'workspaceConnectionInfo': workspace
    }

    try:
        response = requests.post(url, headers=headers, params=params, data=json.dumps(data), timeout=(5, 5))
        resultString = response.text
        print('服务发布状态码:' + str(response.status_code))
        print(resultString)
    except Exception as e:
        print(e)

发布成功会输出:

Token successfully acquired.
服务发布状态码:201
[
    {
        "serviceType": "RESTDATA",
        "serviceAddress": "http://localhost:8090/iserver/services/data-yy2022_shp/rest"
    },
    {
        "serviceType": "RESTMAP",
        "serviceAddress": "http://localhost:8090/iserver/services/map-yy2022_shp/rest"
    }
]

小结

至此,使用SuperMap iServer自动发布地图服务的流程全部结束,在此期间我把能查的资料几乎全看了一遍,这些资料几乎全都写的非常简单,甚至没有,真的是一点点摸索出来的,刚从一个坑跳出来,紧接着又跳进下一个坑里。
SuperMap的资料太少了,官方文档写的也很简单,不过还好的是SuperMap官方论坛很活跃,他们的技术人员回复很快的。有问题都可以上去提问,SuperMap技术问答社区

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。