Maximo/GIS空间查询

Maximo/GIS spatial query

我在 Maximo 7.6.1.1 中有一个工单:

并且在单独的 GIS 数据库中有一个要素 class(多边形)。


我想空间查询 return WO 相交 的多边形记录中的一个属性并使用它在 WO 中填充 zone

我该怎么做?

相关关键字:Maximo Spatial

要在 Maximo 中实时执行此操作,可以使用自动化脚本或将自定义代码写入 Spatial(更具挑战性)。您想使用 /MapServer/identify 工具和 post 几何 xy、坐标系和您要查询的图层。 identify window

您必须正确设置几何对象的格式并从 window 测试您的 post。一旦我开始使用 post,我通常会从开发人员工具的网络部分获取它,并将输出格式更改为 json 并在我的代码中使用它。

您实际上可能根本不需要接触 Maximo 环境。在您的工单上使用触发器怎么样 table ?然后,该触发器可以通过简单的 select 语句自动填充区域 ID,该语句将 x 和 y 与区域 table 中的区域相匹配。这是它的样子。

这假设您的工单在 table 中,如下所示:

create table work_orders (
  wo_id number primary key,
  x number,
  y number,
  zone_id number
);

和 table 中的区域像这样

create table zones (
  zone_id number primary key,
  shape st_geometry
)

那么触发器就是这样

create or replace trigger work_orders_fill_zone
  before insert or update of x,y on work_orders
  for each row
begin
  select zone_id
  into :new.zone_id
  from zones
  where sde.st_contains (zone_shape, sde.st_point (:new.x, :new.y, 4326) ) = 1;
end;
/

一些假设:

  1. xy 列包含 WGS84 longitude/latitude 中的坐标(不在某些投影或其他 long/lat 坐标系中)

  2. 区域不重叠:因此工单点始终位于一个且仅在一个区域中。如果不是,则查询可能 return 多个结果,然后您需要处理这些结果。

  3. 区域完全覆盖您的工作订单可以发生的区域。如果工作订单位置可以在您的所有区域之外,那么您还需要处理它(查询将 return 没有结果)。

  4. xy 列始终被填充。如果它们是可选的,那么您还需要处理这种情况(如果 xyNULL,则将 zone_id 设置为 NULL

之后,每次在work_orderstable中插入新的工单时,zone_id列都会自动更新。

您可以通过简单更新在现有工作订单中初始化 zone_id

update work_orders set x=x, y=y;

这将为 table 中的每一行创建触发器 运行 ...如果 table 很大,可能需要一些时间才能完成。

调整 Maximo 76 Scripting Features (pdf) 的库脚本部分中的代码:

#What the script does:
#     1. Takes the X&Y coordinates of a work order in Maximo
#     2. Generates a URL from the coordinates
#     3. Executes the URL via a separate script/library (LIB_HTTPCLIENT)
#     4. Performs a spatial query in an ESRI REST feature service (a separate GIS system)
#     5. Returns JSON text to Maximo with the attributes of the zone that the work 
#        order intersected
#     6. Parses the zone number from the JSON text
#     7. Inserts the zone number into the work order record

from psdi.mbo import MboConstants
from java.util import HashMap
from com.ibm.json.java import JSONObject

field_to_update = "ZONE"
gis_field_name = "ROADS_ZONE"

def get_coords():
    """
    Get the y and x coordinates(UTM projection) from the WOSERVICEADDRESS table
    via the SERVICEADDRESS system relationship.
    The datatype of the LatitdeY and LongitudeX fields is decimal.
    """
    laty  = mbo.getDouble("SERVICEADDRESS.LatitudeY")
    longx = mbo.getDouble("SERVICEADDRESS.LongitudeX")

    #Test values
    #laty  = 4444444.7001941890
    #longx = 666666.0312127020

    return laty, longx


def is_latlong_valid(laty, longx):
    #Verify if the numbers are legitimate UTM coordinates
    return (4000000 <= laty <= 5000000 and
            600000 <= longx <= 700000)


def make_url(laty, longx, gis_field_name):
    """
    Assembles the URL (including the longx and the laty).
    Note: The coordinates are flipped in the url.
    """

    url = (
        "http://hostname.port"
        "/arcgis/rest/services/Example"
        "/Zones/MapServer/15/query?"
        "geometry={0}%2C{1}&"
        "geometryType=esriGeometryPoint&"
        "spatialRel=esriSpatialRelIntersects&"
        "outFields={2}&"
        "returnGeometry=false&"
        "f=pjson"
    ).format(longx, laty, gis_field_name)

    return url


def fetch_zone(url):
    # Get the JSON text from the feature service (the JSON text contains the zone value).
    ctx = HashMap()
    ctx.put("url", url)
    service.invokeScript("LIBHTTPCLIENT", ctx)
    json_text = str(ctx.get("response"))

    # Parse the zone value from the JSON text
    obj = JSONObject.parse(json_text)
    parsed_val = obj.get("features")[0].get("attributes").get(gis_field_name)

    return parsed_val


try:
    laty, longx = get_coords()
    if not is_latlong_valid(laty, longx):
        service.log('Invalid coordinates')
    else:
        url = make_url(laty, longx, gis_field_name)
        zone = fetch_zone(url)

        #Insert the zone value into the zone field in the work order
        mbo.setValue(field_to_update, zone, MboConstants.NOACCESSCHECK)
        service.log(zone)
except:
    #If the script fails, then set the field value to null.
    mbo.setValue(field_to_update, None, MboConstants.NOACCESSCHECK)
    service.log("An exception occurred")

LIBHTTPCLIENT:(可重复使用的 Jython library script

from psdi.iface.router import HTTPHandler
from java.util import HashMap
from java.lang import String

handler = HTTPHandler()
map = HashMap()
map.put("URL", url)
map.put("HTTPMETHOD", "GET")
responseBytes = handler.invoke(map, None)
response = String(responseBytes, "utf-8")