Worldwind SurfaceImage深度/批量拣货

时间:2016-11-22 21:11:34

标签: java worldwind

我正在使用WorldWind并尝试选择"同一层中的多个表面图像,而不理解它为什么不起作用。

我的印象是这称:

this.getWwd().getSceneController().setDeepPickEnabled(true);

可以让我在同一层中选择多个可渲染项。这似乎适用于SurfaceImage以外的所有其他情况。我还注意到,如果我将加载的SurfaceImage强制进入不同的层,它会按预期工作。

这是我用来测试它的代码:

public class SurfaceImageViewer extends ApplicationTemplate
{
    public static class AppFrame extends ApplicationTemplate.AppFrame
    {
        private JFileChooser fileChooser = new JFileChooser();
        private JSlider opacitySlider;
        private SurfaceImageLayer layer;
        private JLabel statusLabel = new JLabel("status: ready");

        public AppFrame()
        {
            super(true, true, false);

            this.getWwd().getSceneController().setDeepPickEnabled(true);

            try
            {
                this.layer = new SurfaceImageLayer();
                this.layer.setOpacity(1);
                this.layer.setPickEnabled(true);
                this.layer.setName("Surface Images");

                insertBeforeCompass(this.getWwd(), layer);

                this.getControlPanel().add(makeControlPanel(), BorderLayout.SOUTH);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }

            this.getWwd().addSelectListener(new SelectListener() {

                @Override
                public void selected(SelectEvent event) {
                    PickedObjectList pol = AppFrame.this.getWwd().getObjectsAtCurrentPosition();

                    if(event.isLeftClick()){
                        System.out.println("POL SIZE "+pol.size());
                    }

                }
            });


        }

        Action openElevationsAction = new AbstractAction("Open Elevation File...")
        {
            public void actionPerformed(ActionEvent e)
            {
                int status = fileChooser.showOpenDialog(AppFrame.this);
                if (status != JFileChooser.APPROVE_OPTION)
                    return;

                final File imageFile = fileChooser.getSelectedFile();
                if (imageFile == null)
                    return;

                Thread t = new Thread(new Runnable()
                {
                    public void run()
                    {
                        try
                        {
                            CompoundElevationModel cem
                                = (CompoundElevationModel) getWwd().getModel().getGlobe().getElevationModel();
                            LocalElevationModel em = new LocalElevationModel();
                            em.addElevations(imageFile.getPath());
                            cem.addElevationModel(em);
                        }
                        catch (IOException e1)
                        {
                            e1.printStackTrace();
                        }
                    }
                });
                t.setPriority(Thread.MIN_PRIORITY);
                t.start();
            }
        };

        Action openImageAction = new AbstractAction("Open Image File...")
        {
            public void actionPerformed(ActionEvent actionEvent)
            {
                int status = fileChooser.showOpenDialog(AppFrame.this);
                if (status != JFileChooser.APPROVE_OPTION)
                    return;

                final File imageFile = fileChooser.getSelectedFile();
                if (imageFile == null)
                    return;

                Thread t = new Thread(new Runnable()
                {
                    public void run()
                    {
                        try
                        {
                            statusLabel.setText("status: Loading image");
                            // TODO: proper threading
                            layer.addImage(imageFile.getAbsolutePath());

                            getWwd().redraw();
                            statusLabel.setText("status: ready");
                        }
                        catch (IOException e)
                        {
                            e.printStackTrace();
                        }
                    }
                });
                t.setPriority(Thread.MIN_PRIORITY);
                t.start();
            }
        };

        private JPanel makeControlPanel()
        {
            JPanel controlPanel = new JPanel(new GridLayout(0, 1, 5, 5));
            JButton openImageButton = new JButton(openImageAction);
            controlPanel.add(openImageButton);

            this.opacitySlider = new JSlider();
            this.opacitySlider.setMaximum(100);
            this.opacitySlider.setValue((int) (layer.getOpacity() * 100));
            this.opacitySlider.setEnabled(true);
            this.opacitySlider.addChangeListener(new ChangeListener()
            {
                public void stateChanged(ChangeEvent e)
                {
                    int value = opacitySlider.getValue();
                    layer.setOpacity(value / 100d);
                    getWwd().redraw();
                }
            });
            JPanel opacityPanel = new JPanel(new BorderLayout(5, 5));
            opacityPanel.setBorder(new EmptyBorder(0, 10, 0, 0));
            opacityPanel.add(new JLabel("Opacity"), BorderLayout.WEST);
            opacityPanel.add(this.opacitySlider, BorderLayout.CENTER);

            controlPanel.add(opacityPanel);

            JButton openElevationsButton = new JButton(openElevationsAction);
            controlPanel.add(openElevationsButton);

            controlPanel.add(statusLabel);
            controlPanel.setBorder(new EmptyBorder(15, 15, 15, 15));

            return controlPanel;
        }
    }

    public static void main(String[] args)
    {
        ApplicationTemplate.start("World Wind Surface Images", SurfaceImageViewer.AppFrame.class);
    }
}

这两个geotiffs彼此叠加,我一直用来测试它。我希望SelectListener上的println可以打印出#34; 3"当我单击左键单击两个geotiffs。 (我已将地理位置上传到可用的邮政编号here

您将在旧金山看到这些区域,请参见屏幕截图:

enter image description here

1 个答案:

答案 0 :(得分:2)

更新

发现Batch Picking的示例是围绕AbstractSurfaceObject实例定义的,在这种情况下不适用。对于SurfaceImage实例的处理, setAlwaysOnTop 的属性应该配置为false,这似乎让选择事件处理光标下的所有元素。

阅读DeepPicking的示例,实际上有两件事需要完成。

  1. setDeepPickEnabled(真); //这已经完成了。
  2. 禁用所需元素的批量挑选
  3.   

    https://github.com/nasa/World-Wind-Java/blob/master/WorldWind/src/gov/nasa/worldwindx/examples/DeepPicking.java

         

    为了启用深度拣选,必须禁用所需元素的任何批量拣选   必须启用SceneController的深度拾取属性。请参阅{@link gov.nasa.worldwind.SceneController#setDeepPickEnabled(boolean)

    Took me a little while to understand the second one, but it appears to be tied to the AbstractSurfaceObject class.


    • I am assuming that the things that you're drawing on the layer are a subclass of AbstractSurfaceObject

    I believe that in this situation, I would subclass the SurfaceImageLayer, and override the addRenderable methods. I would check the renderable if it was an instance of an AbstractSurfaceObject, and disable batch picking on it before forwarding it to the super class.

    This code may not be the best long-term solution, but it may provide quick results to determine if this is the underlying issue.

    import gov.nasa.worldwind.layers.SurfaceImageLayer;
    import gov.nasa.worldwind.render.AbstractSurfaceObject;
    import gov.nasa.worldwind.render.Renderable;
    
    /**
     * Very Rough extension of SurfaceImageLayer which disables batch picking on all AbstractSurfaceobjects.
     * @author http://stackoverflow.com/users/5407189/jeremiah
     * @since Nov 26, 2016
     *
     */
    public class MySurfaceImageLayer extends SurfaceImageLayer {
    
    
        @Override
        public void addRenderable(Renderable renderable) {
          if (renderable instanceof AbstractSurfaceObject) {
              ((AbstractSurfaceObject)renderable).setEnableBatchPicking(false);
          }
          super.addRenderable(renderable);
        }
    
        @Override
        public void addRenderables(Iterable<? extends Renderable> renderables) {
           for (Renderable r : renderables) {
               addRenderable(r);
           }
        }
    }
    

    如果你想要选择的东西是直接的图像,那么它似乎不支持开箱即用。您需要做一些事情来使SurfaceImageLayer的SurfaceImage引用对doPick上的RenderableLayer可见。这可能会带来一系列新问题需要注意。

    • 作为旁注,如果您正在渲染图标,那么您需要做的就是设置IconRenderer.setAllowBatchPicking(false)

    我希望这至少有点帮助 最好的运气。

相关问题