private Info[] buildSurfaceShapes() { LatLon position = new LatLon(Angle.fromDegrees(38), Angle.fromDegrees(-105)); ArrayList<LatLon> surfaceLinePositions = new ArrayList<LatLon>(); // surfaceLinePositions.add(LatLon.fromDegrees(37.8484, -119.9754)); // surfaceLinePositions.add(LatLon.fromDegrees(38.3540, -119.1526)); // surfaceLinePositions.add(new LatLon(Angle.fromDegrees(0), // Angle.fromDegrees(-150))); // surfaceLinePositions.add(new LatLon(Angle.fromDegrees(60), // Angle.fromDegrees(0))); surfaceLinePositions.add(position); surfaceLinePositions.add(LatLon.fromDegrees(39, -104)); surfaceLinePositions.add(LatLon.fromDegrees(39, -105)); surfaceLinePositions.add(position); return new Info[] { new Info("Circle", new SurfaceCircle(position, 100e3)), new Info("Ellipse", new SurfaceEllipse(position, 100e3, 90e3, Angle.ZERO)), new Info("Square", new SurfaceSquare(position, 100e3)), new Info("Quad", new SurfaceQuad(position, 100e3, 60e3, Angle.ZERO)), new Info("Sector", new SurfaceSector(Sector.fromDegrees(38, 40, -105, -103))), new Info("Polygon", new SurfacePolygon(surfaceLinePositions)), }; }
public void doActionOnButton2() { ArrayList<LatLon> latlons = new ArrayList<LatLon>(); latlons.add(LatLon.fromDegrees(45.50d, -123.3d)); // latlons.add( LatLon.fromDegrees( 45.51d, -123.3d ) ); latlons.add(LatLon.fromDegrees(45.52d, -123.3d)); // latlons.add( LatLon.fromDegrees( 45.53d, -123.3d ) ); latlons.add(LatLon.fromDegrees(45.54d, -123.3d)); // latlons.add( LatLon.fromDegrees( 45.55d, -123.3d ) ); latlons.add(LatLon.fromDegrees(45.56d, -123.3d)); // latlons.add( LatLon.fromDegrees( 45.57d, -123.3d ) ); latlons.add(LatLon.fromDegrees(45.58d, -123.3d)); // latlons.add( LatLon.fromDegrees( 45.59d, -123.3d ) ); latlons.add(LatLon.fromDegrees(45.60d, -123.3d)); Sector sector = Sector.fromDegrees(44d, 46d, -123d, -121d); // Sector sector = Sector.boundingSector( latlons ); double[] elevations = new double[latlons.size()]; // request resolution of DTED2 (1degree / 3600 ) double targetResolution = Angle.fromDegrees(1d).radians / 3600; double resolutionAchieved = this.wwd .getModel() .getGlobe() .getElevationModel() .getElevations(sector, latlons, targetResolution, elevations); StringBuffer sb = new StringBuffer(); for (double e : elevations) { sb.append("\n").append(e); } sb.append("\nresolutionAchieved = ").append(resolutionAchieved); sb.append(", requested resolution = ").append(targetResolution); Logging.logger().info(sb.toString()); }
private Info[] buildFreeShapes() { double elevation = 10e3; ArrayList<Position> positions = new ArrayList<Position>(); positions.add( new Position(Angle.fromDegrees(37.8484), Angle.fromDegrees(-119.9754), elevation)); positions.add( new Position(Angle.fromDegrees(39.3540), Angle.fromDegrees(-110.1526), elevation)); positions.add( new Position(Angle.fromDegrees(38.3540), Angle.fromDegrees(-100.1526), elevation)); ArrayList<Position> positions2 = new ArrayList<Position>(); positions2.add(new Position(Angle.fromDegrees(0), Angle.fromDegrees(-150), elevation)); positions2.add(new Position(Angle.fromDegrees(25), Angle.fromDegrees(-75), elevation)); positions2.add(new Position(Angle.fromDegrees(50), Angle.fromDegrees(0), elevation)); ArrayList<Position> positions3 = new ArrayList<Position>(); for (double lat = 42, lon = -100; lat <= 45; lat += .1, lon += .1) { positions3.add(new Position(Angle.fromDegrees(lat), Angle.fromDegrees(lon), elevation)); } ArrayList<Position> positions4 = new ArrayList<Position>(); positions4.add(new Position(Angle.fromDegrees(90), Angle.fromDegrees(-110), elevation)); positions4.add(new Position(Angle.fromDegrees(-90), Angle.fromDegrees(-110), elevation)); ArrayList<Position> positions5 = new ArrayList<Position>(); for (int i = 0; i < 100; i++) { positions5.add( Position.fromDegrees(38.0 + i * 0.0001, 30.0 + i * 0.0001, 1000.0 + i * 5.0)); } @SuppressWarnings({"UnnecessaryLocalVariable"}) Info[] infos = new Info[] { new Info("Short Path", new Polyline(positions)), new Info("Long Path", new Polyline(positions2)), new Info("Incremental Path", new Polyline(positions3)), new Info("Vertical Path", new Polyline(positions4)), new Info("Small-segment Path", new Polyline(positions5)), new Info("Quad", new Quadrilateral(Sector.fromDegrees(38, 40, -104, -105), elevation)), new Info("None", null) }; return infos; }
/** * Shows how to compute terrain intersections using the highest resolution terrain data available * from a globe's elevation model. * * <p>To generate and show intersections, Shift + LeftClick anywhere on the globe. The program forms * a grid of locations around the selected location. The grid points are shown in yellow. It then * determines whether a line between the selected location and each grid point intersects the * terrain. If it does, the intersection nearest the selected location is shown in cyan and a line * is drawn from the selected location to the intersection. If there is no intersection, a line is * drawn from the selected location to the grid position. * * <p>If the highest resolution terrain is not available for the area around the selected location, * it is retrieved from the elevation model's source, which is most likely a remote server. Since * the high-res data must be retrieved and then loaded from the local disk cache, it will take some * time to compute and show the intersections. * * <p>This example uses a {@link gov.nasa.worldwind.terrain.Terrain} object to perform the terrain * retrieval, generation and intersection calculations.s * * @author tag * @version $Id: TerrainIntersections.java 2109 2014-06-30 16:52:38Z tgaskins $ */ public class TerrainIntersections extends ApplicationTemplate { /** The width and height in degrees of the grid used to calculate intersections. */ protected static final Angle GRID_RADIUS = Angle.fromDegrees(0.05); /** The number of cells along each edge of the grid. */ protected static final int GRID_DIMENSION = 10; // cells per side /** The desired terrain resolution to use in the intersection calculations. */ protected static final Double TARGET_RESOLUTION = 10d; // meters, or null for globe's highest resolution protected static final int NUM_THREADS = 4; // set to 1 to run synchronously public static class AppFrame extends ApplicationTemplate.AppFrame { private static final Cursor WaitCursor = new Cursor(Cursor.WAIT_CURSOR); protected HighResolutionTerrain terrain; protected RenderableLayer gridLayer; protected RenderableLayer intersectionsLayer; protected RenderableLayer sightLinesLayer; protected RenderableLayer tilesLayer; protected Thread calculationDispatchThread; protected JProgressBar progressBar; protected ThreadPoolExecutor threadPool; protected List<Position> grid; protected int numGridPoints; // used to monitor percentage progress protected long startTime, endTime; // for reporting calculation duration protected Position previousCurrentPosition; public AppFrame() { super(true, true, false); // Create a thread pool. this.threadPool = new ThreadPoolExecutor( NUM_THREADS, NUM_THREADS, 200, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); // Display a progress bar. this.progressBar = new JProgressBar(0, 100); this.progressBar.setBorder(new EmptyBorder(0, 10, 0, 10)); this.progressBar.setBorderPainted(false); this.progressBar.setStringPainted(true); this.layerPanel.add(this.progressBar, BorderLayout.SOUTH); // Be sure to re-use the Terrain object to take advantage of its caching. this.terrain = new HighResolutionTerrain(getWwd().getModel().getGlobe(), TARGET_RESOLUTION); this.gridLayer = new RenderableLayer(); this.gridLayer.setName("Grid"); this.getWwd().getModel().getLayers().add(this.gridLayer); this.intersectionsLayer = new RenderableLayer(); this.intersectionsLayer.setName("Intersections"); this.getWwd().getModel().getLayers().add(this.intersectionsLayer); this.sightLinesLayer = new RenderableLayer(); this.sightLinesLayer.setName("Sight Lines"); this.getWwd().getModel().getLayers().add(this.sightLinesLayer); // Set up a mouse handler to generate a grid and start intersection calculations when the user // shift-clicks. this.getWwd() .getInputHandler() .addMouseListener( new MouseAdapter() { public void mouseClicked(MouseEvent mouseEvent) { // Control-Click cancels any currently running operation. if ((mouseEvent.getModifiers() & ActionEvent.CTRL_MASK) != 0) { if (calculationDispatchThread != null && calculationDispatchThread.isAlive()) calculationDispatchThread.interrupt(); return; } // Alt-Click repeats the most recent calculations. if ((mouseEvent.getModifiers() & ActionEvent.ALT_MASK) != 0) { if (previousCurrentPosition == null) return; mouseEvent.consume(); // tell the rest of WW that this event has been processed computeAndShowIntersections(previousCurrentPosition); return; } // Perform the intersection tests in response to Shift-Click. if ((mouseEvent.getModifiers() & ActionEvent.SHIFT_MASK) == 0) return; mouseEvent.consume(); // tell the rest of WW that this event has been processed final Position pos = getWwd().getCurrentPosition(); if (pos == null) return; computeAndShowIntersections(pos); } }); } protected void computeAndShowIntersections(final Position curPos) { this.previousCurrentPosition = curPos; SwingUtilities.invokeLater( new Runnable() { public void run() { setCursor(WaitCursor); } }); // Dispatch the calculation threads in a separate thread to avoid locking up the user // interface. this.calculationDispatchThread = new Thread( new Runnable() { public void run() { try { performIntersectionTests(curPos); } catch (InterruptedException e) { System.out.println("Operation was interrupted"); } } }); this.calculationDispatchThread.start(); } // Create containers to hold the intersection points and the lines emanating from the center. protected List<Position> firstIntersectionPositions = new ArrayList<Position>(); protected List<Position[]> sightLines = new ArrayList<Position[]>(GRID_DIMENSION * GRID_DIMENSION); // Make the picked location's position and model-coordinate point available to all methods. protected Position referencePosition; protected Vec4 referencePoint; // This is a collection of synchronized accessors to the list updated during the calculations. protected synchronized void addIntersectionPosition(Position position) { this.firstIntersectionPositions.add(position); } protected synchronized void addSightLine(Position positionA, Position positionB) { this.sightLines.add(new Position[] {positionA, positionB}); } protected synchronized int getSightlinesSize() { return this.sightLines.size(); } private long lastTime = System.currentTimeMillis(); /** Keeps the progress meter current. When calculations are complete, displays the results. */ protected synchronized void updateProgress() { // Update the progress bar only once every 250 milliseconds to avoid stealing time from // calculations. if (this.sightLines.size() >= this.numGridPoints) endTime = System.currentTimeMillis(); else if (System.currentTimeMillis() < this.lastTime + 250) return; this.lastTime = System.currentTimeMillis(); // On the EDT, update the progress bar and if calculations are complete, update the World // Window. SwingUtilities.invokeLater( new Runnable() { public void run() { int progress = (int) (100d * getSightlinesSize() / (double) numGridPoints); progressBar.setValue(progress); if (progress >= 100) { setCursor(Cursor.getDefaultCursor()); progressBar.setString((endTime - startTime) + " ms"); showResults(); System.out.printf("Calculation time %d milliseconds\n", endTime - startTime); } } }); } /** Updates the World Wind model with the new intersection locations and sight lines. */ protected void showResults() { this.showIntersections(firstIntersectionPositions); this.showSightLines(sightLines); // this.showIntersectingTiles(this.grid, this.referencePosition); this.getWwd().redraw(); } protected void performIntersectionTests(final Position curPos) throws InterruptedException { // Clear the results lists when the user selects a new location. this.firstIntersectionPositions.clear(); this.sightLines.clear(); // Raise the selected location and the grid points a little above ground just to show we can. final double height = 5; // meters // Form the grid. double gridRadius = GRID_RADIUS.degrees; Sector sector = Sector.fromDegrees( curPos.getLatitude().degrees - gridRadius, curPos.getLatitude().degrees + gridRadius, curPos.getLongitude().degrees - gridRadius, curPos.getLongitude().degrees + gridRadius); this.grid = buildGrid(sector, height, GRID_DIMENSION, GRID_DIMENSION); this.numGridPoints = grid.size(); // Compute the position of the selected location (incorporate its height). this.referencePosition = new Position(curPos.getLatitude(), curPos.getLongitude(), height); this.referencePoint = terrain.getSurfacePoint(curPos.getLatitude(), curPos.getLongitude(), height); // // Pre-caching is unnecessary and is useful only when it occurs before the // intersection // // calculations. It will incur extra overhead otherwise. The normal intersection // calculations // // cause the same caching, making subsequent calculations on the same area // faster. // this.preCache(grid, this.referencePosition); // On the EDT, show the grid. SwingUtilities.invokeLater( new Runnable() { public void run() { progressBar.setValue(0); progressBar.setString(null); clearLayers(); showGrid(grid, referencePosition); getWwd().redraw(); } }); // Perform the intersection calculations. this.startTime = System.currentTimeMillis(); for (Position gridPos : this.grid) // for each grid point. { //noinspection ConstantConditions if (NUM_THREADS > 0) this.threadPool.execute(new Intersector(gridPos)); else performIntersection(gridPos); } } /** * Performs one line of sight calculation between the reference position and a specified grid * position. * * @param gridPosition the grid position. * @throws InterruptedException if the operation is interrupted. */ protected void performIntersection(Position gridPosition) throws InterruptedException { // Intersect the line between this grid point and the selected position. Intersection[] intersections = this.terrain.intersect(this.referencePosition, gridPosition); if (intersections == null || intersections.length == 0) { // No intersection, so the line goes from the center to the grid point. this.sightLines.add(new Position[] {this.referencePosition, gridPosition}); return; } // Only the first intersection is shown. Vec4 iPoint = intersections[0].getIntersectionPoint(); Vec4 gPoint = terrain.getSurfacePoint( gridPosition.getLatitude(), gridPosition.getLongitude(), gridPosition.getAltitude()); // Check to see whether the intersection is beyond the grid point. if (iPoint.distanceTo3(this.referencePoint) >= gPoint.distanceTo3(this.referencePoint)) { // Intersection is beyond the grid point; the line goes from the center to the grid point. this.addSightLine(this.referencePosition, gridPosition); return; } // Compute the position corresponding to the intersection. Position iPosition = this.terrain.getGlobe().computePositionFromPoint(iPoint); // The sight line goes from the user-selected position to the intersection position. this.addSightLine(this.referencePosition, new Position(iPosition, 0)); // Keep track of the intersection positions. this.addIntersectionPosition(iPosition); this.updateProgress(); } /** Inner {@link Runnable} to perform a single line/terrain intersection calculation. */ protected class Intersector implements Runnable { protected final Position gridPosition; public Intersector(Position gridPosition) { this.gridPosition = gridPosition; } public void run() { try { performIntersection(this.gridPosition); } catch (InterruptedException e) { e.printStackTrace(); } } } protected List<Position> buildGrid(Sector sector, double height, int nLatCells, int nLonCells) { List<Position> grid = new ArrayList<Position>((nLatCells + 1) * (nLonCells + 1)); double dLat = sector.getDeltaLatDegrees() / nLatCells; double dLon = sector.getDeltaLonDegrees() / nLonCells; for (int j = 0; j <= nLatCells; j++) { double lat = j == nLatCells ? sector.getMaxLatitude().degrees : sector.getMinLatitude().degrees + j * dLat; for (int i = 0; i <= nLonCells; i++) { double lon = i == nLonCells ? sector.getMaxLongitude().degrees : sector.getMinLongitude().degrees + i * dLon; grid.add(Position.fromDegrees(lat, lon, height)); } } return grid; } protected void preCache(List<Position> grid, Position centerPosition) throws InterruptedException { // Pre-cache the tiles that will be needed for the intersection calculations. double n = 0; final long start = System.currentTimeMillis(); for (Position gridPos : grid) // for each grid point. { final double progress = 100 * (n++ / grid.size()); terrain.cacheIntersectingTiles(centerPosition, gridPos); SwingUtilities.invokeLater( new Runnable() { public void run() { progressBar.setValue((int) progress); progressBar.setString(null); } }); } SwingUtilities.invokeLater( new Runnable() { public void run() { progressBar.setValue(100); } }); long end = System.currentTimeMillis(); System.out.printf( "Pre-caching time %d milliseconds, cache usage %f, tiles %d\n", end - start, terrain.getCacheUsage(), terrain.getNumCacheEntries()); } protected void clearLayers() { this.intersectionsLayer.removeAllRenderables(); this.sightLinesLayer.removeAllRenderables(); this.gridLayer.removeAllRenderables(); } protected void showIntersections(List<Position> intersections) { this.intersectionsLayer.removeAllRenderables(); // Display the intersections as CYAN points. PointPlacemarkAttributes intersectionPointAttributes; intersectionPointAttributes = new PointPlacemarkAttributes(); intersectionPointAttributes.setLineMaterial(Material.CYAN); intersectionPointAttributes.setScale(6d); intersectionPointAttributes.setUsePointAsDefaultImage(true); for (Position p : intersections) { PointPlacemark pm = new PointPlacemark(p); pm.setAltitudeMode(WorldWind.CLAMP_TO_GROUND); pm.setAttributes(intersectionPointAttributes); pm.setValue(AVKey.DISPLAY_NAME, p.toString()); this.intersectionsLayer.addRenderable(pm); } } protected void showSightLines(List<Position[]> sightLines) { this.sightLinesLayer.removeAllRenderables(); // Display the sight lines as green lines. ShapeAttributes lineAttributes; lineAttributes = new BasicShapeAttributes(); lineAttributes.setDrawOutline(true); lineAttributes.setDrawInterior(false); lineAttributes.setOutlineMaterial(Material.GREEN); lineAttributes.setOutlineOpacity(0.6); for (Position[] pp : sightLines) { List<Position> endPoints = new ArrayList<Position>(); endPoints.add(pp[0]); endPoints.add(pp[1]); Path path = new Path(endPoints); path.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); path.setAttributes(lineAttributes); this.sightLinesLayer.addRenderable(path); } } protected void showGridSightLines(List<Position> grid, Position cPos) { this.sightLinesLayer.removeAllRenderables(); // Display lines from the center to each grid point. ShapeAttributes lineAttributes; lineAttributes = new BasicShapeAttributes(); lineAttributes.setDrawOutline(true); lineAttributes.setDrawInterior(false); lineAttributes.setOutlineMaterial(Material.GREEN); lineAttributes.setOutlineOpacity(0.6); for (Position p : grid) { List<Position> endPoints = new ArrayList<Position>(); endPoints.add(cPos); endPoints.add(new Position(p.getLatitude(), p.getLongitude(), 0)); Path path = new Path(endPoints); path.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); path.setAttributes(lineAttributes); this.sightLinesLayer.addRenderable(path); } } protected void showGrid(List<Position> grid, Position cPos) { this.gridLayer.removeAllRenderables(); // Display the grid points in yellow. PointPlacemarkAttributes gridPointAttributes; gridPointAttributes = new PointPlacemarkAttributes(); gridPointAttributes.setLineMaterial(Material.YELLOW); gridPointAttributes.setScale(6d); gridPointAttributes.setUsePointAsDefaultImage(true); for (Position p : grid) { PointPlacemark pm = new PointPlacemark(p); pm.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); pm.setAttributes(gridPointAttributes); pm.setLineEnabled(true); pm.setValue(AVKey.DISPLAY_NAME, p.toString()); this.gridLayer.addRenderable(pm); } showCenterPoint(cPos); } protected void showCenterPoint(Position cPos) { // Display the center point in red. PointPlacemarkAttributes selectedLocationAttributes; selectedLocationAttributes = new PointPlacemarkAttributes(); selectedLocationAttributes.setLineMaterial(Material.RED); selectedLocationAttributes.setScale(8d); selectedLocationAttributes.setUsePointAsDefaultImage(true); PointPlacemark pm = new PointPlacemark(cPos); pm.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); pm.setAttributes(selectedLocationAttributes); pm.setValue(AVKey.DISPLAY_NAME, cPos.toString()); pm.setLineEnabled(true); this.gridLayer.addRenderable(pm); } } public static void main(String[] args) { // zoom to San Francisco downtown Configuration.setValue(AVKey.INITIAL_ALTITUDE, 34e3); Configuration.setValue(AVKey.INITIAL_LATITUDE, 37.9521d); Configuration.setValue(AVKey.INITIAL_LONGITUDE, -119.7761d); // Adjust configuration values before instantiation ApplicationTemplate.start("World Wind Terrain Intersections", AppFrame.class); } }
public AppFrame() { super(true, true, false); // Add detail hint slider panel this.getLayerPanel().add(makeDetailHintControlPanel(), BorderLayout.SOUTH); RenderableLayer layer = new RenderableLayer(); // Create and set an attribute bundle. ShapeAttributes attrs = new BasicShapeAttributes(); attrs.setInteriorMaterial(Material.YELLOW); attrs.setInteriorOpacity(0.7); attrs.setEnableLighting(true); attrs.setOutlineMaterial(Material.RED); attrs.setOutlineWidth(2d); attrs.setDrawInterior(true); attrs.setDrawOutline(false); // Create and set an attribute bundle. ShapeAttributes attrs2 = new BasicShapeAttributes(); attrs2.setInteriorMaterial(Material.PINK); attrs2.setInteriorOpacity(1); attrs2.setEnableLighting(true); attrs2.setOutlineMaterial(Material.WHITE); attrs2.setOutlineWidth(2d); attrs2.setDrawOutline(false); // ********* sample Wedges ******************* // Wedge with equal axes, ABSOLUTE altitude mode Wedge wedge3 = new Wedge(Position.fromDegrees(40, -120, 80000), Angle.POS90, 50000, 50000, 50000); wedge3.setAltitudeMode(WorldWind.ABSOLUTE); wedge3.setAttributes(attrs); wedge3.setVisible(true); wedge3.setValue(AVKey.DISPLAY_NAME, "Wedge with equal axes, ABSOLUTE altitude mode"); layer.addRenderable(wedge3); // Wedge with equal axes, RELATIVE_TO_GROUND Wedge wedge4 = new Wedge(Position.fromDegrees(37.5, -115, 50000), Angle.POS90, 50000, 50000, 50000); wedge4.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); wedge4.setAttributes(attrs); wedge4.setVisible(true); wedge4.setValue( AVKey.DISPLAY_NAME, "Wedge with equal axes, RELATIVE_TO_GROUND altitude mode"); layer.addRenderable(wedge4); // Wedge with equal axes, CLAMP_TO_GROUND Wedge wedge5 = new Wedge(Position.fromDegrees(35, -110, 50000), Angle.POS90, 50000, 50000, 50000); wedge5.setAltitudeMode(WorldWind.CLAMP_TO_GROUND); wedge5.setAttributes(attrs); wedge5.setVisible(true); wedge5.setValue(AVKey.DISPLAY_NAME, "Wedge with equal axes, CLAMP_TO_GROUND altitude mode"); layer.addRenderable(wedge5); // Wedge with a texture, using Wedge(position, angle, height, radius) constructor Wedge wedge9 = new Wedge(Position.fromDegrees(0, -90, 600000), Angle.fromDegrees(225), 1200000, 600000); wedge9.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); wedge9.setImageSources("gov/nasa/worldwindx/examples/images/500px-Checkerboard_pattern.png"); wedge9.setAttributes(attrs); wedge9.setVisible(true); wedge9.setValue(AVKey.DISPLAY_NAME, "Wedge with a texture"); layer.addRenderable(wedge9); // Scaled Wedge with default orientation Wedge wedge = new Wedge(Position.ZERO, Angle.fromDegrees(125), 500000, 500000, 500000); wedge.setAltitudeMode(WorldWind.ABSOLUTE); wedge.setAttributes(attrs); wedge.setVisible(true); wedge.setValue(AVKey.DISPLAY_NAME, "Scaled Wedge with default orientation"); layer.addRenderable(wedge); // Scaled Wedge with a pre-set orientation Wedge wedge2 = new Wedge( Position.fromDegrees(0, 30, 750000), Angle.POS90, 500000, 500000, 500000, Angle.fromDegrees(90), Angle.fromDegrees(45), Angle.fromDegrees(30)); wedge2.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); wedge2.setAttributes(attrs2); wedge2.setVisible(true); wedge2.setValue(AVKey.DISPLAY_NAME, "Scaled Wedge with a pre-set orientation"); layer.addRenderable(wedge2); // Scaled Wedge with a pre-set orientation Wedge wedge6 = new Wedge( Position.fromDegrees(30, 30, 750000), Angle.POS90, 500000, 500000, 500000, Angle.fromDegrees(90), Angle.fromDegrees(45), Angle.fromDegrees(30)); wedge6.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); wedge6.setImageSources("gov/nasa/worldwindx/examples/images/500px-Checkerboard_pattern.png"); wedge6.setAttributes(attrs2); wedge6.setVisible(true); wedge6.setValue(AVKey.DISPLAY_NAME, "Scaled Wedge with a pre-set orientation"); layer.addRenderable(wedge6); // Scaled Wedge with a pre-set orientation Wedge wedge7 = new Wedge( Position.fromDegrees(60, 30, 750000), Angle.POS90, 500000, 500000, 500000, Angle.fromDegrees(90), Angle.fromDegrees(45), Angle.fromDegrees(30)); wedge7.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); wedge7.setAttributes(attrs2); wedge7.setVisible(true); wedge7.setValue(AVKey.DISPLAY_NAME, "Scaled Wedge with a pre-set orientation"); layer.addRenderable(wedge7); // Scaled, oriented Wedge in 3rd "quadrant" (-X, -Y, -Z) Wedge wedge8 = new Wedge( Position.fromDegrees(-45, -180, 750000), Angle.POS90, 500000, 1000000, 500000, Angle.fromDegrees(90), Angle.fromDegrees(45), Angle.fromDegrees(30)); wedge8.setAltitudeMode(WorldWind.RELATIVE_TO_GROUND); wedge8.setAttributes(attrs2); wedge8.setVisible(true); wedge8.setValue( AVKey.DISPLAY_NAME, "Scaled, oriented Wedge with in the 3rd 'quadrant' (-X, -Y, -Z)"); layer.addRenderable(wedge8); // Add the layer to the model. insertBeforeCompass(getWwd(), layer); // Update layer panel this.getLayerPanel().update(this.getWwd()); }