5.6 ネットワーク・ユーザー・データ
xxx_SDO_NETWORK_USER_DATAビューを介して定義されたユーザー・データについては、ネットワーク分析中にユーザー・データにアクセスする場合、デフォルトのユーザー・データI/O実装(LODUserDataIOSDO)が使用されます。ただし、一部のユーザー・データは、ノード表またはリンク表に含まれていないため、xxx_SDO_NETWORK_USER_DATAビューを介して登録できません。
このようなユーザー・データについては、ユーザーが、ユーザー・データI/Oインタフェースの独自のカスタム実装を提供する必要があります。カスタムのデータI/Oインタフェースを実装する一般的な方法は、ノードおよびリンクのユーザー・データに対応したBLOB (各パーティションごとに1つのBLOB)を生成してから、ネットワーク分析中にBLOBからユーザー・データ情報を取得することです。
ネットワーク・データ・モデルを使用すると、複数のカテゴリのユーザー定義データ(カテゴリ分けされたユーザー・データ)を単一のネットワークに関連付けることもできます。たとえば、マルチモーダル・ネットワークでは、リンクのマルチモーダル属性の他に、運転に関連する属性(制限速度など)をリンクに関連付ける必要がある場合、ユーザー定義データを2つのカテゴリ(1つは運転に関連する属性用で、もう1つはマルチモーダル属性用)に整理できます。
このようなユーザー定義データの例は、次を参照してください。
5.6.1 ユーザー定義データの例(PL/SQLおよびJava)
この項では、ネットワークのユーザー定義データの使用例を示します。ユーザー定義データとは、ユーザーがネットワーク表現と関連付ける(接続性とは関係のない)情報です。USER_SDO_NETWORK_USER_DATAメタデータ・ビューとALL_SDO_NETWORK_USER_DATAメタデータ・ビュー(「xxx_SDO_NETWORK_USER_DATAビュー」を参照)のどちらにも、ユーザー定義データに関する情報が含まれます。
ユーザー定義データを使用するには、適切なxxx_SDO_NETWORK_METADATAビュー(「xxx_SDO_NETWORK_METADATAビュー」を参照)のUSER_DEFINED_DATA列値をYに設定する必要があります。
例5-1では、リンク関連のユーザー定義データをネットワーク・メタデータに挿入します。
例5-1 ユーザー定義データのネットワーク・メタデータへの挿入
-- Insert link user data named 'interaction' of
-- type varchar2 (50) in network 'bi_test'.
--'interaction' is a column of type varchar2(50) in the link table of network 'bi_
test'.
insert into user_sdo_network_user_data (network, table_type, data_name, data_type, data_length, category_id)
values ('bi_test', 'LINK', 'interaction', 'VARCHAR2', 50, 0) ;
-- insert link user data named 'PROB' of type Number.
--'PROB' is a column of type NUMBER in the link table of network 'bi_test'.
insert into user_sdo_network_user_data (network, table_type, data_name, data_type, category_id)
values ('bi_test','LINK','PROB','NUMBER', 0) ;
After a network or network partition is loaded, user-defined data is available in Java representations. You can access user-defined data through the getCategorizedUserData and setCategorizedUserData methods for the Node, Link, Path, and SubPath interfaces. For example:
//The user data index is the sequence number of a user data within a category sorted by data name.
int interactionUserDataIndex = 0;
int probUserDataIndex = 1;
String interaction = (String)link.getCategorizedUserData().getUserData(0).
get(interactionUseDataIndex);
double prob = ((Double)link.getCategorizedUserData().getUserData(0).
get(probUserdataIndex)).doubleValue();親トピック: ネットワーク・ユーザー・データ
5.6.2 ユーザー定義データの例(カスタムのユーザー・データI/O実装)
この項では、LODUserDataIOインタフェースのカスタムのユーザー・データI/O実装(デフォルト以外の実装)の例を示します。例5-2では、リンクに関連付けられたユーザー・データがBLOB (各パーティションごとに1つのBLOB)に書き込まれ、分析中にBLOBから読み込まれます。この例では、各パーティションのマルチモーダル・データに対するユーザー定義データのBLOBには、パーティションIDとパーティションに関連付けられたリンクの数が含まれ、その後に各リンクの<Link ID, link route ID>が含まれていることを前提としています。
例5-2 LODUserDataIOのwriteUserDataメソッドの実装
//Method getLinksInPartition(partitionId) computes a vector that
// consists of the ID and the route ID of each link associated with a partition
// with ID = partitionId
LinkVector = getLinksInPartition(partitionId);
ObjectOutputStream dout = null;
//Insert an empty blob for the partition with ID = partition_id
String insertStr = "INSERT INTO " + MULTIMODAL_USER_DATA +
" (partition_id, blob) " + " VALUES " + " (?, EMPTY_LOB())" ;
PreparedStatement stmt = conn.prepareStatement(insertStr);
stmt.setInt(1,partitionId);
int n = stmt.executeUpdate();
stmt.close();
//lock the row for blob update
String lockRowStr = "SELECT blob FROM " + MULTIMODAL_USER_DATA +
" WHERE partition_id = ? " + " FOR UPDATE";
stmt = conn.prepareStatement(lockRowStr);
stmt.setInt(1,partitionId);
ResultSet rs = stmt.executeQuery();
rs.next();
oracle.sql.BLOB userDataBlob = (oracle.sql.BLOB) rs.getBlob(1);
stmt.close();
OutputStream blobOut = ((oracle.sql.BLOB) userDataBlob).setBinaryStream(1);
dout = new ObjectOutputStream(blobOut);
//write partition ID
dout.writeInt(partitionId);
int numLinks = linkVector.size()
for (int i=0; i<linkVector.size(); i++) {
//MultimodalLink is a class with variables link ID and route ID
MultimodalLink link = (MultimodalLink) linkVector.elementAt(i);
//write link ID
dout.writeLong(link.getLinkId());
// write route ID into file
dout.writeInt(link.getRouteId());
}
dout.close();
blobOut.close();
rs.close();
後に続く項では、LODUserDataIOインタフェースのwriteUserDataメソッドとreadUserDataメソッドの実装について説明します。
5.6.2.1 LODUserDataIOのwriteUserDataメソッドの実装
LODUserDataIOのwriteUserDataメソッドの実装では、ユーザー定義データのBLOB表の名前がMULTIMODAL_USER_DATAであると想定されています。
//Method getLinksInPartition(partitionId) computes a vector that
// consists of the ID and the route ID of each link associated with a partition
// with ID = partitionId
LinkVector = getLinksInPartition(partitionId);
ObjectOutputStream dout = null;
//Insert an empty blob for the partition with ID = partition_id
String insertStr = "INSERT INTO " + MULTIMODAL_USER_DATA +
" (partition_id, blob) " + " VALUES " + " (?, EMPTY_BLOB())" ;
PreparedStatement stmt = conn.prepareStatement(insertStr);
stmt.setInt(1,partitionId);
int n = stmt.executeUpdate();
stmt.close();
//lock the row for blob update
String lockRowStr = "SELECT blob FROM " + MULTIMODAL_USER_DATA +
" WHERE partition_id = ? " + " FOR UPDATE";
stmt = conn.prepareStatement(lockRowStr);
stmt.setInt(1,partitionId);
ResultSet rs = stmt.executeQuery();
rs.next();
oracle.sql.BLOB userDataBlob = (oracle.sql.BLOB) rs.getBlob(1);
stmt.close();
OutputStream blobOut = ((oracle.sql.BLOB) userDataBlob).setBinaryStream(1);
dout = new ObjectOutputStream(blobOut);
//write partition ID
dout.writeInt(partitionId);
int numLinks = linkVector.size()
for (int i=0; i<linkVector.size(); i++) {
//MultimodalLink is a class with variables link ID and route ID
MultimodalLink link = (MultimodalLink) linkVector.elementAt(i);
//write link ID
dout.writeLong(link.getLinkId());
// write route ID into file
dout.writeInt(link.getRouteId());
}
dout.close();
blobOut.close();
rs.close();5.6.2.2 LODUserDataIOのreadUserDataメソッドの実装
ユーザー定義データにアクセスするには、Node、Link、PathおよびSubPathインタフェースのgetCategorizedUserDataメソッドおよびsetCategorizedUserDataメソッド、およびCategorizedUserDataインタフェースのgetUserDataメソッドおよびsetUserDataメソッドを使用します。
//Read the blob for the required partition from the user data blob table
// In this example,
// MULTIMODAL_USER_DATA is the name of user –defined data blob table
BLOB multimodalBlob = null;
String queryStr = "SELECT blob FROM " + MULTIMODAL_USER_DATA
" WHERE partition_id = ?";
PreparedStatement stmt = conn.prepareStatement(queryStr);
stmt.setInt(1,partitionId);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
multimodalBlob = (oracle.sql.BLOB)rs.getBlob(1);
}
// Materialize the blob value as an input stream
InputStream is = multimodalBlob.getBinaryStream();
//Create an ObjectInputStream that reads from the InputStream is
ObjectInputStream ois = new ObjectInputStream(is);
//Read the values of partition ID and number of links from the blob
int partitionId = ois.readInt();
int numLinks = ois.readInt();
for (int i=0; i<numLinks; i++) {
//Read link ID and route ID for each link
long linkId = ois.readLong();
int routeId = ois.readInt();
//MultimodalLinkUserData is an implementation of NDM LOD UserData interface
//Implementation is provided at the end of the example
linkUserData = new MultimodalLinkUserData(routeId);
//Get the link object corresponding to the link ID
LogicalNetLink link = partition.getLink(linkId);
//Get the (categorized) user data associated with the link.
CategorizedUserData cud = link.getCategorizedUserData();
// If the link does not have categorized user data associated with it,
// initialize it to linkUserData
// Else, set the user data for category USER_DATA_MULTIMODAL
// to linkUserData
if (cud == null) {
UserData [] userDataArray = {linkUserData};
cud = new CategorizedUserDataImpl(userDataArray);
link.setCategorizedUserData(cud);
}
else {
cud.setUserData(USER_DATA_MULTIMODAL,linkUserData);
}
}
次のセグメントでは、分析中にユーザー定義データ(具体的にはリンクに関連付けられたルートID)を読み取る方法を示します。
//info is an instance of LODAnalysisInfo
LogicalLink currentLink = info.getCurrentLink();
//Read the user-defined data (in this case, route ID)
int linkRouteId = (Integer)currentLink.getCategorizedUserData().
getUserData(USER_DATA_MULTIMODAL).
get(INDEX_LINK_ROUTEID);
Implementation of MultimodalLinkUserData :
class MultimodalLinkUserData implements UserData
{
private int routeId;
protected MultimodalLinkUserData(int routeId)
{
this.routeId = routeId;
}
public Object get(int index)
{
switch(index)
{
case INDEX_LINK_ROUTEID:
return routeId;
}
return null;
}
public void set(int index, Object userData)
{
switch(index)
{
case INDEX_LINK_ROUTEID:
this.routeId = (Integer) userData;
}
}
public int getNumberOfUserData()
{
return 1;
}
public Object clone()
{
return new MultimodalLinkUserData(routeId);
}
}