Created
November 12, 2020 20:09
-
-
Save gwaldron/08726aab39801d314e1b2eb041b7088c to your computer and use it in GitHub Desktop.
Example of memory-backed FeatureSource
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <osgEarth/EarthManipulator> | |
#include <osgEarth/ExampleResources> | |
#include <osgEarth/FeatureSource> | |
#include <osgEarth/TMS> | |
#include <osgEarth/FeatureImageLayer> | |
#include <osgEarth/TerrainEngineNode> | |
#include <osgEarth/ViewFitter> | |
#include <osgViewer/Viewer> | |
using namespace osgEarth; | |
using namespace osgEarth::Util; | |
//! Custom feature source that stores features in memory. | |
//! Note: this FS will not serialize | |
struct MemoryFeatureSource : public FeatureSource | |
{ | |
public: // FeatureSource API | |
//! Open the feature source | |
Status openImplementation() override | |
{ | |
setFeatureProfile(new FeatureProfile(GeoExtent( | |
SpatialReference::get("wgs84"), | |
-180.0, -90.0, 180.0, 90.0))); | |
return Status::OK(); | |
} | |
//! Create a cursor for iterating over the features | |
FeatureCursor* createFeatureCursorImplementation( | |
const Query& query, | |
ProgressCallback* progress) override | |
{ | |
ScopedMutexLock lock(_mutex); | |
return new FeatureListCursor(_features); | |
} | |
//! Insert a new feature into the store | |
bool insertFeature(Feature* feature) override | |
{ | |
ScopedMutexLock lock(_mutex); | |
feature->setFID(_fidgen++); | |
_features.push_back(feature); | |
return true; | |
} | |
bool deleteFeature(FeatureID fid) override | |
{ | |
ScopedMutexLock lock(_mutex); | |
return false; // not implemented | |
} | |
//! Can we insert new features into this store? yes | |
bool isWritable() const override | |
{ | |
return true; | |
} | |
private: | |
Mutex _mutex; | |
FeatureList _features; | |
std::atomic_int _fidgen; | |
}; | |
struct App | |
{ | |
MapNode* _mapNode; | |
FeatureSource* _features; | |
EarthManipulator* _manip; | |
Random _prng; | |
}; | |
//! Event handler that adds a new feature when you press 'P' | |
struct AddFeature : public osgGA::GUIEventHandler | |
{ | |
AddFeature(App& app) : _app(app) { } | |
bool handle( | |
const osgGA::GUIEventAdapter& ea, | |
osgGA::GUIActionAdapter& aa, | |
osg::Object*, | |
osg::NodeVisitor* nv) | |
{ | |
if (ea.getEventType() == ea.KEYDOWN && ea.getKey() == ea.KEY_P) | |
{ | |
// construct a new randomized line string: | |
Polygon* line = new Polygon(); | |
line->push_back(osg::Vec3d( | |
-180.0 + 360.0*_app._prng.next(), | |
-45.0 + 90.0*_app._prng.next(), | |
0.0)); | |
line->push_back(osg::Vec3d( | |
line->back().x() + (-10.0 + 20.0*_app._prng.next()), | |
line->back().y() + (-10.0 + 20.0*_app._prng.next()), | |
0.0)); | |
line->push_back(osg::Vec3d( | |
line->back().x() + (-10.0 + 20.0*_app._prng.next()), | |
line->back().y() + (-10.0 + 20.0*_app._prng.next()), | |
0.0)); | |
Feature* feature = new Feature( | |
line, | |
SpatialReference::get("wgs84")); | |
// add it to our local feature source: | |
_app._features->insertFeature(feature); | |
// tell the terrain to update itself: | |
std::vector<const Layer*> layers; | |
layers.push_back(_app._mapNode->getMap()->getLayer<FeatureImageLayer>()); | |
_app._mapNode->getTerrainEngine()->invalidateRegion( | |
layers, | |
feature->getExtent()); | |
// Zoom to look at our new feature | |
Viewpoint vp; | |
feature->getExtent().getCentroid(vp.focalPoint().mutable_value()); | |
_app._manip->setViewpoint(vp, 1.0); | |
return true; | |
} | |
return false; | |
} | |
App _app; | |
}; | |
int | |
main(int argc, char** argv) | |
{ | |
osgEarth::initialize(); | |
osg::ArgumentParser arguments(&argc,argv); | |
App app; | |
app._manip = new EarthManipulator(arguments); | |
app._manip->getSettings()->setArcViewpointTransitions(false); | |
osgViewer::Viewer viewer(arguments); | |
viewer.setCameraManipulator(app._manip); | |
Map* map = new Map(); | |
TMSImageLayer* image = new TMSImageLayer(); | |
image->setURL("http://readymap.org/readymap/tiles/1.0.0/7/"); | |
map->addLayer(image); | |
// our feature store - no need to add it to the map | |
app._features = new MemoryFeatureSource(); | |
// style to use for drawing the features | |
StyleSheet* styles = new StyleSheet(); | |
styles->addStylesFromCSS(R"( | |
default { | |
fill: #afafaf7f; | |
stroke: #ff9f2f; | |
stroke-width: 2px; | |
stroke-tessellation-size: 100km; | |
} | |
)"); | |
FeatureImageLayer* fil = new FeatureImageLayer(); | |
fil->setFeatureSource(app._features); | |
fil->setStyleSheet(styles); | |
map->addLayer(fil); | |
app._mapNode = new MapNode(map); | |
viewer.setSceneData(app._mapNode); | |
viewer.addEventHandler(new AddFeature(app)); | |
OE_NOTICE << "Press 'P' to add a line!" << std::endl; | |
return viewer.run(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment