作者:赵爽
相信有大部分初学者在学习webgl的时候,都遇到pickEvent事件进不去的问题,我最近也查了查相关的问题,也是不少的。下面我就来总结一下pickEvent事件究竟应该怎么写。因为每个人的数据都不太一样,下面分单个数据集和多个数据集两个方向来写
产品配置环境
启动iServer(最后一行显示Server startup in *** ms为启动成功)
将webgl包放在iServer根目录下的webapps文件夹内
将模型数据集加载到场景后,保存场景然后右键该场景进行切缓存,文件类型改为S3M。
生成场景缓存后,会在缓存目录下多出来一个新的工作空间,打开该工作空间然后把single数据源放进去,保存关闭。在iserver上发布该工作空间,选择数据服务和三维服务。
主要函数代码
function onload(Cesium) {
var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene,
url = "http://localhost:8091/iserver/services/3D-single/rest/realspace", //三维服务地址
url2 = "http://localhost:8091/iserver/services/data-single/rest/data"; //数据服务地址
var promise = scene.open(url);
Cesium.when(promise, function(layers) {
var layer = scene.layers.find('Building@single'); //绑定图层,图层名称可在三维服务地址下的datas中看
layer.setQueryParameter({
url: url2,
dataSourceName: "single", //对应数据源名称,数据服务
dataSetName:"Building", //对应数据集名称,数据服务
isMerge: true,
keyWord: 'SmID'
});
})
viewer.pickEvent.addEventListener(function(feature) {
alert("pickEvent事件已生效");
});
因为是以scene.open的方式打开场景的,scene.open是打开该场景下所有图层,所以里面会包含多个图层,因此是layers而不是layer。这个时候如果不写var layer = scene.layers.find(‘Building@single’); 的话,它就不知道我们点击的是哪个图层了,下面的setQueryParameter就无效了。如果数据源名字或者数据集名字写错的话,也是无效的。
主要函数代码
function onload(Cesium) {
var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene,
url = "http://localhost:8091/iserver/services/3D-single/rest/realspace/datas/Building@single/config", //三维服务地址
url2 = "http://localhost:8091/iserver/services/data-single/rest/data"; //数据服务地址
var promise = scene.addS3MTilesLayerByScp(url);
Cesium.when(promise, function(layer) {
scene.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(116.458110477296490 ,39.912298501230481, 2300),//经纬度转笛卡尔
})
layer.setQueryParameter({
url: url2,
dataSourceName: "single", //对应数据源名称,数据服务
dataSetName:"Building", //对应数据集名称,数据服务
isMerge: true,
keyWord: 'SmID'
});
})
viewer.pickEvent.addEventListener(function(feature) {
alert("pickEvent事件已生效");
});
把上面所用的building数据分为3个模型数据集(分别命名为Building_1-3),为了方便区分,我把它们分别给了颜色。
保存场景并对其生成场景缓存,这种方式是每个图层单独切缓存,加载的时候是通过3个scp配置文件加载的。
生成场景缓存后,会在缓存目录下多出来一个新的工作空间,打开该工作空间然后把multiple数据源放进去,保存关闭。在iserver上发布该工作空间,选择数据服务和三维服务。
主要函数代码
function onload(Cesium) {
var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene,
url = "http://localhost:8091/iserver/services/3D-Multiple/rest/realspace", //三维服务地址
url2 = "http://localhost:8091/iserver/services/data-Multiple/rest/data"; //数据服务地址
var promise = scene.open(url);
Cesium.when(promise, function(layers) {
var layer1 = scene.layers.find('Building_1@Multiple');
layer1.setQueryParameter({
url: url2,
dataSourceName: "Multiple", //对应数据源名称,数据服务
dataSetName:"Building_1", //对应数据集名称,数据服务
isMerge: true,
keyWord: 'SmID'
});
var layer2 = scene.layers.find('Building_2@Multiple');
layer2.setQueryParameter({
url: url2,
dataSourceName: "Multiple", //对应数据源名称,数据服务
dataSetName:"Building_2", //对应数据集名称,数据服务
isMerge: true,
keyWord: 'SmID'
});
var layer3 = scene.layers.find('Building_3@Multiple');
layer3.setQueryParameter({
url: url2,
dataSourceName: "Multiple", //对应数据源名称,数据服务
dataSetName:"Building_3", //对应数据集名称,数据服务
isMerge: true,
keyWord: 'SmID'
});
})
viewer.pickEvent.addEventListener(function(feature) {
alert("pickEvent事件已生效");
});
因为场景中一共有三个图层,每个图层对应的数据也不一样,所以一共要写三遍setQueryParameter,这样是不是有一些麻烦?没关系,后面会写一个简单的方法——批量生成场景缓存
主要函数代码
function onload(Cesium) {
var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene,
url1 = "http://localhost:8091/iserver/services/3D-Multiple/rest/realspace/datas/Building_1@Multiple/config", //三维服务地址
url2 = "http://localhost:8091/iserver/services/3D-Multiple/rest/realspace/datas/Building_2@Multiple/config",
url3 = "http://localhost:8091/iserver/services/3D-Multiple/rest/realspace/datas/Building_3@Multiple/config",
url4 = "http://localhost:8091/iserver/services/data-Multiple/rest/data"; //数据服务地址
var promise1 = scene.addS3MTilesLayerByScp(url1,{name:'Building_1@Multiple'});
var promise2 = scene.addS3MTilesLayerByScp(url2,{name:'Building_2@Multiple'});
var promise3 = scene.addS3MTilesLayerByScp(url3,{name:'Building_3@Multiple'});
var promise = [promise1,promise2,promise3];
Cesium.when.all(promise, function(layers) { //注意是when.all
scene.camera.setView({
destination: Cesium.Cartesian3.fromDegrees(116.458110477296490 ,39.912298501230481, 2300),//经纬度转笛卡尔
})
var layer1 = scene.layers.find('Building_1@Multiple');
layer1.setQueryParameter({
url: url4,
dataSourceName: "Multiple", //对应数据源名称,数据服务
dataSetName:"Building_1", //对应数据集名称,数据服务
isMerge: true,
keyWord: 'SmID'
});
var layer2 = scene.layers.find('Building_2@Multiple');
layer2.setQueryParameter({
url: url4,
dataSourceName: "Multiple", //对应数据源名称,数据服务
dataSetName:"Building_2", //对应数据集名称,数据服务
isMerge: true,
keyWord: 'SmID'
});
var layer3 = scene.layers.find('Building_3@Multiple');
layer3.setQueryParameter({
url: url4,
dataSourceName: "Multiple", //对应数据源名称,数据服务
dataSetName:"Building_3", //对应数据集名称,数据服务
isMerge: true,
keyWord: 'SmID'
});
})
viewer.pickEvent.addEventListener(function(feature) {
alert("pickEvent事件已生效");
});
在iDesktop的【三维数据-模型-批量生成缓存】中,可以对这三个数据集批量生成缓存,格式选择S3M,与上面不同的是,这个缓存生成的是一个SCP文件,也就是一个图层。
全是白模,但实际上还是三个数据集。
主要函数代码
function onload(Cesium) {
var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene,
url = "http://localhost:8091/iserver/services/3D-PLMultiple/rest/realspace", //三维服务地址
url2 = "http://localhost:8091/iserver/services/data-PLMultiple/rest/data"; //数据服务地址
var promise = scene.open(url);
Cesium.when(promise, function(layers) {
var layer1 = scene.layers.find('PLMultiple');
layer1.setQueryParameter({
url: url2,
dataSourceName: "Multiple", //对应数据源名称,数据服务
isMerge: true,
keyWord: 'SmID'
});
})
viewer.pickEvent.addEventListener(function(feature) {
alert("pickEvent事件已生效");
});