在实际项目中,经常会遇到需要及时追加数据或者替换数据亦或者是属性更新的情况,比如前面1期收集到的模型,已经制作完成并且缓存已应用于项目中。二期数据收集回来后需要将数据追加到项目中,或者是需要将之前某范围内的模型缓存用新收集的数据替换掉,亦或者只是对缓存数据的部分属性值做更改,这个时候就涉及到模型缓存局部更新功能。
1.实现思路
现在有模型数据集A以及对应的缓存——把模型B追加到模型A上——生成模型AB——然后把A的缓存更新成AB的缓存。
2.关键代码
2.1 主要接口
11i iObjects.Net帮助文档里模型缓存局部更新对应有两个接口,分别是OSGBCacheBuilder.Append 和BIMCacheBuilder.Append。具体如下图所示:
这两个接口所对应的缓存生成方式不同,OSGBCacheBuilder.Append对应OSGBCacheBuilder.Build生成的缓存,BIMCacheBuilder.Append对应BIMCacheBuilder.Build生成的缓存。最为直观的区别是在IDesktop桌面里生成缓存对应的功能按钮不同,1是OSGBCacheBuilder.Build,2是BIMCacheBuilder.Build。
2.2 关键代码
//把数据集 datasetB,更新到数据集 datasetA 生成的缓存文件中
datasetA = (DatasetVector)datasource.Datasets["JZW_BM"];
datasetB = (DatasetVector)datasource.Datasets["B"];
Rectangle2D bounds_B = datasetB.Bounds; //待更新的数据范围
datasetAB = (DatasetVector)datasource.Datasets["JZW_BM_AB"];
//开始更新缓存文件
OSGBCacheBuilder builder = getBuilder();
builder.Bounds = bounds_B;
//必须设置为原始缓存的插入点及瓦片边长
builder.Position = new Point3D(datasetA.Bounds.Center.X, datasetA.Bounds.Center.Y, 0);//114.259640986689,30.596307068879
builder.TileWidth = 300;
//数据集 A 缓存的瓦片边长,数据集更新后 这个边长不能改变,小数点后保留。
// S3M瓦片局部更新类型UpdateType。包括仅更新几何数据(Geometrys)、仅更新属性数据(Attributes)、全部更新(All)三种更新类型。bCreateConfigFile表示是否创建配置文件。
builder.Append(UpdateType.All, false);//当几何发生变化了,需要用ALL,如果只是属性变化了用Attributes
//通过指定更新对象的 bounds,计算需要更新的瓦片。遍历瓦片,求并得出新的 bounds
List<TileInfos> tiles = builder.TileInfosArray;
Rectangle2D newRect = tiles[0].Bounds;
for (int i = 1; i < tiles.Count; i++)
{
newRect.Union(tiles[i].Bounds);
}
builder.Bounds = newRect;
builder.BuildCacheWithoutConfigFile();
//开始更新 scp 及 index,scp和索引更新需要指定整个数据范围
builder.Bounds = datasetAB.Bounds;
String config = _dataPrefix + builder.CacheName + "\\" + builder.CacheName + ".scp";
isSuccess = builder.ToConfigAndIndexFile(config);//根据已有的scp配置文件生成新的混合大文件。
3.运行结果
4.注意事项
4.1 数据方面
4.1.1 id不能发生变化
数据集中的对象如果没有变化,id不能发生变化,否则更新会错乱;最好不要进行紧缩数据源操作,因为会重新更新属性表,id序列会重新排列导致与之前不匹配发生错乱。
4.1.2 需要指定id字段
如果要控制id的话,需要原始数据有自定义的id字段,且是唯一值,生成缓存的时候指定id字段,更新的时候也需要指定同样的字段。指定字段具体见下图红色箭头所指。
4.1.3 更新前后字段名要一致
缓存和数据集的字段名要一致,不能新增或者缺失
4.2 代码方面
4.2.1 参数保持一致
缓存更新代码设置参数要与原始生成缓存的参数保持一致,包括瓦片边长、插入点等,具体见下面代码参数设置。
private OSGBCacheBuilder getBuilder()
{
OSGBCacheBuilder builder = new OSGBCacheBuilder();
builder.Dataset = datasetAB;
builder.OutputFolder = cachePath;
builder.CacheName = cacheName;
builder.FileType = CacheFileType.S3MB;
builder.ObjectFiltrateThreshold = 2;
builder.CacheVersion = S3MVersion.Version_20;
builder.AttributeExtentType = AttributeExtentType.ATTRIBUTE;
builder.TilePyramidSplitType = PyramidSplitType.QuadTree;
builder.LODSize = 3;
var simplifyPercent = new Dictionary<int, double>();
simplifyPercent.Add(0, 0.75);
simplifyPercent.Add(1, 0.5);
simplifyPercent.Add(2, 0.25);
builder.SimplifyPercent = simplifyPercent;
builder.UserIDField = "SmUserID";//指定用户id字段,即便删除对象,也可以保证id字段不变
return builder;
}