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());
        }
        private static int _isPointInPolygonInternal(com.epl.geometry.Polygon inputPolygon, com.epl.geometry.Point2D inputPoint, double 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();
            while (iter.NextPath())
            {
                while (iter.HasNextSegment())
                {
                    com.epl.geometry.Segment segment = iter.NextSegment();
                    if (helper.ProcessSegment(segment))
                    {
                        return(-1);
                    }
                }
            }
            // point on boundary
            return(helper.Result());
        }
        public static int IsPointInRing(com.epl.geometry.MultiPathImpl inputPolygonImpl, int iRing, com.epl.geometry.Point2D inputPoint, double tolerance, com.epl.geometry.QuadTree quadTree)
        {
            com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
            inputPolygonImpl.QueryLooseEnvelope2D(env);
            env.Inflate(tolerance, tolerance);
            if (!env.Contains(inputPoint))
            {
                return(0);
            }
            bool bAltenate = true;

            com.epl.geometry.PointInPolygonHelper helper = new com.epl.geometry.PointInPolygonHelper(bAltenate, inputPoint, tolerance);
            if (quadTree != null)
            {
                com.epl.geometry.Envelope2D queryEnv = new com.epl.geometry.Envelope2D();
                queryEnv.SetCoords(env);
                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.SegmentIteratorImpl       iter  = inputPolygonImpl.QuerySegmentIterator();
                com.epl.geometry.QuadTree.QuadTreeIterator qiter = quadTree.GetIterator(queryEnv, tolerance);
                for (int qhandle = qiter.Next(); qhandle != -1; qhandle = qiter.Next())
                {
                    iter.ResetToVertex(quadTree.GetElement(qhandle), iRing);
                    if (iter.HasNextSegment())
                    {
                        if (iter.GetPathIndex() != iRing)
                        {
                            continue;
                        }
                        com.epl.geometry.Segment segment = iter.NextSegment();
                        if (helper.ProcessSegment(segment))
                        {
                            return(-1);
                        }
                    }
                }
                // point on boundary
                return(helper.Result());
            }
            else
            {
                com.epl.geometry.SegmentIteratorImpl iter = inputPolygonImpl.QuerySegmentIterator();
                iter.ResetToPath(iRing);
                if (iter.NextPath())
                {
                    while (iter.HasNextSegment())
                    {
                        com.epl.geometry.Segment segment = iter.NextSegment();
                        if (helper.ProcessSegment(segment))
                        {
                            return(-1);
                        }
                    }
                }
                // point on boundary
                return(helper.Result());
            }
        }