Maximo/GIS空间查询
Maximo/GIS spatial query
我在 Maximo 7.6.1.1 中有一个工单:
- WO 在“服务地址”选项卡中有
LatitudeY
和 LongitudeX
坐标。
- 工作单有自定义
zone
字段。
并且在单独的 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;
/
一些假设:
x
和 y
列包含 WGS84 longitude/latitude 中的坐标(不在某些投影或其他 long/lat 坐标系中)
区域不重叠:因此工单点始终位于一个且仅在一个区域中。如果不是,则查询可能 return 多个结果,然后您需要处理这些结果。
区域完全覆盖您的工作订单可以发生的区域。如果工作订单位置可以在您的所有区域之外,那么您还需要处理它(查询将 return 没有结果)。
x
和 y
列始终被填充。如果它们是可选的,那么您还需要处理这种情况(如果 x
或 y
是 NULL
,则将 zone_id
设置为 NULL
)
之后,每次在work_orders
table中插入新的工单时,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")
我在 Maximo 7.6.1.1 中有一个工单:
- WO 在“服务地址”选项卡中有
LatitudeY
和LongitudeX
坐标。 - 工作单有自定义
zone
字段。
并且在单独的 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;
/
一些假设:
x
和y
列包含 WGS84 longitude/latitude 中的坐标(不在某些投影或其他 long/lat 坐标系中)区域不重叠:因此工单点始终位于一个且仅在一个区域中。如果不是,则查询可能 return 多个结果,然后您需要处理这些结果。
区域完全覆盖您的工作订单可以发生的区域。如果工作订单位置可以在您的所有区域之外,那么您还需要处理它(查询将 return 没有结果)。
x
和y
列始终被填充。如果它们是可选的,那么您还需要处理这种情况(如果x
或y
是NULL
,则将zone_id
设置为NULL
)
之后,每次在work_orders
table中插入新的工单时,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")