// // public: // bool PreparedPolygonContainsProperly::containsProperly( const geom::Geometry * geom) { // Do point-in-poly tests first, since they are cheaper and may result // in a quick negative result. // If a point of any test components does not lie in target, // result is false bool isAllInPrepGeomArea = isAllTestComponentsInTargetInterior( geom); if ( !isAllInPrepGeomArea ) return false; // If any segments intersect, result is false noding::SegmentString::ConstVect lineSegStr; noding::SegmentStringUtil::extractSegmentStrings( geom, lineSegStr); bool segsIntersect = prepPoly->getIntersectionFinder()->intersects( &lineSegStr); for ( size_t i = 0, ni = lineSegStr.size(); i < ni; i++ ) { delete lineSegStr[ i ]; } if (segsIntersect) return false; /** * Given that no segments intersect, if any vertex of the target * is contained in some test component. * the test is NOT properly contained. */ if ( geom->getGeometryTypeId() == geos::geom::GEOS_MULTIPOLYGON || geom->getGeometryTypeId() == geos::geom::GEOS_POLYGON ) { // TODO: generalize this to handle GeometryCollections bool isTargetGeomInTestArea = isAnyTargetComponentInAreaTest( geom, prepPoly->getRepresentativePoints()); if (isTargetGeomInTestArea) return false; } return true; }
// // public: // bool PreparedPolygonIntersects::intersects( const geom::Geometry * geom) { // Do point-in-poly tests first, since they are cheaper and may result // in a quick positive result. // If a point of any test components lie in target, result is true bool isInPrepGeomArea = isAnyTestComponentInTarget( geom); if ( isInPrepGeomArea ) return true; // If any segments intersect, result is true noding::SegmentString::ConstVect lineSegStr; noding::SegmentStringUtil::extractSegmentStrings( geom, lineSegStr ); bool segsIntersect = prepPoly->getIntersectionFinder()->intersects( &lineSegStr); for ( size_t i = 0, ni = lineSegStr.size(); i < ni; i++ ) { delete lineSegStr[ i ]; } if (segsIntersect) return true; // If the test has dimension = 2 as well, it is necessary to // test for proper inclusion of the target. // Since no segments intersect, it is sufficient to test representative points. if ( geom->getDimension() == 2) { // TODO: generalize this to handle GeometryCollections bool isPrepGeomInArea = isAnyTargetComponentInAreaTest( geom, prepPoly->getRepresentativePoints()); if ( isPrepGeomInArea ) return true; } return false; }
// // protected: // bool AbstractPreparedPolygonContains::eval( const geom::Geometry * geom) { // Do point-in-poly tests first, since they are cheaper and may result // in a quick negative result. // // If a point of any test components does not lie in target, // result is false bool isAllInTargetArea = isAllTestComponentsInTarget( geom); if ( !isAllInTargetArea ) return false; // If the test geometry consists of only Points, // then it is now sufficient to test if any of those // points lie in the interior of the target geometry. // If so, the test is contained. // If not, all points are on the boundary of the area, // which implies not contained. if ( requireSomePointInInterior && geom->getDimension() == 0 ) { bool isAnyInTargetInterior = isAnyTestComponentInTargetInterior( geom); return isAnyInTargetInterior; } // Check if there is any intersection between the line segments // in target and test. // In some important cases, finding a proper interesection implies that the // test geometry is NOT contained. // These cases are: // - If the test geometry is polygonal // - If the target geometry is a single polygon with no holes // In both of these cases, a proper intersection implies that there // is some portion of the interior of the test geometry lying outside // the target, which means that the test is not contained. bool properIntersectionImpliesNotContained = isProperIntersectionImpliesNotContainedSituation( geom); // find all intersection types which exist findAndClassifyIntersections( geom); if ( properIntersectionImpliesNotContained && hasProperIntersection ) return false; // If all intersections are proper // (i.e. no non-proper intersections occur) // we can conclude that the test geometry is not contained in the target area, // by the Epsilon-Neighbourhood Exterior Intersection condition. // In real-world data this is likely to be by far the most common situation, // since natural data is unlikely to have many exact vertex segment intersections. // Thus this check is very worthwhile, since it avoid having to perform // a full topological check. // // (If non-proper (vertex) intersections ARE found, this may indicate // a situation where two shells touch at a single vertex, which admits // the case where a line could cross between the shells and still be wholely contained in them. if ( hasSegmentIntersection && !hasNonProperIntersection ) return false; // If there is a segment intersection and the situation is not one // of the ones above, the only choice is to compute the full topological // relationship. This is because contains/covers is very sensitive // to the situation along the boundary of the target. if ( hasSegmentIntersection ) return fullTopologicalPredicate( geom); // This tests for the case where a ring of the target lies inside // a test polygon - which implies the exterior of the Target // intersects the interior of the Test, and hence the result is false if ( geom->getGeometryTypeId() == geos::geom::GEOS_MULTIPOLYGON || geom->getGeometryTypeId() == geos::geom::GEOS_POLYGON ) { // TODO: generalize this to handle GeometryCollections bool isTargetInTestArea = isAnyTargetComponentInAreaTest( geom, prepPoly->getRepresentativePoints()); if ( isTargetInTestArea ) return false; } return true; }