private static int _isPointInPolygonInternalWithQuadTree(com.epl.geometry.Polygon inputPolygon, com.epl.geometry.QuadTreeImpl quadTree, com.epl.geometry.Point2D inputPoint, double tolerance) { com.epl.geometry.Envelope2D envPoly = new com.epl.geometry.Envelope2D(); inputPolygon.QueryLooseEnvelope(envPoly); envPoly.Inflate(tolerance, tolerance); bool bAltenate = inputPolygon.GetFillRule() == com.epl.geometry.Polygon.FillRule.enumFillRuleOddEven; com.epl.geometry.PointInPolygonHelper helper = new com.epl.geometry.PointInPolygonHelper(bAltenate, inputPoint, tolerance); com.epl.geometry.MultiPathImpl mpImpl = (com.epl.geometry.MultiPathImpl)inputPolygon._getImpl(); com.epl.geometry.SegmentIteratorImpl iter = mpImpl.QuerySegmentIterator(); com.epl.geometry.Envelope2D queryEnv = new com.epl.geometry.Envelope2D(); queryEnv.SetCoords(envPoly); queryEnv.xmax = inputPoint.x + tolerance; // no need to query segments to // the right of the point. // Only segments to the left // matter. queryEnv.ymin = inputPoint.y - tolerance; queryEnv.ymax = inputPoint.y + tolerance; com.epl.geometry.QuadTreeImpl.QuadTreeIteratorImpl qiter = quadTree.GetIterator(queryEnv, tolerance); for (int qhandle = qiter.Next(); qhandle != -1; qhandle = qiter.Next()) { iter.ResetToVertex(quadTree.GetElement(qhandle)); if (iter.HasNextSegment()) { com.epl.geometry.Segment segment = iter.NextSegment(); if (helper.ProcessSegment(segment)) { return(-1); } } } // point on boundary return(helper.Result()); }
public static int IsPointInAnyOuterRing(com.epl.geometry.Polygon inputPolygon, com.epl.geometry.Point2D inputPoint, double tolerance) { com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D(); inputPolygon.QueryLooseEnvelope(env); env.Inflate(tolerance, tolerance); if (!env.Contains(inputPoint)) { return(0); } // Note: // Wolfgang had noted that this could be optimized if the exterior rings // have positive area: // Only test the positive rings and bail out immediately when in a // positive ring. // The worst case complexity is still O(n), but on average for polygons // with holes, that would be faster. // However, that method would not work if polygon is reversed, while the // one here works fine same as PointInPolygon. bool bAltenate = false; // use winding in this test com.epl.geometry.PointInPolygonHelper helper = new com.epl.geometry.PointInPolygonHelper(bAltenate, inputPoint, tolerance); com.epl.geometry.MultiPathImpl mpImpl = (com.epl.geometry.MultiPathImpl)inputPolygon._getImpl(); com.epl.geometry.SegmentIteratorImpl iter = mpImpl.QuerySegmentIterator(); while (iter.NextPath()) { double ringArea = mpImpl.CalculateRingArea2D(iter.GetPathIndex()); bool bIsHole = ringArea < 0; if (!bIsHole) { helper.m_windnum = 0; while (iter.HasNextSegment()) { com.epl.geometry.Segment segment = iter.NextSegment(); if (helper.ProcessSegment(segment)) { return(-1); } } // point on boundary if (helper.m_windnum != 0) { return(1); } } } return(helper.Result()); }
public static int IsPointInPolygon(com.epl.geometry.Polygon inputPolygon, com.epl.geometry.Point2D inputPoint, double tolerance) { if (inputPolygon.IsEmpty()) { return(0); } com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D(); inputPolygon.QueryLooseEnvelope(env); env.Inflate(tolerance, tolerance); if (!env.Contains(inputPoint)) { return(0); } com.epl.geometry.MultiPathImpl mpImpl = (com.epl.geometry.MultiPathImpl)inputPolygon._getImpl(); com.epl.geometry.GeometryAccelerators accel = mpImpl._getAccelerators(); if (accel != null) { // geometry has spatial indices built. Try using them. com.epl.geometry.RasterizedGeometry2D rgeom = accel.GetRasterizedGeometry(); if (rgeom != null) { com.epl.geometry.RasterizedGeometry2D.HitType hit = rgeom.QueryPointInGeometry(inputPoint.x, inputPoint.y); if (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Inside) { return(1); } else { if (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Outside) { return(0); } } } com.epl.geometry.QuadTreeImpl qtree = accel.GetQuadTree(); if (qtree != null) { return(_isPointInPolygonInternalWithQuadTree(inputPolygon, qtree, inputPoint, tolerance)); } } return(_isPointInPolygonInternal(inputPolygon, inputPoint, tolerance)); }
internal static int IsPointInPolygon(com.epl.geometry.Polygon inputPolygon, double inputPointXVal, double inputPointYVal, double tolerance) { if (inputPolygon.IsEmpty()) { return(0); } com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D(); inputPolygon.QueryLooseEnvelope(env); env.Inflate(tolerance, tolerance); if (!env.Contains(inputPointXVal, inputPointYVal)) { return(0); } com.epl.geometry.MultiPathImpl mpImpl = (com.epl.geometry.MultiPathImpl)inputPolygon._getImpl(); com.epl.geometry.GeometryAccelerators accel = mpImpl._getAccelerators(); if (accel != null) { com.epl.geometry.RasterizedGeometry2D rgeom = accel.GetRasterizedGeometry(); if (rgeom != null) { com.epl.geometry.RasterizedGeometry2D.HitType hit = rgeom.QueryPointInGeometry(inputPointXVal, inputPointYVal); if (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Inside) { return(1); } else { if (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Outside) { return(0); } } } } return(_isPointInPolygonInternal(inputPolygon, new com.epl.geometry.Point2D(inputPointXVal, inputPointYVal), tolerance)); }