Ejemplo n.º 1
0
	/**
	 * Stats the given file. If <tt>throttleRate</tt> seconds have passed since
	 * the last time stat() was called on this file, then the file will be
	 * re-stat()ted, otherwise the cached stat information will be returned.
	 *
	 * @param filename The file to stat.
	 * @param stat A pointer to a stat struct; the retrieved stat information
	 *             will be stored here.
	 * @param throttleRate Tells this CachedFileStat that the file may only
	 *        be statted at most every <tt>throttleRate</tt> seconds.
	 * @return 0 if the stat() call succeeded or if the cached stat information was used;
	 *         -1 if something went wrong while statting the file. In the latter
	 *         case, <tt>errno</tt> will be populated with an appropriate error code.
	 * @throws SystemException Something went wrong while retrieving the
	 *         system time. stat() errors will <em>not</em> result in
	 *         SystemException being thrown.
	 * @throws boost::thread_interrupted
	 */
	int stat(const string &filename, struct stat *buf, unsigned int throttleRate = 0) {
		boost::unique_lock<boost::mutex> l(lock);
		EntryMap::iterator it(cache.find(filename));
		EntryPtr entry;
		int ret;
		
		if (it == cache.end()) {
			// Filename not in cache.
			// If cache is full, remove the least recently used
			// cache entry.
			if (maxSize != 0 && cache.size() == maxSize) {
				EntryList::iterator listEnd(entries.end());
				listEnd--;
				string filename((*listEnd)->filename);
				entries.pop_back();
				cache.erase(filename);
			}
			
			// Add to cache as most recently used.
			entry = EntryPtr(new Entry(filename));
			entries.push_front(entry);
			cache[filename] = entries.begin();
		} else {
			// Cache hit.
			entry = *it->second;
			
			// Mark this cache item as most recently used.
			entries.erase(it->second);
			entries.push_front(entry);
			cache[filename] = entries.begin();
		}
		ret = entry->refresh(throttleRate);
		*buf = entry->info;
		return ret;
	}
    /**
     * Creates a complete set of positioned label nodes from a feature list.
     */
    osg::Node* createNode(
        const FeatureList&   input,
        const Style&         style,
        const FilterContext& context )
    {
        const TextSymbol* text = style.get<TextSymbol>();
        if ( !text )
            return 0L;

        osg::Group* group = new osg::Group();
        Decluttering::setEnabled( group->getOrCreateStateSet(), true );
        if ( text->priority().isSet() )
        {
            DeclutteringOptions dco = Decluttering::getOptions();
            dco.sortByPriority() = text->priority().isSet();
            Decluttering::setOptions( dco );
        }    
        
        StringExpression  contentExpr ( *text->content() );
        NumericExpression priorityExpr( *text->priority() );

        if ( text->removeDuplicateLabels() == true )
        {
            // in remove-duplicates mode, make a list of unique features, selecting
            // the one with the largest area as the one we'll use for labeling.

            typedef std::pair<double, osg::ref_ptr<const Feature> > Entry;
            typedef std::map<std::string, Entry>                    EntryMap;

            EntryMap used;
    
            for( FeatureList::const_iterator i = input.begin(); i != input.end(); ++i )
            {
                Feature* feature = i->get();
                if ( feature && feature->getGeometry() )
                {
                    const std::string& value = feature->eval( contentExpr );
                    if ( !value.empty() )
                    {
                        double area = feature->getGeometry()->getBounds().area2d();
                        if ( used.find(value) == used.end() )
                        {
                            used[value] = Entry(area, feature);
                        }
                        else 
                        {
                            Entry& biggest = used[value];
                            if ( area > biggest.first )
                            {
                                biggest.first = area;
                                biggest.second = feature;
                            }
                        }
                    }
                }
            }

            for( EntryMap::iterator i = used.begin(); i != used.end(); ++i )
            {
                const std::string& value = i->first;
                const Feature* feature = i->second.second.get();
                group->addChild( makeLabelNode(context, feature, value, text, priorityExpr) );
            }
        }

        else
        {
            for( FeatureList::const_iterator i = input.begin(); i != input.end(); ++i )
            {
                const Feature* feature = i->get();
                if ( !feature )
                    continue;

                const Geometry* geom = feature->getGeometry();
                if ( !geom )
                    continue;

                const std::string& value = feature->eval( contentExpr, &context );
                if ( value.empty() )
                    continue;

                group->addChild( makeLabelNode(context, feature, value, text, priorityExpr) );
            }
        }

#if 0 // good idea but needs work.
        DepthOffsetGroup* dog = new DepthOffsetGroup();
        dog->setMinimumOffset( 500.0 );
        dog->addChild( group );
        return dog;
#endif
        return group;
    }
Ejemplo n.º 3
0
	/**
	 * Returns whether <tt>filename</tt> is in the cache.
	 */
	bool knows(const string &filename) const {
		boost::unique_lock<boost::mutex> l(lock);
		return cache.find(filename) != cache.end();
	}