作者:taco
近两年知识图谱的概念突然大火了起来,随之而来的就是用户的各种需求,你们的知识图谱能干什么呢?知识图谱有哪些应用呢?在结合客户的一些需求,以及自身的一些想法,写下这篇文章。
一、SuperMap iDesktopX 如何使用知识图谱
在SuperMap iDesktopX产品中,目前支持了两种数据库创建知识图谱(Yukon、Neo4j)。本篇文章以Neo4j图数据库进行讲解。
1.1 安装Neo4j
Neo4j是一款图数据库管理系统,采用图形结构存储数据,支持高效的图形查询和图形分析。它提供了直观易用的界面和高效的计算引擎,支持多种数据输入格式和结果输出格式,同时提供了可视化的结果展示界面。
关于Neo4j图数据的下载可以在官网中下载(Neo4j Graph Database & Analytics | Graph Database Management System),当然也可以通过一些其他途径下载。后面我会把我这里的图库安装包放到资源中供大家下载使用。
在下载的版本选择中大家需要注意Neo4j与JDK有版本对应(Neo4j 4版本需要对应jdk11,3版本需要对应jdk1.8)
将图库解压到本地文件后,需要在本地的环境变量中配置该数据库环境。
新建NEO4J_HOME,并设置为解压路径,同时在path路径中添加%NEO4J_HOME%\bin
1.2 启动Neo4j
在图数据库bin目录中直接启动命令行工具(cmd)。
并在命令行中输入下方命令
neo4j install-service
完成service的安装。安装成功后输入
neo4j start
即可启动neo4j图数据库。我们通过浏览器访问http://localhost:7474可打开neo4j的图形化界面
1.3 SuperMap iDesktopX链接数据库
目前11.1.1版本iDesktopX已支持知识图谱可在官网中进行下载。(SuperMap技术资源中心|为您提供全面的在线技术服务)
下载完成后,打开iDesktopX产品,在【开始】导航栏中,找到图谱进行链接。
连接完成后,导航栏跳转至知识图谱界面。在该界面,我们可以【创建实体】、【构建关系】、查看【图谱结构】等操作。
1.4 创建实体对象
我们将BIM数据的数据源打开,由于目前不支持模型数据集直接创建实体对象。所以需要将模型数据集转成表数据集。
右键模型数据集【浏览属性表】->【Ctrl+A】全选数据->右键【另存为数据集】,修改【结果数据集类型】为属性表,并选择需要字段。完成后我们得到需要的表数据集。
将多(单)个模型数据集转为表数据集后,使用【知识图谱】-【创建实体】功能进行创建。
此时在标签字段中选择需要图谱中展示的字段,也就是圆圈中显示的字段。在包含字段中选择需要存储的字段。由于属性表为非空间对象,此处【包含空间对象】可以去掉勾选。
创建完成后,我们即可在【图谱管理器】列表中查看到实体对象创建完成。右键实体可将其添加至新的图谱页面中展示。
1.5 创建实体关系
在构建实体关系前,我们需要知道有哪些构建的方式。其中空间关系包括了【包含、被包含、相交、邻接】非空间关系包括了【字段连接、关联匹配】
由于我们使用的是属性表进行连接的。所以此处我们需要选择字段进行连接。但是跟谁去连接呢?如何关联属性呢。如果在实际的项目中,则需要根据真实的连接表的相同字段进行连接。
这里我们创建一个假的关联表来管理。用buildtype字段与每一个图层的类别去做关联。
此处填写我们创建的字段对应好关系即可。
完成创建后我们就得到了包含关系的图谱。此处我也将bim与components构建进行了关联,大家可以自行构建。构建结果如下图。
1.6 保存知识图谱
【Ctrl + S】保存知识图谱至图谱列表下。并自定义其命名。保存本地工作空间到所需目录下,我们至此创建图谱的过程就完成了。
二、发布及关联图谱
2.1 发布知识图谱服务
打开SuperMap iServer 产品,进行服务的发布处理。选择【发布服务】,数据源选择【文件型工作空间】找到本地工作空间文件。
服务列表中选择知识图谱服务进行发布即可。
发布完成后我们可以通过for openlayers3的方式进行预览。
2.2 获取节点信息
在官方的示例代码中(https://iclient.supermap.io/examples/leaflet/editor.html#knowledgeGraphMap2),仅提供了加载的方式,并没有提供如何去获取每一个节点的信息。为了达到与三维的绑定。需要想办法实现节点的获取。此时我们唯一的办法就是看文档!看文档!看文档!
官网示例中图层的数据加载后我们我们是可以直接拿到map的,但是map中的graph实例是没有办法获取的。主要原因还是由于代码执行顺序问题,此时需要一个loaded方法进行回调才可以获取到。
const graphmap = new L.supermap.GraphMap(
'http://localhost:8090/iserver/services/knowledgeGraph-BIMbuilding/restjsr/graph/graphmaps/bimtp');
console.log("graphmap===============", graphmap)
graphmap.on('loaded', function() {
let graph = graphmap.graph;
console.log("graph===============", graph)
});
获取到graph实例后,图谱与其他类型的二维图层是一样的都是可以直接绑定到click事件。
此时我们添加graph.on('click', getattHandler)事件去给图谱中的每一节点添加点击的任务。
当我们添加完成点击事件后,那么属性信息又都存储在哪里了呢?每个节点的属性信息可以在item中找到其feature.properties。点击获取节点信息事件完整代码如下
var getattHandler = function(e) {
console.log("e============", e)
let item = e.item;
console.log("item==========", item)
let feature = item._cfg.model;
console.log("feature==========", feature)
let featureProperites = feature.properties;
console.log("featureProperites==========", featureProperites)
}
上述代码即可实现二维属性的点击。
2.3 与三维数据绑定
本示例中使用超图自主客户端产品iClient3D for Webgl ,在绑定之前我们需要打开我们的场景。加载我们所需的三维数据。
var viewer = new SuperMap3D.Viewer('myearth');
let scene = viewer.scene;
var color = new SuperMap3D.Color.fromCssColorString("rgba(23,92,239,0.5)");
var promise = scene.open("http://www.supermapol.com/realspace/services/3D-BIMbuilding-2/rest/realspace");
SuperMap3D.when(promise, function(layers) {
console.log("=====暂时没啥操作")
bdlayer = scene.layers.find('BIMbuilding');
bdlayer.setQueryParameter({
url: "http://www.supermapol.com/realspace/services/data-BIMbuilding/rest/data",
dataSourceName: "BIMBuilding",
isMerge: true
});
bdlayer.datasetInfo().then(function(result) {
list = result;
console.log(list)
});
由于我们属性信息是由三维数据提取出来的。在不更改属性表的前提下,smid与原始三维数据是一致的。所以我们直接将smid传入图层中。即可实现与三维场景中模型的绑定。但是由于场景(图谱)中不仅是构建的属性,我们还需要通过一些特殊的属性来进行区分。做不同的功能。
本示例给出一些简单的方法来创建根据不同属性,控制颜色及显隐信息,大家可作为参考。
if (featureProperites["buildtype"] != undefined) {
var ids = [];
for (var i = 0; i < list.length; i++) {
if (list[i].datasetName == featureProperites["buildtype"]) {
ids = range(list[i].startID, list[i].endID);
break;
}
}
if (ids.length > 0) {
bdlayer.removeAllObjsColor();
bdlayer.setObjsVisible(ids, true);
}else{
bdlayer.visible = false;
}
} else {
var bimid = [];
bimid.push(featureProperites["SmID_1"])
bdlayer.setObjsColor(bimid, color)
bdlayer.setObjsVisible(bimid, true)
}
2.4 效果展示
知识图谱与bim数据绑定