Ejemplo n.º 1
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);
        }
Ejemplo n.º 2
0
        internal virtual bool RgHelper(com.epl.geometry.RasterizedGeometry2D rg, com.epl.geometry.MultiPath mp)
        {
            com.epl.geometry.SegmentIterator iter = mp.QuerySegmentIterator();
            while (iter.NextPath())
            {
                while (iter.HasNextSegment())
                {
                    com.epl.geometry.Segment seg = iter.NextSegment();
                    int count = 20;
                    for (int i = 0; i < count; i++)
                    {
                        double t = (1.0 * i / count);
                        com.epl.geometry.Point2D pt = seg.GetCoord2D(t);
                        com.epl.geometry.RasterizedGeometry2D.HitType hit = rg.QueryPointInGeometry(pt.x, pt.y);
                        if (hit != com.epl.geometry.RasterizedGeometry2D.HitType.Border)
                        {
                            return(false);
                        }
                    }
                }
            }
            if (mp.GetType() != com.epl.geometry.Geometry.Type.Polygon)
            {
                return(true);
            }
            com.epl.geometry.Polygon    poly = (com.epl.geometry.Polygon)mp;
            com.epl.geometry.Envelope2D env  = new com.epl.geometry.Envelope2D();
            poly.QueryEnvelope2D(env);
            int count_1 = 100;

            for (int iy = 0; iy < count_1; iy++)
            {
                double ty = 1.0 * iy / count_1;
                double y  = env.ymin * (1.0 - ty) + ty * env.ymax;
                for (int ix = 0; ix < count_1; ix++)
                {
                    double tx = 1.0 * ix / count_1;
                    double x  = env.xmin * (1.0 - tx) + tx * env.xmax;
                    com.epl.geometry.RasterizedGeometry2D.HitType hit = rg.QueryPointInGeometry(x, y);
                    com.epl.geometry.PolygonUtils.PiPResult       res = com.epl.geometry.PolygonUtils.IsPointInPolygon2D(poly, new com.epl.geometry.Point2D(x, y), 0);
                    if (res == com.epl.geometry.PolygonUtils.PiPResult.PiPInside)
                    {
                        bool bgood = (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Border || hit == com.epl.geometry.RasterizedGeometry2D.HitType.Inside);
                        if (!bgood)
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        if (res == com.epl.geometry.PolygonUtils.PiPResult.PiPOutside)
                        {
                            bool bgood = (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Border || hit == com.epl.geometry.RasterizedGeometry2D.HitType.Outside);
                            if (!bgood)
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            bool bgood = (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Border);
                            if (!bgood)
                            {
                                return(false);
                            }
                        }
                    }
                }
            }
            return(true);
        }
Ejemplo n.º 3
0
            private double BruteForceMultiPathMultiPoint_(com.epl.geometry.MultiPath geometryA, com.epl.geometry.MultiPoint geometryB, bool geometriesAreDisjoint)
            {
                /* const */
                /* const */
                com.epl.geometry.SegmentIterator segIterA      = geometryA.QuerySegmentIterator();
                com.epl.geometry.Envelope2D      env2DSegmentA = new com.epl.geometry.Envelope2D();
                double minSqrDistance = com.epl.geometry.NumberUtils.DoubleMax();

                com.epl.geometry.Point2D inputPoint = new com.epl.geometry.Point2D();
                double t           = -1;
                double sqrDistance = minSqrDistance;

                /* const */
                com.epl.geometry.MultiPointImpl multiPointImplB = (com.epl.geometry.MultiPointImpl)geometryB._getImpl();
                int  pointCountB = multiPointImplB.GetPointCount();
                bool bDoPiPTest  = !geometriesAreDisjoint && (geometryA.GetType() == com.epl.geometry.Geometry.Type.Polygon);

                while (segIterA.NextPath())
                {
                    while (segIterA.HasNextSegment())
                    {
                        /* const */
                        com.epl.geometry.Segment segmentA = segIterA.NextSegment();
                        segmentA.QueryEnvelope2D(env2DSegmentA);
                        // if multipointB has only 1 vertex then it is faster to not
                        // test for
                        // env2DSegmentA.distance(env2DgeometryB)
                        if (pointCountB > 1 && env2DSegmentA.SqrDistance(this.m_env2DgeometryB) > minSqrDistance)
                        {
                            continue;
                        }
                        for (int i = 0; i < pointCountB; i++)
                        {
                            multiPointImplB.GetXY(i, inputPoint);
                            if (bDoPiPTest)
                            {
                                // Test for polygon containment. This takes the
                                // place of a more general intersection test at the
                                // beginning of the operator
                                if (com.epl.geometry.PolygonUtils.IsPointInPolygon2D((com.epl.geometry.Polygon)geometryA, inputPoint, 0) != com.epl.geometry.PolygonUtils.PiPResult.PiPOutside)
                                {
                                    return(0.0);
                                }
                            }
                            t = segmentA.GetClosestCoordinate(inputPoint, false);
                            inputPoint.Sub(segmentA.GetCoord2D(t));
                            sqrDistance = inputPoint.SqrLength();
                            if (sqrDistance < minSqrDistance)
                            {
                                if (sqrDistance == 0.0)
                                {
                                    return(0.0);
                                }
                                minSqrDistance = sqrDistance;
                            }
                        }
                        // No need to do point-in-polygon anymore (if it is a
                        // polygon vs polyline)
                        bDoPiPTest = false;
                    }
                }
                return(System.Math.Sqrt(minSqrDistance));
            }