bool TileSource::hasData(const osgEarth::TileKey& key) const { //sematics: might have data. //If no data extents are provided, just return true if (_dataExtents.size() == 0) return true; const osgEarth::GeoExtent& keyExtent = key.getExtent(); bool intersectsData = false; for (DataExtentList::const_iterator itr = _dataExtents.begin(); itr != _dataExtents.end(); ++itr) { if ((keyExtent.intersects( *itr )) && (!itr->minLevel().isSet() || itr->minLevel() <= key.getLOD()) && (!itr->maxLevel().isSet() || itr->maxLevel() >= key.getLOD())) { intersectsData = true; break; } } return intersectsData; }
void PolyhedralLineOfSightNode::terrainChanged(const osgEarth::TileKey& tileKey, osg::Node* patch) { if ( tileKey.getExtent().intersects(_extent) ) { updateSamples(); } }
bool TileSource::hasData(const osgEarth::TileKey& key) const { //sematics: "might have data" if ( !key.valid() ) return false; // If no data extents are provided, and there's no data level override, // return true because there might be data but there's no way to tell. if (_dataExtents.size() == 0 && !_options.maxDataLevel().isSet()) { return true; } unsigned int lod = key.getLevelOfDetail(); // Remap the lod to an appropriate lod if it's not in the same SRS if (!key.getProfile()->isHorizEquivalentTo( getProfile() ) ) { lod = getProfile()->getEquivalentLOD( key.getProfile(), key.getLevelOfDetail() ); } // If there's an explicit LOD override and we've exceeded it, no data. if (_options.maxDataLevel().isSet() && lod > _options.maxDataLevel().value()) { return false; } // If there are no extents to check, there might be data. if (_dataExtents.size() == 0) { return true; } bool intersectsData = false; const osgEarth::GeoExtent& keyExtent = key.getExtent(); for (DataExtentList::const_iterator itr = _dataExtents.begin(); itr != _dataExtents.end(); ++itr) { if ((keyExtent.intersects( *itr )) && (!itr->minLevel().isSet() || itr->minLevel() <= lod ) && (!itr->maxLevel().isSet() || itr->maxLevel() >= lod )) { intersectsData = true; break; } } return intersectsData; }
void TerrainProfileCalculator::onTileAdded(const osgEarth::TileKey& tileKey, osg::Node* graph, TerrainCallbackContext&) { if (_start.isValid() && _end.isValid()) { GeoExtent extent( _start.getSRS()); extent.expandToInclude(_start.x(), _start.y()); extent.expandToInclude(_end.x(), _end.y()); if (tileKey.getExtent().intersects( extent )) { recompute(); } } }
virtual void onTileAdded(const osgEarth::TileKey& tileKey, osg::Node* terrain, TerrainCallbackContext&) { if ((int)tileKey.getLevelOfDetail() > _minLevel && _maxLevel < (int)tileKey.getLevelOfDetail()) { osg::Vec3d position = _locator->getLocator()->getPosition(); if (tileKey.getExtent().contains(position.x(), position.y())) { //Compute our location in geocentric const osg::EllipsoidModel* ellipsoid = tileKey.getProfile()->getSRS()->getEllipsoid(); double x, y, z; ellipsoid->convertLatLongHeightToXYZ( osg::DegreesToRadians(position.y()), osg::DegreesToRadians(position.x()), 0, x, y, z); //Compute the up vector osg::Vec3d up = ellipsoid->computeLocalUpVector(x, y, z ); up.normalize(); osg::Vec3d world(x, y, z); double segOffset = 50000; osg::Vec3d start = world + (up * segOffset); osg::Vec3d end = world - (up * segOffset); osgUtil::LineSegmentIntersector* i = new osgUtil::LineSegmentIntersector( start, end ); osgUtil::IntersectionVisitor iv; iv.setIntersector( i ); terrain->accept( iv ); osgUtil::LineSegmentIntersector::Intersections& results = i->getIntersections(); if ( !results.empty() ) { const osgUtil::LineSegmentIntersector::Intersection& result = *results.begin(); osg::Vec3d hit = result.getWorldIntersectPoint(); double lat, lon, height; ellipsoid->convertXYZToLatLongHeight(hit.x(), hit.y(), hit.z(), lat, lon, height); position.z() = height; //OE_NOTICE << "Got hit, setting new height to " << height << std::endl; _maxLevel = tileKey.getLevelOfDetail(); _locator->getLocator()->setPosition( position ); } } } }
bool TileSource::hasData(const osgEarth::TileKey& key) const { //If no data extents are provided, just return true if (_dataExtents.size() == 0) return true; const osgEarth::GeoExtent& keyExtent = key.getExtent(); bool intersectsData = false; for (DataExtentList::const_iterator itr = _dataExtents.begin(); itr != _dataExtents.end(); ++itr) { if (keyExtent.intersects( *itr ) && key.getLevelOfDetail() >= itr->getMinLevel() && key.getLevelOfDetail() <= itr->getMaxLevel()) { intersectsData = true; break; } } return intersectsData; }
bool TileSource::getBestAvailableTileKey(const osgEarth::TileKey& key, osgEarth::TileKey& output) const { // trivial reject if ( !key.valid() ) return false; // trivial accept: no data extents = not enough info. if (_dataExtents.size() == 0) { output = key; return true; } // trivial reject: key doesn't intersect the union of data extents at all. if ( !getDataExtentsUnion().intersects(key.getExtent()) ) { return false; } bool intersects = false; unsigned highestLOD = 0; // We must use the equivalent lod b/c the key can be in any profile. int layerLOD = getProfile()->getEquivalentLOD( key.getProfile(), key.getLOD() ); for (DataExtentList::const_iterator itr = _dataExtents.begin(); itr != _dataExtents.end(); ++itr) { // check for 2D intersection: if (key.getExtent().intersects( *itr )) { // check that the extent isn't higher-resolution than our key: if ( !itr->minLevel().isSet() || layerLOD >= itr->minLevel().get() ) { // Got an intersetion; now test the LODs: intersects = true; // Is the high-LOD set? If not, there's not enough information // so just assume our key might be good. if ( itr->maxLevel().isSet() == false ) { output = key; return true; } // Is our key at a lower or equal LOD than the max key in this extent? // If so, our key is good. else if ( layerLOD <= itr->maxLevel().get() ) { output = key; return true; } // otherwise, record the highest encountered LOD that // intersects our key. else if ( itr->maxLevel().get() > highestLOD ) { highestLOD = itr->maxLevel().get(); } } } } if ( intersects ) { output = key.createAncestorKey( highestLOD ); return true; } else { return false; } }