Beispiel #1
0
        // Mirrors wkt
        private static void ExportPolygonToGeoJson_(int export_flags, com.epl.geometry.Polygon polygon, com.epl.geometry.JsonWriter json_writer)
        {
            com.epl.geometry.MultiPathImpl polygon_impl = (com.epl.geometry.MultiPathImpl)(polygon._getImpl());
            if ((export_flags & com.epl.geometry.GeoJsonExportFlags.geoJsonExportFailIfNotSimple) != 0)
            {
                int simple = polygon_impl.GetIsSimple(0.0);
                if (simple != com.epl.geometry.MultiVertexGeometryImpl.GeometryXSimple.Strong)
                {
                    throw new com.epl.geometry.GeometryException("corrupted geometry");
                }
            }
            int point_count   = polygon.GetPointCount();
            int polygon_count = polygon_impl.GetOGCPolygonCount();

            if (point_count > 0 && polygon_count == 0)
            {
                throw new com.epl.geometry.GeometryException("corrupted geometry");
            }
            int  precision   = 17 - (31 & (export_flags >> 13));
            bool bFixedPoint = (com.epl.geometry.GeoJsonExportFlags.geoJsonExportPrecisionFixedPoint & export_flags) != 0;
            bool b_export_zs = polygon_impl.HasAttribute(com.epl.geometry.VertexDescription.Semantics.Z) && (export_flags & com.epl.geometry.GeoJsonExportFlags.geoJsonExportStripZs) == 0;
            bool b_export_ms = polygon_impl.HasAttribute(com.epl.geometry.VertexDescription.Semantics.M) && (export_flags & com.epl.geometry.GeoJsonExportFlags.geoJsonExportStripMs) == 0;

            if (!b_export_zs && b_export_ms)
            {
                throw new System.ArgumentException("invalid argument");
            }
            int path_count = 0;

            com.epl.geometry.AttributeStreamOfDbl   position   = null;
            com.epl.geometry.AttributeStreamOfDbl   zs         = null;
            com.epl.geometry.AttributeStreamOfDbl   ms         = null;
            com.epl.geometry.AttributeStreamOfInt8  path_flags = null;
            com.epl.geometry.AttributeStreamOfInt32 paths      = null;
            if (point_count > 0)
            {
                position   = (com.epl.geometry.AttributeStreamOfDbl)polygon_impl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION);
                path_flags = polygon_impl.GetPathFlagsStreamRef();
                paths      = polygon_impl.GetPathStreamRef();
                path_count = polygon_impl.GetPathCount();
                if (b_export_zs)
                {
                    if (polygon_impl._attributeStreamIsAllocated(com.epl.geometry.VertexDescription.Semantics.Z))
                    {
                        zs = (com.epl.geometry.AttributeStreamOfDbl)polygon_impl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.Z);
                    }
                }
                if (b_export_ms)
                {
                    if (polygon_impl._attributeStreamIsAllocated(com.epl.geometry.VertexDescription.Semantics.M))
                    {
                        ms = (com.epl.geometry.AttributeStreamOfDbl)polygon_impl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.M);
                    }
                }
            }
            if ((export_flags & com.epl.geometry.GeoJsonExportFlags.geoJsonExportPreferMultiGeometry) == 0 && polygon_count <= 1)
            {
                PolygonTaggedText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, paths, path_count, json_writer);
            }
            else
            {
                MultiPolygonTaggedText_(precision, bFixedPoint, b_export_zs, b_export_ms, zs, ms, position, path_flags, paths, polygon_count, path_count, json_writer);
            }
        }
        internal static void ExportPolygonToWkt(int export_flags, com.epl.geometry.Polygon polygon, System.Text.StringBuilder @string)
        {
            com.epl.geometry.MultiPathImpl polygon_impl = (com.epl.geometry.MultiPathImpl)polygon._getImpl();
            if ((export_flags & com.epl.geometry.WktExportFlags.wktExportFailIfNotSimple) != 0)
            {
                int simple = polygon_impl.GetIsSimple(0.0);
                if (simple != com.epl.geometry.MultiVertexGeometryImpl.GeometryXSimple.Strong)
                {
                    throw new com.epl.geometry.GeometryException("corrupted geometry");
                }
            }
            int point_count   = polygon.GetPointCount();
            int polygon_count = polygon_impl.GetOGCPolygonCount();

            if (point_count > 0 && polygon_count == 0)
            {
                throw new com.epl.geometry.GeometryException("corrupted geometry");
            }
            int  precision   = 17 - (7 & (export_flags >> 13));
            bool b_export_zs = polygon_impl.HasAttribute(com.epl.geometry.VertexDescription.Semantics.Z) && (export_flags & com.epl.geometry.WktExportFlags.wktExportStripZs) == 0;
            bool b_export_ms = polygon_impl.HasAttribute(com.epl.geometry.VertexDescription.Semantics.M) && (export_flags & com.epl.geometry.WktExportFlags.wktExportStripMs) == 0;
            int  path_count  = 0;

            com.epl.geometry.AttributeStreamOfDbl   position   = null;
            com.epl.geometry.AttributeStreamOfDbl   zs         = null;
            com.epl.geometry.AttributeStreamOfDbl   ms         = null;
            com.epl.geometry.AttributeStreamOfInt8  path_flags = null;
            com.epl.geometry.AttributeStreamOfInt32 paths      = null;
            if (point_count > 0)
            {
                position   = (com.epl.geometry.AttributeStreamOfDbl)(polygon_impl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION));
                path_flags = polygon_impl.GetPathFlagsStreamRef();
                paths      = polygon_impl.GetPathStreamRef();
                path_count = polygon_impl.GetPathCount();
                if (b_export_zs)
                {
                    if (polygon_impl._attributeStreamIsAllocated(com.epl.geometry.VertexDescription.Semantics.Z))
                    {
                        zs = (com.epl.geometry.AttributeStreamOfDbl)polygon_impl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.Z);
                    }
                }
                if (b_export_ms)
                {
                    if (polygon_impl._attributeStreamIsAllocated(com.epl.geometry.VertexDescription.Semantics.M))
                    {
                        ms = (com.epl.geometry.AttributeStreamOfDbl)polygon_impl.GetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.M);
                    }
                }
            }
            if ((export_flags & com.epl.geometry.WktExportFlags.wktExportPolygon) != 0)
            {
                if (polygon_count > 1)
                {
                    throw new System.ArgumentException("Cannot export a Polygon with specified export flags: " + export_flags);
                }
                PolygonTaggedText_(precision, b_export_zs, b_export_ms, zs, ms, position, path_flags, paths, path_count, @string);
            }
            else
            {
                MultiPolygonTaggedText_(precision, b_export_zs, b_export_ms, zs, ms, position, path_flags, paths, polygon_count, path_count, @string);
            }
        }
        public static void TestRandom()
        {
            int passcount   = 10;
            int figureSize  = 100;
            int figureSize2 = 100;

            com.epl.geometry.Envelope extent1 = new com.epl.geometry.Envelope();
            com.epl.geometry.Envelope extent2 = new com.epl.geometry.Envelope();
            com.epl.geometry.Envelope extent3 = new com.epl.geometry.Envelope();
            com.epl.geometry.Envelope extent4 = new com.epl.geometry.Envelope();
            extent1.SetCoords(-10000, 5000, 10000, 25000);
            // red
            extent2.SetCoords(-10000, 2000, 10000, 8000);
            // blue
            extent3.SetCoords(-10000, -8000, 10000, -2000);
            // blue
            extent4.SetCoords(-10000, -25000, 10000, -5000);
            // red
            com.epl.geometry.RandomCoordinateGenerator generator1 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), extent1, 0.001);
            com.epl.geometry.RandomCoordinateGenerator generator2 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), extent2, 0.001);
            com.epl.geometry.RandomCoordinateGenerator generator3 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), extent3, 0.001);
            com.epl.geometry.RandomCoordinateGenerator generator4 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figureSize, 10000), extent4, 0.001);
            System.Random random   = new System.Random(1982);
            int           rand_max = 511;
            int           qCount   = 0;
            int           eCount   = 0;
            int           bCount   = 0;

            for (int c = 0; c < passcount; c++)
            {
                com.epl.geometry.Polygon polyRed  = new com.epl.geometry.Polygon();
                com.epl.geometry.Polygon polyBlue = new com.epl.geometry.Polygon();
                int r = figureSize;
                if (r < 3)
                {
                    continue;
                }
                com.epl.geometry.Point pt;
                for (int j = 0; j < r; j++)
                {
                    int  rand       = random.Next(rand_max);
                    bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95);
                    pt = generator1.GetRandomCoord();
                    if (j == 0 || bRandomNew)
                    {
                        polyRed.StartPath(pt);
                    }
                    else
                    {
                        polyRed.LineTo(pt);
                    }
                }
                for (int j_1 = 0; j_1 < r; j_1++)
                {
                    int  rand       = random.Next(rand_max);
                    bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95);
                    pt = generator4.GetRandomCoord();
                    if (j_1 == 0 || bRandomNew)
                    {
                        polyRed.StartPath(pt);
                    }
                    else
                    {
                        polyRed.LineTo(pt);
                    }
                }
                r = figureSize2;
                if (r < 3)
                {
                    continue;
                }
                for (int j_2 = 0; j_2 < r; j_2++)
                {
                    int  rand       = random.Next(rand_max);
                    bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95);
                    pt = generator2.GetRandomCoord();
                    if (j_2 == 0 || bRandomNew)
                    {
                        polyBlue.StartPath(pt);
                    }
                    else
                    {
                        polyBlue.LineTo(pt);
                    }
                }
                for (int j_3 = 0; j_3 < r; j_3++)
                {
                    int  rand       = random.Next(rand_max);
                    bool bRandomNew = (r > 10) && ((1.0 * rand) / rand_max > 0.95);
                    pt = generator3.GetRandomCoord();
                    if (j_3 == 0 || bRandomNew)
                    {
                        polyBlue.StartPath(pt);
                    }
                    else
                    {
                        polyBlue.LineTo(pt);
                    }
                }
                com.epl.geometry.Envelope2D env = new com.epl.geometry.Envelope2D();
                // Quad_tree
                com.epl.geometry.QuadTree quadTree = BuildQuadTree(polyBlue);
                com.epl.geometry.QuadTree.QuadTreeIterator iterator    = quadTree.GetIterator();
                com.epl.geometry.SegmentIteratorImpl       _segIterRed = ((com.epl.geometry.MultiPathImpl)polyRed._getImpl()).QuerySegmentIterator();
                while (_segIterRed.NextPath())
                {
                    while (_segIterRed.HasNextSegment())
                    {
                        com.epl.geometry.Segment segmentRed = _segIterRed.NextSegment();
                        segmentRed.QueryEnvelope2D(env);
                        iterator.ResetIterator(env, 0.001);
                        while (iterator.Next() != -1)
                        {
                            qCount++;
                        }
                    }
                }
                // Envelope_2D_intersector
                System.Collections.Generic.List <com.epl.geometry.Envelope2D> envelopes_red  = new System.Collections.Generic.List <com.epl.geometry.Envelope2D>();
                System.Collections.Generic.List <com.epl.geometry.Envelope2D> envelopes_blue = new System.Collections.Generic.List <com.epl.geometry.Envelope2D>();
                com.epl.geometry.SegmentIterator segIterRed = polyRed.QuerySegmentIterator();
                while (segIterRed.NextPath())
                {
                    while (segIterRed.HasNextSegment())
                    {
                        com.epl.geometry.Segment segment = segIterRed.NextSegment();
                        env = new com.epl.geometry.Envelope2D();
                        segment.QueryEnvelope2D(env);
                        envelopes_red.Add(env);
                    }
                }
                com.epl.geometry.SegmentIterator segIterBlue = polyBlue.QuerySegmentIterator();
                while (segIterBlue.NextPath())
                {
                    while (segIterBlue.HasNextSegment())
                    {
                        com.epl.geometry.Segment segment = segIterBlue.NextSegment();
                        env = new com.epl.geometry.Envelope2D();
                        segment.QueryEnvelope2D(env);
                        envelopes_blue.Add(env);
                    }
                }
                com.epl.geometry.Envelope2DIntersectorImpl intersector = new com.epl.geometry.Envelope2DIntersectorImpl();
                intersector.SetTolerance(0.001);
                intersector.StartRedConstruction();
                for (int i = 0; i < envelopes_red.Count; i++)
                {
                    intersector.AddRedEnvelope(i, envelopes_red[i]);
                }
                intersector.EndRedConstruction();
                intersector.StartBlueConstruction();
                for (int i_1 = 0; i_1 < envelopes_blue.Count; i_1++)
                {
                    intersector.AddBlueEnvelope(i_1, envelopes_blue[i_1]);
                }
                intersector.EndBlueConstruction();
                while (intersector.Next())
                {
                    eCount++;
                }
                NUnit.Framework.Assert.IsTrue(qCount == eCount);
            }
        }
Beispiel #4
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;
		}
Beispiel #5
0
        /// <summary>Tests if Point is inside the Polygon's ring.</summary>
        /// <remarks>
        /// Tests if Point is inside the Polygon's ring. Returns PiPOutside if not in
        /// ring, PiPInside if in the ring, PiPBoundary is if on the border. It tests
        /// border only if the tolerance is greater than 0, otherwise PiPBoundary cannot be
        /// returned. Note: If the tolerance is not 0, the test is more expensive
        /// because it calculates closest distance from a point to each segment.
        /// O(n) complexity, where n is the number of ring segments.
        /// </remarks>
        public static com.epl.geometry.PolygonUtils.PiPResult IsPointInRing2D(com.epl.geometry.Polygon polygon, int iRing, com.epl.geometry.Point2D inputPoint, double tolerance)
        {
            com.epl.geometry.MultiPathImpl polygonImpl = (com.epl.geometry.MultiPathImpl)polygon._getImpl();
            int res = com.epl.geometry.PointInPolygonHelper.IsPointInRing(polygonImpl, iRing, inputPoint, tolerance, null);

            if (res == 0)
            {
                return(com.epl.geometry.PolygonUtils.PiPResult.PiPOutside);
            }
            if (res == 1)
            {
                return(com.epl.geometry.PolygonUtils.PiPResult.PiPInside);
            }
            // return PiPResult.PiPBoundary;
            return(com.epl.geometry.PolygonUtils.PiPResult.PiPInside);
        }
        internal static com.epl.geometry.Geometry PolylineMinusArea_(com.epl.geometry.Geometry geometry, com.epl.geometry.Geometry area, int area_type, com.epl.geometry.SpatialReference sr, com.epl.geometry.ProgressTracker progress_tracker)
        {
            // construct the complement of the Polygon (or Envelope)
            com.epl.geometry.Envelope envelope = new com.epl.geometry.Envelope();
            geometry.QueryEnvelope(envelope);
            com.epl.geometry.Envelope2D env_2D = new com.epl.geometry.Envelope2D();
            area.QueryEnvelope2D(env_2D);
            envelope.Merge(env_2D);
            double dw = 0.1 * envelope.GetWidth();
            double dh = 0.1 * envelope.GetHeight();

            envelope.Inflate(dw, dh);
            com.epl.geometry.Polygon complement = new com.epl.geometry.Polygon();
            complement.AddEnvelope(envelope, false);
            com.epl.geometry.MultiPathImpl complementImpl = (com.epl.geometry.MultiPathImpl)(complement._getImpl());
            if (area_type == com.epl.geometry.Geometry.GeometryType.Polygon)
            {
                com.epl.geometry.MultiPathImpl polygonImpl = (com.epl.geometry.MultiPathImpl)(area._getImpl());
                complementImpl.Add(polygonImpl, true);
            }
            else
            {
                complementImpl.AddEnvelope((com.epl.geometry.Envelope)(area), true);
            }
            com.epl.geometry.OperatorFactoryLocal projEnv = com.epl.geometry.OperatorFactoryLocal.GetInstance();
            com.epl.geometry.OperatorIntersection operatorIntersection = (com.epl.geometry.OperatorIntersection)projEnv.GetOperator(com.epl.geometry.Operator.Type.Intersection);
            com.epl.geometry.Geometry             difference           = operatorIntersection.Execute(geometry, complement, sr, progress_tracker);
            return(difference);
        }
Beispiel #7
0
        public static void TestQuadTreeWithDuplicates()
        {
            int pass_count   = 10;
            int figure_size  = 400;
            int figure_size2 = 100;

            com.epl.geometry.Envelope extent1 = new com.epl.geometry.Envelope();
            extent1.SetCoords(-100000, -100000, 100000, 100000);
            com.epl.geometry.RandomCoordinateGenerator generator1 = new com.epl.geometry.RandomCoordinateGenerator(System.Math.Max(figure_size, 10000), extent1, 0.001);
            System.Random random   = new System.Random(2013);
            int           rand_max = 32;

            com.epl.geometry.Polygon poly_red  = new com.epl.geometry.Polygon();
            com.epl.geometry.Polygon poly_blue = new com.epl.geometry.Polygon();
            int r = figure_size;

            for (int c = 0; c < pass_count; c++)
            {
                com.epl.geometry.Point pt;
                for (int j = 0; j < r; j++)
                {
                    int  rand         = random.Next(rand_max);
                    bool b_random_new = r > 10 && ((1.0 * rand) / rand_max > 0.95);
                    pt = generator1.GetRandomCoord();
                    if (j == 0 || b_random_new)
                    {
                        poly_blue.StartPath(pt);
                    }
                    else
                    {
                        poly_blue.LineTo(pt);
                    }
                }
                com.epl.geometry.Envelope2D env                       = new com.epl.geometry.Envelope2D();
                com.epl.geometry.QuadTree   quad_tree_blue            = BuildQuadTree_((com.epl.geometry.MultiPathImpl)poly_blue._getImpl(), false);
                com.epl.geometry.QuadTree   quad_tree_blue_duplicates = BuildQuadTree_((com.epl.geometry.MultiPathImpl)poly_blue._getImpl(), true);
                com.epl.geometry.Envelope2D e1 = quad_tree_blue.GetDataExtent();
                com.epl.geometry.Envelope2D e2 = quad_tree_blue_duplicates.GetDataExtent();
                NUnit.Framework.Assert.IsTrue(e1.Equals(e2));
                NUnit.Framework.Assert.IsTrue(quad_tree_blue.GetElementCount() == poly_blue.GetSegmentCount());
                com.epl.geometry.SegmentIterator seg_iter_blue = poly_blue.QuerySegmentIterator();
                poly_red.SetEmpty();
                r = figure_size2;
                if (r < 3)
                {
                    continue;
                }
                for (int j_1 = 0; j_1 < r; j_1++)
                {
                    int  rand         = random.Next(rand_max);
                    bool b_random_new = r > 10 && ((1.0 * rand) / rand_max > 0.95);
                    pt = generator1.GetRandomCoord();
                    if (j_1 == 0 || b_random_new)
                    {
                        poly_red.StartPath(pt);
                    }
                    else
                    {
                        poly_red.LineTo(pt);
                    }
                }
                com.epl.geometry.QuadTree.QuadTreeIterator        iterator     = quad_tree_blue.GetIterator();
                com.epl.geometry.SegmentIteratorImpl              seg_iter_red = ((com.epl.geometry.MultiPathImpl)poly_red._getImpl()).QuerySegmentIterator();
                System.Collections.Generic.Dictionary <int, bool> map1         = new System.Collections.Generic.Dictionary <int, bool>(0);
                int count = 0;
                int intersections_per_query = 0;
                while (seg_iter_red.NextPath())
                {
                    while (seg_iter_red.HasNextSegment())
                    {
                        com.epl.geometry.Segment segment_red = seg_iter_red.NextSegment();
                        segment_red.QueryEnvelope2D(env);
                        iterator.ResetIterator(env, 0.0);
                        int count_upper = 0;
                        int element_handle;
                        while ((element_handle = iterator.Next()) != -1)
                        {
                            count_upper++;
                            int  index = quad_tree_blue.GetElement(element_handle);
                            bool iter  = map1.ContainsKey(index);
                            if (!iter)
                            {
                                count++;
                                map1[index] = true;
                            }
                            intersections_per_query++;
                        }
                        int intersection_count = quad_tree_blue.GetIntersectionCount(env, 0.0, -1);
                        NUnit.Framework.Assert.IsTrue(intersection_count == count_upper);
                    }
                }
                seg_iter_red.ResetToFirstPath();
                System.Collections.Generic.Dictionary <int, bool> map2 = new System.Collections.Generic.Dictionary <int, bool>(0);
                com.epl.geometry.QuadTree.QuadTreeIterator        iterator_duplicates = quad_tree_blue_duplicates.GetIterator();
                int count_duplicates = 0;
                int intersections_per_query_duplicates = 0;
                while (seg_iter_red.NextPath())
                {
                    while (seg_iter_red.HasNextSegment())
                    {
                        com.epl.geometry.Segment segment_red = seg_iter_red.NextSegment();
                        segment_red.QueryEnvelope2D(env);
                        iterator_duplicates.ResetIterator(env, 0.0);
                        int count_lower = 0;
                        System.Collections.Generic.Dictionary <int, bool> map_per_query = new System.Collections.Generic.Dictionary <int, bool>(0);
                        int count_upper = 0;
                        int element_handle;
                        while ((element_handle = iterator_duplicates.Next()) != -1)
                        {
                            count_upper++;
                            int  index = quad_tree_blue_duplicates.GetElement(element_handle);
                            bool iter  = map2.ContainsKey(index);
                            if (!iter)
                            {
                                count_duplicates++;
                                map2[index] = true;
                            }
                            bool iter_lower = map_per_query.ContainsKey(index);
                            if (!iter_lower)
                            {
                                count_lower++;
                                intersections_per_query_duplicates++;
                                map_per_query[index] = true;
                            }
                            int q = quad_tree_blue_duplicates.GetQuad(element_handle);
                            NUnit.Framework.Assert.IsTrue(quad_tree_blue_duplicates.GetSubTreeElementCount(q) >= quad_tree_blue_duplicates.GetContainedSubTreeElementCount(q));
                        }
                        int  intersection_count = quad_tree_blue_duplicates.GetIntersectionCount(env, 0.0, -1);
                        bool b_has_data         = quad_tree_blue_duplicates.HasData(env, 0.0);
                        NUnit.Framework.Assert.IsTrue(b_has_data || intersection_count == 0);
                        NUnit.Framework.Assert.IsTrue(count_lower <= intersection_count && intersection_count <= count_upper);
                        NUnit.Framework.Assert.IsTrue(count_upper <= 4 * count_lower);
                    }
                }
                NUnit.Framework.Assert.IsTrue(count == count_duplicates);
                NUnit.Framework.Assert.IsTrue(intersections_per_query == intersections_per_query_duplicates);
            }
        }
        internal static com.epl.geometry.Geometry PolygonTaggedText(bool b_multi_polygon, int import_flags, com.epl.geometry.WktParser wkt_parser)
        {
            com.epl.geometry.MultiPath              multi_path;
            com.epl.geometry.MultiPathImpl          multi_path_impl;
            com.epl.geometry.AttributeStreamOfDbl   zs = null;
            com.epl.geometry.AttributeStreamOfDbl   ms = null;
            com.epl.geometry.AttributeStreamOfDbl   position;
            com.epl.geometry.AttributeStreamOfInt32 paths;
            com.epl.geometry.AttributeStreamOfInt8  path_flags;
            position        = (com.epl.geometry.AttributeStreamOfDbl)com.epl.geometry.AttributeStreamBase.CreateDoubleStream(0);
            paths           = (com.epl.geometry.AttributeStreamOfInt32)com.epl.geometry.AttributeStreamBase.CreateIndexStream(1, 0);
            path_flags      = (com.epl.geometry.AttributeStreamOfInt8)com.epl.geometry.AttributeStreamBase.CreateByteStream(1, unchecked ((byte)0));
            multi_path      = new com.epl.geometry.Polygon();
            multi_path_impl = (com.epl.geometry.MultiPathImpl)multi_path._getImpl();
            int current_token = wkt_parser.NextToken();

            if (current_token == com.epl.geometry.WktParser.WktToken.attribute_z)
            {
                zs = (com.epl.geometry.AttributeStreamOfDbl)com.epl.geometry.AttributeStreamBase.CreateDoubleStream(0, com.epl.geometry.NumberUtils.TheNaN);
                multi_path_impl.AddAttribute(com.epl.geometry.VertexDescription.Semantics.Z);
                wkt_parser.NextToken();
            }
            else
            {
                if (current_token == com.epl.geometry.WktParser.WktToken.attribute_m)
                {
                    ms = (com.epl.geometry.AttributeStreamOfDbl)com.epl.geometry.AttributeStreamBase.CreateDoubleStream(0, com.epl.geometry.NumberUtils.TheNaN);
                    multi_path_impl.AddAttribute(com.epl.geometry.VertexDescription.Semantics.M);
                    wkt_parser.NextToken();
                }
                else
                {
                    if (current_token == com.epl.geometry.WktParser.WktToken.attribute_zm)
                    {
                        zs = (com.epl.geometry.AttributeStreamOfDbl)com.epl.geometry.AttributeStreamBase.CreateDoubleStream(0, com.epl.geometry.NumberUtils.TheNaN);
                        ms = (com.epl.geometry.AttributeStreamOfDbl)com.epl.geometry.AttributeStreamBase.CreateDoubleStream(0, com.epl.geometry.NumberUtils.TheNaN);
                        multi_path_impl.AddAttribute(com.epl.geometry.VertexDescription.Semantics.Z);
                        multi_path_impl.AddAttribute(com.epl.geometry.VertexDescription.Semantics.M);
                        wkt_parser.NextToken();
                    }
                }
            }
            int point_count;

            if (b_multi_polygon)
            {
                point_count = MultiPolygonText(zs, ms, position, paths, path_flags, wkt_parser);
            }
            else
            {
                point_count = PolygonText(zs, ms, position, paths, path_flags, 0, wkt_parser);
            }
            if (point_count != 0)
            {
                System.Diagnostics.Debug.Assert((2 * point_count == position.Size()));
                multi_path_impl.SetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.POSITION, position);
                multi_path_impl.SetPathStreamRef(paths);
                multi_path_impl.SetPathFlagsStreamRef(path_flags);
                if (zs != null)
                {
                    multi_path_impl.SetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.Z, zs);
                }
                if (ms != null)
                {
                    multi_path_impl.SetAttributeStreamRef(com.epl.geometry.VertexDescription.Semantics.M, ms);
                }
                multi_path_impl.NotifyModified(com.epl.geometry.MultiVertexGeometryImpl.DirtyFlags.DirtyAll);
                com.epl.geometry.AttributeStreamOfInt8 path_flags_clone = new com.epl.geometry.AttributeStreamOfInt8(path_flags);
                for (int i = 0; i < path_flags_clone.Size() - 1; i++)
                {
                    if (((int)path_flags_clone.Read(i) & (int)com.epl.geometry.PathFlags.enumOGCStartPolygon) != 0)
                    {
                        // Should
                        // be
                        // clockwise
                        if (!com.epl.geometry.InternalUtils.IsClockwiseRing(multi_path_impl, i))
                        {
                            multi_path_impl.ReversePath(i);
                        }
                    }
                    else
                    {
                        // make clockwise
                        // Should be counter-clockwise
                        if (com.epl.geometry.InternalUtils.IsClockwiseRing(multi_path_impl, i))
                        {
                            multi_path_impl.ReversePath(i);
                        }
                    }
                }
                // make
                // counter-clockwise
                multi_path_impl.SetPathFlagsStreamRef(path_flags_clone);
            }
            if ((import_flags & (int)com.epl.geometry.WktImportFlags.wktImportNonTrusted) == 0)
            {
                multi_path_impl.SetIsSimple(com.epl.geometry.MultiVertexGeometryImpl.GeometryXSimple.Weak, 0.0, false);
            }
            multi_path_impl.SetDirtyOGCFlags(false);
            return(multi_path);
        }
        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());
        }
 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));
 }
 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));
 }
        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());
        }
        private static int _isPointInPolygonInternal(com.epl.geometry.Polygon inputPolygon, com.epl.geometry.Point2D inputPoint, double 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();
            while (iter.NextPath())
            {
                while (iter.HasNextSegment())
                {
                    com.epl.geometry.Segment segment = iter.NextSegment();
                    if (helper.ProcessSegment(segment))
                    {
                        return(-1);
                    }
                }
            }
            // point on boundary
            return(helper.Result());
        }