Exemplo n.º 1
0
		internal virtual com.epl.geometry.Geometry Intersect(com.epl.geometry.Geometry input_geom)
		{
			com.epl.geometry.Geometry dst_geom = TryNativeImplementation_(input_geom);
			if (dst_geom != null)
			{
				return dst_geom;
			}
			com.epl.geometry.Envelope2D commonExtent = com.epl.geometry.InternalUtils.GetMergedExtent(m_geomIntersector, input_geom);
			// return Topological_operations::intersection(input_geom,
			// m_geomIntersector, m_spatial_reference, m_progress_tracker);
			// Preprocess geometries to be clipped to the extent of intersection to
			// get rid of extra segments.
			double t = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(m_spatial_reference, commonExtent, true);
			com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
			m_geomIntersector.QueryEnvelope2D(env);
			com.epl.geometry.Envelope2D env1 = new com.epl.geometry.Envelope2D();
			input_geom.QueryEnvelope2D(env1);
			env.Inflate(2.0 * t, 2.0 * t);
			env.Intersect(env1);
			System.Diagnostics.Debug.Assert((!env.IsEmpty()));
			env.Inflate(100 * t, 100 * t);
			double tol = 0;
			com.epl.geometry.Geometry clippedIntersector = com.epl.geometry.Clipper.Clip(m_geomIntersector, env, tol, 0.0);
			com.epl.geometry.Geometry clippedInputGeom = com.epl.geometry.Clipper.Clip(input_geom, env, tol, 0.0);
			// perform the clip
			return com.epl.geometry.TopologicalOperations.Intersection(clippedInputGeom, clippedIntersector, m_spatial_reference, m_progress_tracker);
		}
Exemplo n.º 2
0
		internal virtual com.epl.geometry.GeometryCursor IntersectEx(com.epl.geometry.Geometry input_geom)
		{
			System.Diagnostics.Debug.Assert((m_dimensionMask != -1));
			com.epl.geometry.Geometry dst_geom = TryNativeImplementation_(input_geom);
			if (dst_geom != null)
			{
				com.epl.geometry.Geometry[] res_vec = new com.epl.geometry.Geometry[3];
				res_vec[dst_geom.GetDimension()] = dst_geom;
				return PrepareVector_(input_geom.GetDescription(), m_dimensionMask, res_vec);
			}
			com.epl.geometry.Envelope2D commonExtent = com.epl.geometry.InternalUtils.GetMergedExtent(m_geomIntersector, input_geom);
			double t = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(m_spatial_reference, commonExtent, true);
			// Preprocess geometries to be clipped to the extent of intersection to
			// get rid of extra segments.
			com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
			m_geomIntersector.QueryEnvelope2D(env);
			env.Inflate(2 * t, 2 * t);
			com.epl.geometry.Envelope2D env1 = new com.epl.geometry.Envelope2D();
			input_geom.QueryEnvelope2D(env1);
			env.Intersect(env1);
			System.Diagnostics.Debug.Assert((!env.IsEmpty()));
			env.Inflate(100 * t, 100 * t);
			double tol = 0;
			com.epl.geometry.Geometry clippedIntersector = com.epl.geometry.Clipper.Clip(m_geomIntersector, env, tol, 0.0);
			com.epl.geometry.Geometry clippedInputGeom = com.epl.geometry.Clipper.Clip(input_geom, env, tol, 0.0);
			// perform the clip
			com.epl.geometry.Geometry[] res_vec_1;
			res_vec_1 = com.epl.geometry.TopologicalOperations.IntersectionEx(clippedInputGeom, clippedIntersector, m_spatial_reference, m_progress_tracker);
			return PrepareVector_(input_geom.GetDescription(), m_dimensionMask, res_vec_1);
		}
        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());
        }
        //dbgSaveToBitmap("c:/temp/_dbg.bmp");
        internal bool TryRenderAsSmallEnvelope_(com.epl.geometry.Envelope2D env)
        {
            if (!env.IsIntersecting(m_geomEnv))
            {
                return(true);
            }
            com.epl.geometry.Envelope2D envPix = new com.epl.geometry.Envelope2D();
            envPix.SetCoords(env);
            m_transform.Transform(env);
            double strokeHalfWidthPixX = m_stroke_half_widthX_pix;
            double strokeHalfWidthPixY = m_stroke_half_widthY_pix;

            if (envPix.GetWidth() > 2 * strokeHalfWidthPixX + 1 || envPix.GetHeight() > 2 * strokeHalfWidthPixY + 1)
            {
                return(false);
            }
            // This envelope is too narrow/small, so that it can be just drawn as a
            // rectangle using only boundary color.
            envPix.Inflate(strokeHalfWidthPixX, strokeHalfWidthPixY);
            envPix.xmax += 1.0;
            envPix.ymax += 1.0;
            // take into account that it does not draw right and
            // bottom edges.
            m_callback.SetColor(m_rasterizer, 2);
            FillEnvelope(m_rasterizer, envPix);
            return(true);
        }
        private static int QuickTest2DMultiPointEnvelope(com.epl.geometry.MultiPoint geomA, com.epl.geometry.Envelope2D geomBEnv, double tolerance, int testType)
        {
            // Add early bailout for disjoint test.
            com.epl.geometry.Envelope2D envBMinus = geomBEnv;
            envBMinus.Inflate(-tolerance, -tolerance);
            com.epl.geometry.Envelope2D envBPlus = geomBEnv;
            envBPlus.Inflate(tolerance, tolerance);
            int dres = 0;

            for (int i = 0, n = geomA.GetPointCount(); i < n; i++)
            {
                com.epl.geometry.Point2D ptA;
                ptA = geomA.GetXY(i);
                int res = ReverseResult(QuickTest2DEnvelopePoint(envBPlus, envBMinus, ptA, tolerance));
                if (res != (int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Disjoint)
                {
                    dres |= res;
                    if (testType == (int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Disjoint)
                    {
                        return((int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Intersects);
                    }
                }
            }
            if (dres == 0)
            {
                return((int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Disjoint);
            }
            if (dres == (int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Within)
            {
                return(dres);
            }
            return((int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Overlaps);
        }
Exemplo n.º 6
0
 public com.epl.geometry.Envelope2D GetInflated(double dx, double dy)
 {
     com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
     env.SetCoords(this.xmin, this.ymin, this.xmax, this.ymax);
     env.Inflate(dx, dy);
     return(env);
 }
        internal static com.epl.geometry.Geometry MultiPointSymDiffPoint_(com.epl.geometry.MultiPoint multi_point, com.epl.geometry.Point point, double tolerance, com.epl.geometry.ProgressTracker progress_tracker)
        {
            com.epl.geometry.MultiPointImpl       multipointImpl = (com.epl.geometry.MultiPointImpl)(multi_point._getImpl());
            com.epl.geometry.AttributeStreamOfDbl position       = (com.epl.geometry.AttributeStreamOfDbl)(multipointImpl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION));
            int point_count = multi_point.GetPointCount();

            com.epl.geometry.Point2D    point2D        = point.GetXY();
            com.epl.geometry.MultiPoint new_multipoint = (com.epl.geometry.MultiPoint)(multi_point.CreateInstance());
            double tolerance_cluster = tolerance * System.Math.Sqrt(2.0) * 1.00001;

            com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
            multi_point.QueryEnvelope2D(env);
            env.Inflate(tolerance_cluster, tolerance_cluster);
            if (env.Contains(point2D))
            {
                double tolerance_cluster_sq = tolerance_cluster * tolerance_cluster;
                bool   b_found_covered      = false;
                bool[] covered = new bool[point_count];
                for (int i = 0; i < point_count; i++)
                {
                    covered[i] = false;
                }
                for (int i_1 = 0; i_1 < point_count; i_1++)
                {
                    double x  = position.Read(2 * i_1);
                    double y  = position.Read(2 * i_1 + 1);
                    double dx = x - point2D.x;
                    double dy = y - point2D.y;
                    if (dx * dx + dy * dy <= tolerance_cluster_sq)
                    {
                        b_found_covered = true;
                        covered[i_1]    = true;
                    }
                }
                if (!b_found_covered)
                {
                    new_multipoint.Add(multi_point, 0, point_count);
                    new_multipoint.Add(point);
                }
                else
                {
                    for (int i_2 = 0; i_2 < point_count; i_2++)
                    {
                        if (!covered[i_2])
                        {
                            new_multipoint.Add(multi_point, i_2, i_2 + 1);
                        }
                    }
                }
            }
            else
            {
                new_multipoint.Add(multi_point, 0, point_count);
                new_multipoint.Add(point);
            }
            return(new_multipoint);
        }
 // return the input point
 internal static com.epl.geometry.Geometry PointMinusEnvelope_(com.epl.geometry.Point point, com.epl.geometry.Envelope envelope, double tolerance, com.epl.geometry.ProgressTracker progress_tracker)
 {
     com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
     envelope.QueryEnvelope2D(env);
     env.Inflate(tolerance, tolerance);
     com.epl.geometry.Point2D pt = point.GetXY();
     if (!env.Contains(pt))
     {
         return(point);
     }
     return(point.CreateInstance());
 }
        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 QuickTest2DEnvelopePoint(com.epl.geometry.Envelope2D geomAEnv, com.epl.geometry.Point2D ptB, double tolerance)
 {
     com.epl.geometry.Envelope2D envAMinus = geomAEnv;
     envAMinus.Inflate(-tolerance, -tolerance);
     if (envAMinus.Contains(ptB))
     {
         return((int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Contains);
     }
     // clementini's contains
     com.epl.geometry.Envelope2D envAPlus = geomAEnv;
     envAPlus.Inflate(tolerance, tolerance);
     if (envAPlus.Contains(ptB))
     {
         return((int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Touches);
     }
     // clementini's touches
     return((int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Disjoint);
 }
        internal static com.epl.geometry.Geometry MultiPointMinusPolygon_(com.epl.geometry.MultiPoint multi_point, com.epl.geometry.Polygon polygon, double tolerance, com.epl.geometry.ProgressTracker progress_tracker)
        {
            com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
            polygon.QueryEnvelope2D(env);
            env.Inflate(tolerance, tolerance);
            int  point_count     = multi_point.GetPointCount();
            bool b_found_covered = false;

            bool[] covered = new bool[point_count];
            for (int i = 0; i < point_count; i++)
            {
                covered[i] = false;
            }
            com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D();
            for (int i_1 = 0; i_1 < point_count; i_1++)
            {
                multi_point.GetXY(i_1, pt);
                if (!env.Contains(pt))
                {
                    continue;
                }
                com.epl.geometry.PolygonUtils.PiPResult result = com.epl.geometry.PolygonUtils.IsPointInPolygon2D(polygon, pt, tolerance);
                if (result == com.epl.geometry.PolygonUtils.PiPResult.PiPOutside)
                {
                    continue;
                }
                b_found_covered = true;
                covered[i_1]    = true;
            }
            if (!b_found_covered)
            {
                return(multi_point);
            }
            com.epl.geometry.MultiPoint new_multipoint = (com.epl.geometry.MultiPoint)multi_point.CreateInstance();
            for (int i_2 = 0; i_2 < point_count; i_2++)
            {
                if (!covered[i_2])
                {
                    new_multipoint.Add(multi_point, i_2, i_2 + 1);
                }
            }
            return(new_multipoint);
        }
 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));
 }
Exemplo n.º 13
0
 private static void _testPointsInEnvelope2D(com.epl.geometry.Envelope2D env2D, double[] xyStreamBuffer, int pointCount, double tolerance, com.epl.geometry.PolygonUtils.PiPResult[] testResults)
 {
     if (xyStreamBuffer.Length / 2 < pointCount || testResults.Length < pointCount)
     {
         throw new System.ArgumentException();
     }
     if (env2D.IsEmpty())
     {
         for (int i = 0; i < pointCount; i++)
         {
             testResults[i] = com.epl.geometry.PolygonUtils.PiPResult.PiPOutside;
         }
         return;
     }
     com.epl.geometry.Envelope2D envIn = env2D;
     // note for java port - assignement by value
     envIn.Inflate(-tolerance * 0.5, -tolerance * 0.5);
     com.epl.geometry.Envelope2D envOut = env2D;
     // note for java port - assignement by value
     envOut.Inflate(tolerance * 0.5, tolerance * 0.5);
     for (int i_1 = 0; i_1 < pointCount; i_1++)
     {
         if (envIn.Contains(xyStreamBuffer[i_1 * 2], xyStreamBuffer[i_1 * 2 + 1]))
         {
             testResults[i_1] = com.epl.geometry.PolygonUtils.PiPResult.PiPInside;
         }
         else
         {
             if (!envIn.Contains(xyStreamBuffer[i_1 * 2], xyStreamBuffer[i_1 * 2 + 1]))
             {
                 testResults[i_1] = com.epl.geometry.PolygonUtils.PiPResult.PiPOutside;
             }
             else
             {
                 testResults[i_1] = com.epl.geometry.PolygonUtils.PiPResult.PiPBoundary;
             }
         }
     }
 }
        internal static com.epl.geometry.Geometry PointMinusPolyline_(com.epl.geometry.Point point, com.epl.geometry.Polyline polyline, double tolerance, com.epl.geometry.ProgressTracker progress_tracker)
        {
            com.epl.geometry.Point2D         pt       = point.GetXY();
            com.epl.geometry.SegmentIterator seg_iter = polyline.QuerySegmentIterator();
            double tolerance_cluster    = tolerance * System.Math.Sqrt(2.0) * 1.00001;
            double tolerance_cluster_sq = tolerance_cluster * tolerance_cluster;

            com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
            while (seg_iter.NextPath())
            {
                while (seg_iter.HasNextSegment())
                {
                    com.epl.geometry.Segment segment = seg_iter.NextSegment();
                    segment.QueryEnvelope2D(env);
                    env.Inflate(tolerance_cluster, tolerance_cluster);
                    if (!env.Contains(pt))
                    {
                        continue;
                    }
                    if (segment.IsIntersecting(pt, tolerance))
                    {
                        return(point.CreateInstance());
                    }
                    // check segment end points to the cluster tolerance
                    com.epl.geometry.Point2D end_point = segment.GetStartXY();
                    if (com.epl.geometry.Point2D.SqrDistance(pt, end_point) <= tolerance_cluster_sq)
                    {
                        return(point.CreateInstance());
                    }
                    end_point = segment.GetEndXY();
                    if (com.epl.geometry.Point2D.SqrDistance(pt, end_point) <= tolerance_cluster_sq)
                    {
                        return(point.CreateInstance());
                    }
                }
            }
            return(point);
        }
 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));
 }
        internal void Init(com.epl.geometry.MultiVertexGeometryImpl geom, double toleranceXY, int rasterSizeBytes)
        {
            // _ASSERT(CanUseAccelerator(geom));
            m_width        = System.Math.Max((int)(System.Math.Sqrt(rasterSizeBytes) * 2 + 0.5), 64);
            m_scanLineSize = (m_width * 2 + 31) / 32;
            // 2 bits per pixel
            m_geomEnv     = new com.epl.geometry.Envelope2D();
            m_toleranceXY = toleranceXY;
            // calculate bitmap size
            int size         = 0;
            int width        = m_width;
            int scanLineSize = m_scanLineSize;

            while (width >= 8)
            {
                size        += width * scanLineSize;
                width       /= 2;
                scanLineSize = (width * 2 + 31) / 32;
            }
            // allocate the bitmap, that contains the base and the mip-levels
            m_bitmap = new int[size];
            for (int i = 0; i < size; i++)
            {
                m_bitmap[i] = 0;
            }
            m_rasterizer = new com.epl.geometry.SimpleRasterizer();
            com.epl.geometry.RasterizedGeometry2DImpl.ScanCallbackImpl callback = new com.epl.geometry.RasterizedGeometry2DImpl.ScanCallbackImpl(this, m_bitmap, m_scanLineSize);
            m_callback = callback;
            m_rasterizer.Setup(m_width, m_width, callback);
            geom.QueryEnvelope2D(m_geomEnv);
            if (m_geomEnv.GetWidth() > m_width * m_geomEnv.GetHeight() || m_geomEnv.GetHeight() > m_geomEnv.GetWidth() * m_width)
            {
            }
            // the geometry is thin and the rasterizer is not needed.
            m_geomEnv.Inflate(toleranceXY, toleranceXY);
            com.epl.geometry.Envelope2D worldEnv = new com.epl.geometry.Envelope2D();
            com.epl.geometry.Envelope2D pixEnv   = com.epl.geometry.Envelope2D.Construct(1, 1, m_width - 2, m_width - 2);
            double minWidth = toleranceXY * pixEnv.GetWidth();
            // min width is such
            // that the size of
            // one pixel is
            // equal to the
            // tolerance
            double minHeight = toleranceXY * pixEnv.GetHeight();

            worldEnv.SetCoords(m_geomEnv.GetCenter(), System.Math.Max(minWidth, m_geomEnv.GetWidth()), System.Math.Max(minHeight, m_geomEnv.GetHeight()));
            m_stroke_half_widthX_pix = worldEnv.GetWidth() / pixEnv.GetWidth();
            m_stroke_half_widthY_pix = worldEnv.GetHeight() / pixEnv.GetHeight();
            // The stroke half width. Later it will be inflated to account for
            // pixels size.
            m_stroke_half_width = m_toleranceXY;
            m_transform         = new com.epl.geometry.Transformation2D();
            m_transform.InitializeFromRect(worldEnv, pixEnv);
            // geom to pixels
            com.epl.geometry.Transformation2D identityTransform = new com.epl.geometry.Transformation2D();
            switch (geom.GetType().Value())
            {
            case com.epl.geometry.Geometry.GeometryType.MultiPoint:
            {
                callback.SetColor(m_rasterizer, 2);
                FillPoints(m_rasterizer, (com.epl.geometry.MultiPointImpl)geom, m_stroke_half_width);
                break;
            }

            case com.epl.geometry.Geometry.GeometryType.Polyline:
            {
                callback.SetColor(m_rasterizer, 2);
                StrokeDrawPolyPath(m_rasterizer, (com.epl.geometry.MultiPathImpl)geom._getImpl(), m_stroke_half_width);
                break;
            }

            case com.epl.geometry.Geometry.GeometryType.Polygon:
            {
                bool isWinding = false;
                // NOTE: change when winding is supported
                callback.SetColor(m_rasterizer, 1);
                FillMultiPath(m_rasterizer, m_transform, (com.epl.geometry.MultiPathImpl)geom, isWinding);
                callback.SetColor(m_rasterizer, 2);
                StrokeDrawPolyPath(m_rasterizer, (com.epl.geometry.MultiPathImpl)geom._getImpl(), m_stroke_half_width);
                break;
            }
            }
            m_dx = m_transform.xx;
            m_dy = m_transform.yy;
            m_x0 = m_transform.xd;
            m_y0 = m_transform.yd;
            BuildLevels();
        }
Exemplo n.º 17
0
		internal virtual com.epl.geometry.Geometry TryFastIntersectPolylinePolygon_(com.epl.geometry.Polyline polyline, com.epl.geometry.Polygon polygon)
		{
			com.epl.geometry.MultiPathImpl polylineImpl = (com.epl.geometry.MultiPathImpl)polyline._getImpl();
			com.epl.geometry.MultiPathImpl polygonImpl = (com.epl.geometry.MultiPathImpl)polygon._getImpl();
			double tolerance = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(m_spatial_reference, polygon, false);
			com.epl.geometry.Envelope2D clipEnvelope = new com.epl.geometry.Envelope2D();
			{
				polygonImpl.QueryEnvelope2D(clipEnvelope);
				com.epl.geometry.Envelope2D env1 = new com.epl.geometry.Envelope2D();
				polylineImpl.QueryEnvelope2D(env1);
				env1.Inflate(2.0 * tolerance, 2.0 * tolerance);
				clipEnvelope.Intersect(env1);
				System.Diagnostics.Debug.Assert((!clipEnvelope.IsEmpty()));
			}
			clipEnvelope.Inflate(10 * tolerance, 10 * tolerance);
			if (true)
			{
				double tol = 0;
				com.epl.geometry.Geometry clippedPolyline = com.epl.geometry.Clipper.Clip(polyline, clipEnvelope, tol, 0.0);
				polyline = (com.epl.geometry.Polyline)clippedPolyline;
				polylineImpl = (com.epl.geometry.MultiPathImpl)polyline._getImpl();
			}
			com.epl.geometry.AttributeStreamOfInt32 clipResult = new com.epl.geometry.AttributeStreamOfInt32(0);
			int unresolvedSegments = -1;
			com.epl.geometry.GeometryAccelerators accel = polygonImpl._getAccelerators();
			if (accel != null)
			{
				com.epl.geometry.RasterizedGeometry2D rgeom = accel.GetRasterizedGeometry();
				if (rgeom != null)
				{
					unresolvedSegments = 0;
					clipResult.Reserve(polylineImpl.GetPointCount() + polylineImpl.GetPathCount());
					com.epl.geometry.Envelope2D seg_env = new com.epl.geometry.Envelope2D();
					com.epl.geometry.SegmentIteratorImpl iter = polylineImpl.QuerySegmentIterator();
					while (iter.NextPath())
					{
						while (iter.HasNextSegment())
						{
							com.epl.geometry.Segment seg = iter.NextSegment();
							seg.QueryEnvelope2D(seg_env);
							com.epl.geometry.RasterizedGeometry2D.HitType hit = rgeom.QueryEnvelopeInGeometry(seg_env);
							if (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Inside)
							{
								clipResult.Add(1);
							}
							else
							{
								if (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Outside)
								{
									clipResult.Add(0);
								}
								else
								{
									clipResult.Add(-1);
									unresolvedSegments++;
								}
							}
						}
					}
				}
			}
			if (polygon.GetPointCount() > 5)
			{
				double tol = 0;
				com.epl.geometry.Geometry clippedPolygon = com.epl.geometry.Clipper.Clip(polygon, clipEnvelope, tol, 0.0);
				polygon = (com.epl.geometry.Polygon)clippedPolygon;
				polygonImpl = (com.epl.geometry.MultiPathImpl)polygon._getImpl();
				accel = polygonImpl._getAccelerators();
			}
			//update accelerators
			if (unresolvedSegments < 0)
			{
				unresolvedSegments = polylineImpl.GetSegmentCount();
			}
			// Some heuristics to decide if it makes sense to go with fast intersect
			// vs going with the regular planesweep.
			double totalPoints = (double)(polylineImpl.GetPointCount() + polygonImpl.GetPointCount());
			double thisAlgorithmComplexity = ((double)unresolvedSegments * polygonImpl.GetPointCount());
			// assume the worst case.
			double planesweepComplexity = System.Math.Log(totalPoints) * totalPoints;
			double empiricConstantFactorPlaneSweep = 4;
			if (thisAlgorithmComplexity > planesweepComplexity * empiricConstantFactorPlaneSweep)
			{
				// Based on the number of input points, we deduced that the
				// plansweep performance should be better than the brute force
				// performance.
				return null;
			}
			// resort to planesweep if quadtree does not help
			com.epl.geometry.QuadTreeImpl polygonQuadTree = null;
			com.epl.geometry.SegmentIteratorImpl polygonIter = polygonImpl.QuerySegmentIterator();
			// Some logic to decide if it makes sense to build a quadtree on the
			// polygon segments
			if (accel != null && accel.GetQuadTree() != null)
			{
				polygonQuadTree = accel.GetQuadTree();
			}
			if (polygonQuadTree == null && polygonImpl.GetPointCount() > 20)
			{
				polygonQuadTree = com.epl.geometry.InternalUtils.BuildQuadTree(polygonImpl);
			}
			com.epl.geometry.Polyline result_polyline = (com.epl.geometry.Polyline)polyline.CreateInstance();
			com.epl.geometry.MultiPathImpl resultPolylineImpl = (com.epl.geometry.MultiPathImpl)result_polyline._getImpl();
			com.epl.geometry.QuadTreeImpl.QuadTreeIteratorImpl qIter = null;
			com.epl.geometry.SegmentIteratorImpl polylineIter = polylineImpl.QuerySegmentIterator();
			double[] @params = new double[9];
			com.epl.geometry.AttributeStreamOfDbl intersections = new com.epl.geometry.AttributeStreamOfDbl(0);
			com.epl.geometry.SegmentBuffer segmentBuffer = new com.epl.geometry.SegmentBuffer();
			int start_index = -1;
			int inCount = 0;
			int segIndex = 0;
			bool bOptimized = clipResult.Size() > 0;
			// The algorithm is like that:
			// Loop through all the segments of the polyline.
			// For each polyline segment, intersect it with each of the polygon
			// segments.
			// If no intersections found then,
			// If the polyline segment is completely inside, it is added to the
			// result polyline.
			// If it is outside, it is thrown out.
			// If it intersects, then cut the polyline segment to pieces and test
			// each part of the intersected result.
			// The cut pieces will either have one point inside, or one point
			// outside, or the middle point inside/outside.
			//
			int polylinePathIndex = -1;
			while (polylineIter.NextPath())
			{
				polylinePathIndex = polylineIter.GetPathIndex();
				int stateNewPath = 0;
				int stateAddSegment = 1;
				int stateManySegments = 2;
				int stateManySegmentsContinuePath = 2;
				int stateManySegmentsNewPath = 3;
				int state = stateNewPath;
				start_index = -1;
				inCount = 0;
				while (polylineIter.HasNextSegment())
				{
					int clipStatus = bOptimized ? (int)clipResult.Get(segIndex) : -1;
					segIndex++;
					com.epl.geometry.Segment polylineSeg = polylineIter.NextSegment();
					if (clipStatus < 0)
					{
						System.Diagnostics.Debug.Assert((clipStatus == -1));
						// Analyse polyline segment for intersection with the
						// polygon.
						if (polygonQuadTree != null)
						{
							if (qIter == null)
							{
								qIter = polygonQuadTree.GetIterator(polylineSeg, tolerance);
							}
							else
							{
								qIter.ResetIterator(polylineSeg, tolerance);
							}
							int path_index = -1;
							for (int ind = qIter.Next(); ind != -1; ind = qIter.Next())
							{
								polygonIter.ResetToVertex(polygonQuadTree.GetElement(ind));
								// path_index
								path_index = polygonIter.GetPathIndex();
								com.epl.geometry.Segment polygonSeg = polygonIter.NextSegment();
								// intersect polylineSeg and polygonSeg.
								int count = polylineSeg.Intersect(polygonSeg, null, @params, null, tolerance);
								for (int i = 0; i < count; i++)
								{
									intersections.Add(@params[i]);
								}
							}
						}
						else
						{
							// no quadtree built
							polygonIter.ResetToFirstPath();
							while (polygonIter.NextPath())
							{
								while (polygonIter.HasNextSegment())
								{
									com.epl.geometry.Segment polygonSeg = polygonIter.NextSegment();
									// intersect polylineSeg and polygonSeg.
									int count = polylineSeg.Intersect(polygonSeg, null, @params, null, tolerance);
									for (int i = 0; i < count; i++)
									{
										intersections.Add(@params[i]);
									}
								}
							}
						}
						if (intersections.Size() > 0)
						{
							// intersections detected.
							intersections.Sort(0, intersections.Size());
							// std::sort(intersections.begin(),
							// intersections.end());
							double t0 = 0;
							intersections.Add(1.0);
							int status = -1;
							for (int i = 0, n = intersections.Size(); i < n; i++)
							{
								double t = intersections.Get(i);
								if (t == t0)
								{
									continue;
								}
								bool bWholeSegment = false;
								com.epl.geometry.Segment resSeg;
								if (t0 != 0 || t != 1.0)
								{
									polylineSeg.Cut(t0, t, segmentBuffer);
									resSeg = segmentBuffer.Get();
								}
								else
								{
									resSeg = polylineSeg;
									bWholeSegment = true;
								}
								if (state >= stateManySegments)
								{
									resultPolylineImpl.AddSegmentsFromPath(polylineImpl, polylinePathIndex, start_index, inCount, state == stateManySegmentsNewPath);
									if (AnalyseClipSegment_(polygon, resSeg.GetStartXY(), tolerance) != 1)
									{
										if (AnalyseClipSegment_(polygon, resSeg, tolerance) != 1)
										{
											return null;
										}
									}
									//someting went wrong we'll falback to slower but robust planesweep code.
									resultPolylineImpl.AddSegment(resSeg, false);
									state = stateAddSegment;
									inCount = 0;
								}
								else
								{
									status = AnalyseClipSegment_(polygon, resSeg, tolerance);
									switch (status)
									{
										case 1:
										{
											if (!bWholeSegment)
											{
												resultPolylineImpl.AddSegment(resSeg, state == stateNewPath);
												state = stateAddSegment;
											}
											else
											{
												if (state < stateManySegments)
												{
													start_index = polylineIter.GetStartPointIndex() - polylineImpl.GetPathStart(polylinePathIndex);
													inCount = 1;
													if (state == stateNewPath)
													{
														state = stateManySegmentsNewPath;
													}
													else
													{
														System.Diagnostics.Debug.Assert((state == stateAddSegment));
														state = stateManySegmentsContinuePath;
													}
												}
												else
												{
													inCount++;
												}
											}
											break;
										}

										case 0:
										{
											state = stateNewPath;
											start_index = -1;
											inCount = 0;
											break;
										}

										default:
										{
											return null;
										}
									}
								}
								// may happen if a segment
								// coincides with the border.
								t0 = t;
							}
						}
						else
						{
							clipStatus = AnalyseClipSegment_(polygon, polylineSeg.GetStartXY(), tolerance);
							// simple
							// case
							// no
							// intersection.
							// Both
							// points
							// must
							// be
							// inside.
							if (clipStatus < 0)
							{
								System.Diagnostics.Debug.Assert((clipStatus >= 0));
								return null;
							}
							// something goes wrong, resort to
							// planesweep
							System.Diagnostics.Debug.Assert((AnalyseClipSegment_(polygon, polylineSeg.GetEndXY(), tolerance) == clipStatus));
							if (clipStatus == 1)
							{
								// the whole segment inside
								if (state < stateManySegments)
								{
									System.Diagnostics.Debug.Assert((inCount == 0));
									start_index = polylineIter.GetStartPointIndex() - polylineImpl.GetPathStart(polylinePathIndex);
									if (state == stateNewPath)
									{
										state = stateManySegmentsNewPath;
									}
									else
									{
										System.Diagnostics.Debug.Assert((state == stateAddSegment));
										state = stateManySegmentsContinuePath;
									}
								}
								inCount++;
							}
							else
							{
								System.Diagnostics.Debug.Assert((state < stateManySegments));
								start_index = -1;
								inCount = 0;
							}
						}
						intersections.Clear(false);
					}
					else
					{
						// clip status is determined by other means
						if (clipStatus == 0)
						{
							// outside
							System.Diagnostics.Debug.Assert((AnalyseClipSegment_(polygon, polylineSeg, tolerance) == 0));
							System.Diagnostics.Debug.Assert((start_index < 0));
							System.Diagnostics.Debug.Assert((inCount == 0));
							continue;
						}
						if (clipStatus == 1)
						{
							System.Diagnostics.Debug.Assert((AnalyseClipSegment_(polygon, polylineSeg, tolerance) == 1));
							if (state == stateNewPath)
							{
								state = stateManySegmentsNewPath;
								start_index = polylineIter.GetStartPointIndex() - polylineImpl.GetPathStart(polylinePathIndex);
							}
							else
							{
								if (state == stateAddSegment)
								{
									state = stateManySegmentsContinuePath;
									start_index = polylineIter.GetStartPointIndex() - polylineImpl.GetPathStart(polylinePathIndex);
								}
								else
								{
									System.Diagnostics.Debug.Assert((state >= stateManySegments));
								}
							}
							inCount++;
							continue;
						}
					}
				}
				if (state >= stateManySegments)
				{
					resultPolylineImpl.AddSegmentsFromPath(polylineImpl, polylinePathIndex, start_index, inCount, state == stateManySegmentsNewPath);
					start_index = -1;
				}
			}
			return result_polyline;
		}
Exemplo n.º 18
0
		internal virtual com.epl.geometry.Geometry TryNativeImplementation_(com.epl.geometry.Geometry input_geom)
		{
			// A note on attributes:
			// 1. The geometry with lower dimension wins in regard to the
			// attributes.
			// 2. If the dimensions are the same, the input_geometry attributes win.
			// 3. The exception to the 2. is when the input is an Envelope, and the
			// intersector is a polygon, then the intersector wins.
			// A note on the tolerance:
			// This operator performs a simple intersection operation. Should it use
			// the tolerance?
			// Example: Point is intersected by the envelope.
			// If it is slightly outside of the envelope, should we still return it
			// if it is closer than the tolerance?
			// Should we do crack and cluster and snap the point coordinates to the
			// envelope boundary?
			//
			// Consider floating point arithmetics approach. When you compare
			// doubles, you should use an epsilon (equals means ::fabs(a - b) <
			// eps), however when you add/subtract, etc them, you do not use
			// epsilon.
			// Shouldn't we do same here? Relational operators use tolerance, but
			// the action operators don't.
			com.epl.geometry.Envelope2D mergedExtent = com.epl.geometry.InternalUtils.GetMergedExtent(input_geom, m_geomIntersector);
			double tolerance = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(m_spatial_reference, mergedExtent, false);
			int gtInput = input_geom.GetType().Value();
			bool bInputEmpty = input_geom.IsEmpty();
			bool bGeomIntersectorEmpty = m_geomIntersector.IsEmpty();
			bool bResultIsEmpty = bInputEmpty || bGeomIntersectorEmpty;
			if (!bResultIsEmpty)
			{
				// test envelopes
				com.epl.geometry.Envelope2D env2D1 = new com.epl.geometry.Envelope2D();
				input_geom.QueryEnvelope2D(env2D1);
				com.epl.geometry.Envelope2D env2D2 = new com.epl.geometry.Envelope2D();
				m_geomIntersector.QueryEnvelope2D(env2D2);
				env2D2.Inflate(2.0 * tolerance, 2.0 * tolerance);
				bResultIsEmpty = !env2D1.IsIntersecting(env2D2);
			}
			if (!bResultIsEmpty)
			{
				// try accelerated test
				int res = com.epl.geometry.OperatorInternalRelationUtils.QuickTest2D_Accelerated_DisjointOrContains(m_geomIntersector, input_geom, tolerance);
				if (res == com.epl.geometry.OperatorInternalRelationUtils.Relation.Disjoint)
				{
					// disjoint
					bResultIsEmpty = true;
				}
				else
				{
					if ((res & com.epl.geometry.OperatorInternalRelationUtils.Relation.Within) != 0)
					{
						// intersector
						// is
						// within
						// the
						// input_geom
						// TODO:
						// assign
						// input_geom
						// attributes
						// first
						return m_geomIntersector;
					}
					else
					{
						if ((res & com.epl.geometry.OperatorInternalRelationUtils.Relation.Contains) != 0)
						{
							// intersector
							// contains
							// input_geom
							return input_geom;
						}
					}
				}
			}
			if (bResultIsEmpty)
			{
				// When one geometry or both are empty, we need to
				// return an empty geometry.
				// Here we do that end also ensure the type is
				// correct.
				// That is the lower dimension need to be
				// returned. Also, for Point vs Multi_point, an
				// empty Point need to be returned.
				int dim1 = com.epl.geometry.Geometry.GetDimensionFromType(gtInput);
				int dim2 = com.epl.geometry.Geometry.GetDimensionFromType(m_geomIntersectorType);
				if (dim1 < dim2)
				{
					return ReturnEmpty_(input_geom, bInputEmpty);
				}
				else
				{
					if (dim1 > dim2)
					{
						return ReturnEmptyIntersector_();
					}
					else
					{
						if (dim1 == 0)
						{
							if (gtInput == com.epl.geometry.Geometry.GeometryType.MultiPoint && m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.Point)
							{
								// point
								// vs
								// Multi_point
								// need
								// special
								// treatment
								// to
								// ensure
								// Point
								// is
								// returned
								// always.
								return ReturnEmptyIntersector_();
							}
							else
							{
								// Both input and intersector have same gtype, or input is
								// Point.
								return ReturnEmpty_(input_geom, bInputEmpty);
							}
						}
						else
						{
							return ReturnEmpty_(input_geom, bInputEmpty);
						}
					}
				}
			}
			// Note: No empty geometries after this point!
			// Warning: Do not try clip for polylines and polygons.
			// Try clip of Envelope with Envelope.
			if ((m_dimensionMask == -1 || m_dimensionMask == (1 << 2)) && gtInput == com.epl.geometry.Geometry.GeometryType.Envelope && m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.Envelope)
			{
				com.epl.geometry.Envelope env1 = (com.epl.geometry.Envelope)input_geom;
				com.epl.geometry.Envelope env2 = (com.epl.geometry.Envelope)m_geomIntersector;
				com.epl.geometry.Envelope2D env2D_1 = new com.epl.geometry.Envelope2D();
				env1.QueryEnvelope2D(env2D_1);
				com.epl.geometry.Envelope2D env2D_2 = new com.epl.geometry.Envelope2D();
				env2.QueryEnvelope2D(env2D_2);
				env2D_1.Intersect(env2D_2);
				com.epl.geometry.Envelope result_env = new com.epl.geometry.Envelope();
				env1.CopyTo(result_env);
				result_env.SetEnvelope2D(env2D_1);
				return result_env;
			}
			// Use clip for Point and Multi_point with Envelope
			if ((gtInput == com.epl.geometry.Geometry.GeometryType.Envelope && com.epl.geometry.Geometry.GetDimensionFromType(m_geomIntersectorType) == 0) || (m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.Envelope && com.epl.geometry.Geometry.GetDimensionFromType(gtInput
				) == 0))
			{
				com.epl.geometry.Envelope env = gtInput == com.epl.geometry.Geometry.GeometryType.Envelope ? (com.epl.geometry.Envelope)input_geom : (com.epl.geometry.Envelope)m_geomIntersector;
				com.epl.geometry.Geometry other = gtInput == com.epl.geometry.Geometry.GeometryType.Envelope ? m_geomIntersector : input_geom;
				com.epl.geometry.Envelope2D env_2D = new com.epl.geometry.Envelope2D();
				env.QueryEnvelope2D(env_2D);
				return com.epl.geometry.Clipper.Clip(other, env_2D, tolerance, 0);
			}
			if ((com.epl.geometry.Geometry.GetDimensionFromType(gtInput) == 0 && com.epl.geometry.Geometry.GetDimensionFromType(m_geomIntersectorType) > 0) || (com.epl.geometry.Geometry.GetDimensionFromType(gtInput) > 0 && com.epl.geometry.Geometry.GetDimensionFromType(m_geomIntersectorType
				) == 0))
			{
				// multipoint
				// intersection
				double tolerance1 = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(m_spatial_reference, input_geom, false);
				if (gtInput == com.epl.geometry.Geometry.GeometryType.MultiPoint)
				{
					return com.epl.geometry.TopologicalOperations.Intersection((com.epl.geometry.MultiPoint)input_geom, m_geomIntersector, tolerance1);
				}
				if (gtInput == com.epl.geometry.Geometry.GeometryType.Point)
				{
					return com.epl.geometry.TopologicalOperations.Intersection((com.epl.geometry.Point)input_geom, m_geomIntersector, tolerance1);
				}
				if (m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.MultiPoint)
				{
					return com.epl.geometry.TopologicalOperations.Intersection((com.epl.geometry.MultiPoint)m_geomIntersector, input_geom, tolerance1);
				}
				if (m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.Point)
				{
					return com.epl.geometry.TopologicalOperations.Intersection((com.epl.geometry.Point)m_geomIntersector, input_geom, tolerance1);
				}
				throw com.epl.geometry.GeometryException.GeometryInternalError();
			}
			// Try Polyline vs Polygon
			if ((m_dimensionMask == -1 || m_dimensionMask == (1 << 1)) && (gtInput == com.epl.geometry.Geometry.GeometryType.Polyline) && (m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.Polygon))
			{
				return TryFastIntersectPolylinePolygon_((com.epl.geometry.Polyline)(input_geom), (com.epl.geometry.Polygon)(m_geomIntersector));
			}
			// Try Polygon vs Polyline
			if ((m_dimensionMask == -1 || m_dimensionMask == (1 << 1)) && (gtInput == com.epl.geometry.Geometry.GeometryType.Polygon) && (m_geomIntersectorType == com.epl.geometry.Geometry.GeometryType.Polyline))
			{
				return TryFastIntersectPolylinePolygon_((com.epl.geometry.Polyline)(m_geomIntersector), (com.epl.geometry.Polygon)(input_geom));
			}
			return null;
		}
        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());
            }
        }
        public static void TestEnvelope2Dintersector()
        {
            System.Collections.Generic.List <com.epl.geometry.Envelope2D> envelopes = new System.Collections.Generic.List <com.epl.geometry.Envelope2D>(0);
            com.epl.geometry.Envelope2D env0  = new com.epl.geometry.Envelope2D(2, 3, 4, 4);
            com.epl.geometry.Envelope2D env1  = new com.epl.geometry.Envelope2D(5, 13, 9, 15);
            com.epl.geometry.Envelope2D env2  = new com.epl.geometry.Envelope2D(6, 9, 11, 12);
            com.epl.geometry.Envelope2D env3  = new com.epl.geometry.Envelope2D(8, 10, 9, 17);
            com.epl.geometry.Envelope2D env4  = new com.epl.geometry.Envelope2D(11.001, 12, 14, 14);
            com.epl.geometry.Envelope2D env5  = new com.epl.geometry.Envelope2D(1, 3, 3, 4);
            com.epl.geometry.Envelope2D env6  = new com.epl.geometry.Envelope2D(0, 2, 5, 10);
            com.epl.geometry.Envelope2D env7  = new com.epl.geometry.Envelope2D(4, 7, 5, 10);
            com.epl.geometry.Envelope2D env8  = new com.epl.geometry.Envelope2D(3, 15, 15, 15);
            com.epl.geometry.Envelope2D env9  = new com.epl.geometry.Envelope2D(0, 9, 14, 9);
            com.epl.geometry.Envelope2D env10 = new com.epl.geometry.Envelope2D(0, 8.999, 14, 8.999);
            envelopes.Add(env0);
            envelopes.Add(env1);
            envelopes.Add(env2);
            envelopes.Add(env3);
            envelopes.Add(env4);
            envelopes.Add(env5);
            envelopes.Add(env6);
            envelopes.Add(env7);
            envelopes.Add(env8);
            envelopes.Add(env9);
            envelopes.Add(env10);
            com.epl.geometry.Envelope2DIntersectorImpl intersector = new com.epl.geometry.Envelope2DIntersectorImpl();
            intersector.SetTolerance(0.001);
            intersector.StartConstruction();
            for (int i = 0; i < envelopes.Count; i++)
            {
                intersector.AddEnvelope(i, envelopes[i]);
            }
            intersector.EndConstruction();
            int count = 0;

            while (intersector.Next())
            {
                int env_a = intersector.GetHandleA();
                int env_b = intersector.GetHandleB();
                count++;
                com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                env.SetCoords(envelopes[env_a]);
                env.Inflate(0.001, 0.001);
                NUnit.Framework.Assert.IsTrue(env.IsIntersecting(envelopes[env_b]));
            }
            System.Diagnostics.Debug.Assert((count == 16));
            com.epl.geometry.Envelope2DIntersectorImpl intersector2 = new com.epl.geometry.Envelope2DIntersectorImpl();
            intersector2.SetTolerance(0.0);
            intersector2.StartConstruction();
            for (int i_1 = 0; i_1 < envelopes.Count; i_1++)
            {
                intersector2.AddEnvelope(i_1, envelopes[i_1]);
            }
            intersector2.EndConstruction();
            count = 0;
            while (intersector2.Next())
            {
                int env_a = intersector2.GetHandleA();
                int env_b = intersector2.GetHandleB();
                count++;
                com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                env.SetCoords(envelopes[env_a]);
                NUnit.Framework.Assert.IsTrue(env.IsIntersecting(envelopes[env_b]));
            }
            System.Diagnostics.Debug.Assert((count == 13));
            env0 = new com.epl.geometry.Envelope2D(0, 0, 0, 10);
            env1 = new com.epl.geometry.Envelope2D(0, 10, 10, 10);
            env2 = new com.epl.geometry.Envelope2D(10, 0, 10, 10);
            env3 = new com.epl.geometry.Envelope2D(0, 0, 10, 0);
            envelopes.Clear();
            envelopes.Add(env0);
            envelopes.Add(env1);
            envelopes.Add(env2);
            envelopes.Add(env3);
            com.epl.geometry.Envelope2DIntersectorImpl intersector3 = new com.epl.geometry.Envelope2DIntersectorImpl();
            intersector3.SetTolerance(0.001);
            intersector3.StartConstruction();
            for (int i_2 = 0; i_2 < envelopes.Count; i_2++)
            {
                intersector3.AddEnvelope(i_2, envelopes[i_2]);
            }
            intersector3.EndConstruction();
            count = 0;
            while (intersector3.Next())
            {
                int env_a = intersector3.GetHandleA();
                int env_b = intersector3.GetHandleB();
                count++;
                com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                env.SetCoords(envelopes[env_a]);
                NUnit.Framework.Assert.IsTrue(env.IsIntersecting(envelopes[env_b]));
            }
            NUnit.Framework.Assert.IsTrue(count == 4);
            env0 = new com.epl.geometry.Envelope2D(0, 0, 0, 10);
            envelopes.Clear();
            envelopes.Add(env0);
            envelopes.Add(env0);
            envelopes.Add(env0);
            envelopes.Add(env0);
            com.epl.geometry.Envelope2DIntersectorImpl intersector4 = new com.epl.geometry.Envelope2DIntersectorImpl();
            intersector4.SetTolerance(0.001);
            intersector4.StartConstruction();
            for (int i_3 = 0; i_3 < envelopes.Count; i_3++)
            {
                intersector4.AddEnvelope(i_3, envelopes[i_3]);
            }
            intersector4.EndConstruction();
            count = 0;
            while (intersector4.Next())
            {
                int env_a = intersector4.GetHandleA();
                int env_b = intersector4.GetHandleB();
                count++;
                com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                env.SetCoords(envelopes[env_a]);
                NUnit.Framework.Assert.IsTrue(env.IsIntersecting(envelopes[env_b]));
            }
            System.Diagnostics.Debug.Assert((count == 6));
            env0 = new com.epl.geometry.Envelope2D(0, 10, 10, 10);
            envelopes.Clear();
            envelopes.Add(env0);
            envelopes.Add(env0);
            envelopes.Add(env0);
            envelopes.Add(env0);
            com.epl.geometry.Envelope2DIntersectorImpl intersector5 = new com.epl.geometry.Envelope2DIntersectorImpl();
            intersector5.SetTolerance(0.001);
            intersector5.StartConstruction();
            for (int i_4 = 0; i_4 < envelopes.Count; i_4++)
            {
                intersector5.AddEnvelope(i_4, envelopes[i_4]);
            }
            intersector5.EndConstruction();
            count = 0;
            while (intersector5.Next())
            {
                int env_a = intersector5.GetHandleA();
                int env_b = intersector5.GetHandleB();
                count++;
                com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                env.SetCoords(envelopes[env_a]);
                NUnit.Framework.Assert.IsTrue(env.IsIntersecting(envelopes[env_b]));
            }
            NUnit.Framework.Assert.IsTrue(count == 6);
        }
        internal static com.epl.geometry.Geometry Difference(com.epl.geometry.Geometry geometry_a, com.epl.geometry.Geometry geometry_b, com.epl.geometry.SpatialReference spatial_reference, com.epl.geometry.ProgressTracker progress_tracker)
        {
            if (geometry_a.IsEmpty() || geometry_b.IsEmpty())
            {
                return(geometry_a);
            }
            int dimension_a = geometry_a.GetDimension();
            int dimension_b = geometry_b.GetDimension();

            if (dimension_a > dimension_b)
            {
                return(geometry_a);
            }
            int type_a = geometry_a.GetType().Value();
            int type_b = geometry_b.GetType().Value();

            com.epl.geometry.Envelope2D env_a      = new com.epl.geometry.Envelope2D();
            com.epl.geometry.Envelope2D env_b      = new com.epl.geometry.Envelope2D();
            com.epl.geometry.Envelope2D env_merged = new com.epl.geometry.Envelope2D();
            geometry_a.QueryEnvelope2D(env_a);
            geometry_b.QueryEnvelope2D(env_b);
            env_merged.SetCoords(env_a);
            env_merged.Merge(env_b);
            double tolerance         = com.epl.geometry.InternalUtils.CalculateToleranceFromGeometry(spatial_reference, env_merged, false);
            double tolerance_cluster = tolerance * System.Math.Sqrt(2.0) * 1.00001;

            com.epl.geometry.Envelope2D env_a_inflated = new com.epl.geometry.Envelope2D();
            env_a_inflated.SetCoords(env_a);
            env_a_inflated.Inflate(tolerance_cluster, tolerance_cluster);
            // inflate
            // by
            // cluster
            // tolerance
            if (!env_a_inflated.IsIntersecting(env_b))
            {
                return(geometry_a);
            }
            if (dimension_a == 1 && dimension_b == 2)
            {
                return(PolylineMinusArea_(geometry_a, geometry_b, type_b, spatial_reference, progress_tracker));
            }
            if (type_a == com.epl.geometry.Geometry.GeometryType.Point)
            {
                com.epl.geometry.Geometry geometry_b_;
                if (com.epl.geometry.MultiPath.IsSegment(type_b))
                {
                    geometry_b_ = new com.epl.geometry.Polyline(geometry_b.GetDescription());
                    ((com.epl.geometry.Polyline)(geometry_b_)).AddSegment((com.epl.geometry.Segment)(geometry_b), true);
                }
                else
                {
                    geometry_b_ = geometry_b;
                }
                switch (type_b)
                {
                case com.epl.geometry.Geometry.GeometryType.Polygon:
                {
                    return(PointMinusPolygon_((com.epl.geometry.Point)(geometry_a), (com.epl.geometry.Polygon)(geometry_b_), tolerance, progress_tracker));
                }

                case com.epl.geometry.Geometry.GeometryType.Polyline:
                {
                    return(PointMinusPolyline_((com.epl.geometry.Point)(geometry_a), (com.epl.geometry.Polyline)(geometry_b_), tolerance, progress_tracker));
                }

                case com.epl.geometry.Geometry.GeometryType.MultiPoint:
                {
                    return(PointMinusMultiPoint_((com.epl.geometry.Point)(geometry_a), (com.epl.geometry.MultiPoint)(geometry_b_), tolerance, progress_tracker));
                }

                case com.epl.geometry.Geometry.GeometryType.Envelope:
                {
                    return(PointMinusEnvelope_((com.epl.geometry.Point)(geometry_a), (com.epl.geometry.Envelope)(geometry_b_), tolerance, progress_tracker));
                }

                case com.epl.geometry.Geometry.GeometryType.Point:
                {
                    return(PointMinusPoint_((com.epl.geometry.Point)(geometry_a), (com.epl.geometry.Point)(geometry_b_), tolerance, progress_tracker));
                }

                default:
                {
                    throw new System.ArgumentException();
                }
                }
            }
            else
            {
                if (type_a == com.epl.geometry.Geometry.GeometryType.MultiPoint)
                {
                    switch (type_b)
                    {
                    case com.epl.geometry.Geometry.GeometryType.Polygon:
                    {
                        return(MultiPointMinusPolygon_((com.epl.geometry.MultiPoint)(geometry_a), (com.epl.geometry.Polygon)(geometry_b), tolerance, progress_tracker));
                    }

                    case com.epl.geometry.Geometry.GeometryType.Envelope:
                    {
                        return(MultiPointMinusEnvelope_((com.epl.geometry.MultiPoint)(geometry_a), (com.epl.geometry.Envelope)(geometry_b), tolerance, progress_tracker));
                    }

                    case com.epl.geometry.Geometry.GeometryType.Point:
                    {
                        return(MultiPointMinusPoint_((com.epl.geometry.MultiPoint)(geometry_a), (com.epl.geometry.Point)(geometry_b), tolerance, progress_tracker));
                    }

                    default:
                    {
                        break;
                    }
                    }
                }
            }
            return(com.epl.geometry.TopologicalOperations.Difference(geometry_a, geometry_b, spatial_reference, progress_tracker));
        }
Exemplo n.º 22
0
        internal static com.epl.geometry.Envelope2DIntersectorImpl GetEnvelope2DIntersector(com.epl.geometry.MultiPathImpl multipathImplA, com.epl.geometry.MultiPathImpl multipathImplB, double tolerance)
        {
            com.epl.geometry.Envelope2D env_a = new com.epl.geometry.Envelope2D();
            com.epl.geometry.Envelope2D env_b = new com.epl.geometry.Envelope2D();
            multipathImplA.QueryLooseEnvelope2D(env_a);
            multipathImplB.QueryLooseEnvelope2D(env_b);
            env_a.Inflate(tolerance, tolerance);
            env_b.Inflate(tolerance, tolerance);
            com.epl.geometry.Envelope2D envInter = new com.epl.geometry.Envelope2D();
            envInter.SetCoords(env_a);
            envInter.Intersect(env_b);
            com.epl.geometry.SegmentIteratorImpl       segIterA    = multipathImplA.QuerySegmentIterator();
            com.epl.geometry.SegmentIteratorImpl       segIterB    = multipathImplB.QuerySegmentIterator();
            com.epl.geometry.Envelope2DIntersectorImpl intersector = new com.epl.geometry.Envelope2DIntersectorImpl();
            intersector.SetTolerance(tolerance);
            bool b_found_red = false;

            intersector.StartRedConstruction();
            while (segIterA.NextPath())
            {
                while (segIterA.HasNextSegment())
                {
                    com.epl.geometry.Segment segmentA = segIterA.NextSegment();
                    segmentA.QueryEnvelope2D(env_a);
                    if (!env_a.IsIntersecting(envInter))
                    {
                        continue;
                    }
                    b_found_red = true;
                    com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                    env.SetCoords(env_a);
                    intersector.AddRedEnvelope(segIterA.GetStartPointIndex(), env);
                }
            }
            intersector.EndRedConstruction();
            if (!b_found_red)
            {
                return(null);
            }
            bool b_found_blue = false;

            intersector.StartBlueConstruction();
            while (segIterB.NextPath())
            {
                while (segIterB.HasNextSegment())
                {
                    com.epl.geometry.Segment segmentB = segIterB.NextSegment();
                    segmentB.QueryEnvelope2D(env_b);
                    if (!env_b.IsIntersecting(envInter))
                    {
                        continue;
                    }
                    b_found_blue = true;
                    com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                    env.SetCoords(env_b);
                    intersector.AddBlueEnvelope(segIterB.GetStartPointIndex(), env);
                }
            }
            intersector.EndBlueConstruction();
            if (!b_found_blue)
            {
                return(null);
            }
            return(intersector);
        }
        private static int QuickTest2DEnvelopeEnvelope(com.epl.geometry.Envelope2D geomAEnv, com.epl.geometry.Envelope2D geomBEnv, double tolerance)
        {
            // firstly check for contains and within to give a chance degenerate
            // envelopes to work.
            // otherwise, if there are two degenerate envelopes that are equal,
            // Touch relation may occur.
            int res = 0;

            if (geomAEnv.Contains(geomBEnv))
            {
                res |= (int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Contains;
            }
            if (geomBEnv.Contains(geomAEnv))
            {
                res |= (int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Within;
            }
            if (res != 0)
            {
                return(res);
            }
            com.epl.geometry.Envelope2D envAMinus = geomAEnv;
            envAMinus.Inflate(-tolerance, -tolerance);
            // Envelope A interior
            com.epl.geometry.Envelope2D envBMinus = geomBEnv;
            envBMinus.Inflate(-tolerance, -tolerance);
            // Envelope B interior
            if (envAMinus.IsIntersecting(envBMinus))
            {
                com.epl.geometry.Envelope2D envAPlus = geomAEnv;
                envAPlus.Inflate(tolerance, tolerance);
                // Envelope A interior plus
                // boundary
                res = envAPlus.Contains(geomBEnv) ? (int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Contains : 0;
                com.epl.geometry.Envelope2D envBPlus = geomBEnv;
                envBPlus.Inflate(tolerance, tolerance);
                // Envelope A interior plus
                // boundary
                res |= envBPlus.Contains(geomAEnv) ? (int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Within : 0;
                if (res != 0)
                {
                    return(res);
                }
                return((int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Overlaps);
            }
            else
            {
                // Clementini's Overlap
                com.epl.geometry.Envelope2D envAPlus = geomAEnv;
                envAPlus.Inflate(tolerance, tolerance);
                // Envelope A interior plus
                // boundary
                com.epl.geometry.Envelope2D envBPlus = geomBEnv;
                envBPlus.Inflate(tolerance, tolerance);
                // Envelope A interior plus
                // boundary
                if (envAPlus.IsIntersecting(envBPlus))
                {
                    return((int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Touches);
                }
                else
                {
                    // Clementini Touch
                    return((int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Disjoint);
                }
            }
        }
Exemplo n.º 24
0
        private bool CrackBruteForce_()
        {
            com.epl.geometry.EditShape.VertexIterator iter_1 = m_shape.QueryVertexIterator(false);
            bool b_cracked = false;

            com.epl.geometry.Line       line_1    = new com.epl.geometry.Line();
            com.epl.geometry.Line       line_2    = new com.epl.geometry.Line();
            com.epl.geometry.Envelope2D seg_1_env = new com.epl.geometry.Envelope2D();
            seg_1_env.SetEmpty();
            com.epl.geometry.Envelope2D seg_2_env = new com.epl.geometry.Envelope2D();
            seg_2_env.SetEmpty();
            bool assume_intersecting = false;

            com.epl.geometry.Point helper_point = new com.epl.geometry.Point();
            com.epl.geometry.SegmentIntersector segment_intersector = new com.epl.geometry.SegmentIntersector();
            for (int vertex_1 = iter_1.Next(); vertex_1 != -1; vertex_1 = iter_1.Next())
            {
                com.epl.geometry.ProgressTracker.CheckAndThrow(m_progress_tracker);
                int GT_1 = m_shape.GetGeometryType(iter_1.CurrentGeometry());
                com.epl.geometry.Segment seg_1 = null;
                bool seg_1_zero = false;
                if (!com.epl.geometry.Geometry.IsPoint(GT_1))
                {
                    seg_1 = GetSegment_(vertex_1, line_1);
                    if (seg_1 == null)
                    {
                        continue;
                    }
                    seg_1.QueryEnvelope2D(seg_1_env);
                    seg_1_env.Inflate(m_tolerance, m_tolerance);
                    if (seg_1.IsDegenerate(m_tolerance))
                    {
                        // do not crack with
                        // degenerate segments
                        if (seg_1.IsDegenerate(0))
                        {
                            seg_1_zero = true;
                            seg_1      = null;
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
                com.epl.geometry.EditShape.VertexIterator iter_2 = m_shape.QueryVertexIterator(iter_1);
                int vertex_2 = iter_2.Next();
                if (vertex_2 != -1)
                {
                    vertex_2 = iter_2.Next();
                }
                for (; vertex_2 != -1; vertex_2 = iter_2.Next())
                {
                    int GT_2 = m_shape.GetGeometryType(iter_2.CurrentGeometry());
                    com.epl.geometry.Segment seg_2 = null;
                    bool seg_2_zero = false;
                    if (!com.epl.geometry.Geometry.IsPoint(GT_2))
                    {
                        seg_2 = GetSegment_(vertex_2, line_2);
                        if (seg_2 == null)
                        {
                            continue;
                        }
                        seg_2.QueryEnvelope2D(seg_2_env);
                        if (seg_2.IsDegenerate(m_tolerance))
                        {
                            // do not crack with
                            // degenerate segments
                            if (seg_2.IsDegenerate(0))
                            {
                                seg_2_zero = true;
                                seg_2      = null;
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }
                    int split_count_1 = 0;
                    int split_count_2 = 0;
                    if (seg_1 != null && seg_2 != null)
                    {
                        if (seg_1_env.IsIntersectingNE(seg_2_env))
                        {
                            segment_intersector.PushSegment(seg_1);
                            segment_intersector.PushSegment(seg_2);
                            segment_intersector.Intersect(m_tolerance, assume_intersecting);
                            split_count_1 = segment_intersector.GetResultSegmentCount(0);
                            split_count_2 = segment_intersector.GetResultSegmentCount(1);
                            if (split_count_1 + split_count_2 > 0)
                            {
                                m_shape.SplitSegment_(vertex_1, segment_intersector, 0, true);
                                m_shape.SplitSegment_(vertex_2, segment_intersector, 1, true);
                            }
                            segment_intersector.Clear();
                        }
                    }
                    else
                    {
                        if (seg_1 != null)
                        {
                            com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D();
                            m_shape.GetXY(vertex_2, pt);
                            if (seg_1_env.Contains(pt))
                            {
                                segment_intersector.PushSegment(seg_1);
                                m_shape.QueryPoint(vertex_2, helper_point);
                                segment_intersector.Intersect(m_tolerance, helper_point, 0, 1.0, assume_intersecting);
                                split_count_1 = segment_intersector.GetResultSegmentCount(0);
                                if (split_count_1 > 0)
                                {
                                    m_shape.SplitSegment_(vertex_1, segment_intersector, 0, true);
                                    if (seg_2_zero)
                                    {
                                        //seg_2 was zero length. Need to change all coincident points
                                        //segment at vertex_2 is dzero length, change all attached zero length segments
                                        int v_to = -1;
                                        for (int v = m_shape.GetNextVertex(vertex_2); v != -1 && v != vertex_2; v = m_shape.GetNextVertex(v))
                                        {
                                            seg_2 = GetSegment_(v, line_2);
                                            v_to  = v;
                                            if (seg_2 == null || !seg_2.IsDegenerate(0))
                                            {
                                                break;
                                            }
                                        }
                                        //change from vertex_2 to v_to (inclusive).
                                        for (int v_1 = vertex_2; v_1 != -1; v_1 = m_shape.GetNextVertex(v_1))
                                        {
                                            m_shape.SetPoint(v_1, segment_intersector.GetResultPoint());
                                            if (v_1 == v_to)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        m_shape.SetPoint(vertex_2, segment_intersector.GetResultPoint());
                                    }
                                }
                                segment_intersector.Clear();
                            }
                        }
                        else
                        {
                            if (seg_2 != null)
                            {
                                com.epl.geometry.Point2D pt = new com.epl.geometry.Point2D();
                                m_shape.GetXY(vertex_1, pt);
                                seg_2_env.Inflate(m_tolerance, m_tolerance);
                                if (seg_2_env.Contains(pt))
                                {
                                    segment_intersector.PushSegment(seg_2);
                                    m_shape.QueryPoint(vertex_1, helper_point);
                                    segment_intersector.Intersect(m_tolerance, helper_point, 0, 1.0, assume_intersecting);
                                    split_count_2 = segment_intersector.GetResultSegmentCount(0);
                                    if (split_count_2 > 0)
                                    {
                                        m_shape.SplitSegment_(vertex_2, segment_intersector, 0, true);
                                        if (seg_1_zero)
                                        {
                                            //seg_1 was zero length. Need to change all coincident points
                                            //segment at vertex_2 is dzero length, change all attached zero length segments
                                            int v_to = -1;
                                            for (int v = m_shape.GetNextVertex(vertex_1); v != -1 && v != vertex_1; v = m_shape.GetNextVertex(v))
                                            {
                                                seg_2 = GetSegment_(v, line_2);
                                                //using here seg_2 for seg_1
                                                v_to = v;
                                                if (seg_2 == null || !seg_2.IsDegenerate(0))
                                                {
                                                    break;
                                                }
                                            }
                                            //change from vertex_2 to v_to (inclusive).
                                            for (int v_1 = vertex_1; v_1 != -1; v_1 = m_shape.GetNextVertex(v_1))
                                            {
                                                m_shape.SetPoint(v_1, segment_intersector.GetResultPoint());
                                                if (v_1 == v_to)
                                                {
                                                    break;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            m_shape.SetPoint(vertex_1, segment_intersector.GetResultPoint());
                                        }
                                    }
                                    segment_intersector.Clear();
                                }
                            }
                            else
                            {
                                continue;
                            }
                        }
                    }
                    // points on points
                    if (split_count_1 + split_count_2 != 0)
                    {
                        if (split_count_1 != 0)
                        {
                            seg_1 = m_shape.GetSegment(vertex_1);
                            // reload segment
                            // after split
                            if (seg_1 == null)
                            {
                                if (!m_shape.QueryLineConnector(vertex_1, line_1))
                                {
                                    continue;
                                }
                                seg_1 = line_1;
                                line_1.QueryEnvelope2D(seg_1_env);
                            }
                            else
                            {
                                seg_1.QueryEnvelope2D(seg_1_env);
                            }
                            if (seg_1.IsDegenerate(m_tolerance))
                            {
                                // do not crack with
                                // degenerate
                                // segments
                                break;
                            }
                        }
                        b_cracked = true;
                    }
                }
            }
            return(b_cracked);
        }
Exemplo n.º 25
0
        internal static com.epl.geometry.Envelope2DIntersectorImpl GetEnvelope2DIntersectorForParts(com.epl.geometry.MultiPathImpl multipathImplA, com.epl.geometry.MultiPathImpl multipathImplB, double tolerance, bool bExteriorOnlyA, bool bExteriorOnlyB)
        {
            int type_a = multipathImplA.GetType().Value();
            int type_b = multipathImplB.GetType().Value();

            com.epl.geometry.Envelope2D env_a = new com.epl.geometry.Envelope2D();
            com.epl.geometry.Envelope2D env_b = new com.epl.geometry.Envelope2D();
            multipathImplA.QueryLooseEnvelope2D(env_a);
            multipathImplB.QueryLooseEnvelope2D(env_b);
            env_a.Inflate(tolerance, tolerance);
            env_b.Inflate(tolerance, tolerance);
            com.epl.geometry.Envelope2D envInter = new com.epl.geometry.Envelope2D();
            envInter.SetCoords(env_a);
            envInter.Intersect(env_b);
            com.epl.geometry.Envelope2DIntersectorImpl intersector = new com.epl.geometry.Envelope2DIntersectorImpl();
            intersector.SetTolerance(tolerance);
            bool b_found_red = false;

            intersector.StartRedConstruction();
            for (int ipath_a = 0, npaths = multipathImplA.GetPathCount(); ipath_a < npaths; ipath_a++)
            {
                if (bExteriorOnlyA && type_a == com.epl.geometry.Geometry.GeometryType.Polygon && !multipathImplA.IsExteriorRing(ipath_a))
                {
                    continue;
                }
                multipathImplA.QueryPathEnvelope2D(ipath_a, env_a);
                if (!env_a.IsIntersecting(envInter))
                {
                    continue;
                }
                b_found_red = true;
                intersector.AddRedEnvelope(ipath_a, env_a);
            }
            intersector.EndRedConstruction();
            if (!b_found_red)
            {
                return(null);
            }
            bool b_found_blue = false;

            intersector.StartBlueConstruction();
            for (int ipath_b = 0, npaths = multipathImplB.GetPathCount(); ipath_b < npaths; ipath_b++)
            {
                if (bExteriorOnlyB && type_b == com.epl.geometry.Geometry.GeometryType.Polygon && !multipathImplB.IsExteriorRing(ipath_b))
                {
                    continue;
                }
                multipathImplB.QueryPathEnvelope2D(ipath_b, env_b);
                if (!env_b.IsIntersecting(envInter))
                {
                    continue;
                }
                b_found_blue = true;
                intersector.AddBlueEnvelope(ipath_b, env_b);
            }
            intersector.EndBlueConstruction();
            if (!b_found_blue)
            {
                return(null);
            }
            return(intersector);
        }
Exemplo n.º 26
0
 /// <summary>Changes the dimensions of the envelope while preserving the center.</summary>
 /// <remarks>
 /// Changes the dimensions of the envelope while preserving the center. New width
 /// is Width + 2 * dx, new height is Height + 2 * dy. If the result envelope
 /// width or height becomes negative, the envelope is set to be empty.
 /// </remarks>
 /// <param name="dx">The inflation along the x-axis.</param>
 /// <param name="dy">The inflation along the y-axis.</param>
 public virtual void Inflate(double dx, double dy)
 {
     _touch();
     m_envelope.Inflate(dx, dy);
 }