positions.add(Position.fromDegrees(Double.parseDouble(xy[1]), Double.parseDouble(xy[0]), 0)); Path path = new Path(positions, attrs); path.setHighlightAttributes(highlightAttrs); path.setAltitudeMode(WorldWind.CLAMP_TO_GROUND); path.setPathType(WorldWind.LINEAR); path.setFollowTerrain(true); // essential for preventing long segments from intercepting ellipsoid. path.setDisplayName(attributes);
@Override public boolean handleMessage(Message msg) { if (this.animationAmount < 1) { // Increment the animation amount. this.animationAmount += this.animationIncrement; for (int idx = 0, len = this.flightPathLayer.count(); idx < len; idx++) { // Identify the departure airport and destination airport associated with each flight path. Path path = (Path) this.flightPathLayer.getRenderable(idx); Airport dept = (Airport) path.getUserProperty("dept"); Airport dest = (Airport) path.getUserProperty("dest"); // Compute the location on the great circle path between the departure and the destination that // corresponds to the animation amount. Position nextPos = dept.pos.interpolateAlongPath(dest.pos, WorldWind.GREAT_CIRCLE, this.animationAmount, new Position()); // Compute the altitude on the flight path that corresponds to the animation amount. We mock altitude // using an inverse parabolic function scaled to reach a max altitude of 10% of the flight distance. double dist = dept.pos.greatCircleDistance(dest.pos) * this.getWorldWindow().getGlobe().getEquatorialRadius(); double altCurve = (1 - this.animationAmount) * this.animationAmount * 4; nextPos.altitude = altCurve * dist * 0.1; // Append the location and altitude to the flight path's list of positions. List<Position> positions = path.getPositions(); positions.add(nextPos); path.setPositions(positions); } // Redraw the WorldWindow to display the changes. this.getWorldWindow().requestRedraw(); // Continue the animation after a delay. this.handler.sendEmptyMessageDelayed(0 /*what*/, 1000); } return false; }
protected void populateFlightPaths() { ShapeAttributes attrs = new ShapeAttributes(); attrs.getInteriorColor().set(0.8f, 0.8f, 1.0f, 0.8f); attrs.getOutlineColor().set(1.0f, 1.0f, 0.0f, 1.0f); Airport dept = this.airportIkoIndex.get("KSEA"); for (Airport dest : this.airportTable) { if (dest.equals(dept)) { continue; // the destination and departure must be different } if (dest.iko.length() != 4) { continue; // the destination must be a major airfield } if (!dest.na3.startsWith("US")) { continue; // the destination must be in the United States } if (!dest.use.equals("49")) { continue; // the destination must a Civilian/Public airport } List<Position> positions = new ArrayList<>(); positions.add(dept.pos); Path path = new Path(positions, attrs); path.putUserProperty("dept", dept); path.putUserProperty("dest", dest); this.flightPathLayer.addRenderable(path); } }
Position.fromDegrees(50, -40, 1e5) ); Path path = new Path(positions); layer.addRenderable(path); Position.fromDegrees(40, -40, 0) ); path = new Path(positions); path.setAltitudeMode(WorldWind.CLAMP_TO_GROUND); // clamp the path vertices to the ground path.setFollowTerrain(true); // follow the ground between path vertices layer.addRenderable(path); Position.fromDegrees(30, -40, 1e5) ); path = new Path(positions); path.setExtrude(true); // extrude the path from the ground to each path position's altitude layer.addRenderable(path); attrs.setInteriorColor(new Color(1, 1, 1, 0.5f)); // 50% transparent white attrs.setOutlineWidth(3); path = new Path(positions, attrs); path.setExtrude(true); // extrude the path from the ground to each path position's altitude layer.addRenderable(path);
Position.fromDegrees(0.0, -100.0, 1e5) ); Path path = new Path(positions); ShapeAttributes sa = new ShapeAttributes(thickenLine); sa.setOutlineImageSource(ImageSource.fromLineStipple(2 /*factor*/, (short) 0xF0F0 /*pattern*/)); path.setAttributes(sa); layer.addRenderable(path); Position.fromDegrees(0.0, -90.0, 5e4) ); path = new Path(positions); sa = new ShapeAttributes(thickenLine); sa.setOutlineImageSource(ImageSource.fromLineStipple(4 /*factor*/, (short) 0xF0F0 /*pattern*/)); path.setAttributes(sa); layer.addRenderable(path); Position.fromDegrees(0.0, -80.0, 0.0) ); path = new Path(positions); sa = new ShapeAttributes(thickenLine); sa.setOutlineImageSource(ImageSource.fromLineStipple(8 /*factor*/, (short) 0xDFF6 /*pattern*/)); path.setAttributes(sa); path.setAltitudeMode(WorldWind.CLAMP_TO_GROUND); path.setFollowTerrain(true); layer.addRenderable(path);
if (this.mustAssembleGeometry(rc)) { this.assembleGeometry(rc); this.vertexBufferKey = nextCacheKey(); this.elementBufferKey = nextCacheKey(); drawable = DrawableSurfaceShape.obtain(pool); drawState = ((DrawableSurfaceShape) drawable).drawState; cameraDistance = this.cameraDistanceGeographic(rc, this.boundingSector); ((DrawableSurfaceShape) drawable).sector.set(this.boundingSector); } else { drawable = DrawableShape.obtain(pool); drawState = ((DrawableShape) drawable).drawState; cameraDistance = this.cameraDistanceCartesian(rc, this.vertexArray.array(), this.vertexArray.size(), VERTEX_STRIDE, this.vertexOrigin); this.computeRepeatingTexCoordTransform(texture, metersPerPixel, this.texCoordMatrix); drawState.texture(texture); drawState.texCoordMatrix(texCoordMatrix);
this.addVertex(rc, begin.latitude, begin.longitude, begin.altitude, false /*intermediate*/); this.addIntermediateVertices(rc, begin, end); this.addVertex(rc, end.latitude, end.longitude, end.altitude, false /*intermediate*/); begin = end;
this.addVertex(rc, loc.latitude, loc.longitude, alt, true /*intermediate*/); dist += deltaDist; alt += deltaAlt;