//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);
        }
        internal static com.epl.geometry.QuadTreeImpl BuildQuadTree(com.epl.geometry.MultiPathImpl multipathImpl, com.epl.geometry.Envelope2D extentOfInterest)
        {
            com.epl.geometry.Envelope2D extent = new com.epl.geometry.Envelope2D();
            multipathImpl.QueryLooseEnvelope2D(extent);
            com.epl.geometry.QuadTreeImpl quad_tree_impl = new com.epl.geometry.QuadTreeImpl(extent, 8);
            int hint_index = -1;

            com.epl.geometry.Envelope2D          boundingbox = new com.epl.geometry.Envelope2D();
            com.epl.geometry.SegmentIteratorImpl seg_iter    = multipathImpl.QuerySegmentIterator();
            bool resized_extent = false;

            while (seg_iter.NextPath())
            {
                while (seg_iter.HasNextSegment())
                {
                    com.epl.geometry.Segment segment = seg_iter.NextSegment();
                    int index = seg_iter.GetStartPointIndex();
                    segment.QueryEnvelope2D(boundingbox);
                    if (boundingbox.IsIntersecting(extentOfInterest))
                    {
                        hint_index = quad_tree_impl.Insert(index, boundingbox, hint_index);
                        if (hint_index == -1)
                        {
                            if (resized_extent)
                            {
                                throw com.epl.geometry.GeometryException.GeometryInternalError();
                            }
                            // resize extent
                            multipathImpl.CalculateEnvelope2D(extent, false);
                            resized_extent = true;
                            quad_tree_impl.Reset(extent, 8);
                            seg_iter.ResetToFirstPath();
                            break;
                        }
                    }
                }
            }
            return(quad_tree_impl);
        }
        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);
        }
        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);
        }
示例#5
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 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));
        }
        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);
                }
            }
        }
示例#9
0
 public virtual bool IsIntersecting(com.epl.geometry.Envelope2D other)
 {
     return(m_envelope.IsIntersecting(other));
 }