void onHit(ObjectID id) { FeatureIndex* index = Registry::objectIndex()->get<FeatureIndex>( id ); 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 onHit(ObjectID id) { // First see whether it's a feature: FeatureIndex* index = Registry::objectIndex()->get<FeatureIndex>( id ); Feature* feature = index ? index->getFeature( id ) : 0L; if ( feature ) { s_fidLabel->setText( Stringify() << "Feature ID = " << feature->getFID() << " (oid = " << id << ")" ); s_nameLabel->setText( Stringify() << "Name = " << feature->getString("name") ); } else { // Check whether it's an annotation: AnnotationNode* anno = Registry::objectIndex()->get<AnnotationNode>( id ); if ( anno ) { s_fidLabel->setText( Stringify() << "ObjectID = " << id ); s_nameLabel->setName( Stringify() << "Name = " << anno->getName() ); } // None of the above.. clear. else { s_fidLabel->setText( Stringify() << "oid = " << id ); s_nameLabel->setText( "Name = " ); } } s_highlightUniform->set( id ); }
FilterContext BufferFilter::push( FeatureList& input, FilterContext& context ) { if ( !isSupported() ) { OE_WARN << "BufferFilter support not enabled - please compile osgEarth with GEOS" << std::endl; return context; } //OE_NOTICE << "Buffer: input = " << input.size() << " features" << std::endl; for( FeatureList::iterator i = input.begin(); i != input.end(); ) { Feature* feature = i->get(); if ( !feature || !feature->getGeometry() ) continue; osg::ref_ptr<Symbology::Geometry> output; Symbology::BufferParameters params; params._capStyle = _capStyle == Stroke::LINECAP_ROUND ? Symbology::BufferParameters::CAP_ROUND : _capStyle == Stroke::LINECAP_SQUARE ? Symbology::BufferParameters::CAP_SQUARE : _capStyle == Stroke::LINECAP_FLAT ? Symbology::BufferParameters::CAP_FLAT : Symbology::BufferParameters::CAP_SQUARE; params._cornerSegs = _numQuadSegs; if ( feature->getGeometry()->buffer( _distance.value(), output, params ) ) { feature->setGeometry( output.get() ); ++i; } else { i = input.erase( i ); OE_DEBUG << LC << "feature " << feature->getFID() << " yielded no geometry" << std::endl; } } return context; }
v8::Handle<v8::Value> JSFeature::PropertyCallback(v8::Local<v8::String> name, const v8::AccessorInfo& info) { Feature* feature = V8Util::UnwrapObject<Feature>(info.Holder()); v8::String::Utf8Value utf8_value(name); std::string prop(*utf8_value); if (!feature || prop.empty()) return v8::Handle<v8::Value>(); if (prop == "fid") return v8::Uint32::New(feature->getFID()); else if (prop == "attrs" || prop == "attributes") return V8Util::WrapObject(feature, GetAttributesObjectTemplate()); else if (prop == "geometry") return JSSymbologyGeometry::WrapGeometry(feature->getGeometry()); //return GetFeatureAttr(prop, feature); return v8::Handle<v8::Value>(); }
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) { if ( ea.getEventType() == ea.RELEASE ) { IntersectionPicker picker(dynamic_cast<osgViewer::View*>(aa.asView())); IntersectionPicker::Hits hits; if(picker.pick(ea.getX(), ea.getY(), hits)) { std::set<ObjectID> oids; if (picker.getObjectIDs(hits, oids)) { ObjectIndex* index = Registry::objectIndex(); ObjectID oid = *oids.begin(); osg::ref_ptr<FeatureIndex> fi = index->get<FeatureIndex>(oid); if ( fi.valid() ) { OE_NOTICE << "IsectPicker: found OID " << oid << "\n"; Feature* f = fi->getFeature(oid); if ( f ) { OE_NOTICE << "...feature ID = " << f->getFID() << "\n"; } } osg::ref_ptr<Feature> f = index->get<Feature>(oid); if ( f.valid() ) { OE_NOTICE << "IsectPicker: found OID " << oid << "\n"; OE_NOTICE << "...feature ID = " << f->getFID() << "\n"; } osg::ref_ptr<AnnotationNode> a = index->get<AnnotationNode>(oid); if ( a ) { OE_NOTICE << "IsectPicker: found annotation " << a->getName() << "\n"; } } else { OE_NOTICE << "IsectPicker: picked, but no OIDs\n"; } } else { OE_NOTICE << "IsectPicker: no intersect\n"; } } return false; }
bool ExtrudeGeometryFilter::process( FeatureList& features, FilterContext& context ) { // seed our random number generators Random wallSkinPRNG( _wallSkinSymbol.valid()? *_wallSkinSymbol->randomSeed() : 0, Random::METHOD_FAST ); Random roofSkinPRNG( _roofSkinSymbol.valid()? *_roofSkinSymbol->randomSeed() : 0, Random::METHOD_FAST ); for( FeatureList::iterator f = features.begin(); f != features.end(); ++f ) { Feature* input = f->get(); GeometryIterator iter( input->getGeometry(), false ); while( iter.hasMore() ) { Geometry* part = iter.next(); osg::ref_ptr<osg::Geometry> walls = new osg::Geometry(); walls->setUseVertexBufferObjects(USE_VBOS); osg::ref_ptr<osg::Geometry> rooflines = 0L; osg::ref_ptr<osg::Geometry> baselines = 0L; osg::ref_ptr<osg::Geometry> outlines = 0L; if ( part->getType() == Geometry::TYPE_POLYGON ) { rooflines = new osg::Geometry(); rooflines->setUseVertexBufferObjects(USE_VBOS); // prep the shapes by making sure all polys are open: static_cast<Polygon*>(part)->open(); } // fire up the outline geometry if we have a line symbol. if ( _outlineSymbol != 0L ) { outlines = new osg::Geometry(); outlines->setUseVertexBufferObjects(USE_VBOS); } // make a base cap if we're doing stencil volumes. if ( _makeStencilVolume ) { baselines = new osg::Geometry(); baselines->setUseVertexBufferObjects(USE_VBOS); } // calculate the extrusion height: float height; if ( _heightCallback.valid() ) { height = _heightCallback->operator()(input, context); } else if ( _heightExpr.isSet() ) { height = input->eval( _heightExpr.mutable_value(), &context ); } else { height = *_extrusionSymbol->height(); } // calculate the height offset from the base: float offset = 0.0; if ( _heightOffsetExpr.isSet() ) { offset = input->eval( _heightOffsetExpr.mutable_value(), &context ); } osg::StateSet* wallStateSet = 0L; osg::StateSet* roofStateSet = 0L; // calculate the wall texturing: SkinResource* wallSkin = 0L; if ( _wallSkinSymbol.valid() ) { if ( _wallResLib.valid() ) { SkinSymbol querySymbol( *_wallSkinSymbol.get() ); querySymbol.objectHeight() = fabs(height) - offset; wallSkin = _wallResLib->getSkin( &querySymbol, wallSkinPRNG, context.getDBOptions() ); } else { //TODO: simple single texture? } } // calculate the rooftop texture: SkinResource* roofSkin = 0L; if ( _roofSkinSymbol.valid() ) { if ( _roofResLib.valid() ) { SkinSymbol querySymbol( *_roofSkinSymbol.get() ); roofSkin = _roofResLib->getSkin( &querySymbol, roofSkinPRNG, context.getDBOptions() ); } else { //TODO: simple single texture? } } // calculate the colors: osg::Vec4f wallColor(1,1,1,1), roofColor(1,1,1,1), outlineColor(1,1,1,1); if ( _wallPolygonSymbol.valid() ) { wallColor = _wallPolygonSymbol->fill()->color(); } if ( _roofPolygonSymbol.valid() ) { roofColor = _roofPolygonSymbol->fill()->color(); } if ( _outlineSymbol.valid() ) { outlineColor = _outlineSymbol->stroke()->color(); } // Create the extruded geometry! if (extrudeGeometry( part, height, offset, *_extrusionSymbol->flatten(), walls.get(), rooflines.get(), baselines.get(), outlines.get(), wallColor, roofColor, outlineColor, wallSkin, roofSkin, context ) ) { if ( wallSkin ) { wallStateSet = context.resourceCache()->getStateSet( wallSkin ); } // generate per-vertex normals, altering the geometry as necessary to avoid // smoothing around sharp corners #if OSG_MIN_VERSION_REQUIRED(2,9,9) //Crease angle threshold wasn't added until osgUtil::SmoothingVisitor::smooth( *walls.get(), osg::DegreesToRadians(_wallAngleThresh_deg) ); #else osgUtil::SmoothingVisitor::smooth(*walls.get()); #endif // tessellate and add the roofs if necessary: if ( rooflines.valid() ) { osgUtil::Tessellator tess; tess.setTessellationType( osgUtil::Tessellator::TESS_TYPE_GEOMETRY ); tess.setWindingType( osgUtil::Tessellator::TESS_WINDING_ODD ); tess.retessellatePolygons( *(rooflines.get()) ); // generate default normals (no crease angle necessary; they are all pointing up) // TODO do this manually; probably faster if ( !_makeStencilVolume ) osgUtil::SmoothingVisitor::smooth( *rooflines.get() ); // texture the rooflines if necessary //applyOverlayTexturing( rooflines.get(), input, env ); // mark this geometry as DYNAMIC because otherwise the OSG optimizer will destroy it. // TODO: why?? rooflines->setDataVariance( osg::Object::DYNAMIC ); if ( roofSkin ) { roofStateSet = context.resourceCache()->getStateSet( roofSkin ); } } if ( baselines.valid() ) { osgUtil::Tessellator tess; tess.setTessellationType( osgUtil::Tessellator::TESS_TYPE_GEOMETRY ); tess.setWindingType( osgUtil::Tessellator::TESS_WINDING_ODD ); tess.retessellatePolygons( *(baselines.get()) ); } std::string name; if ( !_featureNameExpr.empty() ) name = input->eval( _featureNameExpr, &context ); FeatureSourceIndex* index = context.featureIndex(); FeatureID fid = input->getFID(); addDrawable( walls.get(), wallStateSet, name, fid, index ); if ( rooflines.valid() ) { addDrawable( rooflines.get(), roofStateSet, name, fid, index ); } if ( baselines.valid() ) { addDrawable( baselines.get(), 0L, name, fid, index ); } if ( outlines.valid() ) { addDrawable( outlines.get(), 0L, name, fid, index ); } } } } return true; }