public CellCompiler( string _cell_id, string _abs_output_uri, FeatureLayer layer, FilterGraph graph, float _min_range, float _max_range, FilterEnv env, ResourcePackager _packager, osgDB.Archive _archive, // =NULL, object user_data) : // =NULL ); base(_abs_output_uri, layer, graph, env) { packager = _packager; cell_id = _cell_id; abs_output_uri = _abs_output_uri; min_range = _min_range; max_range = _max_range; archive = _archive; //TODO: maybe the FilterEnv should just have one of these by default. SmartReadCallback smart = new SmartReadCallback(); smart.setMinRange(min_range); env.setTerrainReadCallback(smart); setUserData(_user_data); output_status = CellCompiler.OutputStatus.OUTPUT_UNKNOWN; }
protected osg.Node createLeafIndexNode(QuadKey key, SmartReadCallback cb) { osg.Group group = null; for (uint i = 0; i < 4; i++) { QuadKey quadrant_key = key.createSubKey(i); if (osgDB.fileExists(createAbsPathFromTemplate("g" + quadrant_key.toString()))) { if (!group) { group = new osg.Group(); group.setName(key.toString()); } #if USE_PAGEDLODS_IN_INDEX osg.PagedLOD *pointer = new osg.PagedLOD(); pointer.setFileName(0, createRelPathFromTemplate("g" + quadrant_key.toString())); pointer.setRange(0, 0, 1e10); pointer.setPriorityScale(0, 1000.0f); // top priority! pointer.setPriorityOffset(0, 1000.0f); setCenterAndRadius(pointer, quadrant_key.getExtent(), reader); #else osg.ProxyNode pointer = new osg.ProxyNode(); pointer.setLoadingExternalReferenceMode(osg.ProxyNode.LOAD_IMMEDIATELY); pointer.setFileName(0, createRelPathFromTemplate("g" + quadrant_key.toString())); //setCenterAndRadius( pointer, quadrant_key.getExtent(), reader ); #endif group.addChild(pointer); } } return(group); }
protected void setCenterAndRadius(osg.Node node, GeoExtent cell_extent, SmartReadCallback reader) { SpatialReference srs = map_layer.getOutputSRS(getSession(), getTerrainSRS()); // first get the output srs centroid: GeoPoint centroid = srs.transform(cell_extent.getCentroid()); GeoPoint sw = srs.transform(cell_extent.getSouthwest()); double radius = map_layer.getEncodeCellRadius() ? (centroid - sw).length() : -1.0; if (terrain_node.valid() && terrain_srs != null) { GeoPoint clamped; for (int t = 0; t < 5; t++) { clamped = GeomUtils.clampToTerrain(centroid, terrain_node.get(), terrain_srs, reader); if (!clamped.isValid()) { // if the clamp failed, it's due to the geocentric intersection bug in which the isect // fails when coplanar with a tile boundary/skirt. Fudge the centroid and try again. double fudge = 0.001 * ((double)(1 + (Random.Rand() % 10))); centroid.X += fudge; centroid.Y -= fudge; centroid.Z += fudge * fudge; } else { break; } } if (!clamped.isValid()) { SpatialReference geo = srs.getGeographicSRS(); GeoPoint latlon = geo.transform(centroid); //osgGIS.warn() << "*** UNABLE TO CLAMP CENTROID: ***" << latlon.toString() << std.endl; } else { centroid = clamped; } } else { //osgGIS.warn() << "*** Failed to clamp Center/Radius for cell" << std.endl; } if (node is osg.LOD) { osg.LOD plod = (osg.LOD)node; plod.setCenter(centroid); plod.setRadius(radius); } else if (node is osg.ProxyNode) { osg.ProxyNode proxy = (osg.ProxyNode)node; proxy.setCenter(centroid); proxy.setRadius(radius); } }
protected osg.Node createIntermediateIndexNode(QuadKey key, float min_range, float max_range, SmartReadCallback cb) { osg.Group group = null; for (uint quadrant = 0; quadrant < 4; quadrant++) { QuadKey subkey = key.createSubKey(quadrant); if (osgDB.fileExists(createAbsPathFromTemplate("g" + subkey.toString()))) { if (!group) { group = new osg.Group(); group.setName(key.toString()); } //osgGIS.notice() << "QK=" << subkey.toString() << ", Extent=" << subkey.getExtent().toString() << std.endl; // enter the subtile set as a paged index node reference: osg.PagedLOD plod = new osg.PagedLOD(); setCenterAndRadius(plod, subkey.getExtent(), reader); #if USE_PAGEDLODS_IN_INDEX osg.PagedLOD *pointer = new osg.PagedLOD(); pointer.setFileName(0, createRelPathFromTemplate("g" + subkey.toString())); pointer.setRange(0, 0, 1e10); pointer.setPriorityScale(0, 1000.0f); // top priority, hopefully pointer.setPriorityOffset(0, 1000.0f); pointer.setCenter(plod.getCenter()); pointer.setRadius(plod.getRadius()); #else osg.ProxyNode pointer = new osg.ProxyNode(); pointer.setLoadingExternalReferenceMode(osg.ProxyNode.LOAD_IMMEDIATELY); pointer.setFileName(0, createRelPathFromTemplate("g" + subkey.toString())); //setCenterAndRadius( pointer, subkey.getExtent(), reader ); #endif plod.addChild(pointer, max_range, 1e10); plod.setFileName(1, createRelPathFromTemplate("i" + subkey.toString())); plod.setRange(1, 0, max_range); // last one should always be min=0 plod.setPriorityScale(1, MY_PRIORITY_SCALE); group.addChild(plod); //osg.Geode* geode = new osg.Geode(); //osg.Sphere* g1 = new osg.Sphere( osg.Vec3(0,0,0), plod.getRadius() ); //osg.ShapeDrawable* sd1 = new osg.ShapeDrawable( g1 ); //sd1.setColor( osg.Vec4f(1,0,0,.2) ); //geode.addDrawable( sd1 ); ////osg.Vec3d p = terrain_srs.transform( subkey.getExtent().getCentroid() ); ////osg.Vec3d n = p; n.normalize(); ////osg.Geometry* g3 = new osg.Geometry(); ////osg.Vec3Array* v3 = new osg.Vec3Array(2); ////(*v3)[0] = osg.Vec3d(0,0,0); ////(*v3)[1] = n * 3000.0; ////g3.setVertexArray( v3 ); ////osg.Vec4Array* c3 = new osg.Vec4Array(1); ////(*c3)[0].set(1,1,0,1); ////g3.setColorArray( c3 ); ////g3.setColorBinding(osg.Geometry.BIND_OVERALL); ////g3.addPrimitiveSet( new osg.DrawArrays(GL_LINES, 0, 2) ); ////g3.getOrCreateStateSet().setMode( GL_LIGHTING, osg.StateAttribute.OFF ); ////geode.addDrawable( g3 ); ////osg.Sphere* g2 = new osg.Sphere( osg.Vec3(0,0,0), 25 ); ////osg.ShapeDrawable* sd2 = new osg.ShapeDrawable( g2 ); ////sd2.setColor( osg.Vec4f(1,1,0,1) ); ////geode.addDrawable( sd2 ); ////osg.Matrixd mx = osg.Matrixd.translate( p ); //osg.Matrixd mx = osg.Matrixd.translate( plod.getCenter() ); //osg.MatrixTransform* mt = new osg.MatrixTransform( mx ); //mt.addChild( geode ); //mt.getOrCreateStateSet().setMode( GL_BLEND, osg.StateAttribute.ON ); //mt.getOrCreateStateSet().setRenderingHint( osg.StateSet.TRANSPARENT_BIN ); //group.addChild( mt ); } } return(group); }
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); } } } } } }
protected osg.Node createLeafIndexNode(QuadKey key, SmartReadCallback cb) { osg.Group group = null; for (uint i = 0; i < 4; i++) { QuadKey quadrant_key = key.createSubKey(i); if (osgDB.fileExists(createAbsPathFromTemplate("g" + quadrant_key.toString()))) { if (!group) { group = new osg.Group(); group.setName(key.toString()); } #if USE_PAGEDLODS_IN_INDEX osg.PagedLOD* pointer = new osg.PagedLOD(); pointer.setFileName( 0, createRelPathFromTemplate( "g" + quadrant_key.toString() ) ); pointer.setRange( 0, 0, 1e10 ); pointer.setPriorityScale( 0, 1000.0f ); // top priority! pointer.setPriorityOffset( 0, 1000.0f ); setCenterAndRadius( pointer, quadrant_key.getExtent(), reader ); #else osg.ProxyNode pointer = new osg.ProxyNode(); pointer.setLoadingExternalReferenceMode(osg.ProxyNode.LOAD_IMMEDIATELY); pointer.setFileName(0, createRelPathFromTemplate("g" + quadrant_key.toString())); //setCenterAndRadius( pointer, quadrant_key.getExtent(), reader ); #endif group.addChild(pointer); } } return group; }
protected osg.Node createIntermediateIndexNode(QuadKey key, float min_range, float max_range, SmartReadCallback cb) { osg.Group group = null; for (uint quadrant = 0; quadrant < 4; quadrant++) { QuadKey subkey = key.createSubKey(quadrant); if (osgDB.fileExists(createAbsPathFromTemplate("g" + subkey.toString()))) { if (!group) { group = new osg.Group(); group.setName(key.toString()); } //osgGIS.notice() << "QK=" << subkey.toString() << ", Extent=" << subkey.getExtent().toString() << std.endl; // enter the subtile set as a paged index node reference: osg.PagedLOD plod = new osg.PagedLOD(); setCenterAndRadius(plod, subkey.getExtent(), reader); #if USE_PAGEDLODS_IN_INDEX osg.PagedLOD* pointer = new osg.PagedLOD(); pointer.setFileName( 0, createRelPathFromTemplate( "g" + subkey.toString() ) ); pointer.setRange( 0, 0, 1e10 ); pointer.setPriorityScale( 0, 1000.0f ); // top priority, hopefully pointer.setPriorityOffset( 0, 1000.0f ); pointer.setCenter( plod.getCenter() ); pointer.setRadius( plod.getRadius() ); #else osg.ProxyNode pointer = new osg.ProxyNode(); pointer.setLoadingExternalReferenceMode(osg.ProxyNode.LOAD_IMMEDIATELY); pointer.setFileName(0, createRelPathFromTemplate("g" + subkey.toString())); //setCenterAndRadius( pointer, subkey.getExtent(), reader ); #endif plod.addChild(pointer, max_range, 1e10); plod.setFileName(1, createRelPathFromTemplate("i" + subkey.toString())); plod.setRange(1, 0, max_range); // last one should always be min=0 plod.setPriorityScale(1, MY_PRIORITY_SCALE); group.addChild(plod); //osg.Geode* geode = new osg.Geode(); //osg.Sphere* g1 = new osg.Sphere( osg.Vec3(0,0,0), plod.getRadius() ); //osg.ShapeDrawable* sd1 = new osg.ShapeDrawable( g1 ); //sd1.setColor( osg.Vec4f(1,0,0,.2) ); //geode.addDrawable( sd1 ); ////osg.Vec3d p = terrain_srs.transform( subkey.getExtent().getCentroid() ); ////osg.Vec3d n = p; n.normalize(); ////osg.Geometry* g3 = new osg.Geometry(); ////osg.Vec3Array* v3 = new osg.Vec3Array(2); ////(*v3)[0] = osg.Vec3d(0,0,0); ////(*v3)[1] = n * 3000.0; ////g3.setVertexArray( v3 ); ////osg.Vec4Array* c3 = new osg.Vec4Array(1); ////(*c3)[0].set(1,1,0,1); ////g3.setColorArray( c3 ); ////g3.setColorBinding(osg.Geometry.BIND_OVERALL); ////g3.addPrimitiveSet( new osg.DrawArrays(GL_LINES, 0, 2) ); ////g3.getOrCreateStateSet().setMode( GL_LIGHTING, osg.StateAttribute.OFF ); ////geode.addDrawable( g3 ); ////osg.Sphere* g2 = new osg.Sphere( osg.Vec3(0,0,0), 25 ); ////osg.ShapeDrawable* sd2 = new osg.ShapeDrawable( g2 ); ////sd2.setColor( osg.Vec4f(1,1,0,1) ); ////geode.addDrawable( sd2 ); ////osg.Matrixd mx = osg.Matrixd.translate( p ); //osg.Matrixd mx = osg.Matrixd.translate( plod.getCenter() ); //osg.MatrixTransform* mt = new osg.MatrixTransform( mx ); //mt.addChild( geode ); //mt.getOrCreateStateSet().setMode( GL_BLEND, osg.StateAttribute.ON ); //mt.getOrCreateStateSet().setRenderingHint( osg.StateSet.TRANSPARENT_BIN ); //group.addChild( mt ); } } return group; }
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); } } } } } }
protected void setCenterAndRadius(osg.Node node, GeoExtent cell_extent, SmartReadCallback reader) { SpatialReference srs = map_layer.getOutputSRS(getSession(), getTerrainSRS()); // first get the output srs centroid: GeoPoint centroid = srs.transform(cell_extent.getCentroid()); GeoPoint sw = srs.transform(cell_extent.getSouthwest()); double radius = map_layer.getEncodeCellRadius() ? (centroid - sw).length() : -1.0; if (terrain_node.valid() && terrain_srs != null) { GeoPoint clamped; for (int t = 0; t < 5; t++) { clamped = GeomUtils.clampToTerrain(centroid, terrain_node.get(), terrain_srs, reader); if (!clamped.isValid()) { // if the clamp failed, it's due to the geocentric intersection bug in which the isect // fails when coplanar with a tile boundary/skirt. Fudge the centroid and try again. double fudge = 0.001 * ((double)(1 + (Random.Rand() % 10))); centroid.X += fudge; centroid.Y -= fudge; centroid.Z += fudge * fudge; } else { break; } } if (!clamped.isValid()) { SpatialReference geo = srs.getGeographicSRS(); GeoPoint latlon = geo.transform(centroid); //osgGIS.warn() << "*** UNABLE TO CLAMP CENTROID: ***" << latlon.toString() << std.endl; } else { centroid = clamped; } } else { //osgGIS.warn() << "*** Failed to clamp Center/Radius for cell" << std.endl; } if (node is osg.LOD) { osg.LOD plod = (osg.LOD)node; plod.setCenter(centroid); plod.setRadius(radius); } else if (node is osg.ProxyNode) { osg.ProxyNode proxy = (osg.ProxyNode)node; proxy.setCenter(centroid); proxy.setRadius(radius); } }