void BuildGeomFilter::applyFragmentName( Fragment* frag, Feature* feature, FilterEnv* env ) { if ( getFeatureNameScript() ) { ScriptResult r = env->getScriptEngine()->run( getFeatureNameScript(), feature, env ); if ( r.isValid() ) frag->setName( r.asString() ); else env->getReport()->error( r.asString() ); } }
const std::string& Feature::eval( StringExpression& expr, FilterContext const* context ) const { const StringExpression::Variables& vars = expr.variables(); for( StringExpression::Variables::const_iterator i = vars.begin(); i != vars.end(); ++i ) { std::string val = ""; AttributeTable::const_iterator ai = _attrs.find(toLower(i->first)); if (ai != _attrs.end()) { val = ai->second.getString(); } else if (context) { //No attr found, look for script ScriptEngine* engine = context->getSession()->getScriptEngine(); if (engine) { ScriptResult result = engine->run(i->first, this, context); if (result.success()) val = result.asString(); else OE_WARN << LC << "Feature Script error on '" << expr.expr() << "': " << result.message() << std::endl; } } expr.set( *i, val ); } return expr.eval(); }
FragmentList BuildGeomFilter::process( FeatureList& input, FilterEnv* env ) { // if features are arriving in batch, resolve the color here. // otherwise we will resolve it later in process(feature,env). is_batch = input.size() > 1; batch_feature_color = overall_color; if ( is_batch && getColorScript() ) { ScriptResult r = env->getScriptEngine()->run( getColorScript(), env ); if ( r.isValid() ) batch_feature_color = r.asVec4(); else env->getReport()->error( r.asString() ); } return FragmentFilter::process( input, env ); }
osg::Vec4 BuildGeomFilter::getColorForFeature( Feature* feature, FilterEnv* env ) { osg::Vec4 result = overall_color; if ( is_batch ) { result = batch_feature_color; } else if ( getColorScript() ) { ScriptResult r = env->getScriptEngine()->run( getColorScript(), feature, env ); if ( r.isValid() ) result = r.asVec4(); else env->getReport()->error( r.asString() ); } return result; }
void BuildGeomFilter::applyOverlayTexturing( osg::Geometry* geom, Feature* input, FilterEnv* env ) { GeoExtent tex_extent; if ( getRasterOverlayScript() ) { // if there's a raster script for this filter, we're applying textures per-feature: tex_extent = GeoExtent( input->getExtent().getSouthwest().getAbsolute(), input->getExtent().getNortheast().getAbsolute() ); } else { // otherwise prepare the geometry for an overlay texture covering the entire working extent: tex_extent = env->getExtent(); } float width = (float)tex_extent.getWidth(); float height = (float)tex_extent.getHeight(); // now visit the verts and calculate texture coordinates for each one. osg::Vec3Array* verts = dynamic_cast<osg::Vec3Array*>( geom->getVertexArray() ); if ( verts ) { // if we are dealing with geocentric data, we will need to xform back to a real // projection in order to determine texture coords: GeoExtent tex_extent_geo; if ( env->getInputSRS()->isGeocentric() ) { tex_extent_geo = GeoExtent( tex_extent.getSRS()->getGeographicSRS()->transform( tex_extent.getSouthwest() ), tex_extent.getSRS()->getGeographicSRS()->transform( tex_extent.getNortheast() ) ); } osg::Vec2Array* texcoords = new osg::Vec2Array( verts->size() ); for( unsigned int j=0; j<verts->size(); j++ ) { // xform back to raw SRS w.o. ref frame: GeoPoint vert( (*verts)[j], env->getInputSRS() ); GeoPoint vert_map = vert.getAbsolute(); float tu, tv; if ( env->getInputSRS()->isGeocentric() ) { tex_extent_geo.getSRS()->transformInPlace( vert_map ); tu = (vert_map.x() - tex_extent_geo.getXMin()) / width; tv = (vert_map.y() - tex_extent_geo.getYMin()) / height; } else { tu = (vert_map.x() - tex_extent.getXMin()) / width; tv = (vert_map.y() - tex_extent.getYMin()) / height; } (*texcoords)[j].set( tu, tv ); } geom->setTexCoordArray( 0, texcoords ); } // if we are applying the raster per-feature, do so now. // TODO: deprecate? will we ever use this versus the BuildNodesFilter overlay? maybe if ( getRasterOverlayScript() ) { ScriptResult r = env->getScriptEngine()->run( getRasterOverlayScript(), input, env ); if ( r.isValid() ) { RasterResource* raster = env->getSession()->getResources()->getRaster( r.asString() ); if ( raster ) { osg::Image* image = NULL; std::stringstream builder; builder << "rtex_" << input->getOID() << ".jpg"; //TODO: dds with DXT1 compression osg::ref_ptr<osg::StateSet> raster_ss = new osg::StateSet(); if ( raster->applyToStateSet( raster_ss.get(), tex_extent, getRasterOverlayMaxSize(), &image ) ) { image->setFileName( builder.str() ); geom->setStateSet( raster_ss.get() ); // add this as a skin resource so the compiler can properly localize and deploy it. env->getResourceCache()->addSkin( raster_ss.get() ); } } } else { env->getReport()->error( r.asString() ); } } }