to have wwjava run in fullscreen, try the following:
- - instantiate your worlwind JFrame (WWFrame in supplied demos)
- - make it non-resizable (wwFrame.setResizable(false);)
- - finally type the following incantation:
GraphicsDevice graphicsDevice = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
graphicsDevice.setFullScreenWindow(wwFrame);
wwFrame.setVisible(true);
where wwFrame is your worldwind frame.
let’s say you want to display a non-opaque filled shape in worldwind java. you tried to set the containing layer opacity to, say, 0.5, but that didn’t work. better try with an AlphaComposite:
1- inherit SurfaceShape
2- implement the drawShape method of the Surface class you want to have translucent (unfortunately the drawShape method is final, so no overriding is possible here). here is how it goes for a SurfacePolygon:
public class AlphaSurfacePolygon extends SurfaceShape {
private static final double TO_RADIANS = (Math.PI / 180);
private AlphaComposite composite;
/**
* A Renderable polygon shape defined by a list of LatLon
*
* @param positions the list of LatLon positions that makes the polygon
* @param color the interior fill color
* @param borderColor the border color
*/
public AlphaSurfacePolygon(Iterable<LatLon> positions, Color color, Color borderColor,double opacity)
{
super(positions, color, borderColor, null);
setOpacity(opacity);
}
/**
* A Renderable polygon shape defined by a list of LatLon
*
* @param positions the list of LatLon positions that makes the polygon
*/
public AlphaSurfacePolygon(Iterable<LatLon> positions, double opacity)
{
super(positions, null, null, null);
setOpacity(opacity);
}
public AlphaSurfacePolygon(Iterable<LatLon> positions, Color color, Color borderColor, Dimension textureSize, double opacity)
{
super(positions, color, borderColor, textureSize);
setOpacity(opacity);
}
/**
* Draw all or part of the shape that intersects a given Sector into the given BufferedImage
*/
protected final BufferedImage drawShape(Globe globe, Sector sector, BufferedImage image)
{
double rsw = globe.getRadiusAt(sector.getMinLatitude(), sector.getMinLongitude());
double rne = globe.getRadiusAt(sector.getMaxLatitude(), sector.getMaxLongitude());
double xsw = rsw * sector.getMinLongitude().radians;
double ysw = rsw * sector.getMinLatitude().radians;
double xne = rne * sector.getMaxLongitude().radians;
double yne = rne * sector.getMaxLatitude().radians;
double dy = yne - ysw;
double dx = xne - xsw;
// Note : WWJ-36 negate latScale to define path upside-down
// (will be drawn with a mirror transform - this gets paint patterns right)
double latScale = dy > 0 ? -(image.getHeight() - 1) / dy : 0;
double lonScale = dx > 0 ? (image.getWidth() - 1) / dx : 0;
// If we may cross +-180 degrees longitude, then offset
// all longitudes 180 degrees the other way
double lonOffset = 0;
if (sector.getMaxLongitude().getDegrees() == 180 && sector.getDeltaLonDegrees() < 180)
lonOffset = -180;
if (sector.getMinLongitude().getDegrees() == -180 && sector.getDeltaLonDegrees() < 180)
lonOffset = 180;
GeneralPath path = new GeneralPath();
Iterator<LatLon> positions = this.getPositions().iterator();
if (!positions.hasNext())
return image;
// Start position
LatLon pos = this.computeDrawLatLon(positions.next(), sector, lonOffset);
double r = globe.getRadiusAt(pos.getLatitude(), pos.getLongitude());
double x = lonScale * (r * pos.getLongitude().radians - r * TO_RADIANS * lonOffset - xsw);
double y = latScale * (r * pos.getLatitude().radians - ysw);
path.moveTo((float) x, (float) y);
while (positions.hasNext())
{
// Next position
LatLon posNext = this.computeDrawLatLon(positions.next(), sector, lonOffset);
// Compute number of necessary steps
int numIntervals = (int) Math.max(1d,
this.getNumEdgeIntervalsPerDegree() * LatLon.sphericalDistance(pos, posNext).degrees);
double delta = 1d / numIntervals;
// Draw segments to next position
for (int i = 1; i < numIntervals; i++)
{
// In between steps
LatLon p = LatLon.interpolate(i * delta, pos, posNext);
r = globe.getRadiusAt(p.getLatitude(), p.getLongitude());
x = lonScale * (r * p.getLongitude().radians - r * TO_RADIANS * lonOffset - xsw);
y = latScale * (r * p.getLatitude().radians - ysw);
path.lineTo((float) x, (float) y);
}
// Set the last point directly to avoid any round-off error in the iteration above.
r = globe.getRadiusAt(posNext.getLatitude(), posNext.getLongitude());
x = lonScale * (r * posNext.getLongitude().radians - r * TO_RADIANS * lonOffset - xsw);
y = latScale * (r * posNext.getLatitude().radians - ysw);
path.lineTo((float) x, (float) y);
// Next
pos = posNext;
}
Graphics2D g2 = image.createGraphics();
// Set mirror Y transform
g2.setTransform(AffineTransform.getScaleInstance(1, -1));
// Set antiliasing hint
if (this.isAntiAlias())
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Draw interior
if (this.isDrawInterior())
{
g2.setPaint(this.getPaint());
g2.setComposite(composite);
g2.fill(path);
}
// Draw border
if (this.isDrawBorder())
{
g2.setPaint(this.getBorderColor());
g2.setStroke(this.getStroke());
g2.setComposite(composite);
g2.draw(path);
}
return image;
}
public void setOpacity(double opacity)
{
composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, (float)opacity);
}
/**
* Returns the drawing LatLon relative to a given Sector and a longitude offset Can go beyond +-180 degrees
* longitude if the offset is zero
*
* @param pos the real LatLon
* @param sector the drawing Sector
* @param lonOffset the current longitude offset in degrees
* @return the appropiate drawing LatLon
*/
private LatLon computeDrawLatLon(LatLon pos, Sector sector, double lonOffset)
{
int directionOffset;
directionOffset = sector.getMaxLongitude().degrees - pos.getLongitude().getDegrees() > 180 ?
360 : 0;
directionOffset = pos.getLongitude().getDegrees() - sector.getMinLongitude().getDegrees() > 180 ?
-360 : directionOffset;
return LatLon.fromDegrees(pos.getLatitude().getDegrees(),
pos.getLongitude().getDegrees() + directionOffset + lonOffset);
}
}
here is a quick hack to add esri shapefiles support in worlwind java:
1- get gistoolkit
2- strip de bones (keep only gistoolkit.features.*, gistoolkit.common and gistoolkit.datasources.shapefile)
3 - Link to your project.
4- then you can add a shapefile to a layer by doing something like this, if you are really lazy:
ShapeFile shp = new ShapeFile(fn);
if (shp == null)
return;
try {
shp.readRecords();
} catch(Exception e) {
err("Error while reading shape.");
return;
}
ShapeFileRecord[] r = shp.getRecords();
int i, j;
fireLayer.clearList();
gistoolkit.features.Point lastCenter = null;
for(i=0; i<r.length; i++)
{
gistoolkit.features.Shape s = r[i].getShape();
if (s.getShapeType() == "MULTIPOLYGON") {
gistoolkit.features.MultiPolygon m = (gistoolkit.features.MultiPolygon) s;
gistoolkit.features.Polygon[] polys = m.getPolygons();
for(j=0; j<polys.length; j++) {
addPolygon(polys[j]);
lastCenter = polys[j].getCentroid();
}
}
}
private void addPolygon(gistoolkit.features.Polygon p)
{
int i;
ArrayList<LatLon> positions = new ArrayList<LatLon>();
gistoolkit.features.Point[] pts = p.getPoints();
for(i=0; i<pts.length; i++)
{
positions.add(LatLon.fromDegrees(pts[i].y, pts[i].x));
}
Dimension texSize = new Dimension();
texSize.setSize(1024, 1024);
SurfacePolygon fire = new SurfacePolygon(positions, new Color(1f, 0f, 0f), new Color(1f, 0f, 0f), texSize);
fire.setDrawInterior(true);
fireLayer.addRenderable(fire);
}
fireLayer is a RenderableLayer that was initialized previously.
texSize is needed so that the shape doesn’t look too blurry.