首页 / 浏览问题 / 组件GIS / 问题详情
iObject java 生成切片缓存后添加失败
9EXP 2023年05月31日

使用产品:iObject java 11.0.1

数据类型: BIM模型

问题:java代码使用SceneCacheBuilder生成缓存后,缓存生成成功,但是接下来layer3SDs.add()方法报错,代码如下

                Datasource datasource = datasources.get(i);
                Dataset dataset = datasource.getDatasets().get(0);
                boolean datasetOpen = dataset.open();
                log.info("打开数据集");
                SceneCacheBuilder cacheBuilder = new SceneCacheBuilder();
                cacheBuilder.setStorageType(StorageType.Original);
                cacheBuilder.setOutputFolder(bimPath);
                cacheBuilder.setOutputSceneName(dataset.getName());
                cacheBuilder.setS3MVersion(S3MVersion.VERSION_10);
                boolean build = cacheBuilder.build();
                log.info("生成切片缓存"+build);
                Scene scene = new Scene(workspace);
                Layer3Ds layers = scene.getLayers();
                String cachePath = 
                bimPath+File.separator+dataset.getName()+File.separator+dataset.getName()+".scp";
                Layer3D add = layers.add(cachePath, Layer3DType.MODEL, true);
                add.setEditable(true);
                add.setVisible(true);
                scene.ensureVisible(add);
                //添加缓存
                log.info("添加缓存");
                Scenes scenes = workspace.getScenes();
                scenes.add(dataset.getName(), scene.toXML());

报错如下

1个回答

您好,根据上述提供的信息不足以准确定位往三维场景中添加 scp 缓存图层导致 JVM 崩溃的原因,有以下建议可供参考:

  1. 在 iDesktopX 桌面端新建三维场景加载生成的 scp 缓存,看能否正常显示;
  2. 检查 iObjects Java 组件的 log 目录下是否有异常日志,不是 JVM 崩溃日志;
  3. 将 JVM 崩溃日志信息完整地粘贴出来,或者粘贴有崩溃的 DLL 信息那段,以便我们能够更加准确的定位 JVM 崩溃原因。

希望可以帮到您。

2,253EXP 2023年05月31日
1.代码生成的缓存可以使用iDesktop可以正常显示;

2.有日志代码如下

链接:https://pan.baidu.com/s/1wFjiTCFS3cPgHml4NiYguA
提取码:tnga

您好,根据您提供的JVM崩溃日志和iObjects Java组件异常日志分析,是添加三维切片缓存成功后在三维场景中全幅浏览时计算缓存图层全幅范围时发生的异常,最终导致JVM崩溃的。

有以下建议可供参考:

  1. 建议检查生成的缓存 scp 文件中的 <sml:BoundingBox> 节点值是否正常;
  2. 用同样的数据在桌面端生成三维缓存切片,用 iObjects Java 组件直接在场景中加载,全幅浏览检查是否依然存在问题;
  3. 若桌面端生成的缓存使用 iObjects Java 组件加载浏览无问题,则对比两份三维切片缓存在数据和scp配置上有什么区别。

面端生成的缓存使用 iObjects Java 组件加载浏览同样出现了此问题,代码如下:

        Workspace workspace = new Workspace();
        WorkspaceConnectionInfo workspaceConnectionInfo = new WorkspaceConnectionInfo();
        workspaceConnectionInfo.setType(WorkspaceType.SXWU);
        workspaceConnectionInfo.setServer(sxwuPath);
        boolean b = workspace.open(workspaceConnectionInfo);
        if (!b){
            System.out.println("打开文件型工作空间失败");
        }
        Datasources datasources = workspace.getDatasources();

        Datasource datasource = datasources.get(0);
        Dataset dataset = datasource.getDatasets().get(0);
        Scene scene = new Scene(workspace);
        Layer3Ds layers = scene.getLayers();
        Layer3D add = layers.add(codeScp, Layer3DType.MODEL, true);
//        Layer3D add = layers.add(desktopScp, Layer3DType.MODEL, true);
        add.setEditable(true);
        add.setVisible(true);
        Scenes scenes = workspace.getScenes();
        scenes.add(dataset.getName(), scene.toXML());

        workspace.save();

报错日志以及scp如下:

链接:https://pan.baidu.com/s/1fsY2GVjZWDFVYozwqMVjZw 
提取码:7ar5

您的代码逻辑有点儿不合理的地方,建议先在 SceneControl 中设置当前新创建的 Scene 对象,然后再添加三维切片缓存进行浏览。

请注意:SceneControl 需要先添加到 Java 程序界面。

换了另外一种方法来添加缓存,成功了,代码如下:

                Datasource datasource = datasources.get(i);
                DatasetVector dataset = (DatasetVector)datasource.getDatasets().get(0);
                PrjCoordSys prjCoordSys = new PrjCoordSys();
                prjCoordSys.fromEPSGCode(4490);
                dataset.setPrjCoordSys(prjCoordSys);
                Rectangle2D bounds = dataset.getBounds();
                OSGBCacheBuilder builder = new OSGBCacheBuilder();
                builder.setDataset(dataset);//设置生成缓存的数据集
                builder.setOutputFolder(filePath);//设置缓存输出路径,与原始缓存一致
                builder.setCacheName(cacheName);//设置缓存名称,与原始缓存一致
                builder.setFileType(CacheFileType.S3MB);//设置缓存文件类型
                builder.setBounds(bounds);//
                builder.setTileWidth(300);
                builder.setPosition(new Point3D(dataset.getBounds().getCenter().x,dataset.getBounds().getCenter().y,0));
                builder.buildWithoutConfigFile();
                String config = filePath +File.separator + builder.getCacheName() + "\\" +builder.getCacheName()+ ".scp";
                boolean isSuccess = builder.toConfigAndIndexFile(config);
                System.out.println(isSuccess);
                Scene scene = new Scene(workspace);
                Layer3Ds layers = scene.getLayers();
                Layer3D add = layers.add(config, Layer3DType.OSGB, true);
                add.setEditable(true);
                add.setVisible(true);
//                scene.ensureVisible(add);
                //添加缓存
                Scenes scenes = workspace.getScenes();
                scenes.add(dataset.getName(), scene.toXML());

                workspace.save();

使用以上方法的时候

scene.ensureVisible(add);

这一行也报了JVM崩溃的错误,将其注释之后就可以正常生成并添加缓存了

报错日志如下:

链接:https://pan.baidu.com/s/1w17P_QJUUhvwhAwW18qEYg 
提取码:dwnd

您好,请您参考上述建议调整您代码中不合理的逻辑,上面的回复已经说得很清楚了,scene.ensureVisible 接口必须依赖 SceneControl 控件,单独的 Scene 对象是无法调用 ensureVisible 接口的,组件功能是这样设计的。
...