WorldWind Point Placemark Heading

In NASA WorldWind Java, I use PointPlacemark to represent the image because it stays the same size regardless of the zoom level. The problem is that I want to set the title on the Point Placemark method and leave it on this compass, even when the camera is tilted. It works exactly the way I want when I look at an infinite globe, but when I bend, the label continues to collide with the screen instead of tilting with the globe, which makes it act weirdly.

Here is a GIF illustrating what I see: https://giphy.com/embed/3o7WIqZUceR8xh6BOg

I would like the Point Placemark Image to remain on the title bar relative to the globe, even when it is tilted - so that the image is essentially “flattened” when the image is tilted, but it remains the same size regardless of the zoom level.

Here is a piece of code that I am using. I set attrs.setHeadingReference (AVKey.RELATIVE_TO_GLOBE); on the related attributes of PointPlacemarkAttributes. In this example, I set the title to 135 degrees.

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); } } 

I also played using Polygon with a texture applied to it. The way it is oriented is what I am looking for - except that I want the icon to remain the same size regardless of the zoom level (for example, what PointPlacemark does).

Here is a GIF illustrating what I see when using Polygon. Pay attention to how it acts when the globe is tilted: https://giphy.com/embed/xThta4USlDzd8Ii5ZS

Here is the source I'm using for Polygon:

 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); } } 

For completeness - this is the image that I use as my plane. png:

2oARv.png

So, to summarize what I'm looking for:

  • A Renderable represented by Icon
  • The icon remains the same regardless of the zoom level.
  • The icon remains oriented to the heading of the compass of the globe, even if the camera view is tilted.
+7
java opengl jogl worldwind
source share
2 answers

I thought that it would be a difficult task, but it turned out that this is not so. PointPlacemark seems to have a pitch attribute. I thought that just setting it to the height of the view, I would be golden. attrs.setPitch(wwjPanel.getWwd().getView().getPitch().degrees);

I was not. There seems to be an error (I'm not familiar with OpenGL at all, but assuming setPitch() , which doesn't work, sounds like an error to me), and if you do the above, you will get something like this:

cropped 1

If you rotate it more, you will get the following:

cropped 2

Then I told myself, wait a minute, how does the compass rotate along the X axis? I was looking for a class that deals with compass, and there is this snippet in CompassLayer

 if (this.showTilt) // formula contributed by Ty Hayden gl.glRotated(70d * (pitch / 90.0), 1d, 0d, 0d); 

I tried using it for PointPlacemark , but (what a surprise) it does not work.

I have no ideas (and because of the time at the moment), so good luck with that, and I hope this can help get started. I donated the answer to the community, so if you ever find out the solution, feel free to update it.

+5
source share

What you want to achieve is the scale of your polygon based on the position of the camera’s eyes, and hold the map-oriented polygon.

You can try updating your second solution and adding RenderingListener ro to update the size of your polygon before rendering:

 wwd.addRenderingListener(new RenderingListener() { public void stageChanged(RenderingEvent event) { if (RenderingEvent.BEFORE_RENDERING.equals(event.getStage()) { if (wwd.getView() != null && wwd.getView().getEyePosition() != null) { // compute distance between eyePosition and object position, and set the scale. } } } }); 
+4
source share

All Articles