Javascript 在Cesium.js中加载GeoJsonDataSource更新的数据
我正在尝试将Cesium 1.11与现有的发送GeoJSON的后端集成。我能够从第一条消息成功地将数据加载到视图中,但是对load()的后续调用不会更新显示 我已经将这个问题简化为以下内容,也可以作为一个示例使用Javascript 在Cesium.js中加载GeoJsonDataSource更新的数据,javascript,cesium,Javascript,Cesium,我正在尝试将Cesium 1.11与现有的发送GeoJSON的后端集成。我能够从第一条消息成功地将数据加载到视图中,但是对load()的后续调用不会更新显示 我已经将这个问题简化为以下内容,也可以作为一个示例使用 我希望第二次加载调用会更新显示,将标记移动到纽约,但它会留在伦敦 Feature窗口仍然将“foo”属性显示为123,我希望是456 代码 我试过的 通过调用source.entities.removeAll()来“强制”更新,但是如果功能窗口在更新过程中打开,则会产生关闭功能窗
- 我希望第二次加载调用会更新显示,将标记移动到纽约,但它会留在伦敦李>
- Feature窗口仍然将“foo”属性显示为123,我希望是456
- 通过调用
来“强制”更新,但是如果功能窗口在更新过程中打开,则会产生关闭功能窗口的副作用。我每秒都会收到消息,所以这是不可取的source.entities.removeAll()
- 是的,我知道专有的CZML系统,但是对于这个相对简单的系统,我想坚持使用GeoJSON
- GeoJsonDataSource中的load()helper方法调用
。这介于suspendEvents()和resumeEvents()之间,因此不会导致功能窗口关闭that.\u entityCollection.removeAll()
- 在resumeEvents()之后,即使实体已实际重新创建,也会触发“更改”事件
- Cesium.Viewer创建的现有BillboardVisualizer将缓存实例保存到它第一次渲染时使用的实体
- BillboardVisualizer.update()一直从“过时”实体实例读取第一个位置,因此看不到更新
removeAll
策略以及加载后重置所选实体(这应该保持信息框,这就是我假设您所说的功能窗口)来解决此问题。下面是一个完整的示例,您可以根据此示例查看它的实际操作
var viewer = new Cesium.Viewer('cesiumContainer');
var source = new Cesium.GeoJsonDataSource("name123");
viewer.dataSources.add(source);
Sandcastle.addToolbarButton('Load 1', function(){
source.entities.removeAll();
source.load({
type: "FeatureCollection",
crs: {
type: "name",
properties: {
name: "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
features: [{
type: "Feature",
properties: {
foo: 123
},
geometry: {
type: "Point",
coordinates: [0.1275, 51.5072] // London
},
id: "123"
}]
}).then(function(){
viewer.selectedEntity = source.entities.values[0];
});
});
Sandcastle.addToolbarButton('Load 2', function() {
source.entities.removeAll();
source.load({
type: "FeatureCollection",
crs: {
type: "name",
properties: {
name: "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
features: [{
type: "Feature",
properties: {
foo: 456
},
geometry: {
type: "Point",
coordinates: [-75.1890, 42.3482] // New York
},
id: "123"
}]
}).then(function(){
viewer.selectedEntity = source.entities.values[0];
});
});
这看起来像是我刚刚提交的Cesium中的一个bug,并将在8月3日尝试在1.12版本中进行修复。同时,您应该能够使用
removeAll
策略以及加载后重置所选实体(这应该保持信息框,这就是我假设您所说的功能窗口)来解决此问题。下面是一个完整的示例,您可以根据此示例查看它的实际操作
var viewer = new Cesium.Viewer('cesiumContainer');
var source = new Cesium.GeoJsonDataSource("name123");
viewer.dataSources.add(source);
Sandcastle.addToolbarButton('Load 1', function(){
source.entities.removeAll();
source.load({
type: "FeatureCollection",
crs: {
type: "name",
properties: {
name: "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
features: [{
type: "Feature",
properties: {
foo: 123
},
geometry: {
type: "Point",
coordinates: [0.1275, 51.5072] // London
},
id: "123"
}]
}).then(function(){
viewer.selectedEntity = source.entities.values[0];
});
});
Sandcastle.addToolbarButton('Load 2', function() {
source.entities.removeAll();
source.load({
type: "FeatureCollection",
crs: {
type: "name",
properties: {
name: "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
features: [{
type: "Feature",
properties: {
foo: 456
},
geometry: {
type: "Point",
coordinates: [-75.1890, 42.3482] // New York
},
id: "123"
}]
}).then(function(){
viewer.selectedEntity = source.entities.values[0];
});
});
另一种解决方案是仅使用GeoJsonDataSource从JSON创建实体,并将添加/更新手动添加到查看器全局实体集合中
var viewer = new Cesium.Viewer('cesiumContainer');
var source = new Cesium.GeoJsonDataSource("name123");
// don't add source to viewer
source.load(...);
// sometime later...
source.load(...);
// manually update
viewer.entities.suspendEvents();
source.entities.values.forEach(function(entity) {
var existing = viewer.entities.getById(entity.id);
if (existing === undefined) {
viewer.entities.add(entity);
} else {
entity.propertyNames.forEach(function(name) {
existing[name] = entity[name];
});
}
}, this);
viewer.entities.resumeEvents();
另一种解决方案是仅使用GeoJsonDataSource从JSON创建实体,并将添加/更新手动添加到查看器全局实体集合中
var viewer = new Cesium.Viewer('cesiumContainer');
var source = new Cesium.GeoJsonDataSource("name123");
// don't add source to viewer
source.load(...);
// sometime later...
source.load(...);
// manually update
viewer.entities.suspendEvents();
source.entities.values.forEach(function(entity) {
var existing = viewer.entities.getById(entity.id);
if (existing === undefined) {
viewer.entities.add(entity);
} else {
entity.propertyNames.forEach(function(name) {
existing[name] = entity[name];
});
}
}, this);
viewer.entities.resumeEvents();
感谢您关注这一点,您的解决方案确实解决了InfoBox问题,但是InfoBox始终显示第一次更新时的“过时”值。请尝试添加
viewer.selectedEntity=undefined代码>在分配之前。感谢您查看此内容,您的解决方案确实解决了InfoBox问题,但是InfoBox始终显示第一次更新时的“过时”值。请尝试添加viewer.selectedEntity=undefined代码>在分配之前。