public static com.epl.geometry.QuadTree BuildQuadTree(com.epl.geometry.MultiPath multipath)
        {
            com.epl.geometry.Envelope2D extent = new com.epl.geometry.Envelope2D();
            multipath.QueryEnvelope2D(extent);
            com.epl.geometry.QuadTree quadTree = new com.epl.geometry.QuadTree(extent, 8);
            int hint_index = -1;

            com.epl.geometry.SegmentIterator seg_iter = multipath.QuerySegmentIterator();
            while (seg_iter.NextPath())
            {
                while (seg_iter.HasNextSegment())
                {
                    com.epl.geometry.Segment segment = seg_iter.NextSegment();
                    int index = seg_iter.GetStartPointIndex();
                    com.epl.geometry.Envelope2D boundingbox = new com.epl.geometry.Envelope2D();
                    segment.QueryEnvelope2D(boundingbox);
                    hint_index = quadTree.Insert(index, boundingbox, hint_index);
                }
            }
            return(quadTree);
        }
Exemple #2
0
        internal virtual com.epl.geometry.Proximity2DResult MultiPathGetNearestCoordinate(com.epl.geometry.MultiPath geom, com.epl.geometry.Point2D inputPoint, bool bTestPolygonInterior, bool bCalculateLeftRightSide)
        {
            if (geom.GetType() == com.epl.geometry.Geometry.Type.Polygon && bTestPolygonInterior)
            {
                com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                geom.QueryEnvelope2D(env);
                double tolerance = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(null, env, false);
                com.epl.geometry.PolygonUtils.PiPResult pipResult;
                if (bCalculateLeftRightSide)
                {
                    pipResult = com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geom, inputPoint, 0.0);
                }
                else
                {
                    pipResult = com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geom, inputPoint, tolerance);
                }
                if (pipResult != com.epl.geometry.PolygonUtils.PiPResult.PiPOutside)
                {
                    com.epl.geometry.Proximity2DResult result = new com.epl.geometry.Proximity2DResult(inputPoint, 0, 0.0);
                    if (bCalculateLeftRightSide)
                    {
                        result.SetRightSide(true);
                    }
                    return(result);
                }
            }
            com.epl.geometry.SegmentIterator segIter = geom.QuerySegmentIterator();
            com.epl.geometry.Point2D         closest = new com.epl.geometry.Point2D();
            int    closestVertexIndex = -1;
            int    closestPathIndex   = -1;
            double closestDistanceSq  = com.epl.geometry.NumberUtils.DoubleMax();
            bool   bRight             = false;
            int    num_candidates     = 0;

            while (segIter.NextPath())
            {
                while (segIter.HasNextSegment())
                {
                    com.epl.geometry.Segment segment = segIter.NextSegment();
                    double t = segment.GetClosestCoordinate(inputPoint, false);
                    com.epl.geometry.Point2D point = segment.GetCoord2D(t);
                    double distanceSq = com.epl.geometry.Point2D.SqrDistance(point, inputPoint);
                    if (distanceSq < closestDistanceSq)
                    {
                        num_candidates     = 1;
                        closest            = point;
                        closestVertexIndex = segIter.GetStartPointIndex();
                        closestPathIndex   = segIter.GetPathIndex();
                        closestDistanceSq  = distanceSq;
                    }
                    else
                    {
                        if (distanceSq == closestDistanceSq)
                        {
                            num_candidates++;
                        }
                    }
                }
            }
            com.epl.geometry.Proximity2DResult result_1 = new com.epl.geometry.Proximity2DResult(closest, closestVertexIndex, System.Math.Sqrt(closestDistanceSq));
            if (bCalculateLeftRightSide)
            {
                segIter.ResetToVertex(closestVertexIndex, closestPathIndex);
                com.epl.geometry.Segment segment = segIter.NextSegment();
                bRight = (com.epl.geometry.Point2D.OrientationRobust(inputPoint, segment.GetStartXY(), segment.GetEndXY()) < 0);
                if (num_candidates > 1)
                {
                    com.epl.geometry.OperatorProximity2DLocal.Side_helper sideHelper = new com.epl.geometry.OperatorProximity2DLocal.Side_helper(this);
                    sideHelper.Reset();
                    bRight = sideHelper.Calc_side(inputPoint, bRight, geom, closestVertexIndex, closestPathIndex);
                }
                result_1.SetRightSide(bRight);
            }
            return(result_1);
        }