![]() |
|
|||||||
| Development Help Help for building applications or diagnosing problems with WWJ |
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Guest
Posts: n/a
|
Hi all,
I am trying to create a custom layer that renders Annotations, as for my application I am using many custom layers and a lot of openGL. I have an application that is injected with events from XML messages over the Java Messaging Service, so when my application starts up, it doesn't have any Annotations showing because the data structure is empty. Then as my data structure fills up, I want to create an annotation for each object in my data structure. I have modeled my class off of an icon rendering class that was modeled off of QuadTreeIconLayer in another thread: http://forum.worldwindcentral.com/sh...light=quadTree I stuck a garbage data annotation at the beginning of my workhorse method, but that does not render at startup. Nor do the other points get annotations when the data structure fills up. I think this may have to do with the way that BasicAnnotationRenderer handles its render method as opposed to the IconRenderer? The documentation here: http://www.bugaco.com/worldwind/gov/...nRenderer.html gives a render(DrawContext dc, Iterable<Annotation> annotations) method, but the actual source doesn't have this method. to add the layer, in an initialization method: Code:
this.annotationsLayer = new ObjectAnnotationsLayer(); wwjPanel.wwd.getModel().getLayers().add(this.annotationsLayer.getLayer()); Code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.layers.AbstractLayer;
import gov.nasa.worldwind.layers.AnnotationLayer;
import gov.nasa.worldwind.layers.Layer;
import gov.nasa.worldwind.layers.RenderableLayer;
import gov.nasa.worldwind.render.Annotation;
import gov.nasa.worldwind.render.AnnotationAttributes;
import gov.nasa.worldwind.render.BasicAnnotationRenderer;
import gov.nasa.worldwind.render.DrawContext;
import gov.nasa.worldwind.render.GlobeAnnotation;
public class ObjectAnnotationsLayer extends AbstractLayer{
public ObjectAnnotationsLayer() {
this.setName("Annotations");
}
private BasicAnnotationRenderer noteRenderer = new BasicAnnotationRenderer();
private RenderableLayer layer = new RenderableLayer();
public RenderableLayer getLayer() {
return layer;
}
public void setLayer(RenderableLayer layer) {
this.layer = layer;
}
@Override
protected void doRender(DrawContext dc) {
List notes = collectAnnotations(dc);
noteRenderer.render(dc, (List<Annotation>) notes, layer);
}
private List collectAnnotations(DrawContext dc) {
List notes = new ArrayList();
AnnotationAttributes aa = new AnnotationAttributes();
aa.setBackgroundColor(Color.WHITE);
aa.setBorderColor(Color.BLACK);
aa.setSize(new Dimension(240, 0));
aa.setHighlightScale(1);
aa.setInsets(new Insets(12, 12, 12, 20));
aa.setFont(Font.decode("SansSerif-PLAIN-14"));
aa.setTextColor(Color.BLACK);
collectAnnotations(dc, notes, aa);
return notes;
}
private void collectAnnotations(DrawContext dc, List notes, AnnotationAttributes aa) {
GlobeAnnotation ga;
ga = new GlobeAnnotation("<p>Welcome...</p>", Position.fromDegrees(44, -100, 0), aa);
notes.add(ga);
TreeMap data = SingletonData.getSingletonData();
if(data!= null){
synchronized(data){
Set<Integer> keySet = data.keySet();
for(Integer objNum : keySet){
synchronized (data.get(objNum)){
notes.add(new GlobeAnnotation("text",
data.get(objNum).getPos(),
aa));
}
}
}
}
this.firePropertyChange(AVKey.LAYER, null, this);
}
}
|
|
|
|
#2 |
|
WWJ Consultant
Join Date: Jun 2005
Location: Saint-Paul de Vence, Alpes Maritimes, France
Posts: 3,412
|
Your ObjectAnnotationsLayer instance doRender() method is never called because it is not in the model layer list - the 'internal' RenderablLayer instance (layer) is.
Simply remove the internal renderable layer from your code and add your OAL instance to the model layer list rather then the one you obtain from getLayer(). |
|
|
|
|
|
#3 |
|
Junior Member
Join Date: Oct 2009
Posts: 6
|
Hello again,
I was able to get my annotations to render correctly, thanks! However, for another part of my application I have had to set the clipping planes to large values to correctly render objects that stick out of the globe at high altitudes. When I did this, it caused annotations for objects that are directly behind the globe to be transparently rendered. My other custom layers are made up of openGL calls, and I can keep depth testing enabled on those in order to keep keep the icons and other objects from rendering when behind the globe. This one is stumping me, however. Do I need to overwrite the BasicAnnotationRenderer to not always set the annotation to isAlwaysOnTop? Is there an annotation attribute that could help with this? Thanks, kluhm |
|
|
|
|
|
#4 |
|
Junior Member
Join Date: Oct 2009
Posts: 6
|
I have solved this using a workaround. In the layer where I create the annotations, before rendering, I create a line segment from the eyePoint of the view to the Vec4 point of the position. I then see if there are any intersections of this line with the Globe:
Intersection[] intersections = dc.getGlobe().intersect(line, 0); If there are intersections, I check to see if the intersection or the object is closer to the eyePoint and only render the object if it is closer than the intersection. Last edited by kluhm; 03-09-2010 at 10:47 PM. |
|
|
|
|
|
#5 |
|
WWJ Consultant
Join Date: Jun 2005
Location: Saint-Paul de Vence, Alpes Maritimes, France
Posts: 3,412
|
Can you post a screenshot of the issue you are having? Thanks.
|
|
|
|
|
|
#6 |
|
Junior Member
Join Date: Oct 2009
Posts: 6
|
Like I said, I solved it, but I needed a little extra code; here is what I added:
Code:
public boolean isVisible(DrawContext dc, Position soPos){
Vec4 soPoint = dc.getGlobe().computePointFromPosition(soPos);
Vec4 eyePoint = dc.getView().getEyePoint();
Line eyeToSO = Line.fromSegment(soPoint, eyePoint);
Intersection[] intersections = dc.getGlobe().intersect(eyeToSO, 0);
if (intersections == null)
return true;
else {
for (Intersection idx : intersections) {
double intersectDistance = Math.abs(idx.getIntersectionPoint().
distanceTo3(eyePoint));
double objectDistance = Math.abs(soPoint.distanceTo3(eyePoint));
if (objectDistance < intersectDistance)
return true;
}
return false;
}
}
Last edited by kluhm; 03-10-2010 at 07:22 PM. Reason: Grammar/Clarification |
|
|
|
|
|
#7 |
|
Guest
Posts: n/a
|
I want to ask where is the eyepoint.
eyepoint=dc.getView().getEyePoint(); can everyone help me,thanks. |
|
![]() |
| Tags |
| annotation, basicannotationrenderer, layers |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|