MuliGeometry with different Styles on VisibleLayer

classic Classic list List threaded Threaded
10 messages Options
speterson speterson
Reply | Threaded
Open this post in threaded view
|

MuliGeometry with different Styles on VisibleLayer

Hello,
I am attempting to create multiple geometry on a single layer where each geometry has a different fill style/line style associated.  I have found numerous articles somewhat relating to this but none have lead to a solution or final result.  They all faded off with just stating create a FeatureSource or use VisibleLayer etc.  None have shown how to use them.  I am not an experienced osg/osgEarth developer so hinting towards things as such leads me down non ending other searches and development paths that get me no closer to what I need as a final result.

Is there any examples anyone can point me to that would achieve such a task.  I seem to be not able to figure this out.

What I have figured out is subclassing VisibleLayer, I am able to create mutligeometry get them placed on a modellayer, created a osgEarth::Thread to dynamically update the data and get it to refresh every so often by getting the ModelSource from the ModelLayer then getting the FeatureModelSource from the ModelSource and finally getting the FeatureSource from the FeatureModelSource and calling dirty().  

I am able to apply a fill style and line style but this effects every geometry the same on the layer, I don't know how to get a different style for each geometry. I am mainly using the polygonsymbol/linesymbol for styles and drawing polygons.  I created multiple styles but it only ever uses the last style I create and changes every polygons style information.

That's as far as I have working I struggle to get past this point.

Any help would be great.

Thanks

Shannon
gwaldron gwaldron
Reply | Threaded
Open this post in threaded view
|

Re: MuliGeometry with different Styles on VisibleLayer

Shannon,

If you want a separate style for each Feature, you can probably just use FeatureNode. FeatureNode will allow you to compile one or more Features against a single style. Then you can put all your FeatureNodes under a single AnnotationLayer and be done with it.

You can reference the osgearth_annotation.cpp example for guidance.

Good luck!
Glenn Waldron / Pelican Mapping
speterson speterson
Reply | Threaded
Open this post in threaded view
|

Re: MuliGeometry with different Styles on VisibleLayer

In reply to this post by speterson
Sorry probably will help if I give my verison information.

OSG 3.6.3
OSGEarth 2.10
speterson speterson
Reply | Threaded
Open this post in threaded view
|

Re: MuliGeometry with different Styles on VisibleLayer

This post was updated on .
In reply to this post by gwaldron
Hello again,
Sorry for being such a noob with osgEarth but how do I get features onto a layer and then onto a map?

osgEarth::Annotation::FeatureNode* afn = new osgEarth::Annotation::FeatureNode(f, shapeStyle);
osgEarth::Annotation::FeatureNode* afn2 = new osgEarth::Annotation::FeatureNode(f2, shapeStyle2);

so have these featurenodes with my feature f and f2 with style shapeStyle2 and .

I use to do the following with my ModelLayer but have no idea how to use Annotation Layers been searching for hour or so now and can't find any examples that help with this.  In every example it uses the map->addChild() and I seem to not have that access level because I am working at the VisibleLayer.  also not I will need to update the features ever so often did this with 2nd code piece below.

/* set _wa_geom to initial polygon shape */
_wa_featureOptions.geometry() = &_wa_geom;
_wa_geomOptions.featureOptions() = _wa_featureOptions;
_wa_geomOptions.styles() = new osgEarth::StyleSheet();
_wa_geomOptions.styles()->addStyle(_wa_shapeStyle);
_wa_geomOptions.enableLighting() = false;
osgEarth::ModelLayerOptions wa_layerOptions("polygon", _wa_geomOptions);
osgEarth::ModelLayer* wa_modellayer = new osgEarth::ModelLayer("wind_animations", wa_layerOptions);
// Enable Shaders
_wa_modellayer_ss = wa_modellayer->getOrCreateStateSet();
osgEarth::VirtualProgram* vp = osgEarth::VirtualProgram::getOrCreate(_wa_modellayer_ss);
vp->setName("windanimations");
myshaders shaders;
shaders.load(vp, shaders.myimagecc_Vertex);
shaders.load(vp, shaders.myimagecc_Fragment);

// Add Layer to Map
_map->addLayer(wa_modellayer);

and then use this code to do my updates every so often:

/*change _wa_geom to new polygon shape*/
_wa_featureOptions.geometry() = &_wa_geom;
_wa_geomOptions.featureOptions() = _wa_featureOptions;
wa_layer = _map->getLayerByName("wind_animations");
wa_modellayer = dynamic_cast<osgEarth::ModelLayer*>(wa_layer);
wa_featuremodelsource = (osgEarth::Features::FeatureModelSource*)wa_modellayer->getModelSource();
wa_featuremodelsource->getFeatureSource()->dirty();

Thanks

Shannon

10/2/2019 - fixed typeo in initial post
gwaldron gwaldron
Reply | Threaded
Open this post in threaded view
|

Re: MuliGeometry with different Styles on VisibleLayer

// make a new annotation layer:
AnnotationLayer* layer = new AnnotationLayer();
map->addLayer(layer);

// add your feature nodes:
layer->getGroup()->addChild(afn);
layer->getGroup()->addChild(afn2);

...

// update a feature node:
afn->dirty();
Glenn Waldron / Pelican Mapping
speterson speterson
Reply | Threaded
Open this post in threaded view
|

Re: MuliGeometry with different Styles on VisibleLayer

Thanks Waldron that was very helpful I would have been lurking around forums for a long time before I'd have found

layer->getGroup()->addChild(afn);
layer->getGroup()->addChild(afn2);

Not seen that used.

Do you know if there is any architecture diagram for this application.  My main disconnect it seems is understanding how everything connects together and how the data flows.  I get so lost trying to figure out what does what and seem to get myself going in circles when digging through the code following how things process.

Once again thanks, I am now again working forward instead of sitting stumped.
--
Shannon
speterson speterson
Reply | Threaded
Open this post in threaded view
|

Re: MuliGeometry with different Styles on VisibleLayer

In reply to this post by gwaldron
Something else now that pops up,  am I suppose to be using some type of mutex scope locking in the function where I am updating the nodes?  I will be removing and adding new annotation feature nodes but when I do this I do get random crash errors from the engine where the vector index on some traverse goes out of range.  

It is almost as if the render engine and my code are out of sync while I am manipulating the nodes.  I have seen different mutex locks used in different code examples but how do I know which one to use for what I am working on?

thanks

Shannon

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

Re: MuliGeometry with different Styles on VisibleLayer

As with all things OSG, it is only legal to change the scene graph from the main thread or from the UPDATE traversal.
Glenn Waldron / Pelican Mapping
speterson speterson
Reply | Threaded
Open this post in threaded view
|

Re: MuliGeometry with different Styles on VisibleLayer

This post was updated on .
Ok so I been trying to figure this out below is description of what I was attempting to do but it seems to be wrong still.  Please let me know if I am way off on how to get this achieved.

In my VisibleLayer derived class I register as a REGISTER_OSGEARTH_LAYER I placed this class inside my class:

public:
      struct UpdateCallback : public osg::StateAttributeCallback
      {
        virtual void operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv);
      };

EDIT
I also tried the following callback with the appropriate changes to my functions below

public:
      struct NodeCallback : public osg::Callback
      {
        virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
      };


I then just for giggles to see if I could get something to trigger have my operator function just set an int with a breakpoint attached.

void myexample::UpdateCallback::operator () (osg::StateAttribute* attr, osg::NodeVisitor* nv)
{
  int i = 0;
}


Tried the following but neither would trigger a callback when I either tried to update an existing node or tried to add a new node

featurenode->setUpdateCallback(new myexample::UpdateCallback());

featurelayer->getGroup()->setUpdateCallback(new myexample::UpdateCallback());

I fail to understand how to setup these callbacks to the Update traversal.  I do not have access to the main thread code to add an update there, I am working in some extension code I am registering dynamically.
speterson speterson
Reply | Threaded
Open this post in threaded view
|

Re: MuliGeometry with different Styles on VisibleLayer

Ok think I am getting a little farther.

using something like this

featurelayer->setCullCallback(new myexample::MyCallback(featurelayer));

and

public:
      struct MyCallback : public Layer::TraversalCallback
      {
        osgEarth::Annotation::AnnotationLayer* _layer;
        MyCallback(osgEarth::Annotation::AnnotationLayer* layer);
        void operator()(osg::Node*, osg::NodeVisitor*) const;
      };

and

myexample::MyCallback::MyCallback(osgEarth::Annotation::AnnotationLayer* layer) : _layer(layer)
{
}

void myexample::MyCallback::operator()(osg::Node* node, osg::NodeVisitor* nv) const {
  if (nv->getVisitorType() == nv->CULL_VISITOR)
  {
    osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(nv);
   
    // If we have zones, select the current one and apply its state set.
    if (_layer != nullptr && _layer->getGroup()->getNumChildren() > 0)
    {
       // will do work here
    }
  }
  else
  {
    traverse(node, nv);
  }
}

I am able to get a callback to happen once in awhile now.  I am planning place my layer update work in the "will do work here" section such as _layer->getGroup()->addChild(featurenode); or featurenode->dirty(); and other type actions.

Hopefully this is a more correct way to update the Map compared to how I was doing it before which would cause random crashes.

If this doesn't look right please chime in to help me not spend tons of hours doing things wrong please.

Thanks