/** * 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; }
private void addLine(Coordinate[] pts) { SegmentString segStr = new BasicSegmentString(pts, null); List segChains = MonotoneChainBuilder.getChains(segStr.getCoordinates(), segStr); for (Iterator i = segChains.iterator(); i.hasNext(); ) { MonotoneChain mc = (MonotoneChain) i.next(); index.insert(mc.getEnvelope(), mc); } }
private void init(Geometry geom) { List lines = LinearComponentExtracter.getLines(geom); for (Iterator i = lines.iterator(); i.hasNext(); ) { LineString line = (LineString) i.next(); Coordinate[] pts = line.getCoordinates(); addLine(pts); } }
/** * Tests whether any component of the test Geometry intersects the interior of the target * geometry. Handles test geometries with both linear and point components. * * @param geom a geometry to test * @return true if any component of the argument intersects the prepared area geometry interior */ protected boolean isAnyTestComponentInTargetInterior(Geometry testGeom) { List coords = ComponentCoordinateExtracter.getCoordinates(testGeom); for (Iterator i = coords.iterator(); i.hasNext(); ) { Coordinate p = (Coordinate) i.next(); int loc = targetPointLocator.locate(p); if (loc == Location.INTERIOR) return true; } return false; }
/** * Tests whether any representative point of the test Geometry intersects the target geometry. * Only handles test geometries which are Puntal (dimension 0) * * @param geom a Puntal geometry to test * @return true if any point of the argument intersects the prepared geometry */ protected boolean isAnyTestPointInTarget(Geometry testGeom) { /** * This could be optimized by using the segment index on the lineal target. However, it seems * like the L/P case would be pretty rare in practice. */ PointLocator locator = new PointLocator(); List coords = ComponentCoordinateExtracter.getCoordinates(testGeom); for (Iterator i = coords.iterator(); i.hasNext(); ) { Coordinate p = (Coordinate) i.next(); if (locator.intersects(p, prepLine.getGeometry())) return true; } return false; }
/** * Tests whether any component of the target geometry intersects the test geometry (which must be * an areal geometry) * * @param geom the test geometry * @param repPts the representative points of the target geometry * @return true if any component intersects the areal test geometry */ protected boolean isAnyTargetComponentInAreaTest(Geometry testGeom, List targetRepPts) { PointOnGeometryLocator piaLoc = new SimplePointInAreaLocator(testGeom); for (Iterator i = targetRepPts.iterator(); i.hasNext(); ) { Coordinate p = (Coordinate) i.next(); int loc = piaLoc.locate(p); if (loc != Location.EXTERIOR) return true; } return false; }
private void countSegs( RayCrossingCounter rcc, Envelope rayEnv, List monoChains, MCSegmentCounter mcSegCounter) { for (Iterator i = monoChains.iterator(); i.hasNext(); ) { MonotoneChain mc = (MonotoneChain) i.next(); mc.select(rayEnv, mcSegCounter); // short-circuit if possible if (rcc.isOnSegment()) return; } }