Worldwind - Фигуры всегда отображаются поверх изображений?

У меня есть два слоя, добавленных в список слоев WorldWindowGLJPanel. Один из них — RenderableLayer, который содержит фигуры, а другой — BasicTiledImageLayer, содержащий растровые изображения. (Один слой содержит один объект). Проблема заключается в том, что когда я меняю порядок слоев с помощью панели менеджера слоев, поверх изображений всегда отображается только порядок объектов, которые имеют один и тот же тип слоя, и формы всегда отображаются поверх изображений, независимо от того, какой порядок у них есть. Есть ли способ исправить это?

Скриншоты:

Показан только растр (выбрано)

Выбраны и растр, и фигура

Выбраны и растр, и фигура (уменьшить масштаб)

Выбраны и растр, и фигура (порядок отображения изменен)

И мой код выглядит следующим образом:

    /*
 * Copyright (C) 2012 United States Government as represented by the Administrator of the
 * National Aeronautics and Space Administration.
 * All Rights Reserved.
 */
package gov.nasa.worldwindx.examples;

import java.awt.Cursor;
import java.io.File;

import javax.swing.SwingUtilities;

import org.w3c.dom.Document;

import gov.nasa.worldwind.BasicFactory;
import gov.nasa.worldwind.WorldWind;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.avlist.AVList;
import gov.nasa.worldwind.avlist.AVListImpl;
import gov.nasa.worldwind.cache.FileStore;
import gov.nasa.worldwind.data.TiledImageProducer;
import gov.nasa.worldwind.formats.shapefile.ShapefileLayerFactory;
import gov.nasa.worldwind.formats.shapefile.ShapefileRecord;
import gov.nasa.worldwind.formats.shapefile.ShapefileRenderable;
import gov.nasa.worldwind.geom.Sector;
import gov.nasa.worldwind.layers.Layer;
import gov.nasa.worldwind.util.Logging;
import gov.nasa.worldwind.util.WWIO;
import gov.nasa.worldwindx.examples.dataimport.DataInstallUtil;
import gov.nasa.worldwindx.examples.util.ExampleUtil;
import gov.nasa.worldwindx.examples.util.RandomShapeAttributes;

/**
 * Illustrates how to import ESRI Shapefiles into World Wind. This uses a <code>{@link ShapefileLayerFactory}</code> to
 * parse a Shapefile's contents and convert the shapefile into an equivalent World Wind shape.
 *
 * @version $Id: Shapefiles.java 3212 2015-06-18 02:45:56Z tgaskins $
 */
public class ShapeRaster extends ApplicationTemplate
{
    protected static final String BASE_CACHE_PATH = "Examples/"; // Define a subdirectory in the installed-data area

    // This example's imagery is loaded from the following class-path resource.
    protected static final String IMAGE_PATH = "gov/nasa/worldwindx/examples/data/craterlake-imagery-30m.tif";

    public static class AppFrame extends ApplicationTemplate.AppFrame
    {
        private static final long serialVersionUID = -7733929990972508866L;

        public AppFrame()
        {
            ShapefileLayerFactory factory = new ShapefileLayerFactory();

            // Specify an attribute delegate to assign random attributes to each shape file record.
            final RandomShapeAttributes randomAttrs = new RandomShapeAttributes();
            factory.setAttributeDelegate(new ShapefileRenderable.AttributeDelegate()
            {
                @Override
                public void assignAttributes(ShapefileRecord shapefileRecord,
                    ShapefileRenderable.Record renderableRecord)
                {
                    renderableRecord.setAttributes(randomAttrs.nextAttributes().asShapeAttributes());
                }
            });

            // Load the shape file. Define the completion callback.
            factory.createFromShapefileSource("testData/shapefiles/TM_WORLD_BORDERS-0.3.shp",
                new ShapefileLayerFactory.CompletionCallback()
                {
                    @Override
                    public void completion(Object result)
                    {
                        final Layer layer = (Layer) result; // the result is the layer the factory created
                        layer.setName(WWIO.getFilename(layer.getName()));
                        layer.clearList();

                        // Add the layer to the World Window's layer list on the Event Dispatch Thread.
                        SwingUtilities.invokeLater(new Runnable()
                        {
                            @Override
                            public void run()
                            {
                                AppFrame.this.getWwd().getModel().getLayers().add(layer);
                            }
                        });
                    }

                    @Override
                    public void exception(Exception e)
                    {
                        Logging.logger().log(java.util.logging.Level.SEVERE, e.getMessage(), e);
                    }
                });

            // Show the WAIT cursor because the installation may take a while.
            this.setCursor(new Cursor(Cursor.WAIT_CURSOR));

            // Install the imagery on a thread other than the event-dispatch thread to avoid freezing the UI.
            Thread t = new Thread(new Runnable()
            {
                public void run()
                {
                    installImagery();

                    // Restore the cursor.
                    setCursor(Cursor.getDefaultCursor());
                }
            });

            t.start();
        }

        protected void installImagery()
        {
            // Download the source file.
            File sourceFile = ExampleUtil.saveResourceToTempFile(IMAGE_PATH, ".tif");

            // Get a reference to the FileStore into which we'll install the imagery.
            FileStore fileStore = WorldWind.getDataFileStore();

            // Install the imagery into the FileStore.
            final Layer layer = installSurfaceImage("Crater Lake Imagery 30m", sourceFile, fileStore);
            if (layer == null)
                return;

            // Display a layer with the new imagery. Must do it on the event dispatch thread.
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    // Add the layer created by the install method to the layer list.
                    insertBeforePlacenames(AppFrame.this.getWwd(), layer);

                    // Set the view to look at the installed image. Get the location from the layer's construction
                    // parameters.
                    AVList params = (AVList) layer.getValue(AVKey.CONSTRUCTION_PARAMETERS);
                    Sector sector = (Sector) params.getValue(AVKey.SECTOR);
                    ExampleUtil.goTo(getWwd(), sector);
                }
            });
        }

        protected Layer installSurfaceImage(String displayName, Object imageSource, FileStore fileStore)
        {
            // Use the FileStore's install location as the destination for the installed imagery. The default install
            // location is the FileStore's area for permanent storage.
            File fileStoreLocation = DataInstallUtil.getDefaultInstallLocation(fileStore);

            // Create a unique cache name that specifies the installed data's location within the FileStore.
            String cacheName = BASE_CACHE_PATH + WWIO.replaceIllegalFileNameCharacters(displayName);

            // Create a parameter list specifying the install location information.
            AVList params = new AVListImpl();
            params.setValue(AVKey.FILE_STORE_LOCATION, fileStoreLocation.getAbsolutePath());
            params.setValue(AVKey.DATA_CACHE_NAME, cacheName);
            params.setValue(AVKey.DATASET_NAME, displayName);

            // Create a TiledImageProducer to install the imagery.
            TiledImageProducer producer = new TiledImageProducer();
            try
            {
                // Configure the TiledImageProducer with the parameter list and the image source.
                producer.setStoreParameters(params);
                producer.offerDataSource(imageSource, null);

                // Install the imagery.
                producer.startProduction();
            }
            catch (Exception e)
            {
                producer.removeProductionState(); // Clean up on failure.
                e.printStackTrace();
                return null;
            }

            // Extract the data configuration document from the installed results. If the installation successfully
            // completed, the TiledImageProducer should always contain a document in the production results, but test
            // the results anyway.
            Iterable<?> results = producer.getProductionResults();
            if (results == null || results.iterator() == null || !results.iterator().hasNext())
                return null;

            Object o = results.iterator().next();
            if (o == null || !(o instanceof Document))
                return null;

            // Construct a Layer by passing the data configuration document to a LayerFactory.
            Layer layer = (Layer) BasicFactory.create(AVKey.LAYER_FACTORY, ((Document) o).getDocumentElement());

            // The layer factory creates layers that are initially disabled, so enable the layer.
            layer.setEnabled(true);

            return layer;
        }
    }

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

person orkan    schedule 01.06.2017    source источник


Ответы (1)


Это зависит от созданных форм для данных в вашем шейп-файле. Формы, созданные с помощью ShapefileLayerFactory, могут относиться к поверхностным формам типа SurfacePlygon или SurfaceCircle. Эти формы всегда находятся поверх изображений. Другие формы, такие как ExtrudedPolygon, могут иметь высоту. Для этого типа фигур, если высота больше 0, она все равно будет над изображениями.

person hadi.mansouri    schedule 14.06.2017