【问题标题】:Maximo/GIS spatial queryMaximo/GIS 空间查询
【发布时间】:2019-06-13 19:37:23
【问题描述】:

我在 Maximo 7.6.1.1 中有一个工单:

  • WO 在服务地址选项卡中有LatitudeYLongitudeX 坐标。
  • WO 有一个自定义的zone 字段。

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


我想做空间查询以从WO相交的多边形记录中返回一个属性,并用它来填充WO中的zone

我该怎么做?

相关关键字:Maximo Spatial

【问题讨论】:

  • 您能否让 Maximo 运行一些自定义 SQL 语句?如果是,您可以让它运行一个 SELECT 语句,该语句将返回包含您的点的区域的 ID。
  • @AlbertGodfrind 好主意。我对 Maximo 定制的了解还不够,无法回答这个问题。我问了一个关于 referencing an Oracle function 的单独问题,但被告知这是一种不好的做法。
  • 啊,不好的做法。或者好的做法。我读过很多书籍和会议论文,作者在其中提出了自己关于什么是“好”或“坏”实践的想法。您可能想问为什么准确调用 SELECT 是不好的做法...
  • 另一方面,有一种可能不需要在 Maximo 中进行更改:只需在工作订单表上添加一个触发器,它会在插入工作订单时自动填充区域列(或位置现有工单的更改)。该触发器只需要使用简单的 SELECT 获取包含工作订单位置的区域的 ID。
  • 我无法提供详细信息来作为答案,但我已使用 Maximo 的自动化脚本通过 HTTPS 上的 REST API 调用 ArcGIS Reverse Geocoding 服务。我给它发送了一个点(纬度/经度),它给了我 JSON 中的内容。 Scripting 76 Features 帮了大忙。

标签: json rest gis maximo spatial-query


【解决方案1】:

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

您必须正确格式化几何对象并从窗口测试您的帖子。一旦我让它工作并将输出格式更改为 json 并在我的代码中使用它,我通常会从开发人员工具的网络部分获取该帖子。

【讨论】:

    【解决方案2】:

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

    这假设您的工作订单在这样的表格中:

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

    以及像这样的表格中的区域

    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 经度/纬度坐标(不在某些投影或其他经度/纬度坐标系中)

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

    3. 区域完全覆盖了您的工作订单可以执行的区域。如果工作订单位置可以在您的所有区域之外,那么您还需要处理该问题(查询将不返回任何结果)。

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

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

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

    update work_orders set x=x, y=y;
    

    这将使触发器针对表中的每一行运行...如果表很大,可能需要一些时间才能完成。

    【讨论】:

    • Maximo 的业务逻辑位于数据库之外的 Java 类中。这些类验证数据,在验证数据时执行额外的“临时”工作,记录审计跟踪,并将更新发送到集成的外部系统等。因此,虽然这个答案质量很好并且付出了很多努力,但 Maximo 开发人员强烈建议不要使用数据库触发器。自动化脚本旨在取代对数据库触发器的需求。
    【解决方案3】:

    修改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")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多