private static int QuickTest2DMVEnvelopeRasterOnly(com.epl.geometry.MultiVertexGeometry geomA, com.epl.geometry.Envelope2D geomBEnv, double tolerance)
 {
     // Use rasterized Geometry only:
     com.epl.geometry.RasterizedGeometry2D    rgeomA;
     com.epl.geometry.MultiVertexGeometryImpl mpImpl = (com.epl.geometry.MultiVertexGeometryImpl)geomA._getImpl();
     com.epl.geometry.GeometryAccelerators    gaccel = mpImpl._getAccelerators();
     if (gaccel != null)
     {
         rgeomA = gaccel.GetRasterizedGeometry();
     }
     else
     {
         return(-1);
     }
     if (rgeomA != null)
     {
         com.epl.geometry.RasterizedGeometry2D.HitType hitres = rgeomA.QueryEnvelopeInGeometry(geomBEnv);
         if (hitres == com.epl.geometry.RasterizedGeometry2D.HitType.Outside)
         {
             return((int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Disjoint);
         }
         if (hitres == com.epl.geometry.RasterizedGeometry2D.HitType.Inside)
         {
             return((int)com.epl.geometry.OperatorInternalRelationUtils.Relation.Contains);
         }
     }
     else
     {
         return(-1);
     }
     return(0);
 }
 internal virtual void _clearAccelerators()
 {
     if (m_accelerators != null)
     {
         m_accelerators = null;
     }
 }
예제 #3
0
        internal static void TestPointsOnPolyline2D_(com.epl.geometry.Polyline poly, com.epl.geometry.Point2D[] input_points, int count, double tolerance, com.epl.geometry.PolygonUtils.PiPResult[] test_results)
        {
            com.epl.geometry.MultiPathImpl        mp_impl = (com.epl.geometry.MultiPathImpl)poly._getImpl();
            com.epl.geometry.GeometryAccelerators accel   = mp_impl._getAccelerators();
            com.epl.geometry.RasterizedGeometry2D rgeom   = null;
            if (accel != null)
            {
                rgeom = accel.GetRasterizedGeometry();
            }
            int pointsLeft = count;

            for (int i = 0; i < count; i++)
            {
                test_results[i] = com.epl.geometry.PolygonUtils.PiPResult.PiPInside;
                // set to impossible value
                if (rgeom != null)
                {
                    com.epl.geometry.Point2D input_point = input_points[i];
                    com.epl.geometry.RasterizedGeometry2D.HitType hit = rgeom.QueryPointInGeometry(input_point.x, input_point.y);
                    if (hit == com.epl.geometry.RasterizedGeometry2D.HitType.Outside)
                    {
                        test_results[i] = com.epl.geometry.PolygonUtils.PiPResult.PiPOutside;
                        pointsLeft--;
                    }
                }
            }
            if (pointsLeft != 0)
            {
                com.epl.geometry.SegmentIteratorImpl iter = mp_impl.QuerySegmentIterator();
                while (iter.NextPath() && pointsLeft != 0)
                {
                    while (iter.HasNextSegment() && pointsLeft != 0)
                    {
                        com.epl.geometry.Segment segment = iter.NextSegment();
                        for (int i_1 = 0; i_1 < count && pointsLeft != 0; i_1++)
                        {
                            if (test_results[i_1] == com.epl.geometry.PolygonUtils.PiPResult.PiPInside)
                            {
                                if (segment.IsIntersecting(input_points[i_1], tolerance))
                                {
                                    test_results[i_1] = com.epl.geometry.PolygonUtils.PiPResult.PiPBoundary;
                                    pointsLeft--;
                                }
                            }
                        }
                    }
                }
            }
            for (int i_2 = 0; i_2 < count; i_2++)
            {
                if (test_results[i_2] == com.epl.geometry.PolygonUtils.PiPResult.PiPInside)
                {
                    test_results[i_2] = com.epl.geometry.PolygonUtils.PiPResult.PiPOutside;
                }
            }
        }
예제 #4
0
 /// <summary>Removes accelerators from given geometry.</summary>
 /// <param name="geometry">The geometry instance to remove accelerators from.</param>
 public static void DeaccelerateGeometry(com.epl.geometry.Geometry geometry)
 {
     com.epl.geometry.Geometry.Type gt = geometry.GetType();
     if (com.epl.geometry.Geometry.IsMultiVertex(gt.Value()))
     {
         com.epl.geometry.GeometryAccelerators accel = ((com.epl.geometry.MultiVertexGeometryImpl)geometry._getImpl())._getAccelerators();
         if (accel != null)
         {
             accel._setRasterizedGeometry(null);
             accel._setQuadTree(null);
         }
     }
 }
 public MultiVertexGeometryImpl()
 {
     // TODO implement accelerators
     // the BBOX for all attributes
     // the number of vertices reserved and
     // initialized to default value.
     // HEADER DEFINED
     // Cpp
     // Checked vs. Jan 11, 2011
     m_flagsMask          = com.epl.geometry.MultiVertexGeometryImpl.DirtyFlags.DirtyAllInternal;
     m_pointCount         = 0;
     m_reservedPointCount = -1;
     m_accelerators       = null;
 }
 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));
 }
 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));
 }
예제 #8
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;
		}
예제 #9
0
 internal PairwiseIntersectorImpl(com.epl.geometry.MultiPathImpl multi_path_impl_a, com.epl.geometry.MultiPathImpl multi_path_impl_b, double tolerance, bool b_paths)
 {
     m_multi_path_impl_a = multi_path_impl_a;
     m_multi_path_impl_b = multi_path_impl_b;
     m_b_paths           = b_paths;
     m_path_index        = -1;
     m_b_quad_tree       = false;
     com.epl.geometry.GeometryAccelerators geometry_accelerators_a = multi_path_impl_a._getAccelerators();
     if (geometry_accelerators_a != null)
     {
         com.epl.geometry.QuadTreeImpl qtree_a = (!b_paths ? geometry_accelerators_a.GetQuadTree() : geometry_accelerators_a.GetQuadTreeForPaths());
         if (qtree_a != null)
         {
             m_b_done          = false;
             m_tolerance       = tolerance;
             m_quad_tree       = qtree_a;
             m_qt_iter         = m_quad_tree.GetIterator();
             m_b_quad_tree     = true;
             m_b_swap_elements = true;
             m_function        = com.epl.geometry.PairwiseIntersectorImpl.State.nextPath;
             if (!b_paths)
             {
                 m_seg_iter = multi_path_impl_b.QuerySegmentIterator();
             }
             else
             {
                 m_path_index = multi_path_impl_b.GetPathCount();
             }
         }
     }
     // we will iterate backwards until we hit -1
     if (!m_b_quad_tree)
     {
         com.epl.geometry.GeometryAccelerators geometry_accelerators_b = multi_path_impl_b._getAccelerators();
         if (geometry_accelerators_b != null)
         {
             com.epl.geometry.QuadTreeImpl qtree_b = (!b_paths ? geometry_accelerators_b.GetQuadTree() : geometry_accelerators_b.GetQuadTreeForPaths());
             if (qtree_b != null)
             {
                 m_b_done          = false;
                 m_tolerance       = tolerance;
                 m_quad_tree       = qtree_b;
                 m_qt_iter         = m_quad_tree.GetIterator();
                 m_b_quad_tree     = true;
                 m_b_swap_elements = false;
                 m_function        = com.epl.geometry.PairwiseIntersectorImpl.State.nextPath;
                 if (!b_paths)
                 {
                     m_seg_iter = multi_path_impl_a.QuerySegmentIterator();
                 }
                 else
                 {
                     m_path_index = multi_path_impl_a.GetPathCount();
                 }
             }
         }
     }
     // we will iterate backwards until we hit -1
     if (!m_b_quad_tree)
     {
         if (!b_paths)
         {
             m_intersector = com.epl.geometry.InternalUtils.GetEnvelope2DIntersector(multi_path_impl_a, multi_path_impl_b, tolerance);
         }
         else
         {
             bool b_simple_a = multi_path_impl_a.GetIsSimple(0.0) >= 1;
             bool b_simple_b = multi_path_impl_b.GetIsSimple(0.0) >= 1;
             m_intersector = com.epl.geometry.InternalUtils.GetEnvelope2DIntersectorForParts(multi_path_impl_a, multi_path_impl_b, tolerance, b_simple_a, b_simple_b);
         }
     }
 }