首页 / 浏览问题 / 组件GIS / 问题详情
iobjectjava 11 可视域计算 viewshed.getBarrierPoints()返回空
4EXP 2024年03月12日

想实现可视域百分比的计算,想通过后台代码直接计算结果(有坐标和相关参数)

String cbd3DUrl = "D:\\Program Files\\SuperMap\\SuperMap iDesktopX 11i\\sampleData\\3D\\CBDDataset\\CBD.smwu";
        Workspace workspace = new Workspace();
        WorkspaceConnectionInfo workspaceConnectionInfo = new WorkspaceConnectionInfo();
        workspaceConnectionInfo.setType(WorkspaceType.SMWU);
        workspaceConnectionInfo.setServer(cbd3DUrl);
        boolean open = workspace.open(workspaceConnectionInfo);
        System.out.println(open);


        String dbPath = "D:\\Program Files\\SuperMap\\SuperMap iDesktopX 11i\\sampleData\\3D\\CBDDataset\\CBD.udb";
        DatasourceConnectionInfo info = new DatasourceConnectionInfo();
        // 主要是这里设置数据类型
                info.setEngineType(EngineType.IMAGEPLUGINS);
        // 这里设置路径比如***/***/test.udbx
                info.setServer(dbPath);

//        打开数据源
        Datasource datasource = workspace.getDatasources().get(0);
        System.out.println("打开数据源别名为:" + datasource.getAlias() + "  数据源打开的状态:" + datasource.isOpened() + "  数据源是否以只读方式打开:" + datasource.isReadOnly());//打印查询其描述信息


//        workspace.getDatasources().create(info);
        System.out.println("datasource open:" + datasource.isOpened());
        System.out.println("数据源数量datasource:"+datasource.getDatasets().getCount());

        Datasets datasets = datasource.getDatasets();
        // 输出result
        System.out.println("Datasets:"+datasets.getCount());
        Scene sceneObject = new Scene(workspace);//返回三维地图场景(Scene)对象
        sceneObject.setSceneType(SceneType.GLOBE);//设置三维场景的类型,选择球体模式(Globe)和平面模式(Flat)两种。
        System.out.println("场景数量:" + workspace.getScenes().getCount() + "场景名称:" + sceneObject.getName());
        //添加图层
        Layer3Ds layer3Ds = sceneObject.getLayers();
        System.out.println("场景中原有图层数量:" + layer3Ds.getCount());//打印数据集名称



//        Viewshed3D viewshed3D = new Viewshed3D(sceneControl.getScene());
        Viewshed3D viewshed3D = new Viewshed3D(sceneObject);
        viewshed3D.setViewerPosition(new Point3D(116.44559728682049, 39.906862697933875, 6.914911785993112));
        viewshed3D.build();

        new Thread(()->{
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            viewshed3D.setVisibleAreaColor(Color.GREEN);
            viewshed3D.setHiddenAreaColor(Color.RED);
            viewshed3D.setQuality(AnalysisQuality.MEDIUM);
            viewshed3D.setDistDirByPoint(new Point3D(116.4455483958302, 39.90637922190338, 21.990817157546257));
            viewshed3D.setVerticalFov(60);
            viewshed3D.setHorizontalFov(90);

//        viewshed3D.setPitch(24.44518319874657);
//        viewshed3D.setDirection(184.66703436851276);
//        viewshed3D.setDistance(60.179869114881974);

            System.out.println("相机俯仰角:"+viewshed3D.getPitch());
            System.out.println("与正北方向的夹角:"+viewshed3D.getDirection());
            System.out.println("可视距离:"+viewshed3D.getDistance());

            List<Point3D> point3DList = viewshed3D.getBarrierPoints();
            GeoModel3D total3D = viewshed3D.getFrustumBody();
            GeoModel3D visible3D = viewshed3D.getVisibleBody();
            double totalArea = total3D.getArea();
            double visibleArea = visible3D.getArea();
            System.out.println(totalArea);
            System.out.println(visibleArea);
        }).start();

加载smwu文件和udb文件后,打印显示已经有图层,数据也已经打开了,但是viewshed计算为空

1个回答

您好,在可视域计算方法执行后,如果要获取可视域结果,需要使用timer.schedule(task, delay)等待几秒显卡绘制出可视域分析结果,再从viewshedD获取结果
3,750EXP 2024年03月12日

您好,感谢大佬回复,按照修改增加了延迟触发,但是获取还是空的,debug发现这个地方是null

那边需要在timer中执行获取哈,类似这样

Timer timer = new Timer();

timer.schedule(new TimerTask(){
   public void run()
   {
      viewshed3D.getFrustumBody();//获取数据
   }
},3000);

是的,就是这样写的,但是还是null,我在猜测是不是我没有执行计算方法,是设置好viewposition后,build(),然后设置

DistDirByPoint就可以自动执行可视域计算了是吗?还是要有其他操作呢?
        viewshed3D = new Viewshed3D(sceneObject);
        viewshed3D.setViewerPosition(new Point3D(116.44559728682049, 39.906862697933875, 6.914911785993112));
        viewshed3D.setVisibleAreaColor(Color.GREEN);
        viewshed3D.setHiddenAreaColor(Color.RED);
        viewshed3D.setVerticalFov(60);
        viewshed3D.setHorizontalFov(90);
        boolean buildRes = viewshed3D.build();
        System.out.println("创建3D模型结果:"+buildRes);





//执行计算?
        viewshed3D.setQuality(AnalysisQuality.MEDIUM);
        viewshed3D.setDistDirByPoint(new Point3D(116.4455483958302, 39.90637922190338, 21.990817157546257));
//        viewshed3D.setPitch(24.44518319874657);
//        viewshed3D.setDirection(184.66703436851276);
//        viewshed3D.setDistance(60.179869114881974);

        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println("相机俯仰角:"+viewshed3D.getPitch());
                System.out.println("与正北方向的夹角:"+viewshed3D.getDirection());
                System.out.println("可视距离:"+viewshed3D.getDistance());
                List<Point3D> point3DList = viewshed3D.getBarrierPoints();
                GeoModel3D total3D = viewshed3D.getFrustumBody();
                GeoModel3D visible3D = viewshed3D.getVisibleBody();
                double totalArea = total3D.getArea();
                double visibleArea = visible3D.getArea();
                System.out.println(totalArea);
                System.out.println(visibleArea);
            }
        };
        Timer timer = new Timer();
        timer.schedule(task, 5000);

使用范例如下:

viewshed3D = new Viewshed3D(sceneControl.getScene());
viewshed3D.setDirection(104.6559);// 设置当前相机的方向与正北方向的夹角,单位:度。
viewshed3D.setDistance(2998.26);//设置可视距离,单位:米。
viewshed3D.setViewerPosition(new Point3D(115.0827,39.8351,1452.1555));//设置观察点的位置。
viewshed3D.setPitch(-8.8891);//设置当前分析的相机俯仰角。
viewshed3D.setQuality(AnalysisQuality.HIGH);// 设置分析的质量级别
viewshed3D.setInViewport(0);//设置可视域分析在指定视口进行
viewshed3D.setVisibleAreaColor(new Color(28,255, 40));//设置可视区域的颜色
viewshed3D.setHiddenAreaColor(new Color(255,2,3));//设置不可视区域的颜色
viewshed3D.setHorizontalFov(90);//设置可视域分析的水平视角范围
viewshed3D.setVerticalFov(60);//设置可视域分析垂直视角范围
boolean vshed = viewshed3D.build();//执行可视域分析
...