/** * Tests whether this PreparedPolygon intersects a given geometry. * * @param geom the test geometry * @return true if the test geometry intersects */ public boolean intersects(Geometry geom) { /** * Do point-in-poly tests first, since they are cheaper and may result in a quick positive * result. * * <p>If a point of any test components lie in target, result is true */ boolean isInPrepGeomArea = isAnyTestComponentInTarget(geom); if (isInPrepGeomArea) return true; /** If any segments intersect, result is true */ List lineSegStr = SegmentStringUtil.extractSegmentStrings(geom); // only request intersection finder if there are segments (ie NOT for point inputs) if (lineSegStr.size() > 0) { boolean segsIntersect = prepPoly.getIntersectionFinder().intersects(lineSegStr); 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 boolean isPrepGeomInArea = isAnyTargetComponentInAreaTest(geom, prepPoly.getRepresentativePoints()); if (isPrepGeomInArea) return true; } return false; }
/** * Tests whether this geometry intersects a given geometry. * * @param geom the test geometry * @return true if the test geometry intersects */ public boolean intersects(Geometry geom) { /** If any segments intersect, obviously intersects = true */ List lineSegStr = SegmentStringUtil.extractSegmentStrings(geom); boolean segsIntersect = prepLine.getIntersectionFinder().intersects(lineSegStr); // MD - performance testing // boolean segsIntersect = false; if (segsIntersect) return true; /** For L/L case we are done */ if (geom.getDimension() == 1) return false; /** For L/A case, need to check for proper inclusion of the target in the test */ if (geom.getDimension() == 2 && prepLine.isAnyTargetComponentInTest(geom)) return true; /** For L/P case, need to check if any points lie on line(s) */ if (geom.getDimension() == 0) return isAnyTestPointInTarget(geom); // return prepLine.getGeometry().intersects(geom); return false; }
/** * Evaluate the <tt>contains</tt> or <tt>covers</tt> relationship for the given geometry. * * @param geom the test geometry * @return true if the test geometry is contained */ protected boolean eval(Geometry geom) { /** * Do point-in-poly tests first, since they are cheaper and may result in a quick negative * result. * * <p>If a point of any test components does not lie in target, result is false */ boolean 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) { boolean 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: * * <ul> * <li>If the test geometry is polygonal * <li>If the target geometry is a single polygon with no holes * <ul> * 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. */ boolean properIntersectionImpliesNotContained = isProperIntersectionImpliesNotContainedSituation(geom); // MD - testing only // properIntersectionImpliesNotContained = true; // 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. * * <p>(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); // System.out.println(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 instanceof Polygonal) { // TODO: generalize this to handle GeometryCollections boolean isTargetInTestArea = isAnyTargetComponentInAreaTest(geom, prepPoly.getRepresentativePoints()); if (isTargetInTestArea) return false; } return true; }