bool remove(const Bounds& area, const Bounds& b) { if (m_leaf) return area.contains(m_data.item); int cdel = 0; for (int i = 0; i < 4; ++i) { Node** c = m_data.children + i; if (!*c) continue; Bounds cb = b.quadrant(i); if (area.intersects(cb) && (*c)->remove(area, cb)) { delete *c; * c = 0; ++cdel; } } return cdel == 4; // true if all sub-nodes were removed }
void iterate(QuadTree::Iteration& iter, const Bounds& area, const Bounds& b) const { if (m_leaf && b.contains(m_data.item)) iter.process(m_data.item); else for (int i = 0; i < 4; ++i) { if (m_data.children[i]) { Bounds cb = b.quadrant(i); if (area.intersects(cb)) m_data.children[i]->iterate(iter, area, cb); } } }
ChunkReader::QueryRange ChunkReader::candidates(const Bounds& queryBounds) const { if (queryBounds.contains(m_bounds)) { return QueryRange(m_points.begin(), m_points.end()); } const auto& gb(m_metadata.boundsScaledCubic()); const PointInfo min(Tube::calcTick(queryBounds.min(), gb, m_depth)); const PointInfo max(Tube::calcTick(queryBounds.max(), gb, m_depth)); It begin(std::lower_bound(m_points.begin(), m_points.end(), min)); It end(std::upper_bound(m_points.begin(), m_points.end(), max)); return QueryRange(begin, end); }
Bounds Bounds::intersectionWith(const Bounds& rhs) const { if ( valid() && !rhs.valid() ) return *this; if ( !valid() && rhs.valid() ) return rhs; if ( this->contains(rhs) ) return rhs; if ( rhs.contains(*this) ) return *this; if ( !intersects(rhs) ) return Bounds(); double xmin, xmax, ymin, ymax; xmin = ( xMin() > rhs.xMin() && xMin() < rhs.xMax() ) ? xMin() : rhs.xMin(); xmax = ( xMax() > rhs.xMin() && xMax() < rhs.xMax() ) ? xMax() : rhs.xMax(); ymin = ( yMin() > rhs.yMin() && yMin() < rhs.yMax() ) ? yMin() : rhs.yMin(); ymax = ( yMax() > rhs.yMin() && yMax() < rhs.yMax() ) ? yMax() : rhs.yMax(); return Bounds(xmin, ymin, xmax, ymax); }
bool FeatureGridder::cullFeatureListToCell( int i, FeatureList& features ) const { bool success = true; int inCount = features.size(); Bounds b; if ( getCellBounds( i, b ) ) { if ( _policy.cullingTechnique() == GriddingPolicy::CULL_BY_CENTROID ) { for( FeatureList::iterator f_i = features.begin(); f_i != features.end(); ) { bool keepFeature = false; Feature* feature = f_i->get(); Symbology::Geometry* featureGeom = feature->getGeometry(); if ( featureGeom ) { osg::Vec3d centroid = featureGeom->getBounds().center(); if ( b.contains( centroid.x(), centroid.y() ) ) { keepFeature = true; } } if ( keepFeature ) ++f_i; else f_i = features.erase( f_i ); } } else // CULL_BY_CROPPING (requires GEOS) { #ifdef OSGEARTH_HAVE_GEOS // create the intersection polygon: osg::ref_ptr<Symbology::Polygon> poly = new Symbology::Polygon( 4 ); poly->push_back( osg::Vec3d( b.xMin(), b.yMin(), 0 )); poly->push_back( osg::Vec3d( b.xMax(), b.yMin(), 0 )); poly->push_back( osg::Vec3d( b.xMax(), b.yMax(), 0 )); poly->push_back( osg::Vec3d( b.xMin(), b.yMax(), 0 )); for( FeatureList::iterator f_i = features.begin(); f_i != features.end(); ) { bool keepFeature = false; Feature* feature = f_i->get(); Symbology::Geometry* featureGeom = feature->getGeometry(); if ( featureGeom ) { osg::ref_ptr<Symbology::Geometry> croppedGeometry; if ( featureGeom->crop( poly.get(), croppedGeometry ) ) { feature->setGeometry( croppedGeometry.get() ); keepFeature = true; } } if ( keepFeature ) ++f_i; else f_i = features.erase( f_i ); } #endif // OSGEARTH_HAVE_GEOS } } OE_INFO << LC << "Grid cell " << i << ": bounds=" << b.xMin() << "," << b.yMin() << " => " << b.xMax() << "," << b.yMax() << "; in=" << inCount << "; out=" << features.size() << std::endl; return success; }