gwaldron / osgearth

3D Maps for OpenSceneGraph / C++14
https://www.pelicanmapping.com/home-1/opensource
Other
1.48k stars 774 forks source link

RTTPicker cann't pick feature #2606

Closed zyxgis closed 1 month ago

zyxgis commented 1 month ago

i use vcpkg toolchain to compile osgearth

this is my osgearth's version infos:

osgearth_versiond.exe --caps [osgearth info] Hello, world. [osgearth info] [Capabilities] osgEarth Version: 3.6.0 build 158 [osgearth info] [Capabilities] GDAL Version: 3.9.0 [osgearth info] [Capabilities] OSG Version: 3.6.5 [osgearth info] [Capabilities] OSG GL3 Features: yes [osgearth info] [Capabilities] OSG FFP Available: no [osgearth info] [Capabilities] CPU Cores: 12 [osgearth info] [Capabilities] GL_VENDOR: Intel [osgearth info] [Capabilities] GL_RENDERER: Intel(R) UHD Graphics 630 [osgearth info] [Capabilities] GL_VERSION: 3.3.0 - Build 31.0.101.2127 [osgearth info] [Capabilities] GL CORE Profile: yes [osgearth info] Goodbye.

my code is from "osgearth_featurequery.cpp", the code is:


using namespace osgEarth::Util;
using namespace osgEarth::Util::Controls;

//-----------------------------------------------------------------------

/**
 * Creates a simple user interface for the demo.
 */
Container *createUI()
{
  VBox *vbox = new VBox();
  vbox->setVertAlign(Control::ALIGN_TOP);
  vbox->setHorizAlign(Control::ALIGN_RIGHT);
  vbox->addControl(new LabelControl("Feature Query Demo", Color::Yellow));
  vbox->addControl(new LabelControl("Click on a feature to see its attributes."));
  return vbox;
}

//-----------------------------------------------------------------------

/**
 * Query Callback that displays the targeted feature's attributes in a
 * user interface grid control.
 */

class ReadoutCallback : public RTTPicker::Callback
{
public:
  ReadoutCallback(ControlCanvas *container) : _lastFID(~0)
  {
    _grid = new Grid();
    _grid->setBackColor(osg::Vec4(0, 0, 0, 0.7f));
    container->addControl(_grid);
  }

  void onHit(ObjectID id)
  {
    FeatureIndex *index = Registry::objectIndex()->get<FeatureIndex>(id).get();
    Feature *feature = index ? index->getFeature(id) : 0L;
    if (feature && feature->getFID() != _lastFID)
    {
      _grid->clearControls();
      unsigned r = 0;

      _grid->setControl(0, r, new LabelControl("FID", Color::Red));
      _grid->setControl(1, r, new LabelControl(Stringify() << feature->getFID(), Color::White));
      ++r;

      const AttributeTable &attrs = feature->getAttrs();
      for (AttributeTable::const_iterator i = attrs.begin(); i != attrs.end(); ++i, ++r)
      {
        _grid->setControl(0, r, new LabelControl(i->first, 14.0f, Color::Yellow));
        _grid->setControl(1, r, new LabelControl(i->second.getString(), 14.0f, Color::White));
      }
      if (!_grid->visible())
        _grid->setVisible(true);

      _lastFID = feature->getFID();
    }
  }

  void onMiss()
  {
    _grid->setVisible(false);
    _lastFID = 0u;
  }

  bool accept(const osgGA::GUIEventAdapter &ea, const osgGA::GUIActionAdapter &aa)
  {
    return ea.getEventType() == ea.MOVE; // RELEASE
  }

  Grid *_grid;
  FeatureID _lastFID;
};

//------------------------------------------------------------------------

int main(int argc, char **argv)
{
  osg::ArgumentParser arguments(&argc, argv);

  // a basic OSG viewer
  osgViewer::Viewer viewer(arguments);

  // install our default manipulator (do this before using MapNodeHelper)
  viewer.setCameraManipulator(new EarthManipulator());

  // load an earth file, and support all or our example command-line options
  // and earth file <external> tags
  osg::Group *root = MapNodeHelper().load(arguments, &viewer)->asGroup();
  if (root)
  {
    viewer.setSceneData(root);
    root->addChild(createUI());
    MapNode *mapNode = MapNode::findMapNode(root);
    if (mapNode)
    {
      osgEarth::OGRFeatureSource *featureSource = new osgEarth::OGRFeatureSource();
      featureSource->setName("vector-1");
      featureSource->setURL("E:/osgearth/data/world.shp"); //
      // this->getMapNode()->getMap()->addLayer(featureSource);
      //
      osgEarth::Style style;
      style.getOrCreateSymbol<osgEarth::LineSymbol>()->stroke().mutable_value().color() = osgEarth::Color::Yellow;
      style.getOrCreateSymbol<osgEarth::LineSymbol>()->stroke().mutable_value().width() = 2.0f;
      style.getOrCreateSymbol<osgEarth::LineSymbol>()->tessellationSize() = osgEarth::Distance(100, osgEarth::Units::KILOMETERS);
      style.getOrCreate<osgEarth::AltitudeSymbol>()->clamping() = osgEarth::AltitudeSymbol::CLAMP_TO_TERRAIN;
      style.getOrCreate<osgEarth::AltitudeSymbol>()->technique() = osgEarth::AltitudeSymbol::TECHNIQUE_GPU;
      style.getOrCreate<osgEarth::RenderSymbol>()->depthOffset().mutable_value().enabled() = true;
      //
      osgEarth::FeatureModelLayer *featureModelLayer = new osgEarth::FeatureModelLayer();
      featureModelLayer->setFeatureSource(featureSource);
      osgEarth::StyleSheet *styleSheet = new osgEarth::StyleSheet();
      styleSheet->addStyle(style);
      featureModelLayer->setStyleSheet(styleSheet);
      featureModelLayer->setName("vector-1");
      mapNode->getMap()->addLayer(featureModelLayer);

      // Install the query tool.
      RTTPicker *picker = new RTTPicker();
      viewer.addEventHandler(picker);
      picker->addChild(mapNode);

      // Install a readout for feature metadata.
      ControlCanvas *canvas = ControlCanvas::getOrCreate(&viewer);
      picker->setDefaultCallback(new ReadoutCallback(canvas));
    }

    return viewer.run();
  }
  else
  {
    OE_NOTICE
        << "\nUsage: " << argv[0] << " file.earth" << std::endl
        << MapNodeHelper().usage() << std::endl;
  }
}
gwaldron commented 1 month ago

The RTTPicker is deprecated in favor of the newer ObjectIDPicker. There's an example of how to use it in the Picker imgui panel here: https://github.com/gwaldron/osgearth/blob/master/src/osgEarthImGui/PickerGUI

You will also need to enable feature indexing on your layer for picking to work. You can call

featureModelLayer->options().featureIndexing()->enabled() = true;

before opening the layer or adding it to the Map. Good luck!

zyxgis commented 1 month ago

@gwaldron thank you for your reply

i try to run osgearth_imguid,

osgearth_imguid.exe D:\data\osm.earth

and use Picker tool , but it cann't pick feature

pick

the content of my earth file is :

<map name="Worldwide OSM feature data">
  <options>

  </options>
  <XYZImage name="OSM Imagery">
    <url>https://[abc].tile.geofabrik.de/549e80f319af070f8ea8d0f149a149c2/{z}/{x}/{y}.png</url> 
    <profile>spherical-mercator</profile>
    <cache_policy usage="read_write"/>
    <attribution>&#169;OpenStreetMap contributors</attribution>
  </XYZImage>

    <OGRFeatures name="world-data">
        <url>E:/data/world.shp</url>
    </OGRFeatures>

    <!--
    <FeatureImage name="Countries" opacity="0.75">
        <features>world-data</features>
        <styles>        
            <style type="text/css">
                default {
                    fill:          #ff7700;
                    stroke:        #ffff00;
                    stroke-width:  5km;
                }
            </style>
        </styles>
    </FeatureImage>  
    -->

    <FeatureModel name="Country boundaries" features="world-data" feature_indexing="true">

        <!--<layout tile_size="500000" crop_features="true" paged="true">
            <level max_range="1e10"/>
        </layout>-->

        <styles>
            <style type="text/css">
                world {
                   fill:          #ff7700;
                   stroke:                   #ffff00;
                   stroke-width:             3px;
                   stroke-tessellation-size: 1km;
                   render-lighting:          false;
                   altitude-clamping:        terrain-drape;        
                }            
            </style>
        </styles>

    </FeatureModel>

  <!--
  <TMSElevation name="ReadyMap 90m Elevation">
    <url>http://readymap.org/readymap/tiles/1.0.0/116/</url>
  </TMSElevation>
  -->
</map>
gwaldron commented 1 month ago

Replace feature_indexing="true" with pickable="true".

This is shorthand for

<feature_indexing enabled="true"/>

Good luck.

zyxgis commented 1 month ago

@gwaldron thank you very much. it is ok.