protected virtual uint queueTasks(Profile profile, TaskManager task_man)
        {
            uint level = 0;
            foreach (MapLayerLevelOfDetail i in map_layer.getLevels())
            {
                MapLayerLevelOfDetail level_def = i;

                string s = level.ToString();

                FilterEnv cell_env = getSession().createFilterEnv();
                cell_env.setExtent(map_layer.getAreaOfInterest()); //GeoExtent.infinite() );
                cell_env.setTerrainNode(getTerrainNode());
                cell_env.setTerrainSRS(getTerrainSRS());
                foreach (Property prop in level_def.getEnvProperties())
                    cell_env.setProperty(prop);

                Task task = new CellCompiler(s,
                                            s,
                                            level_def.getFeatureLayer(),
                                            level_def.getFilterGraph(),
                                            level_def.getMinRange(),
                                            level_def.getMaxRange(),
                                            cell_env,
                                            null, null, null);

                task_man.queueTask(task);
            }
            return level;
        }
 protected virtual void buildIndex(Profile profile, osg.Group scene_graph)
 {
     //scene_graph = new osg.Group();
     if (lod.valid())
     {
         scene_graph.addChild(lod.get());
     }
 }
 public CompileSessionImpl(TaskManager _task_man,
     Profile _profile,
     uint _total_tasks,
     osg.Timer_t _start_time)
 {
     task_man = _task_man;
     profile = _profile;
     total_tasks = _total_tasks; start_time = _start_time;
     //NOP
 }
 //virtual void collectCells( Profile* ) =0;
 protected abstract uint queueTasks(Profile profile, TaskManager tm);
 protected abstract void buildIndex(Profile profile, osg.Group group);
 /**
  * Creates a cursor that you can use to iterate over all the cells comprising
  * the map layer under the specified profile.
  *
  * @return
  *      A cell cursor. Caller is responsible for deleting the return object.
  */
 public virtual CellCursor createCellCursor(Profile profile);
 public virtual CellCursor createCellCursor(Profile profile)
 {
     //TODO
     return null;
 }
 public virtual CellCursor createCellCursor(Profile _profile)
 {
     QuadTreeProfile profile = (QuadTreeProfile)_profile;
     //TODO
     return null;
 }
        //virtual void collectCellKeys( Profile* profile );
        protected virtual uint queueTasks(Profile _profile, TaskManager task_man)
        {
            QuadTreeProfile profile = (QuadTreeProfile)_profile;
            if (profile != null)
            {
                // Now, build the index and collect the list of keys for which to compile data.
                QuadKeyList keys;
                collectGeometryKeys(profile.getQuadMap(), keys);

                // make a build task for each quad cell we collected:
                //int total_tasks = keys.size();
                foreach (QuadKey i in keys)
                {
                    Cell cell = new Cell(i.toString(), i.getExtent());
                    if (!cell_selector.valid() || cell_selector.selectCell(cell.get())) //i.toString() ) )
                    {
                        task_man.queueTask(createQuadKeyTask(*i));
                    }
                }

                return keys.size();
            }
            else
            {
                return 0;
            }
        }
        protected virtual void buildIndex(Profile _profile, osg.Group scene_graph)
        {
            QuadTreeProfile profile = (QuadTreeProfile)_profile;
            if (profile == null) return;

            //osgGIS.notice() << "Rebuilding index..." << std.endl;

            // first, determine the SRS of the output scene graph so that we can
            // make pagedlod/lod centroids.
            SpatialReference output_srs = map_layer.getOutputSRS(getSession(), getTerrainSRS());

            // first build the very top level.
            //scene_graph = new osg.Group();

            // the starting LOD is the best fit the the cell size:
            uint top_lod = getTopLod(profile.getQuadMap(), map_layer);

            SmartReadCallback reader = new SmartReadCallback();

            foreach (MapLayerLevelOfDetail i in map_layer.getLevels())
            {
                MapLayerLevelOfDetail level_def = i;
                uint lod = top_lod + level_def.getDepth();

                MapLayerLevelOfDetail sub_level_def = i + 1 != map_layer.getLevels().end() ? (i + 1).get() : null;
                float min_range, max_range;
                if (sub_level_def != null)
                {
                    min_range = sub_level_def.getMinRange();
                    max_range = sub_level_def.getMaxRange();
                }

                // get the extent of tiles that we will build based on the AOI:
                uint cell_xmin, cell_ymin, cell_xmax, cell_ymax;
                profile.getQuadMap().getCells(
                    map_layer.getAreaOfInterest(), lod,
                    cell_xmin, cell_ymin, cell_xmax, cell_ymax);

                for (uint y = cell_ymin; y <= cell_ymax; y++)
                {
                    for (uint x = cell_xmin; x <= cell_xmax; x++)
                    {
                        osg.Node node;

                        QuadKey key = new QuadKey(x, y, lod, profile.getQuadMap());

                        //osgGIS.notify( osg.NOTICE )
                        //    << "Cell: " << std.endl
                        //    << "   Quadkey = " << key.toString() << std.endl
                        //    << "   LOD = " << key.getLOD() << std.endl
                        //    << "   Extent = " << key.getExtent().toString() << " (w=" << key.getExtent().getWidth() << ", h=" << key.getExtent().getHeight() << ")" << std.endl
                        //    << std.endl;

                        node = sub_level_def ?
                            createIntermediateIndexNode(key, min_range, max_range, reader.get()) :
                            createLeafIndexNode(key, reader);

                        if (node.valid())
                        {
                            string out_file = createAbsPathFromTemplate("i" + key.toString());

                            if (!osgDB.writeNodeFile(*(node.get()), out_file))
                            {
                                // osgGIS.warn() << "FAILED to write index file " << out_file << std.endl;
                            }

                            // at the top level, assemble the root node
                            if (i == map_layer.getLevels().begin())
                            {
                                double top_min_range = sub_level_def != null ? 0 : level_def.getMinRange();

                                osg.PagedLOD plod = new osg.PagedLOD();
                                plod.setName(key.toString());
                                plod.setFileName(0, createRelPathFromTemplate("i" + key.toString()));
                                plod.setRange(0, top_min_range, level_def.getMaxRange());
                                plod.setPriorityScale(0, MY_PRIORITY_SCALE);
                                setCenterAndRadius(plod, key.getExtent(), reader.get());

                                //osgGIS.notice() << "QK=" << key.toString() << ", Ex=" << key.getExtent().toString() << ", Cen=" << key.getExtent().getCentroid().toString() << std.endl;

                                scene_graph.addChild(plod);
                            }
                        }
                    }
                }
            }
        }