Best way to dynamically add new features

classic Classic list List threaded Threaded
14 messages Options
David David
Reply | Threaded
Open this post in threaded view
|

Best way to dynamically add new features

I need to be able to let the user draw lines, polygons, ellipses, etc on the map.  Thus I can't just define some models in my .earth file, I need to add new features at run-time using the API.  I looked at the osgearth_features example and it looks like what that example does is basically:

* Define the geometry (a Ring in the example)
* Define a Style
* Define an OGRFeatureOptions object that references the geometry.
* Define a FeatureGeomModelOptions object that references the style and the geometry via the feature options.
* Define a ModelLayerOptions object that references the FeatureGeomModelOptions
* Add a ModelLayer to the map using the ModelLayerOptions.

I need to be able to create a lot of these things.  Some of them will use the same style, but some won't; it will be a mix of different fill and line colors.  Do I need to do all of those steps for every new feature, or can I reuse the some of the same objects?  Should I try to combine models that use the same styles on the same layer?  Are there other optimization tricks I should keep in mind when doing this?
gwaldron gwaldron
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

David,
That process is geared towards loading external datasets and styling them. If your user is drawing individual features, I suggest using the FeatureNode in the Annotations library. You can start with the osgearth_annotation example. You can add FeatureNodes directly to the MapNode, or you can put them under an AnnotationLayer.

Hope this helps.
Glenn Waldron / Pelican Mapping
David David
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

I had previously tried using a FeatureNode and the shape wasn't showing up in a 2D (projected) map.  I'll try again, looking at the annotation examples.

Is there an advantage to using an AnnotationLayer as opposed to just adding the FeatureNodes directly to the map?
gwaldron gwaldron
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

David,
Not a lot - it lets you manage the data as part of the Map model - you can toggle the visibility or the enabled state globally for the layer. Some day we might add serialization support (so you can save it to an earth file).
Glenn Waldron / Pelican Mapping
David David
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

Ok, I'll give that a shot.  Thanks for to feedback!
ago ago
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

This post was updated on .
This is similar to an editor, and SXEarth is an osgearth editor. osgEarth has a lot of styles that need to be configured via GUI.

Support for mouse drawing annotation,select annotation, configuration through the GUI, and then writing to the earth file.

osgDB::writeNodeFile(*mapNode.get(), earthPath);


36.gif








SXEarth,a free osgEarth GUI Editor and Flight Simulation.

Email: seegogo@126.com
SXEarth download: http://www.sxsim.com/en/

David David
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

In reply to this post by gwaldron
I got it working using just a Feature and a FeatureNode like gwaldron suggested.  I realized my problem with it not showing up in my 2D (projected) map was that I wasn't converting the coordinates from (lon, lat, alt) to the projected scene's SpatialReference.

Adding new points to the end of the geometry is pretty trivial, but is there a better way to insert, remove, or update points at arbitrary positions in the geometry other than clearing it and repopulating it from scratch?  I don't see any methods to update existing points in the geometry.
gwaldron gwaldron
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

David,
The geometry is just a std::vector so you can use whatever STL methods are available to manipulate it. Is that what you're asking?
Glenn Waldron / Pelican Mapping
David David
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

Yes, that's what I was looking for.  It turns out my stupid intellisense just wasn't showing the methods from the MixinVector subclass so I didn't see that they existed, but if I just call them then it works as expected.
iyigitel iyigitel
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

In reply to this post by gwaldron
Hi, I have a couple of questions related  this subject, and would be happy if you could answer them
1- Is there a practical limit on the number of AnnotationLayers that can be added to a map?
2- How to programatically add AnnotationNodes to an AnnotationLayer?
Iskender Yigitel
gwaldron gwaldron
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

Iskender,

1) Nothing specific to AnnotationLayer, no.

2) AnnotationLayer->getGroup()->addChild() should work.
Glenn Waldron / Pelican Mapping
iyigitel iyigitel
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

Thank you very much for the reply.
Iskender Yigitel
iyigitel iyigitel
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

In reply to this post by gwaldron
Glen,

I checked the methods of AnnotationLayer but I could not see a public method called GetGroup. I am using the 2.9 version by the way. Is it added in the new 2.10 version?

Since I could not find that method, I used the following code instead

osg::ref_ptr<Annotation::AnnotationLayer> annoLayer = new Annotation::AnnotationLayer();
_mapNode->getMap()->addLayer(annoLayer.get());
osg::ref_ptr<osg::Node>  layerNode = annoLayer->getOrCreateNode();
osg::ref_ptr<osg::Group> layerGroupNode = layerNode->asGroup();

if (layerGroupNode != nullptr)
{
        std::cout << "this is a group node";
        layerGroupNode->addChild(circle);
        layerGroupNode->addChild(new Annotation::CircleNodeEditor(circle));
}
else
{
        std::cout << "this is not a group node.";
}
I saw my circleNode as expected.
Is this OK?
Iskender Yigitel
gwaldron gwaldron
Reply | Threaded
Open this post in threaded view
|

Re: Best way to dynamically add new features

Or just call getOrCreateNode() and cast it to a group.
Glenn Waldron / Pelican Mapping