WorldWind PointPlacemark Heading
Na NASA WorldWind Java, estou usando o PointPlacemark para representar uma imagem, pois ela permanece do mesmo tamanho, independentemente do nível de zoom. O problema é que eu quero definir o cabeçalho no marcador de ponto e mantê-lo nessa direção da bússola, mesmo quando a câmera estiver inclinada. Funciona exatamente como eu quero ao visualizar um globo inclinado, mas quando inclino, o marcador continua voltado para a tela em vez de inclinar com o globo, o que faz com que ele aja de maneira estranha.
Aqui está um GIF que ilustra o que estou vendo:https://giphy.com/embed/3o7WIqZUceR8xh6BOg
Gostaria que a imagem do marcador de ponto permanecesse em um cabeçalho em relação ao globo, mesmo quando inclinada - para que a imagem seja "achatada" conforme a vista é inclinada, mantendo o mesmo tamanho, independentemente do nível de zoom.
Aqui está um trecho de código que estou usando. Estou definindo attrs.setHeadingReference (AVKey.RELATIVE_TO_GLOBE); no PointPlacemarkAttributes associado. Neste exemplo, estou definindo o cabeçalho para 135 graus.
import gov.nasa.worldwind.WorldWind;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.layers.RenderableLayer;
import gov.nasa.worldwind.render.Offset;
import gov.nasa.worldwind.render.PointPlacemark;
import gov.nasa.worldwind.render.PointPlacemarkAttributes;
public class Placemarks extends ApplicationTemplate {
public static class AppFrame extends ApplicationTemplate.AppFrame {
public AppFrame() {
super(true, true, false);
final RenderableLayer layer = new RenderableLayer();
PointPlacemark pp = new PointPlacemark(Position.fromDegrees(28, -102, 30000));
pp.setLabelText("Airplane");
pp.setLineEnabled(false);
pp.setAltitudeMode(WorldWind.ABSOLUTE);
PointPlacemarkAttributes attrs = new PointPlacemarkAttributes();
attrs.setImageAddress("images/airplane.png");
attrs.setScale(0.05);
attrs.setImageOffset(Offset.CENTER);
//Point to 135.0
attrs.setHeading(135.0);
attrs.setHeadingReference(AVKey.RELATIVE_TO_GLOBE);
pp.setAttributes(attrs);
layer.addRenderable(pp);
// Add the layer to the model.
insertBeforeCompass(getWwd(), layer);
}
}
public static void main(String[] args) {
ApplicationTemplate.start("WorldWind Placemarks", AppFrame.class);
}
}
Também brinquei com o uso de um polígono com uma textura aplicada a ele. A maneira como ela é orientada é o que estou procurando - exceto que quero que o ícone permaneça do mesmo tamanho, independentemente do nível de zoom (como o que o PointPlacemark faz).
Aqui está um GIF que ilustra o que estou vendo ao usar um polígono. Observe como ele age quando o globo é inclinado:https://giphy.com/embed/xThta4USlDzd8Ii5ZS
Aqui está a fonte que estou usando para o polígono:
import java.awt.geom.AffineTransform;
import java.util.Arrays;
import java.util.List;
import gov.nasa.worldwind.WorldWind;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.layers.RenderableLayer;
import gov.nasa.worldwind.render.BasicShapeAttributes;
import gov.nasa.worldwind.render.Polygon;
public class TexturedPolygon extends ApplicationTemplate {
public static Polygon createPolygonTexturedImage(String filePath, Position pos, double heading, double scale) {
double offsetDist = 1.0D * scale;
Position p1 = Position.fromDegrees(pos.getLatitude().addDegrees(-offsetDist).getDegrees(),
pos.getLongitude().addDegrees(-offsetDist).getDegrees(), pos.getAltitude());
Position p2 = Position.fromDegrees(pos.getLatitude().addDegrees(offsetDist).getDegrees(),
pos.getLongitude().addDegrees(-offsetDist).getDegrees());
Position p3 = Position.fromDegrees(pos.getLatitude().addDegrees(offsetDist).getDegrees(),
pos.getLongitude().addDegrees(offsetDist).getDegrees());
Position p4 = Position.fromDegrees(pos.getLatitude().addDegrees(-offsetDist).getDegrees(),
pos.getLongitude().addDegrees(offsetDist).getDegrees());
double[] points = new double[] { p1.getLatitude().getDegrees(), p1.getLongitude().getDegrees(),
p2.getLatitude().getDegrees(), p2.getLongitude().getDegrees(), p3.getLatitude().getDegrees(),
p3.getLongitude().getDegrees(), p4.getLatitude().getDegrees(), p4.getLongitude().getDegrees() };
double[] transformedPoints = new double[8];
AffineTransform rotation = new AffineTransform();
rotation.rotate(Math.toRadians(heading), pos.getLatitude().getDegrees(), pos.getLongitude().getDegrees());
rotation.transform(points, 0, transformedPoints, 0, 4);
double altitude = pos.getAltitude();
p1 = Position.fromDegrees(transformedPoints[0], transformedPoints[1], altitude);
p2 = Position.fromDegrees(transformedPoints[2], transformedPoints[3], altitude);
p3 = Position.fromDegrees(transformedPoints[4], transformedPoints[5], altitude);
p4 = Position.fromDegrees(transformedPoints[6], transformedPoints[7], altitude);
List<Position> positions = Arrays.asList(p1, p2, p3, p4);
Polygon polygon = new Polygon(positions);
polygon.setAltitudeMode(WorldWind.ABSOLUTE);
BasicShapeAttributes mattr = new BasicShapeAttributes();
mattr.setDrawOutline(false);
mattr.setDrawInterior(true);
polygon.setAttributes(mattr);
polygon.setTextureImageSource(filePath, new float[] { 0.0F, 0.0F, 1.0F, 0.0F, 1.0F, 1.0F, 0.0F, 1.0F }, 4);
return polygon;
}
public static class AppFrame extends ApplicationTemplate.AppFrame {
public AppFrame() {
super(true, true, false);
final RenderableLayer layer = new RenderableLayer();
Position pos = Position.fromDegrees(28, -102, 30000);
String url = "images/airplane.png";
layer.addRenderable(createPolygonTexturedImage(url, pos, 135.0, 1.05));
// Add the layer to the model.
insertBeforeCompass(getWwd(), layer);
}
}
public static void main(String[] args) {
ApplicationTemplate.start("WorldWind Placemarks", AppFrame.class);
}
}
Para completar, aqui está a imagem que estou usando como meu airplane.png:
Então, para resumir, o que estou procurando:
Um renderizável representado por uma imagem de íconeO ícone permanece o mesmo tamanho, independentemente do nível de zoomO ícone permanece orientado na direção da bússola, mesmo quando a câmera está inclinada